add global config
This commit is contained in:
34
README.md
34
README.md
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
使用 Vue 、ts 和 Vite 创建 kintone plugin 的初始化模板,先由 [create-plugin](https://cybozu.dev/ja/kintone/sdk/development-environment/create-plugin/) 生成之后再手动引入 Vue。
|
使用 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/
|
> プラグイン開発手順: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
|
```diff
|
||||||
function purchaseLicense() {
|
{
|
||||||
// ...
|
"license": {
|
||||||
+ window.open(`修改购买页面,或者重用也不是不可以`)
|
"enabled": true, // 是否开启 License 检查
|
||||||
- window.open(`https://alisurvey.alicorns.co.jp/s/Iuc5RxZv?${queryParams}`);
|
"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 // 进行提醒的剩余天数
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import { useI18n } from 'vue-i18n';
|
|||||||
import { LicenseService } from '@/services/license-service';
|
import { LicenseService } from '@/services/license-service';
|
||||||
import type { LicenseInfo } from '@/types/license';
|
import type { LicenseInfo } from '@/types/license';
|
||||||
import { LicenseStorage } from '@/utils/license-storage';
|
import { LicenseStorage } from '@/utils/license-storage';
|
||||||
|
import config from '@/config.json';
|
||||||
|
|
||||||
const { t: $t } = useI18n();// 配置国际化
|
const { t: $t } = useI18n();// 配置国际化
|
||||||
|
|
||||||
@@ -65,6 +66,13 @@ const licenseDisplayInfo = computed<LicenseDisplayInfo>(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
if (!config.license.enabled) {
|
||||||
|
// 许可证功能未启用,不显示组件
|
||||||
|
shown.value = false;
|
||||||
|
loading.value = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const result = await LicenseService.checkLicense();
|
const result = await LicenseService.checkLicense();
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||||
licenseInfo.value = result.license;
|
licenseInfo.value = result.license;
|
||||||
@@ -144,10 +152,10 @@ function purchaseLicense() {
|
|||||||
const pluginId = licenseInfo.value?.pluginId;
|
const pluginId = licenseInfo.value?.pluginId;
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
name: { inputId: 'input1761283314263', value: name },
|
name: { inputId: config.license.purchase.formIds.name, value: name },
|
||||||
email: { inputId: 'input1761283275767', value: email },
|
email: { inputId: config.license.purchase.formIds.email, value: email },
|
||||||
domain: { inputId: 'input1761283180784', value: domain },
|
domain: { inputId: config.license.purchase.formIds.domain, value: domain },
|
||||||
pluginId: { inputId: 'input1761283200616', value: pluginId }
|
pluginId: { inputId: config.license.purchase.formIds.pluginId, value: pluginId }
|
||||||
};
|
};
|
||||||
|
|
||||||
const queryParams = Object.values(params)
|
const queryParams = Object.values(params)
|
||||||
@@ -155,7 +163,7 @@ function purchaseLicense() {
|
|||||||
.map(param => `${param.inputId}=${encodeURIComponent(param.value as string)}`)
|
.map(param => `${param.inputId}=${encodeURIComponent(param.value as string)}`)
|
||||||
.join('&');
|
.join('&');
|
||||||
|
|
||||||
window.open(`https://alisurvey.alicorns.co.jp/s/Iuc5RxZv?${queryParams}`);
|
window.open(`${config.license.purchase.url}?${queryParams}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function hidePaidMsg() {
|
function hidePaidMsg() {
|
||||||
|
|||||||
19
src/config.json
Normal file
19
src/config.json
Normal file
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,12 +7,12 @@ import { MobileNotification } from 'kintone-ui-component/lib/mobile/notification
|
|||||||
import manifestJson from '@/manifest.json';
|
import manifestJson from '@/manifest.json';
|
||||||
import { KJUR } from 'jsrsasign';
|
import { KJUR } from 'jsrsasign';
|
||||||
import rsaPublicKey from '../../rsa_public.pem?raw';
|
import rsaPublicKey from '../../rsa_public.pem?raw';
|
||||||
|
import config from '@/config.json';
|
||||||
|
|
||||||
const { t: $t } = i18n.global;
|
const { t: $t } = i18n.global;
|
||||||
|
|
||||||
export class LicenseService {
|
export class LicenseService {
|
||||||
// 常量定义
|
// 常量定义
|
||||||
private static readonly WARNING_DAYS_BEFORE_EXPIRY = 7;
|
|
||||||
private static PLUGIN_ID: string = '';
|
private static PLUGIN_ID: string = '';
|
||||||
// ============ 基础工具函数 ============
|
// ============ 基础工具函数 ============
|
||||||
|
|
||||||
@@ -97,6 +97,12 @@ export class LicenseService {
|
|||||||
* 许可证验证
|
* 许可证验证
|
||||||
*/
|
*/
|
||||||
static async checkLicense(): Promise<LicenseCheckResult> {
|
static async checkLicense(): Promise<LicenseCheckResult> {
|
||||||
|
if (!config.license.enabled || rsaPublicKey.trim() === '') {
|
||||||
|
return {
|
||||||
|
isLicenseValid: true,
|
||||||
|
license: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
const localLicense = this.getLocalLicenseInfo() || undefined;
|
const localLicense = this.getLocalLicenseInfo() || undefined;
|
||||||
if (localLicense) {
|
if (localLicense) {
|
||||||
return {
|
return {
|
||||||
@@ -111,13 +117,13 @@ export class LicenseService {
|
|||||||
* 调用远程许可证API
|
* 调用远程许可证API
|
||||||
*/
|
*/
|
||||||
private static async callRemoteLicenseAPI(domain: string, pluginId: string): Promise<string | null> {
|
private static async callRemoteLicenseAPI(domain: string, pluginId: string): Promise<string | null> {
|
||||||
const url = 'https://kintone.alicorns.co.jp/api/license/check';
|
const url = config.license.api.checkUrl;
|
||||||
const method = 'POST';
|
const method = 'POST';
|
||||||
const headers = { 'Content-Type': 'application/json' };
|
const headers = { 'Content-Type': 'application/json' };
|
||||||
const body = {
|
const body = {
|
||||||
domain,
|
domain,
|
||||||
pluginId,
|
pluginId,
|
||||||
pluginKey: 'kintone-vue-template',
|
pluginKey: config.license.api.pluginKey,
|
||||||
};
|
};
|
||||||
const proxyResponse = await kintone.proxy(url, method, headers, body);
|
const proxyResponse = await kintone.proxy(url, method, headers, body);
|
||||||
if (proxyResponse[1] !== 200) {
|
if (proxyResponse[1] !== 200) {
|
||||||
@@ -180,7 +186,7 @@ export class LicenseService {
|
|||||||
*/
|
*/
|
||||||
static isExpiringSoon(expiryTimestamp: number): boolean {
|
static isExpiringSoon(expiryTimestamp: number): boolean {
|
||||||
const now = Date.now();
|
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;
|
return now >= warningTime && expiryTimestamp > now;
|
||||||
}
|
}
|
||||||
@@ -247,6 +253,12 @@ export class LicenseService {
|
|||||||
static async loadPluginIfAuthorized(pluginId: string, callback: () => void | Promise<void>) {
|
static async loadPluginIfAuthorized(pluginId: string, callback: () => void | Promise<void>) {
|
||||||
this.PLUGIN_ID = pluginId;
|
this.PLUGIN_ID = pluginId;
|
||||||
try {
|
try {
|
||||||
|
if (!config.license.enabled) {
|
||||||
|
// 许可证功能未启用,直接加载插件
|
||||||
|
await callback();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 检查许可证(内部已经包含本地检查无效时自动获取远程的逻辑)
|
// 检查许可证(内部已经包含本地检查无效时自动获取远程的逻辑)
|
||||||
const licenseCheck = await this.checkLicense();
|
const licenseCheck = await this.checkLicense();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user