Files
certd/packages/ui/certd-client/src/components/vip-button/index.vue
xiaojunnuo 4053e72782 chore: 1
2024-10-03 01:49:38 +08:00

228 lines
6.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="layout-vip isPlus" @click="openUpgrade">
<contextHolder />
<fs-icon icon="mingcute:vip-1-line" :title="text.title" />
<div v-if="mode !== 'icon'" class="text">
<a-tooltip>
<template #title> {{ text.title }}</template>
<span>{{ text.name }}</span>
</a-tooltip>
</div>
</div>
</template>
<script lang="tsx" setup>
import { ref, reactive, computed } from "vue";
import { useUserStore } from "/src/store/modules/user";
import dayjs from "dayjs";
import { message, Modal } from "ant-design-vue";
import * as api from "./api";
import { useSettingStore } from "/@/store/modules/settings";
import { useRouter } from "vue-router";
const props = withDefaults(
defineProps<{
mode?: "button" | "nav" | "icon";
}>(),
{
mode: "button"
}
);
type Text = {
name: string;
title?: string;
};
const text = computed<Text>(() => {
const vipLabel = userStore.vipLabel;
const map = {
isPlus: {
button: {
name: `${vipLabel}已开通`,
title: "到期时间:" + expireTime.value
},
icon: {
name: "",
title: `${vipLabel}已开通`
},
nav: {
name: `${vipLabel}`,
title: "到期时间:" + expireTime.value
}
},
free: {
button: {
name: "此为专业版功能",
title: "升级专业版享受更多VIP特权"
},
icon: {
name: "",
title: "此为专业版功能"
},
nav: {
name: "免费版",
title: "升级专业版享受更多VIP特权"
}
}
};
if (userStore.isPlus) {
return map.isPlus[props.mode];
} else {
return map.free[props.mode];
}
});
const userStore = useUserStore();
const expireTime = computed(() => {
if (userStore.isPlus) {
return dayjs(userStore.plusInfo.expireTime).format("YYYY-MM-DD");
}
return "";
});
const expiredDays = computed(() => {
if (userStore.plusInfo?.isPlus && !userStore.isPlus) {
//已过期多少天
const days = dayjs().diff(dayjs(userStore.plusInfo.expireTime), "day");
return `${userStore.vipLabel}已过期${days}`;
}
return "";
});
const formState = reactive({
code: ""
});
const router = useRouter();
async function doActive() {
if (!formState.code) {
message.error("请输入激活码");
throw new Error("请输入激活码");
}
const res = await api.doActive(formState);
if (res) {
await userStore.reInit();
const vipLabel = userStore.vipLabel;
Modal.success({
title: "激活成功",
content: `您已成功激活${vipLabel},有效期至:${dayjs(userStore.plusInfo.expireTime).format("YYYY-MM-DD")}`,
onOk() {
if (!(settingStore.installInfo.bindUserId > 0)) {
//未绑定账号
Modal.confirm({
title: "是否绑定袖手账号",
content: "绑定账号后可以避免License丢失强烈建议绑定",
onOk() {
router.push("/sys/account");
}
});
}
}
});
}
}
const settingStore = useSettingStore();
const computedSiteId = computed(() => settingStore.installInfo?.siteId);
const [modal, contextHolder] = Modal.useModal();
function openUpgrade() {
if (!userStore.isAdmin) {
message.info("仅限管理员操作");
return;
}
const placeholder = "请输入激活码";
const isPlus = userStore.isPlus;
let title = "激活专业版/商业版";
if (userStore.isComm) {
title = "续期商业版";
} else if (userStore.isPlus) {
title = "续期专业版/升级商业版";
}
modal.confirm({
title,
async onOk() {
return await doActive();
},
maskClosable: true,
okText: "激活",
width: 900,
content: () => {
const vipLabel = userStore.vipLabel;
return (
<div class="mt-10 mb-10">
<div>
<a-row gutter={20}>
<a-col span={8}>
<h3 class="block-header">免费版</h3>
<ul>
<li>证书申请功能无限制</li>
<li>证书流水线数量限制10条</li>
<li>部分部署插件不可用</li>
</ul>
</a-col>
<a-col span={8}>
<h3 class="block-header">专业版</h3>
<ul>
<li>可加VIP群需求优先实现</li>
<li>证书流水线数量无限制</li>
<li>免配置发邮件功能</li>
<li>宝塔易盾群晖cdnfly1Panel等部署插件</li>
<li>多用户有限制</li>
</ul>
</a-col>
<a-col span={8}>
<h3 class="block-header">商业版</h3>
<ul>
<li>拥有专业版所有特权</li>
<li>修改logo标题</li>
<li>多用户无限制</li>
<li>支持用户支付</li>
<li>允许商用</li>
</ul>
</a-col>
</a-row>
</div>
<div>
<h3 class="block-header">{isPlus ? "续期" : "立刻激活"}</h3>
<div>{isPlus ? `当前${vipLabel}已激活,到期时间` + dayjs(userStore.plusInfo.expireTime).format("YYYY-MM-DD") : ""}</div>
<div class="mt-10">
<div class="flex-o w-100">
<span>站点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} />
</div>
<div class="mt-10">
没有激活码
<a href="https://afdian.com/a/greper" target="_blank">
爱发电赞助VIP会员后获取
</a>
</div>
</div>
</div>
);
}
});
}
</script>
<style lang="less">
.layout-vip {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
cursor: pointer;
&.isPlus {
color: #c5913f;
}
.text {
margin-left: 5px;
}
}
</style>