fix i18n
This commit is contained in:
@@ -11,8 +11,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="action-area">
|
<div class="action-area">
|
||||||
<kuc-button text="キャンセル" type="normal" @click="cancel" />
|
<kuc-button :text="$t('config.cancel')" type="normal" @click="cancel" />
|
||||||
<kuc-button text="保存する" class="save-btn" type="submit" @click="save" />
|
<kuc-button :text="$t('config.save')" class="save-btn" type="submit" @click="save" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 必须使用 v-show 让 spinner dom 创建的时候不显示 -->
|
<!-- 必须使用 v-show 让 spinner dom 创建的时候不显示 -->
|
||||||
@@ -54,11 +54,14 @@ onMounted(async () => {
|
|||||||
const savedSetting = kintone.plugin.app.getConfig(props.pluginId);
|
const savedSetting = kintone.plugin.app.getConfig(props.pluginId);
|
||||||
setting.buttonName = savedSetting?.buttonName || $t('config.button.default');
|
setting.buttonName = savedSetting?.buttonName || $t('config.button.default');
|
||||||
setting.message = savedSetting?.message || $t('config.message.default');
|
setting.message = savedSetting?.message || $t('config.message.default');
|
||||||
|
|
||||||
|
// 测试 KintoneRestAPIClient
|
||||||
const { plugins } = await client.app.getPlugins({
|
const { plugins } = await client.app.getPlugins({
|
||||||
app: kintone.app.getId() as number,
|
app: kintone.app.getId() as number,
|
||||||
});
|
});
|
||||||
const pluginsInfo = plugins.map((p: any) => p.name).join(';show');
|
const pluginsInfo = plugins.map((p: any) => p.name).join('、');
|
||||||
console.log('pluginsInfo', pluginsInfo);
|
console.log('pluginsInfo', pluginsInfo);
|
||||||
|
|
||||||
// 模拟加载时间,展示 spinner 效果
|
// 模拟加载时间,展示 spinner 效果
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||||
|
|
||||||
@@ -79,7 +82,7 @@ watch(loading, (load) => {
|
|||||||
*/
|
*/
|
||||||
function validate(setting: Setting): boolean {
|
function validate(setting: Setting): boolean {
|
||||||
if (!setting.buttonName.trim()) {
|
if (!setting.buttonName.trim()) {
|
||||||
error.value = 'ボタン名を入力してください。';
|
error.value = $t('config.button.error.required');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
<div v-if="shown" class="license-status-info">
|
<div v-if="shown" class="license-status-info">
|
||||||
<div class="license-content">
|
<div class="license-content">
|
||||||
<div class="license-status-text">
|
<div class="license-status-text">
|
||||||
<strong>许可证状态: </strong>
|
<strong>{{ $t('license.status.label') }}</strong>
|
||||||
<span v-if="licenseDisplayInfo" v-html="licenseStatusText"></span><span v-else> ... </span>
|
<span v-if="licenseDisplayInfo" v-html="licenseStatusText"></span><span v-else> ... </span>
|
||||||
</div>
|
</div>
|
||||||
<div class="license-actions">
|
<div class="license-actions">
|
||||||
<template v-if="!licenseDisplayInfo.isPaid">
|
<template v-if="!licenseDisplayInfo.isPaid">
|
||||||
<button class="action-btn" @click="refreshLicenseStatus" :disabled="checking" ref="checkButton">检查</button>
|
<button class="action-btn" @click="refreshLicenseStatus" :disabled="checking" ref="checkButton">{{ $t('license.button.checkLicense.label') }}</button>
|
||||||
<kuc-tooltip title="重新检查许可证状态" :container="checkButton"></kuc-tooltip>
|
<kuc-tooltip :title="$t('license.button.checkLicense.desc')" :container="checkButton"></kuc-tooltip>
|
||||||
<button class="action-btn main" @click="purchaseLicense" ref="buyButton">购买</button>
|
<button class="action-btn main" @click="purchaseLicense" ref="buyButton">{{ $t('license.button.purchase.label') }}</button>
|
||||||
<kuc-tooltip title="购买后当前域名下所有应用都可使用" :container="buyButton"></kuc-tooltip>
|
<kuc-tooltip :title="$t('license.button.purchase.desc')" :container="buyButton"></kuc-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<button v-else class="action-btn" @click="hidePaidMsg">不再显示</button>
|
<button v-else class="action-btn" @click="hidePaidMsg">{{ $t('license.button.hide') }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -20,10 +20,13 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, onMounted, computed, shallowRef } from 'vue';
|
import { ref, onMounted, computed, shallowRef } from 'vue';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
import { LicenseService } from '@/services/LicenseService';
|
import { LicenseService } from '@/services/LicenseService';
|
||||||
import type { LicenseInfo, LicenseCheckResult } from '@/types/license';
|
import type { LicenseInfo } from '@/types/license';
|
||||||
import { LicenseStorage } from '@/utils/LicenseStorage';
|
import { LicenseStorage } from '@/utils/LicenseStorage';
|
||||||
|
|
||||||
|
const { t: $t } = useI18n();// 配置国际化
|
||||||
|
|
||||||
type LicenseDisplayInfo = {
|
type LicenseDisplayInfo = {
|
||||||
isPaid: boolean;
|
isPaid: boolean;
|
||||||
expiryDate: string;
|
expiryDate: string;
|
||||||
@@ -44,7 +47,7 @@ const licenseDisplayInfo = computed<LicenseDisplayInfo>(() => {
|
|||||||
if (!licenseInfo.value || loading.value) {
|
if (!licenseInfo.value || loading.value) {
|
||||||
return {
|
return {
|
||||||
isPaid: false,
|
isPaid: false,
|
||||||
expiryDate: '未知',
|
expiryDate: $t('license.status.unknown'),
|
||||||
isExpired: false,
|
isExpired: false,
|
||||||
remainingDays: 1,
|
remainingDays: 1,
|
||||||
};
|
};
|
||||||
@@ -74,7 +77,7 @@ const addPaidLabel = () => {
|
|||||||
const isExist = !!document.querySelector('#license-label')
|
const isExist = !!document.querySelector('#license-label')
|
||||||
if (!shown.value && !isExist) {
|
if (!shown.value && !isExist) {
|
||||||
const spanElement = document.createElement('span');
|
const spanElement = document.createElement('span');
|
||||||
spanElement.textContent = '已授权';
|
spanElement.textContent = $t('license.status.permanent'),
|
||||||
spanElement.id = 'license-label';
|
spanElement.id = 'license-label';
|
||||||
document.querySelector('#app > .settings-heading')?.appendChild(spanElement);
|
document.querySelector('#app > .settings-heading')?.appendChild(spanElement);
|
||||||
}
|
}
|
||||||
@@ -93,29 +96,28 @@ const isPaidAreaShown = () => {
|
|||||||
|
|
||||||
const licenseStatusText = computed(() => {
|
const licenseStatusText = computed(() => {
|
||||||
if (!licenseDisplayInfo.value) {
|
if (!licenseDisplayInfo.value) {
|
||||||
return '未知';
|
return $t('license.status.unknown');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (loading.value) {
|
if (loading.value) {
|
||||||
return '加载中...';
|
return $t('license.status.checking');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (licenseDisplayInfo.value.isPaid) {
|
if (licenseDisplayInfo.value.isPaid) {
|
||||||
return '<span class="text-green">永久可用</span>';
|
return `<span class="text-green">${$t('license.status.permanentDisplay')}</span>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
let status = `到期时间 ${licenseDisplayInfo.value.expiryDate} `;
|
let status = $t('license.expiry.expiryDate', { date: licenseDisplayInfo.value.expiryDate });
|
||||||
|
|
||||||
if (licenseDisplayInfo.value.isExpired) {
|
if (licenseDisplayInfo.value.isExpired) {
|
||||||
status += '(<span class="text-red">已过期</span>)';
|
status += `(<span class="text-red">${$t('license.status.expired')}</span>)`;
|
||||||
} else if (licenseDisplayInfo.value.remainingDays == 0) {
|
return status;
|
||||||
status += '(今天)';
|
|
||||||
} else if (licenseDisplayInfo.value.remainingDays == 1) {
|
|
||||||
status += '(明天)';
|
|
||||||
} else {
|
|
||||||
status += '(剩余 ' + licenseDisplayInfo.value.remainingDays + ' 天)';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const remainingDays = licenseDisplayInfo.value.remainingDays;
|
||||||
|
const days = $t('license.notification.days', remainingDays)
|
||||||
|
status += `(${days})`;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,40 +6,55 @@ export default {
|
|||||||
title: 'kintone Vue template',
|
title: 'kintone Vue template',
|
||||||
desc: 'kintone Vue template for creating plugin',
|
desc: 'kintone Vue template for creating plugin',
|
||||||
button: {
|
button: {
|
||||||
label: 'button name',
|
label: 'Button name',
|
||||||
default: 'button',
|
default: 'Button',
|
||||||
|
error: {
|
||||||
|
required: '@:config.button.label is required.'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
label: 'message',
|
label: 'message',
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
cancel: 'Cancel',
|
||||||
|
save: 'Save',
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
noAreaError: 'Header menu space element is required.',
|
||||||
},
|
},
|
||||||
license: {
|
license: {
|
||||||
expiry: {
|
expiry: {
|
||||||
title: 'License Expired - {domain} - {plugin}',
|
expiryDate: 'Expiry Date {date}'
|
||||||
message: 'Your plugin license has expired. To continue using this feature, please purchase a new license.',
|
|
||||||
domain: 'Domain',
|
|
||||||
plugin: 'Plugin',
|
|
||||||
expiryDate: 'Expiry Date'
|
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
purchase: 'Purchase License',
|
purchase: {
|
||||||
checkLicense: 'Check Again',
|
label: 'Purchase',
|
||||||
close: 'Close'
|
desc: 'All applications under this domain can be used.'
|
||||||
|
},
|
||||||
|
checkLicense: {
|
||||||
|
label: 'Check',
|
||||||
|
desc: 'Recheck the license status.'
|
||||||
|
},
|
||||||
|
hide: 'Hide'
|
||||||
},
|
},
|
||||||
notification: {
|
notification: {
|
||||||
dontShowAgain: 'Don\'t show again'
|
days: 'today | tomorrow | {count} days later',
|
||||||
},
|
gotoLink: 'Please visit <a class="notification-link" href="{link}">Plugin Setting Page</a>.',
|
||||||
permission: {
|
expired: 'Your plugin {plugin} license has expired.<br>@:license.notification.gotoLink',
|
||||||
noAccess: 'You do not have permission to access this feature',
|
warning: 'Your plugin {plugin} license will be expired {days}.<br>@:license.notification.gotoLink'
|
||||||
adminRequired: 'Administrator privileges required'
|
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
|
label: 'License Status: ',
|
||||||
checking: 'Checking license...',
|
checking: 'Checking license...',
|
||||||
valid: 'License is valid',
|
expired: 'Expired',
|
||||||
expired: 'License has expired',
|
expiredDisplay: 'License has expired',
|
||||||
expiringSoon: 'License expires soon',
|
permanent: 'Permanent license',
|
||||||
permanent: 'Permanent license'
|
permanentDisplay: 'Permanent license',
|
||||||
|
unknown: 'Unknown'
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
fetchFailed: 'Remote license check failed: {e}',
|
||||||
|
checkFailed: 'License check failed, plugin disabled: {e}'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
// 日语语言包配置
|
// 日语语言包配置
|
||||||
|
|
||||||
|
import { warn } from "vue";
|
||||||
|
|
||||||
// 包含配置页面相关的翻译文本
|
// 包含配置页面相关的翻译文本
|
||||||
export default {
|
export default {
|
||||||
hello: "こんにちは!",
|
hello: "こんにちは!",
|
||||||
@@ -8,38 +11,53 @@ export default {
|
|||||||
button: {
|
button: {
|
||||||
label: 'ボタン名',
|
label: 'ボタン名',
|
||||||
default: 'ボタン',
|
default: 'ボタン',
|
||||||
|
error: {
|
||||||
|
required: '@:config.button.labelを入力してください。'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
label: 'メッセージ',
|
label: 'メッセージ',
|
||||||
default: 'こんにちは、世界',
|
default: '',
|
||||||
},
|
},
|
||||||
|
cancel: 'キャンセル',
|
||||||
|
save: '保存する',
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
noAreaError: 'このページではヘッダー要素が利用できません。',
|
||||||
},
|
},
|
||||||
license: {
|
license: {
|
||||||
expiry: {
|
expiry: {
|
||||||
title: 'ライセンスの有効期限が切れました - {domain} - {plugin}',
|
expiryDate: '有効期限 {date} ',
|
||||||
message: 'プラグインのライセンス有効期限が切れています。この機能を引き続き使用するには、新しいライセンスを購入してください。',
|
|
||||||
domain: 'ドメイン',
|
|
||||||
plugin: 'プラグイン',
|
|
||||||
expiryDate: '有効期限'
|
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
purchase: 'ライセンスを購入',
|
purchase: {
|
||||||
checkLicense: '再確認',
|
label: '購入',
|
||||||
close: '閉じる'
|
desc: '購入後、このドメイン下の全アプリで利用可能'
|
||||||
|
},
|
||||||
|
checkLicense: {
|
||||||
|
label: '再確認',
|
||||||
|
desc: 'ライセンス状態を再確認'
|
||||||
|
},
|
||||||
|
hide: '非表示'
|
||||||
},
|
},
|
||||||
notification: {
|
notification: {
|
||||||
dontShowAgain: '今後表示しない'
|
days: '今日 | 明日 | {count}日後',
|
||||||
},
|
gotoLink: 'ご利用には<a class="notification-link" href="{link}">「プラグインの設定」</a>をご確認ください。',
|
||||||
permission: {
|
expired: 'プラグイン「{plugin}」の有効期限が切れました。<br>@:license.notification.gotoLink',
|
||||||
noAccess: 'この機能にアクセスする権限がありません',
|
warning: 'プラグイン「{plugin}」の試用期間が{days}で終了します。<br>@:license.notification.gotoLink'
|
||||||
adminRequired: '管理者権限が必要です'
|
|
||||||
},
|
},
|
||||||
status: {
|
status: {
|
||||||
checking: 'ライセンスを確認しています...',
|
label: 'ライセンス状態: ',
|
||||||
valid: 'ライセンスは有効です',
|
checking: '確認しています...',
|
||||||
expired: 'ライセンスの有効期限が切れました',
|
expired: '期限切れ',
|
||||||
expiringSoon: 'ライセンスの有効期限が近づいています',
|
expiredDisplay: 'ライセンスの有効期限が切れました',
|
||||||
permanent: '永久ライセンス'
|
permanent: '永久ライセンス',
|
||||||
|
permanentDisplay: '永久利用可能',
|
||||||
|
unknown: '不明'
|
||||||
|
},
|
||||||
|
error: {
|
||||||
|
fetchFailed: 'リモートライセンスチェックに失敗しました: {e}',
|
||||||
|
checkFailed: 'ライセンスチェックに失敗しました。プラグイン機能が無効になりました: {e}'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -25,15 +25,15 @@ import { Button } from 'kintone-ui-component/lib/button';
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 测试 i18n
|
||||||
|
const { t } = i18n.global;
|
||||||
|
|
||||||
// 获取 Header 容器元素
|
// 获取 Header 容器元素
|
||||||
const headerSpace = kintone.app.getHeaderMenuSpaceElement();
|
const headerSpace = kintone.app.getHeaderMenuSpaceElement();
|
||||||
if (!headerSpace) {
|
if (!headerSpace) {
|
||||||
throw new Error('このページではヘッダー要素が利用できません。');
|
throw new Error(t('error.noAreaError'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 测试 i18n
|
|
||||||
const { t } = i18n.global;
|
|
||||||
|
|
||||||
// 创建按钮
|
// 创建按钮
|
||||||
const button = new Button({
|
const button = new Button({
|
||||||
text: setting.buttonName,
|
text: setting.buttonName,
|
||||||
@@ -56,11 +56,6 @@ import { Button } from 'kintone-ui-component/lib/button';
|
|||||||
});
|
});
|
||||||
headerSpace.appendChild(button);
|
headerSpace.appendChild(button);
|
||||||
},
|
},
|
||||||
{
|
|
||||||
expiryDialogTitle: '自定义插件到期提示',
|
|
||||||
expiryDialogMessage: '您的自定义插件许可证已过期,请联系管理员购买新的许可证。',
|
|
||||||
// warningDialogMessage: '您的自定义插件许可证还有3天就到期了,请及时续费。',
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
})(kintone.$PLUGIN_ID);
|
})(kintone.$PLUGIN_ID);
|
||||||
|
|||||||
@@ -6,60 +6,55 @@ import { MobileButton } from 'kintone-ui-component/lib/mobile/button';
|
|||||||
|
|
||||||
(function (PLUGIN_ID) {
|
(function (PLUGIN_ID) {
|
||||||
kintone.events.on('mobile.app.record.index.show', () => {
|
kintone.events.on('mobile.app.record.index.show', () => {
|
||||||
// 授权了才能使用
|
// 授权了才能使用
|
||||||
LicenseService.loadPluginIfAuthorized(PLUGIN_ID,
|
LicenseService.loadPluginIfAuthorized(PLUGIN_ID,
|
||||||
async () => {
|
async () => {
|
||||||
// 获取当前应用ID
|
// 获取当前应用ID
|
||||||
const appIdNum = kintone.mobile.app.getId();
|
const appIdNum = kintone.mobile.app.getId();
|
||||||
if (!appIdNum) {
|
if (!appIdNum) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
const appId = appIdNum.toString();
|
const appId = appIdNum.toString();
|
||||||
|
|
||||||
// 从插件配置中读取设置信息
|
// 从插件配置中读取设置信息
|
||||||
const setting: Setting = kintone.plugin.app.getConfig(PLUGIN_ID);
|
const setting: Setting = kintone.plugin.app.getConfig(PLUGIN_ID);
|
||||||
|
|
||||||
// 检查按钮是否已存在,防止翻页时重复添加
|
// 检查按钮是否已存在,防止翻页时重复添加
|
||||||
const btnId = 'template-btn-id';
|
const btnId = 'template-btn-id';
|
||||||
if (document.getElementById(btnId)) {
|
if (document.getElementById(btnId)) {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取 Header 容器元素
|
// 测试 i18n
|
||||||
const headerSpace = kintone.mobile.app.getHeaderSpaceElement();
|
const { t } = i18n.global;
|
||||||
if (!headerSpace) {
|
|
||||||
throw new Error('このページではヘッダー要素が利用できません。');
|
// 获取 Header 容器元素
|
||||||
|
const headerSpace = kintone.mobile.app.getHeaderSpaceElement();
|
||||||
|
if (!headerSpace) {
|
||||||
|
throw new Error(t('error.noAreaError'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建按钮
|
||||||
|
const button = new MobileButton({
|
||||||
|
text: setting.buttonName,
|
||||||
|
type: 'submit',
|
||||||
|
id: btnId,
|
||||||
|
});
|
||||||
|
button.addEventListener('click', async () => {
|
||||||
|
try {
|
||||||
|
// 测试 KintoneRestAPIClient,显示所有已启用的插件名
|
||||||
|
const { plugins } = await client.app.getPlugins({
|
||||||
|
app: appId,
|
||||||
|
});
|
||||||
|
const pluginsInfo = plugins.map((p) => p.name).join('、');
|
||||||
|
|
||||||
|
const message = t('hello') + "\n" + setting.message + '\n--------\n【Plugins】 ' + pluginsInfo;
|
||||||
|
alert(message);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to fetch plugins:', error);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
// 测试 i18n
|
headerSpace.appendChild(button);
|
||||||
const { t } = i18n.global;
|
|
||||||
|
|
||||||
// 创建按钮
|
|
||||||
const button = new MobileButton({
|
|
||||||
text: setting.buttonName,
|
|
||||||
type: 'submit',
|
|
||||||
id: btnId,
|
|
||||||
});
|
|
||||||
button.addEventListener('click', async () => {
|
|
||||||
try {
|
|
||||||
// 测试 KintoneRestAPIClient,显示所有已启用的插件名
|
|
||||||
const { plugins } = await client.app.getPlugins({
|
|
||||||
app: appId,
|
|
||||||
});
|
|
||||||
const pluginsInfo = plugins.map((p) => p.name).join('、');
|
|
||||||
|
|
||||||
const message = t('hello') + "\n" + setting.message + '\n--------\n【Plugins】 ' + pluginsInfo;
|
|
||||||
alert(message);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Failed to fetch plugins:', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
headerSpace.appendChild(button);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
expiryDialogTitle: '自定义插件到期提示',
|
|
||||||
expiryDialogMessage: '您的自定义插件许可证已过期,请联系管理员购买新的许可证。',
|
|
||||||
// warningDialogMessage: '您的自定义插件许可证还有3天就到期了,请及时续费。',
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import type { LicenseInfo, LicenseCheckResult } from '@/types/license';
|
import type { LicenseInfo, LicenseCheckResult } from '@/types/license';
|
||||||
|
import i18n from '@/i18n';
|
||||||
import { LicenseStorage } from '@/utils/LicenseStorage';
|
import { LicenseStorage } from '@/utils/LicenseStorage';
|
||||||
import { PermissionService } from '@/utils/permissions';
|
import { PermissionService } from '@/utils/permissions';
|
||||||
import { Notification } from 'kintone-ui-component/lib/notification';
|
import { Notification } from 'kintone-ui-component/lib/notification';
|
||||||
import { MobileNotification } from 'kintone-ui-component/lib/mobile/notification';
|
import { MobileNotification } from 'kintone-ui-component/lib/mobile/notification';
|
||||||
|
|
||||||
|
const { t: $t } = i18n.global;
|
||||||
|
|
||||||
export class LicenseService {
|
export class LicenseService {
|
||||||
// 常量定义
|
// 常量定义
|
||||||
private static readonly WARNING_DAYS_BEFORE_EXPIRY = 7;
|
private static readonly WARNING_DAYS_BEFORE_EXPIRY = 7;
|
||||||
@@ -98,7 +101,7 @@ export class LicenseService {
|
|||||||
};
|
};
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Remote license check failed:', error);
|
console.error($t('license.error.fetchFailed', { e: error }));
|
||||||
return {
|
return {
|
||||||
isLicenseValid: true,
|
isLicenseValid: true,
|
||||||
};
|
};
|
||||||
@@ -121,7 +124,7 @@ export class LicenseService {
|
|||||||
* 格式化到期时间
|
* 格式化到期时间
|
||||||
*/
|
*/
|
||||||
static formatExpiryDate(timestamp: number): string {
|
static formatExpiryDate(timestamp: number): string {
|
||||||
if (timestamp === -1) return '永久';
|
if (timestamp === -1) return $t('license.status.permanent');
|
||||||
return new Date(timestamp).toLocaleDateString(kintone.getLoginUser().language);
|
return new Date(timestamp).toLocaleDateString(kintone.getLoginUser().language);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,56 +138,26 @@ export class LicenseService {
|
|||||||
return Math.floor(remainingMs / (24 * 60 * 60 * 1000));
|
return Math.floor(remainingMs / (24 * 60 * 60 * 1000));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取许可证显示信息
|
|
||||||
*/
|
|
||||||
static getLicenseDisplayInfo(license: any) {
|
|
||||||
if (!license) return null;
|
|
||||||
|
|
||||||
return {
|
|
||||||
domain: this.getDomain(),
|
|
||||||
plugin: this.getPluginId(),
|
|
||||||
expiryDate: this.formatExpiryDate(license.expiredTime)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============ UI显示函数 ============
|
// ============ UI显示函数 ============
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示到期弹框
|
|
||||||
*/
|
|
||||||
static showExpiryModal(licenseInfo: any, options?: {
|
|
||||||
expiryDialogTitle?: string;
|
|
||||||
expiryDialogMessage?: string;
|
|
||||||
}) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示到期警告通知
|
* 显示到期警告通知
|
||||||
*/
|
*/
|
||||||
static async showExpiryWarning(license: any, options?: {
|
static async showNotification(license: LicenseInfo | undefined, isWarning: boolean) {
|
||||||
warningDialogMessage?: string;
|
let message;
|
||||||
}) {
|
|
||||||
const remainingDays = this.getDaysRemaining(license.expiredTime);
|
|
||||||
if (remainingDays <= 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const msg = remainingDays > 1 ? ` ${remainingDays} 天后` : (remainingDays > 0 ? '明天' : '今天')
|
|
||||||
const link = `https://alicorn.cybozu.com/k/admin/app/${kintone.app.getId()}/plugin/config?pluginId=${this.getPluginId()}`
|
const link = `https://alicorn.cybozu.com/k/admin/app/${kintone.app.getId()}/plugin/config?pluginId=${this.getPluginId()}`
|
||||||
const defaultMessage = `您的插件将在${msg}试用结束<br>如需使用请进入<a class="notification-link" href="${link}">「プラグインの設定」</a>查看详情。`;
|
if (isWarning) {
|
||||||
|
// 尚未到期
|
||||||
// 使用自定义消息或默认消息
|
const remainingDays = this.getDaysRemaining(license!.expiredTime);
|
||||||
const message = options?.warningDialogMessage || defaultMessage;
|
if (remainingDays < 0) {
|
||||||
|
return
|
||||||
// 检查是否已设置不再提醒
|
}
|
||||||
// const settings = LicenseStorage.getSettings(this.getPluginId());
|
const days = $t('license.notification.days', remainingDays)
|
||||||
// if (settings.suppressMsgTime && this.isToday(settings.suppressMsgTime)) {
|
message = $t('license.notification.warning', { plugin: this.getPluginId(), link, days });
|
||||||
// return
|
} else {
|
||||||
// }
|
// 既に期限切れ
|
||||||
// delete settings.suppressMsgTime
|
message = $t('license.notification.expired', { plugin: this.getPluginId(), link });
|
||||||
// LicenseStorage.saveSetting(settings, this.getPluginId());
|
}
|
||||||
|
|
||||||
if (await kintone.isMobilePage()) {
|
if (await kintone.isMobilePage()) {
|
||||||
const notification = new MobileNotification({
|
const notification = new MobileNotification({
|
||||||
content: message,
|
content: message,
|
||||||
@@ -193,7 +166,7 @@ export class LicenseService {
|
|||||||
} else {
|
} else {
|
||||||
const notification = new Notification({
|
const notification = new Notification({
|
||||||
content: message,
|
content: message,
|
||||||
type: 'info',
|
type: isWarning ? 'info' : 'danger',
|
||||||
});
|
});
|
||||||
notification.open();
|
notification.open();
|
||||||
}
|
}
|
||||||
@@ -207,11 +180,6 @@ export class LicenseService {
|
|||||||
static async loadPluginIfAuthorized(
|
static async loadPluginIfAuthorized(
|
||||||
pluginId: string,
|
pluginId: string,
|
||||||
callback: () => void | Promise<void>,
|
callback: () => void | Promise<void>,
|
||||||
options?: {
|
|
||||||
expiryDialogTitle?: string;
|
|
||||||
expiryDialogMessage?: string;
|
|
||||||
warningDialogMessage?: string;
|
|
||||||
}
|
|
||||||
) {
|
) {
|
||||||
this.PLUGIN_ID = pluginId;
|
this.PLUGIN_ID = pluginId;
|
||||||
try {
|
try {
|
||||||
@@ -222,18 +190,14 @@ export class LicenseService {
|
|||||||
const permissions = await PermissionService.checkPermissions();
|
const permissions = await PermissionService.checkPermissions();
|
||||||
const isManager = permissions.canManagePlugins;
|
const isManager = permissions.canManagePlugins;
|
||||||
|
|
||||||
// 许可证无效的情况
|
// 许可证无效的情况,直接返回不加载
|
||||||
if (!licenseCheck.isLicenseValid) {
|
if (!licenseCheck.isLicenseValid) {
|
||||||
if (!isManager) {
|
if (!isManager) {
|
||||||
// 普通用户静默输出
|
// 普通用户静默输出
|
||||||
console.warn('License check failed, plugin functionality disabled');
|
console.warn($t('license.status.expiredDisplay'));
|
||||||
} else {
|
} else {
|
||||||
// 管理员可以看到过期弹框
|
// 管理员可以看到过期弹框
|
||||||
alert('许可证无效')
|
this.showNotification(licenseCheck.license, false);
|
||||||
// this.showExpiryModal(this.getLicenseDisplayInfo(license.license), {
|
|
||||||
// expiryDialogTitle: options?.expiryDialogTitle,
|
|
||||||
// expiryDialogMessage: options?.expiryDialogMessage
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -244,16 +208,14 @@ export class LicenseService {
|
|||||||
!licenseCheck.license.isPaid &&
|
!licenseCheck.license.isPaid &&
|
||||||
this.isExpiringSoon(licenseCheck.license.expiredTime)) {
|
this.isExpiringSoon(licenseCheck.license.expiredTime)) {
|
||||||
// 管理员可以看到过期弹框
|
// 管理员可以看到过期弹框
|
||||||
this.showExpiryWarning(licenseCheck.license, {
|
this.showNotification(licenseCheck.license, true);
|
||||||
warningDialogMessage: options?.warningDialogMessage
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 许可证有效,可以加载插件功能
|
// 许可证有效,可以加载插件功能
|
||||||
await callback();
|
await callback();
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('License check failed, plugin functionality disabled:', error);
|
console.warn($t('license.error.checkFailed'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user