chore: buy

This commit is contained in:
xiaojunnuo
2025-11-09 00:12:31 +08:00
parent 0c99f41bd9
commit c31eef6b82
4 changed files with 99 additions and 36 deletions
@@ -12,7 +12,7 @@
</div> </div>
</template> </template>
<script lang="tsx" setup> <script lang="tsx" setup>
import { computed, onMounted, reactive } from "vue"; import { computed, onMounted, reactive, ref } from "vue";
import dayjs from "dayjs"; import dayjs from "dayjs";
import { message, Modal } from "ant-design-vue"; import { message, Modal } from "ant-design-vue";
import * as api from "./api"; import * as api from "./api";
@@ -243,6 +243,41 @@ function openUpgrade() {
const goBuyUrl = `${env.VIP_PRODUCT_URL}?appKey=${appKey}&subjectId=${subjectId}&callback=${callbackUrl}`; const goBuyUrl = `${env.VIP_PRODUCT_URL}?appKey=${appKey}&subjectId=${subjectId}&callback=${callbackUrl}`;
const goBuyCommUrl = `${goBuyUrl}&vipType=comm`; const goBuyCommUrl = `${goBuyUrl}&vipType=comm`;
const productInfo = settingStore.productInfo; const productInfo = settingStore.productInfo;
function checkPerpetualPlus() {
if (settingStore.isPerpetual) {
Modal.warn({
title: t("vip.already_perpetual_plus"),
okText: t("vip.confirm"),
});
throw new Error(t("vip.already_perpetual_plus"));
}
}
function goBuyPlusPage() {
checkPerpetualPlus();
if (settingStore.isComm) {
Modal.warn({
title: t("vip.already_comm"),
okText: t("vip.confirm"),
});
return;
}
window.open(goBuyUrl);
}
function goBuyCommPage() {
checkPerpetualPlus();
if (settingStore.isPlus && !settingStore.isComm) {
Modal.confirm({
title: t("vip.already_plus"),
okText: t("vip.confirm"),
onOk() {
window.open(goBuyCommUrl);
},
});
return;
}
window.open(goBuyCommUrl);
}
const vipTypeDefine = { const vipTypeDefine = {
free: { free: {
title: t("vip.basic_edition"), title: t("vip.basic_edition"),
@@ -269,7 +304,7 @@ function openUpgrade() {
get() { get() {
return ( return (
<a-tooltip title={t("vip.afdian_support_vip")}> <a-tooltip title={t("vip.afdian_support_vip")}>
<a-button size="small" type="primary" href={goBuyUrl} target="_blank"> <a-button size="small" type="primary" onClick={goBuyPlusPage}>
{t("vip.get_after_support")} {t("vip.get_after_support")}
</a-button> </a-button>
</a-tooltip> </a-tooltip>
@@ -293,32 +328,49 @@ function openUpgrade() {
}, },
get() { get() {
return ( return (
<a-button size="small" type="primary" href={goBuyCommUrl} target="_blank"> <a-button size="small" type="primary" onClick={goBuyCommPage}>
{t("vip.contact_author_for_trial")} {t("vip.buy")}
</a-button> </a-button>
); );
}, },
}, },
}; };
const modalRef = modal.confirm({ const manualActiveFlag = ref();
function showManualActivation() {
manualActiveFlag.value = true;
}
const modalRef = modal.success({
title, title,
async onOk() {
return await doActive();
},
maskClosable: true, maskClosable: true,
okText: t("vip.activate"), okText: t("vip.close"),
width: 1100, width: 1100,
content: () => { content: () => {
let activationCodeGetWay = ( let manualActiveBlock: any = "";
<span> if (manualActiveFlag.value) {
<a href={goBuyUrl} target="_blank"> manualActiveBlock = (
{t("vip.get_pro_code_after_support")} <div>
</a> <div class="mt-10">
<span> {t("vip.business_contact_author")}</span> <a-input-search class="w-2/6" v-model:value={formState.code} placeholder={placeholder} enter-button={t("vip.activate")} onSearch={doActive}></a-input-search>
</span> </div>
); <div class="mt-10">
{t("vip.activation_code_one_use")}
<a onClick={goAccount}>{t("vip.bind_account")}</a>{t("vip.transfer_vip")}
</div>
</div>
);
}
const vipLabel = settingStore.vipLabel; const vipLabel = settingStore.vipLabel;
let plusInfo: any = "";
if (isPlus) {
plusInfo = (
<div class="mt-10">
{t("vip.current")} {vipLabel} {t("vip.activated_expire_time")}
{settingStore.expiresText}
</div>
);
}
const slots = []; const slots = [];
for (const key in vipTypeDefine) { for (const key in vipTypeDefine) {
// @ts-ignore // @ts-ignore
@@ -384,26 +436,19 @@ function openUpgrade() {
<a-row gutter={20}>{slots}</a-row> <a-row gutter={20}>{slots}</a-row>
</div> </div>
<div class="mt-10"> <div class="mt-10">
<h3 class="block-header">{isPlus ? t("vip.renew") : t("vip.activate_immediately")}</h3> <div class="flex-o w-100">
<div>{isPlus ? `${t("vip.current")} ${vipLabel} ${t("vip.activated_expire_time")}` + settingStore.expiresText : ""}</div> <span>{t("vip.site_id")}</span>
<div class="mt-10"> <fs-copyable v-model={computedSiteId.value}></fs-copyable>
<div class="flex-o w-100">
<span>{t("vip.site_id")}</span>
<fs-copyable class="flex-1" v-model={computedSiteId.value}></fs-copyable>
</div>
<a-input class="mt-10" v-model:value={formState.code} placeholder={placeholder} />
<a-input class="mt-10" v-model:value={formState.inviteCode} placeholder={t("vip.invite_code_optional")} />
</div>
<div class="mt-10">
{t("vip.no_activation_code")}
{activationCodeGetWay}
</div>
<div class="mt-10">
{t("vip.activation_code_one_use")}
<a onClick={goAccount}>{t("vip.bind_account")}</a>{t("vip.transfer_vip")}
</div> </div>
</div> </div>
{plusInfo}
<div class="mt-10">
{t("vip.have_activation_code")}
<span>
<a onClick={showManualActivation}>{t("vip.manual_activation")}</a>
</span>
</div>
<div class="mt-10">{manualActiveBlock}</div>
</div> </div>
); );
}, },
@@ -89,4 +89,12 @@ export default {
activation_code_one_use: "Activation code can only be used once. To change site, please ", activation_code_one_use: "Activation code can only be used once. To change site, please ",
bind_account: "bind account", bind_account: "bind account",
transfer_vip: ' then "Transfer VIP"', transfer_vip: ' then "Transfer VIP"',
manual_activation: "Manual activation use code",
close: "Close",
have_activation_code: "Already have activation code?",
buy: "Buy",
already_plus: "Already Professional Edition, will upgrade to Business Edition, Professional Edition time will be lost",
already_comm: "Already Business Edition, can't change to Professional Edition",
already_perpetual_plus: "You already have a perpetual Professional Edition, can't upgrade",
confirm: "Confirm",
}; };
@@ -73,7 +73,6 @@ export default {
plugin_management: "插件管理", plugin_management: "插件管理",
unlimited_multi_users: "多用户无限制", unlimited_multi_users: "多用户无限制",
support_user_payment: "支持用户支付", support_user_payment: "支持用户支付",
contact_author_for_trial: "立即购买",
activate: "激活", activate: "激活",
get_pro_code_after_support: "前往获取", get_pro_code_after_support: "前往获取",
business_contact_author: "", business_contact_author: "",
@@ -89,4 +88,12 @@ export default {
activation_code_one_use: "激活码使用过一次之后,不可再次使用,如果要更换站点,请", activation_code_one_use: "激活码使用过一次之后,不可再次使用,如果要更换站点,请",
bind_account: "绑定账号", bind_account: "绑定账号",
transfer_vip: ',然后"转移VIP"即可', transfer_vip: ',然后"转移VIP"即可',
manual_activation: "激活码手动激活",
close: "关闭",
have_activation_code: "已经有激活码了?",
buy: "立即购买",
already_plus: "已经是专业版了,是否升级为商业版?注意:专业版时长将被覆盖",
already_comm: "已经是商业版了,不能降级为专业版",
already_perpetual_plus: "您已经是永久专业版了,无法继续升级",
confirm: "确认",
}; };
@@ -126,6 +126,9 @@ export const useSettingStore = defineStore({
getInstallInfo(): SysInstallInfo { getInstallInfo(): SysInstallInfo {
return this.installInfo; return this.installInfo;
}, },
isPerpetual(): boolean {
return this.plusInfo?.isPlus && this.plusInfo?.expireTime === -1;
},
isPlus(): boolean { isPlus(): boolean {
return this.plusInfo?.isPlus && (this.plusInfo?.expireTime === -1 || this.plusInfo?.expireTime > new Date().getTime()); return this.plusInfo?.isPlus && (this.plusInfo?.expireTime === -1 || this.plusInfo?.expireTime > new Date().getTime());
}, },