修复platform的支付问题

This commit is contained in:
2026-09-16 10:35:55 +08:00
parent 71a14c46f9
commit 19687658e1
7 changed files with 415 additions and 148 deletions
+180 -12
View File
@@ -71,6 +71,7 @@
v-for="module in basicModules"
:key="module.path"
class="module-card"
:class="{ disabled: !module.enabled }"
@click="handleNavigate(module)"
>
<div class="card-header">
@@ -79,8 +80,27 @@
</div>
<div class="card-divider"></div>
<div class="card-content">
<p class="card-desc">{{ module.description || "暂无描述" }}</p>
<template v-if="module.enabled">
<p class="card-desc">{{ module.description || "暂无描述" }}</p>
</template>
<template v-else>
<div class="card-locked">
<el-icon class="lock-icon"><Lock /></el-icon>
<p class="lock-tip">请购买套餐后使用</p>
</div>
</template>
</div>
<template v-if="!module.enabled">
<el-button
size="small"
type="primary"
link
class="buy-btn"
@click.stop="handleBuyPackage(module)"
>
购买套餐
</el-button>
</template>
</div>
</div>
</div>
@@ -93,6 +113,7 @@
v-for="module in systemModules"
:key="module.path"
class="module-card"
:class="{ disabled: !module.enabled }"
@click="handleNavigate(module)"
>
<div class="card-header">
@@ -101,8 +122,27 @@
</div>
<div class="card-divider"></div>
<div class="card-content">
<p class="card-desc">{{ module.description || "暂无描述" }}</p>
<template v-if="module.enabled">
<p class="card-desc">{{ module.description || "暂无描述" }}</p>
</template>
<template v-else>
<div class="card-locked">
<el-icon class="lock-icon"><Lock /></el-icon>
<p class="lock-tip">请购买套餐后使用</p>
</div>
</template>
</div>
<template v-if="!module.enabled">
<el-button
size="small"
type="primary"
link
class="buy-btn"
@click.stop="handleBuyPackage(module)"
>
购买套餐
</el-button>
</template>
</div>
</div>
</div>
@@ -115,6 +155,7 @@
v-for="module in uncategorizedModules"
:key="module.path"
class="module-card"
:class="{ disabled: !module.enabled }"
@click="handleNavigate(module)"
>
<div class="card-header">
@@ -123,8 +164,27 @@
</div>
<div class="card-divider"></div>
<div class="card-content">
<p class="card-desc">{{ module.description || "暂无描述" }}</p>
<template v-if="module.enabled">
<p class="card-desc">{{ module.description || "暂无描述" }}</p>
</template>
<template v-else>
<div class="card-locked">
<el-icon class="lock-icon"><Lock /></el-icon>
<p class="lock-tip">请购买套餐后使用</p>
</div>
</template>
</div>
<template v-if="!module.enabled">
<el-button
size="small"
type="primary"
link
class="buy-btn"
@click.stop="handleBuyPackage(module)"
>
购买套餐
</el-button>
</template>
</div>
</div>
</div>
@@ -157,6 +217,7 @@ import {
Sunny,
Moon,
OfficeBuilding,
Lock,
} from "@element-plus/icons-vue";
import { getTenantList } from "@/api/modules";
@@ -175,6 +236,7 @@ interface ModuleItem {
status: number;
type: number;
title?: string;
enabled?: boolean;
}
const router = useRouter();
@@ -267,6 +329,11 @@ const tenantName = computed(() => authStore.user?.tenant_name || "");
// 处理导航跳转
function handleNavigate(module: ModuleItem) {
if (module.enabled === false) {
ElMessage.warning(`「${module.name}」暂未开通,请先购买对应套餐`);
return;
}
const isWebsiteManagement = module.name === "网站管理" || module.path.startsWith("/apps/cms");
const targetPath = isWebsiteManagement
? "/apps/cms/analytics/content"
@@ -275,6 +342,12 @@ function handleNavigate(module: ModuleItem) {
if (targetPath) router.push(targetPath);
}
// 未开通功能 → 引导购买套餐
function handleBuyPackage(module: ModuleItem) {
ElMessage.info(`购买「${module.name}」套餐功能 —— 请联系管理员或前往平台套餐中心`);
// TODO: 未来接入购买页面后 router.push(...) 到对应套餐购买界面
}
// 刷新菜单
async function handleRefreshMenus() {
refreshLoading.value = true;
@@ -325,16 +398,20 @@ async function loadModules() {
const list = res.data?.list || [];
const filteredList = list
.filter((item: ModuleItem) => item.status === 1 && item.is_show === 1)
.sort((a, b) => Number(a.sort) - Number(b.sort));
moduleList.value = filteredList
.map((item: ModuleItem) => {
const mapped = {
...item,
type: item.type ?? 0, // 默认为0(未分类)
title: item.name // 添加title字段用于显示分类标题
};
return mapped;
.map((item: ModuleItem) => ({
...item,
enabled: item.enabled !== false, // 后端返回 enabled,缺失时默认 true
title: item.name,
}))
.sort((a: ModuleItem, b: ModuleItem) => {
// 已开通在前
if (a.enabled !== b.enabled) return a.enabled ? -1 : 1;
// 同状态内按 sort 升序、id 升序
const sortDiff = Number(a.sort) - Number(b.sort);
if (sortDiff !== 0) return sortDiff;
return Number(a.id) - Number(b.id);
});
moduleList.value = filteredList;
}
} catch (error) {
console.error("加载模块列表失败:", error);
@@ -649,6 +726,71 @@ onMounted(() => {
opacity: 0;
}
}
// 未开通的套餐模块(disabled 状态)
&.disabled {
cursor: not-allowed;
background: #f7f8fa;
border-color: #e4e7ed;
box-shadow: none;
.card-title {
color: #909399;
}
.card-icon-wrapper {
color: #c0c4cc;
}
.card-divider {
border-bottom-color: #ebeef5;
}
// hover 禁用所有悬浮效果
&:hover {
transform: none;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
background: #f7f8fa;
.card-title,
.card-desc {
color: #909399;
}
.card-icon-wrapper {
color: #c0c4cc;
}
.card-divider {
opacity: 1;
}
}
// 锁图标 + 提示文字
.card-locked {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
padding: 6px 0 0;
.lock-icon {
font-size: 22px;
color: #c0c4cc;
}
.lock-tip {
font-size: 12px;
color: #909399;
margin: 0;
}
}
.buy-btn {
margin-top: 6px;
font-size: 12px;
}
}
}
}
@@ -947,6 +1089,32 @@ onMounted(() => {
.card-divider {
border-color: #3d3d3d;
}
// 暗色主题下未开通卡片
&.disabled {
background: #222;
border-color: #333;
.card-title {
color: #666 !important;
}
.card-icon-wrapper {
color: #555;
}
.card-divider {
border-color: #2e2e2e;
}
.card-locked .lock-icon {
color: #555;
}
.card-locked .lock-tip {
color: #666;
}
}
}
}