From 63a2cfc18624035e52cf769d898358eb98cb10da Mon Sep 17 00:00:00 2001 From: xuejiahao Date: Mon, 3 Nov 2025 10:24:13 +0800 Subject: [PATCH] add global config --- README.md | 34 +++++++++++++++++++++++++------- src/components/LicenseStatus.vue | 18 ++++++++++++----- src/config.json | 19 ++++++++++++++++++ src/services/license-service.ts | 20 +++++++++++++++---- 4 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 src/config.json diff --git a/README.md b/README.md index 602456f..e0d2b27 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ 使用 Vue 、ts 和 Vite 创建 kintone plugin 的初始化模板,先由 [create-plugin](https://cybozu.dev/ja/kintone/sdk/development-environment/create-plugin/) 生成之后再手动引入 Vue。 -并且提供了 [License 检查](#License-检查) 的功能。 +并且提供了 [License 检查](#license-检查) 的功能。 > プラグイン開発手順:https://cybozu.dev/ja/kintone/tips/development/plugins/development-plugin/ @@ -78,15 +78,35 @@ npm install # 或 yarn } ``` -3. 如果需要使用 License 检查,请参考: [License 检查](#License-检查) +3. 如果需要使用 License 检查,请参考: [License 检查](#license-检查) -一般需要修改 `LicenseStatus.vue` 里面的 `purchaseLicense()` 中打开的链接。 +需要修改 `src/config.json`: ```diff -function purchaseLicense() { - // ... -+ window.open(`修改购买页面,或者重用也不是不可以`) -- window.open(`https://alisurvey.alicorns.co.jp/s/Iuc5RxZv?${queryParams}`); +{ + "license": { + "enabled": true, // 是否开启 License 检查 + "api": { + "checkUrl": "https://kintone.alicorns.co.jp/api/license/check", // server 路径,一般不需要修改 ++ "pluginKey": 插件的 id,需要和后端数据库中保持一致 +- "pluginKey": "kintone-vue-template" + }, + "purchase": { ++ "url": 购买页面打开的链接 +- "url": "https://alisurvey.alicorns.co.jp/s/Iuc5RxZv", + "formIds": { ++ "name": 表单中存储申请人的名字的 field id, 会设置为 kintone 的登陆用户名,为空就跳过 +- "name": "input1761283314263", ++ "email": 表单中存储申请人 email 的 field id, 会设置为 kintone 的登陆邮箱,为空就跳过 +- "email": "input1761283275767", ++ "domain": 表单中存储用户 url domain 的 field id, 会设置为 url +- "domain": "input1761283180784", ++ "pluginId": 表单中存储用户 plugin id 的 field id, 会设置为 plugin id +- "pluginId": "input1761283200616" + } + }, + "warningDaysBeforeExpiry": 7 // 进行提醒的剩余天数 + } } ``` diff --git a/src/components/LicenseStatus.vue b/src/components/LicenseStatus.vue index e01fbda..a9e7c30 100644 --- a/src/components/LicenseStatus.vue +++ b/src/components/LicenseStatus.vue @@ -28,6 +28,7 @@ import { useI18n } from 'vue-i18n'; import { LicenseService } from '@/services/license-service'; import type { LicenseInfo } from '@/types/license'; import { LicenseStorage } from '@/utils/license-storage'; +import config from '@/config.json'; const { t: $t } = useI18n();// 配置国际化 @@ -65,6 +66,13 @@ const licenseDisplayInfo = computed(() => { }); onMounted(async () => { + if (!config.license.enabled) { + // 许可证功能未启用,不显示组件 + shown.value = false; + loading.value = false; + return; + } + const result = await LicenseService.checkLicense(); await new Promise((resolve) => setTimeout(resolve, 500)); licenseInfo.value = result.license; @@ -144,10 +152,10 @@ function purchaseLicense() { const pluginId = licenseInfo.value?.pluginId; const params = { - name: { inputId: 'input1761283314263', value: name }, - email: { inputId: 'input1761283275767', value: email }, - domain: { inputId: 'input1761283180784', value: domain }, - pluginId: { inputId: 'input1761283200616', value: pluginId } + name: { inputId: config.license.purchase.formIds.name, value: name }, + email: { inputId: config.license.purchase.formIds.email, value: email }, + domain: { inputId: config.license.purchase.formIds.domain, value: domain }, + pluginId: { inputId: config.license.purchase.formIds.pluginId, value: pluginId } }; const queryParams = Object.values(params) @@ -155,7 +163,7 @@ function purchaseLicense() { .map(param => `${param.inputId}=${encodeURIComponent(param.value as string)}`) .join('&'); - window.open(`https://alisurvey.alicorns.co.jp/s/Iuc5RxZv?${queryParams}`); + window.open(`${config.license.purchase.url}?${queryParams}`); } function hidePaidMsg() { diff --git a/src/config.json b/src/config.json new file mode 100644 index 0000000..672ff8f --- /dev/null +++ b/src/config.json @@ -0,0 +1,19 @@ +{ + "license": { + "enabled": true, + "api": { + "checkUrl": "https://kintone.alicorns.co.jp/api/license/check", + "pluginKey": "kintone-vue-template" + }, + "purchase": { + "url": "https://alisurvey.alicorns.co.jp/s/Iuc5RxZv", + "formIds": { + "name": "input1761283314263", + "email": "input1761283275767", + "domain": "input1761283180784", + "pluginId": "input1761283200616" + } + }, + "warningDaysBeforeExpiry": 7 + } +} diff --git a/src/services/license-service.ts b/src/services/license-service.ts index e78bdbf..87851e4 100644 --- a/src/services/license-service.ts +++ b/src/services/license-service.ts @@ -7,12 +7,12 @@ import { MobileNotification } from 'kintone-ui-component/lib/mobile/notification import manifestJson from '@/manifest.json'; import { KJUR } from 'jsrsasign'; import rsaPublicKey from '../../rsa_public.pem?raw'; +import config from '@/config.json'; const { t: $t } = i18n.global; export class LicenseService { // 常量定义 - private static readonly WARNING_DAYS_BEFORE_EXPIRY = 7; private static PLUGIN_ID: string = ''; // ============ 基础工具函数 ============ @@ -97,6 +97,12 @@ export class LicenseService { * 许可证验证 */ static async checkLicense(): Promise { + if (!config.license.enabled || rsaPublicKey.trim() === '') { + return { + isLicenseValid: true, + license: undefined, + }; + } const localLicense = this.getLocalLicenseInfo() || undefined; if (localLicense) { return { @@ -111,13 +117,13 @@ export class LicenseService { * 调用远程许可证API */ private static async callRemoteLicenseAPI(domain: string, pluginId: string): Promise { - const url = 'https://kintone.alicorns.co.jp/api/license/check'; + const url = config.license.api.checkUrl; const method = 'POST'; const headers = { 'Content-Type': 'application/json' }; const body = { domain, pluginId, - pluginKey: 'kintone-vue-template', + pluginKey: config.license.api.pluginKey, }; const proxyResponse = await kintone.proxy(url, method, headers, body); if (proxyResponse[1] !== 200) { @@ -180,7 +186,7 @@ export class LicenseService { */ static isExpiringSoon(expiryTimestamp: number): boolean { const now = Date.now(); - const warningTime = expiryTimestamp - this.WARNING_DAYS_BEFORE_EXPIRY * 24 * 60 * 60 * 1000; + const warningTime = expiryTimestamp - config.license.warningDaysBeforeExpiry * 24 * 60 * 60 * 1000; return now >= warningTime && expiryTimestamp > now; } @@ -247,6 +253,12 @@ export class LicenseService { static async loadPluginIfAuthorized(pluginId: string, callback: () => void | Promise) { this.PLUGIN_ID = pluginId; try { + if (!config.license.enabled) { + // 许可证功能未启用,直接加载插件 + await callback(); + return; + } + // 检查许可证(内部已经包含本地检查无效时自动获取远程的逻辑) const licenseCheck = await this.checkLicense();