mirror of
https://github.com/certd/certd.git
synced 2026-04-03 14:10:54 +08:00
chore: vip modal content转到单独的组件中
This commit is contained in:
@@ -15,3 +15,10 @@ export async function getVipTrial(vipType: string) {
|
||||
data: { vipType },
|
||||
});
|
||||
}
|
||||
|
||||
export async function getTodayVipOrderCount() {
|
||||
return await request({
|
||||
url: "/sys/plus/getTodayVipOrderCount",
|
||||
method: "post",
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,16 +14,20 @@
|
||||
<script lang="tsx" setup>
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import dayjs from "dayjs";
|
||||
import { computed, onMounted, reactive, ref } from "vue";
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRouter } from "vue-router";
|
||||
import * as api from "./api";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import { useSettingStore } from "/src/store/settings/index";
|
||||
import { useUserStore } from "/@/store/user";
|
||||
import { env } from "/@/utils/util.env";
|
||||
import { mitter } from "/@/utils/util.mitt";
|
||||
import VipModalContent from "./vip-modal-content.vue";
|
||||
const { t } = useI18n();
|
||||
|
||||
defineOptions({
|
||||
name: "VipButton",
|
||||
});
|
||||
const settingStore = useSettingStore();
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
@@ -113,58 +117,16 @@ const expireTime = computed(() => {
|
||||
|
||||
const expiredDays = computed(() => {
|
||||
if (settingStore.plusInfo?.isPlus && !settingStore.isPlus) {
|
||||
//已过期多少天
|
||||
const days = dayjs().diff(dayjs(settingStore.plusInfo.expireTime), "day");
|
||||
return `${settingStore.vipLabel}已过期${days}天`;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
|
||||
const formState = reactive({
|
||||
code: "",
|
||||
inviteCode: "",
|
||||
});
|
||||
|
||||
const router = useRouter();
|
||||
async function doActive() {
|
||||
if (!formState.code) {
|
||||
message.error(t("vip.enterCode"));
|
||||
throw new Error(t("vip.enterCode"));
|
||||
}
|
||||
const res = await api.doActive(formState);
|
||||
if (res) {
|
||||
await settingStore.init();
|
||||
const vipLabel = settingStore.vipLabel;
|
||||
Modal.success({
|
||||
title: t("vip.successTitle"),
|
||||
content: t("vip.successContent", {
|
||||
vipLabel,
|
||||
expireDate: dayjs(settingStore.plusInfo.expireTime).format("YYYY-MM-DD"),
|
||||
}),
|
||||
onOk() {
|
||||
if (!(settingStore.installInfo.bindUserId > 0)) {
|
||||
Modal.confirm({
|
||||
title: t("vip.bindAccountTitle"),
|
||||
content: t("vip.bindAccountContent"),
|
||||
onOk() {
|
||||
router.push("/sys/account");
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const computedSiteId = computed(() => settingStore.installInfo?.siteId);
|
||||
const [modal, contextHolder] = Modal.useModal();
|
||||
const userStore = useUserStore();
|
||||
|
||||
function goAccount() {
|
||||
Modal.destroyAll();
|
||||
router.push("/sys/account");
|
||||
}
|
||||
|
||||
async function getVipTrial(vipType = "plus") {
|
||||
const res = await api.getVipTrial(vipType);
|
||||
message.success(t("vip.congratulations_vip_trial", { duration: res.duration }));
|
||||
@@ -253,6 +215,7 @@ function openUpgrade() {
|
||||
throw new Error(t("vip.already_perpetual_plus"));
|
||||
}
|
||||
}
|
||||
|
||||
function goBuyPlusPage() {
|
||||
checkPerpetualPlus();
|
||||
if (settingStore.isComm) {
|
||||
@@ -264,6 +227,7 @@ function openUpgrade() {
|
||||
}
|
||||
window.open(goBuyUrl);
|
||||
}
|
||||
|
||||
function goBuyCommPage() {
|
||||
checkPerpetualPlus();
|
||||
if (settingStore.isPlus && !settingStore.isComm) {
|
||||
@@ -278,75 +242,6 @@ function openUpgrade() {
|
||||
}
|
||||
window.open(goBuyCommUrl);
|
||||
}
|
||||
const vipTypeDefine = {
|
||||
free: {
|
||||
title: t("vip.basic_edition"),
|
||||
desc: t("vip.community_free_version"),
|
||||
type: "free",
|
||||
icon: "lucide:package-open",
|
||||
privilege: [t("vip.unlimited_certificate_application"), t("vip.unlimited_domain_count"), t("vip.unlimited_certificate_pipelines"), t("vip.common_deployment_plugins"), t("vip.email_webhook_notifications")],
|
||||
},
|
||||
plus: {
|
||||
title: t("vip.professional_edition"),
|
||||
desc: t("vip.open_source_support"),
|
||||
type: "plus",
|
||||
privilege: [t("vip.vip_group_priority"), t("vip.unlimited_site_certificate_monitoring"), t("vip.more_notification_methods"), t("vip.plugins_fully_open")],
|
||||
trial: {
|
||||
title: t("vip.click_to_get_7_day_trial"),
|
||||
click: () => {
|
||||
openStarModal("plus");
|
||||
},
|
||||
},
|
||||
icon: "stash:thumb-up",
|
||||
priceText: productInfo.plus.priceText || `¥${productInfo.plus.price}/${t("vip.years")}`,
|
||||
discountText: productInfo.plus.discountText || `¥${productInfo.plus.price3}/3${t("vip.years")}`,
|
||||
tooltip: productInfo.plus.tooltip,
|
||||
get() {
|
||||
return (
|
||||
<a-tooltip title={t("vip.afdian_support_vip")}>
|
||||
<a-button size="small" type="primary" onClick={goBuyPlusPage}>
|
||||
{t("vip.get_after_support")}
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
);
|
||||
},
|
||||
},
|
||||
comm: {
|
||||
title: t("vip.business_edition"),
|
||||
desc: t("vip.commercial_license"),
|
||||
type: "comm",
|
||||
icon: "vaadin:handshake",
|
||||
privilege: [t("vip.all_pro_privileges"), t("vip.allow_commercial_use_modify_logo_title"), t("vip.data_statistics"), t("vip.plugin_management"), t("vip.unlimited_multi_users"), t("vip.support_user_payment")],
|
||||
priceText: productInfo.comm.priceText || `¥${productInfo.comm.price}/${t("vip.years")}`,
|
||||
discountText: productInfo.comm.discountText || `¥${productInfo.comm.price3}/3${t("vip.years")}`,
|
||||
tooltip: productInfo.comm.tooltip,
|
||||
trial: {
|
||||
title: t("vip.click_to_get_7_day_trial"),
|
||||
click: () => {
|
||||
openStarModal("comm");
|
||||
},
|
||||
},
|
||||
get() {
|
||||
return (
|
||||
<a-button size="small" type="primary" onClick={goBuyCommPage}>
|
||||
{t("vip.buy")}
|
||||
</a-button>
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const manualActiveFlag = ref();
|
||||
function showManualActivation() {
|
||||
manualActiveFlag.value = true;
|
||||
}
|
||||
|
||||
function goBindAccount() {
|
||||
modalRef?.destroy();
|
||||
router.push({
|
||||
path: "/sys/account",
|
||||
});
|
||||
}
|
||||
const modalRef = modal.success({
|
||||
title,
|
||||
class: "vip-modal",
|
||||
@@ -354,119 +249,7 @@ function openUpgrade() {
|
||||
okText: t("vip.close"),
|
||||
width: 1100,
|
||||
content: () => {
|
||||
let manualActiveBlock: any = "";
|
||||
if (manualActiveFlag.value) {
|
||||
manualActiveBlock = (
|
||||
<div>
|
||||
<div class="mt-10">
|
||||
<a-input-search class="w-2/6" v-model:value={formState.code} placeholder={placeholder} enter-button={t("vip.activate")} onSearch={doActive}></a-input-search>
|
||||
</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;
|
||||
let plusInfo: any = "";
|
||||
if (isPlus) {
|
||||
plusInfo = (
|
||||
<div class="mt-10 flex flex-col md:flex-row ">
|
||||
<span class="mr-2">
|
||||
{t("vip.current")} {vipLabel} {t("vip.activated_expire_time")} {settingStore.expiresText}
|
||||
</span>
|
||||
<a href="https://app.handfree.work/subject/#/page/detail/1" target="_blank">
|
||||
{t("vip.learn_more")}
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const slots = [];
|
||||
for (const key in vipTypeDefine) {
|
||||
// @ts-ignore
|
||||
const item = vipTypeDefine[key];
|
||||
const vipBlockClass = `vip-block ${key === settingStore.plusInfo.vipType ? "current" : ""}`;
|
||||
slots.push(
|
||||
<div class="w-full md:w-1/3 mb-4 p-5">
|
||||
<div class={vipBlockClass}>
|
||||
<h3 class="block-header ">
|
||||
<span class="flex-o">{item.title}</span>
|
||||
{item.trial && (
|
||||
<span class="trial">
|
||||
<a-tooltip title={item.trial.message}>
|
||||
<a onClick={item.trial.click}>{item.trial.title}</a>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
)}
|
||||
</h3>
|
||||
<div style="color:green" class="flex-o">
|
||||
<fs-icon icon={item.icon} class="fs-16 flex-o" />
|
||||
{item.desc}
|
||||
</div>
|
||||
<ul class="flex-1 privilege">
|
||||
{item.privilege.map((p: string) => (
|
||||
<li class="flex-baseline">
|
||||
<fs-icon class="color-green" icon="ion:checkmark-sharp" />
|
||||
{p}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div class="footer flex-between flex-vc">
|
||||
<div class="price-show">
|
||||
{item.priceText && (
|
||||
<span class="flex">
|
||||
<span class="-text">{item.priceText}</span>
|
||||
<a-tooltip class="ml-5" title={item.discountText}>
|
||||
<fs-icon class="pointer color-red" icon="ic:outline-discount"></fs-icon>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
)}
|
||||
{!item.priceText && (
|
||||
<span>
|
||||
<span class="price-text">{t("vip.freee")}</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div class="get-show">{item.get && <div>{item.get()}</div>}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<div class="mt-10 mb-10 vip-active-modal">
|
||||
{productInfo.notice && (
|
||||
<div class="mb-10">
|
||||
<a-alert type="error" message={productInfo.notice}></a-alert>
|
||||
</div>
|
||||
)}
|
||||
<div class="vip-type-vs">
|
||||
<a-row gutter={20}>{slots}</a-row>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://certd.docmirror.cn/guide/donate/#相关问题" target="_blank">
|
||||
{t("vip.question")}
|
||||
</a>
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
<div class=" w-100 flex-col md:flex-row ">
|
||||
<span>{t("vip.site_id")}:</span>
|
||||
<fs-copyable v-model={computedSiteId.value} class="mr-2"></fs-copyable>
|
||||
<a onClick={goBindAccount}>{t("vip.not_effective")}</a>
|
||||
</div>
|
||||
</div>
|
||||
{plusInfo}
|
||||
<div class="mt-10 ">
|
||||
<span class="mr-2">{t("vip.have_activation_code")}</span>
|
||||
<span>
|
||||
<a onClick={showManualActivation}>{t("vip.manual_activation")}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="mt-10">{manualActiveBlock}</div>
|
||||
</div>
|
||||
);
|
||||
return <VipModalContent placeholder={placeholder} isPlus={isPlus} productInfo={productInfo} goBuyPlusPage={goBuyPlusPage} goBuyCommPage={goBuyCommPage} openStarModal={openStarModal} modalRef={modalRef} />;
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -502,69 +285,4 @@ onMounted(() => {
|
||||
.text {
|
||||
}
|
||||
}
|
||||
|
||||
.vip-active-modal {
|
||||
.vip-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 5px;
|
||||
height: 275px;
|
||||
line-height: 24px;
|
||||
|
||||
.privilege {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
//background-color: rgba(250, 237, 167, 0.79);
|
||||
&.current {
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
.block-header {
|
||||
padding: 0px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.trial {
|
||||
font-size: 12px;
|
||||
font-wight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
padding-top: 5px;
|
||||
margin-top: 0px;
|
||||
border-top: 1px solid #eee;
|
||||
|
||||
.price-text {
|
||||
font-size: 18px;
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: unset;
|
||||
margin-left: 0px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.color-green {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.vip-type-vs {
|
||||
.privilege {
|
||||
.fs-icon {
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
|
||||
.fs-icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
<template>
|
||||
<div class="mt-10 mb-10 vip-active-modal">
|
||||
<div v-if="productInfo.notice" class="mb-10">
|
||||
<a-alert type="error" :message="productInfo.notice"></a-alert>
|
||||
</div>
|
||||
<div class="vip-type-vs">
|
||||
<a-row :gutter="20">
|
||||
<div v-for="(item, key) in vipTypeDefine" :key="key" class="w-full md:w-1/3 mb-4 p-5">
|
||||
<div :class="`vip-block ${key === settingStore.plusInfo.vipType ? 'current' : ''}`">
|
||||
<h3 class="block-header">
|
||||
<span class="flex-o">{{ item.title }}</span>
|
||||
<span v-if="item.trial" class="trial">
|
||||
<a-tooltip :title="item.trial.message">
|
||||
<a @click="item.trial.click">{{ item.trial.title }}</a>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
</h3>
|
||||
<div style="color: green" class="flex-o">
|
||||
<fs-icon :icon="item.icon" class="fs-16 flex-o" />
|
||||
{{ item.desc }}
|
||||
</div>
|
||||
<ul class="flex-1 privilege">
|
||||
<li v-for="p in item.privilege" :key="p" class="flex-baseline">
|
||||
<fs-icon class="color-green" icon="ion:checkmark-sharp" />
|
||||
{{ p }}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="footer flex-between flex-vc">
|
||||
<div class="price-show">
|
||||
<span v-if="item.priceText" class="flex">
|
||||
<span class="-text">{{ item.priceText }}</span>
|
||||
<a-tooltip class="ml-5" :title="item.discountText">
|
||||
<fs-icon class="pointer color-red" icon="ic:outline-discount"></fs-icon>
|
||||
</a-tooltip>
|
||||
</span>
|
||||
<span v-else>
|
||||
<span class="price-text">{{ t("vip.freee") }}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="get-show">
|
||||
<template v-if="item.type === 'plus'">
|
||||
<a-tooltip :title="t('vip.afdian_support_vip')">
|
||||
<a-button size="small" type="primary" @click="goBuyPlusPage">
|
||||
{{ t("vip.get_after_support") }}
|
||||
</a-button>
|
||||
</a-tooltip>
|
||||
</template>
|
||||
<template v-else-if="item.type === 'comm'">
|
||||
<a-button size="small" type="primary" @click="goBuyCommPage">
|
||||
{{ t("vip.buy") }}
|
||||
</a-button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-row>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://certd.docmirror.cn/guide/donate/#相关问题" target="_blank">
|
||||
{{ t("vip.question") }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
<div class="w-100 flex-col md:flex-row">
|
||||
<span>{{ t("vip.site_id") }}:</span>
|
||||
<fs-copyable v-model="computedSiteId" class="mr-2"></fs-copyable>
|
||||
<a @click="goBindAccount">{{ t("vip.not_effective") }}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isPlus" class="mt-10 flex flex-col md:flex-row">
|
||||
<span class="mr-2"> {{ t("vip.current") }} {{ vipLabel }} {{ t("vip.activated_expire_time") }} {{ settingStore.expiresText }} </span>
|
||||
<a href="https://app.handfree.work/subject/#/page/detail/1" target="_blank">
|
||||
{{ t("vip.learn_more") }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
<span class="mr-2">{{ t("vip.have_activation_code") }}</span>
|
||||
<span>
|
||||
<a @click="showManualActivation">{{ t("vip.manual_activation") }}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="manualActiveFlag" class="mt-10">
|
||||
<div class="mt-10">
|
||||
<a-input-search v-model:value="formState.code" class="w-2/6" :placeholder="placeholder" :enter-button="t('vip.activate')" @search="doActive"></a-input-search>
|
||||
</div>
|
||||
<div class="mt-10">
|
||||
{{ t("vip.activation_code_one_use") }}
|
||||
<a @click="goAccount">{{ t("vip.bind_account") }}</a
|
||||
>,{{ t("vip.transfer_vip") }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, reactive, ref } from "vue";
|
||||
import { message, Modal } from "ant-design-vue";
|
||||
import dayjs from "dayjs";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useSettingStore } from "/@/store/settings";
|
||||
import * as api from "./api";
|
||||
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const settingStore = useSettingStore();
|
||||
|
||||
const props = defineProps<{
|
||||
placeholder: string;
|
||||
isPlus: boolean;
|
||||
productInfo: any;
|
||||
goBuyPlusPage: () => void;
|
||||
goBuyCommPage: () => void;
|
||||
openStarModal: (vipType: string) => void;
|
||||
modalRef: any;
|
||||
}>();
|
||||
|
||||
const formState = reactive({
|
||||
code: "",
|
||||
inviteCode: "",
|
||||
});
|
||||
|
||||
async function doActive() {
|
||||
if (!formState.code) {
|
||||
message.error(t("vip.enterCode"));
|
||||
throw new Error(t("vip.enterCode"));
|
||||
}
|
||||
const res = await api.doActive(formState);
|
||||
if (res) {
|
||||
await settingStore.init();
|
||||
const vipLabel = settingStore.vipLabel;
|
||||
Modal.success({
|
||||
title: t("vip.successTitle"),
|
||||
content: t("vip.successContent", {
|
||||
vipLabel,
|
||||
expireDate: dayjs(settingStore.plusInfo.expireTime).format("YYYY-MM-DD"),
|
||||
}),
|
||||
onOk() {
|
||||
if (!(settingStore.installInfo.bindUserId > 0)) {
|
||||
Modal.confirm({
|
||||
title: t("vip.bindAccountTitle"),
|
||||
content: t("vip.bindAccountContent"),
|
||||
onOk() {
|
||||
router.push("/sys/account");
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const vipLabel = computed(() => settingStore.vipLabel);
|
||||
const computedSiteId = computed(() => settingStore.installInfo?.siteId);
|
||||
|
||||
const manualActiveFlag = ref(false);
|
||||
|
||||
function showManualActivation() {
|
||||
manualActiveFlag.value = true;
|
||||
}
|
||||
|
||||
function goAccount() {
|
||||
props.modalRef?.destroy();
|
||||
router.push("/sys/account");
|
||||
}
|
||||
|
||||
function goBindAccount() {
|
||||
props.modalRef?.destroy();
|
||||
router.push({
|
||||
path: "/sys/account",
|
||||
});
|
||||
}
|
||||
|
||||
const vipTypeDefine: any = {
|
||||
free: {
|
||||
title: t("vip.basic_edition"),
|
||||
desc: t("vip.community_free_version"),
|
||||
type: "free",
|
||||
icon: "lucide:package-open",
|
||||
privilege: [t("vip.unlimited_certificate_application"), t("vip.unlimited_domain_count"), t("vip.unlimited_certificate_pipelines"), t("vip.common_deployment_plugins"), t("vip.email_webhook_notifications")],
|
||||
},
|
||||
plus: {
|
||||
title: t("vip.professional_edition"),
|
||||
desc: t("vip.open_source_support"),
|
||||
type: "plus",
|
||||
privilege: [t("vip.vip_group_priority"), t("vip.unlimited_site_certificate_monitoring"), t("vip.more_notification_methods"), t("vip.plugins_fully_open")],
|
||||
trial: {
|
||||
title: t("vip.click_to_get_7_day_trial"),
|
||||
click: () => {
|
||||
props.openStarModal("plus");
|
||||
},
|
||||
},
|
||||
icon: "stash:thumb-up",
|
||||
priceText: props.productInfo.plus.priceText || `¥${props.productInfo.plus.price}/${t("vip.years")}`,
|
||||
discountText: props.productInfo.plus.discountText || `¥${props.productInfo.plus.price3}/3${t("vip.years")}`,
|
||||
tooltip: props.productInfo.plus.tooltip,
|
||||
},
|
||||
comm: {
|
||||
title: t("vip.business_edition"),
|
||||
desc: t("vip.commercial_license"),
|
||||
type: "comm",
|
||||
icon: "vaadin:handshake",
|
||||
privilege: [t("vip.all_pro_privileges"), t("vip.allow_commercial_use_modify_logo_title"), t("vip.data_statistics"), t("vip.plugin_management"), t("vip.unlimited_multi_users"), t("vip.support_user_payment")],
|
||||
priceText: props.productInfo.comm.priceText || `¥${props.productInfo.comm.price}/${t("vip.years")}`,
|
||||
discountText: props.productInfo.comm.discountText || `¥${props.productInfo.comm.price3}/3${t("vip.years")}`,
|
||||
tooltip: props.productInfo.comm.tooltip,
|
||||
trial: {
|
||||
title: t("vip.click_to_get_7_day_trial"),
|
||||
click: () => {
|
||||
props.openStarModal("comm");
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const TodayVipOrderCountRef = ref(0);
|
||||
|
||||
async function getTodayVipOrderCount() {
|
||||
const res = await api.getTodayVipOrderCount();
|
||||
if (res) {
|
||||
TodayVipOrderCountRef.value = res.count;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
getTodayVipOrderCount();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.vip-active-modal {
|
||||
.vip-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 10px;
|
||||
border: 1px solid #eee;
|
||||
border-radius: 5px;
|
||||
height: 275px;
|
||||
line-height: 24px;
|
||||
|
||||
.privilege {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
&.current {
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
.block-header {
|
||||
padding: 0px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.trial {
|
||||
font-size: 12px;
|
||||
font-wight: 400;
|
||||
}
|
||||
}
|
||||
|
||||
.footer {
|
||||
padding-top: 5px;
|
||||
margin-top: 0px;
|
||||
border-top: 1px solid #eee;
|
||||
|
||||
.price-text {
|
||||
font-size: 18px;
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
list-style-type: unset;
|
||||
margin-left: 0px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.color-green {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.vip-type-vs {
|
||||
.privilege {
|
||||
.fs-icon {
|
||||
color: green;
|
||||
}
|
||||
}
|
||||
|
||||
.fs-icon {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -48,6 +48,11 @@ export class SysPlusController extends BaseController {
|
||||
const res = await this.plusService.getVipTrial(vipType);
|
||||
return this.ok(res);
|
||||
}
|
||||
@Post('/getTodayVipOrderCount', { summary: 'sys:settings:edit' })
|
||||
async getTodayVipOrderCount() {
|
||||
const res = await this.plusService.getTodayOrderCount();
|
||||
return this.ok(res);
|
||||
}
|
||||
//
|
||||
// @Get('/test', { summary: Constants.per.guest })
|
||||
// async test() {
|
||||
|
||||
Reference in New Issue
Block a user