improve UIUX
This commit is contained in:
151
src/components/LicenseStatus.vue
Normal file
151
src/components/LicenseStatus.vue
Normal file
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<div v-if="shown" class="license-status-info">
|
||||
<div class="license-content">
|
||||
<div class="license-status-text">
|
||||
<strong>许可证状态: </strong>
|
||||
<span v-if="licenseDisplayInfo" v-html="licenseStatusText"></span><span v-else> ... </span>
|
||||
</div>
|
||||
<div class="license-actions">
|
||||
<template v-if="!licenseDisplayInfo.isPaid">
|
||||
<button class="action-btn" @click="refreshLicenseStatus" :disabled="checking" ref="checkButton">检查</button>
|
||||
<kuc-tooltip title="重新检查许可证状态" :container="checkButton"></kuc-tooltip>
|
||||
<button class="action-btn main" @click="purchaseLicense" ref="buyButton">购买</button>
|
||||
<kuc-tooltip title="购买后当前域名下所有应用都可使用" :container="buyButton"></kuc-tooltip>
|
||||
</template>
|
||||
<button v-else class="action-btn" @click="hidePaidMsg">不再显示</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, computed, shallowRef } from 'vue';
|
||||
import { LicenseService } from '@/services/LicenseService';
|
||||
import type { LicenseInfo, LicenseCheckResult } from '@/types/license';
|
||||
import { LicenseStorage } from '@/utils/LicenseStorage';
|
||||
|
||||
type LicenseDisplayInfo = {
|
||||
isPaid: boolean;
|
||||
expiryDate: string;
|
||||
isExpired: boolean;
|
||||
remainingDays: number;
|
||||
};
|
||||
|
||||
// 状态管理
|
||||
const licenseInfo = ref<LicenseInfo | undefined>();
|
||||
const loading = ref(true);
|
||||
const shown = ref(false);
|
||||
const checking = ref(false);
|
||||
const checkButton = shallowRef<HTMLButtonElement | null>(null);
|
||||
const buyButton = shallowRef<HTMLButtonElement | null>(null);
|
||||
|
||||
// 许可证显示信息
|
||||
const licenseDisplayInfo = computed<LicenseDisplayInfo>(() => {
|
||||
if (!licenseInfo.value || loading.value) {
|
||||
return {
|
||||
isPaid: false,
|
||||
expiryDate: '未知',
|
||||
isExpired: false,
|
||||
remainingDays: 1,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
isPaid: licenseInfo.value.isPaid,
|
||||
expiryDate: LicenseService.formatExpiryDate(licenseInfo.value.expiredTime),
|
||||
isExpired: licenseInfo.value.expiredTime < Date.now() && !licenseInfo.value.isPaid,
|
||||
remainingDays: LicenseService.getDaysRemaining(licenseInfo.value.expiredTime),
|
||||
};
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
const result = await LicenseService.checkLicense();
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
licenseInfo.value = result.license;
|
||||
|
||||
shown.value = isPaidAreaShown();
|
||||
if (!shown.value) {
|
||||
addPaidLabel();
|
||||
}
|
||||
loading.value = false;
|
||||
});
|
||||
|
||||
const addPaidLabel = () => {
|
||||
const isExist = !!document.querySelector('#license-label')
|
||||
if (!shown.value && !isExist) {
|
||||
const spanElement = document.createElement('span');
|
||||
spanElement.textContent = '已授权';
|
||||
spanElement.id = 'license-label';
|
||||
document.querySelector('#app > .settings-heading')?.appendChild(spanElement);
|
||||
}
|
||||
}
|
||||
|
||||
const isPaidAreaShown = () => {
|
||||
if (!licenseInfo.value?.isPaid) {
|
||||
return true;
|
||||
}
|
||||
const settings = LicenseStorage.getSettings(licenseInfo.value.pluginId);
|
||||
if (settings.hideLicenseAreaIfPaid) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const licenseStatusText = computed(() => {
|
||||
if (!licenseDisplayInfo.value) {
|
||||
return '未知';
|
||||
}
|
||||
|
||||
if (loading.value) {
|
||||
return '加载中...';
|
||||
}
|
||||
|
||||
if (licenseDisplayInfo.value.isPaid) {
|
||||
return '<span class="text-green">永久可用</span>';
|
||||
}
|
||||
|
||||
let status = `到期时间 ${licenseDisplayInfo.value.expiryDate} `;
|
||||
|
||||
if (licenseDisplayInfo.value.isExpired) {
|
||||
status += '(<span class="text-red">已过期</span>)';
|
||||
} else if (licenseDisplayInfo.value.remainingDays == 0) {
|
||||
status += '(今天)';
|
||||
} else if (licenseDisplayInfo.value.remainingDays == 1) {
|
||||
status += '(明天)';
|
||||
} else {
|
||||
status += '(剩余 ' + licenseDisplayInfo.value.remainingDays + ' 天)';
|
||||
}
|
||||
|
||||
return status;
|
||||
});
|
||||
|
||||
async function refreshLicenseStatus() {
|
||||
checking.value = true;
|
||||
loading.value = true;
|
||||
// 模拟加载时间,展示 spinner 效果
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
|
||||
const result = await LicenseService.forceRefreshLicense();
|
||||
licenseInfo.value = result.license;
|
||||
loading.value = false;
|
||||
checking.value = false;
|
||||
}
|
||||
|
||||
function purchaseLicense() {
|
||||
alert(
|
||||
`请联系管理员或访问官方网站购买许可证。\nDomain: ${licenseInfo.value?.domain}\nPlugin: ${licenseInfo.value?.pluginId}`,
|
||||
);
|
||||
}
|
||||
|
||||
function hidePaidMsg() {
|
||||
const pluginId = licenseInfo.value?.pluginId;
|
||||
if (!pluginId) {
|
||||
return;
|
||||
}
|
||||
const settings = LicenseStorage.getSettings(pluginId);
|
||||
settings.hideLicenseAreaIfPaid = true;
|
||||
LicenseStorage.saveSetting(settings, pluginId);
|
||||
shown.value = false;
|
||||
addPaidLabel();
|
||||
}
|
||||
</script>
|
||||
Reference in New Issue
Block a user