完善购买和套餐功能
This commit is contained in:
Vendored
+3
@@ -18,6 +18,7 @@ declare module 'vue' {
|
||||
ElAutocomplete: typeof import('element-plus/es')['ElAutocomplete']
|
||||
ElAvatar: typeof import('element-plus/es')['ElAvatar']
|
||||
ElBacktop: typeof import('element-plus/es')['ElBacktop']
|
||||
ElBadge: typeof import('element-plus/es')['ElBadge']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElButtonGroup: typeof import('element-plus/es')['ElButtonGroup']
|
||||
ElCard: typeof import('element-plus/es')['ElCard']
|
||||
@@ -28,6 +29,7 @@ declare module 'vue' {
|
||||
ElCollapse: typeof import('element-plus/es')['ElCollapse']
|
||||
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
|
||||
ElCollapseTransition: typeof import('element-plus/es')['ElCollapseTransition']
|
||||
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
|
||||
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
|
||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||
@@ -52,6 +54,7 @@ declare module 'vue' {
|
||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
||||
ElOption: typeof import('element-plus/es')['ElOption']
|
||||
ElOptionGroup: typeof import('element-plus/es')['ElOptionGroup']
|
||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||
ElPopover: typeof import('element-plus/es')['ElPopover']
|
||||
ElProgress: typeof import('element-plus/es')['ElProgress']
|
||||
|
||||
@@ -231,6 +231,22 @@ export async function loadAndAddDynamicRoutes() {
|
||||
return routesLoadingPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新拉取菜单并重建动态路由。
|
||||
* 动态路由在构建时会把「未开通模块」的菜单注册为锁定占位页(views/locked),
|
||||
* 仅调用 menuStore.refreshMenus() 只更新菜单数据、不会重建路由,
|
||||
* 因此支付开通/套餐变更后必须调用本方法,才能让占位页切换为真实页面。
|
||||
*/
|
||||
export async function reloadMenusAndDynamicRoutes() {
|
||||
const { useMenuStore } = await import("@/stores/menu");
|
||||
const menuStore = useMenuStore();
|
||||
// 强制从接口拉取最新菜单(含 locked 标记),写入 store 与缓存
|
||||
await menuStore.refreshMenus();
|
||||
// 重置加载标志后重建路由表
|
||||
resetDynamicRoutes();
|
||||
await loadAndAddDynamicRoutes();
|
||||
}
|
||||
|
||||
// 核心修改:移除扁平化,直接使用嵌套菜单生成路由
|
||||
function addDynamicRoutes(menus) {
|
||||
if (!menus?.length) {
|
||||
|
||||
@@ -232,6 +232,7 @@ import {
|
||||
import { getTenantList } from "@/api/modules";
|
||||
import { getProductOrderStatus } from "@/api/product";
|
||||
import { getCurrentUserProfile, logout } from "@/api/login";
|
||||
import { reloadMenusAndDynamicRoutes } from "@/router";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { useMenuStore } from "@/stores/menu";
|
||||
|
||||
@@ -372,7 +373,8 @@ function handleBuyProduct(module: ModuleItem) {
|
||||
async function handleRefreshMenus() {
|
||||
refreshLoading.value = true;
|
||||
try {
|
||||
await menuStore.refreshMenus();
|
||||
// 仅刷新菜单数据不会替换动态路由里的锁定占位页,需一并重建路由
|
||||
await Promise.all([reloadMenusAndDynamicRoutes(), loadModules()]);
|
||||
ElMessage.success("菜单已刷新");
|
||||
} catch {
|
||||
ElMessage.error("刷新菜单失败");
|
||||
@@ -462,8 +464,12 @@ async function syncReturnedPayment() {
|
||||
return;
|
||||
}
|
||||
if (status === "activated") {
|
||||
// 订单已开通:重新拉取模块与菜单,解锁「请购买后使用」的卡片
|
||||
await Promise.all([loadModules(), menuStore.refreshMenus()]);
|
||||
// 订单已开通:重建动态路由 + 刷新模块,解锁「功能未开通」菜单占位页与「请购买后使用」卡片
|
||||
try {
|
||||
await Promise.all([loadModules(), reloadMenusAndDynamicRoutes()]);
|
||||
} catch (e) {
|
||||
console.warn("支付成功后刷新菜单失败:", e);
|
||||
}
|
||||
ElMessage.success("支付成功,功能已开通");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -79,10 +79,11 @@
|
||||
type="primary"
|
||||
size="large"
|
||||
:loading="buyingIds[pkg.id]"
|
||||
:disabled="isPurchasedOnce(pkg)"
|
||||
@click="handleBuy(pkg)"
|
||||
class="buy-btn"
|
||||
>
|
||||
立即购买
|
||||
{{ isPurchasedOnce(pkg) ? "已购买(限购一次)" : "立即购买" }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
@@ -141,6 +142,7 @@ import { ElMessage } from "element-plus";
|
||||
import { ArrowLeft, OfficeBuilding, Box, User, InfoFilled } from "@element-plus/icons-vue";
|
||||
import QRCode from "qrcode";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { reloadMenusAndDynamicRoutes } from "@/router";
|
||||
import {
|
||||
getPackageList,
|
||||
createPackageOrder,
|
||||
@@ -223,6 +225,10 @@ const renderQR = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
/** 仅可购买一次的套餐(体验套餐)在已购买过之后禁用购买按钮 */
|
||||
const isPurchasedOnce = (pkg: any) =>
|
||||
Number(pkg?.allow_repurchase) === 0 && pkg?.purchased === true;
|
||||
|
||||
const handleBuy = async (pkg: any) => {
|
||||
buyingIds.value[pkg.id] = true;
|
||||
try {
|
||||
@@ -295,6 +301,8 @@ const checkOrder = async (orderNo: string, silent = false) => {
|
||||
ElMessage.success("购买成功,套餐已开通");
|
||||
payVisible.value = false;
|
||||
loadMyOrders();
|
||||
// 重建动态路由,把新开通模块的「功能未开通」菜单占位页切换为真实页面
|
||||
reloadMenusAndDynamicRoutes().catch(() => {});
|
||||
return;
|
||||
}
|
||||
if (status === "paid") {
|
||||
|
||||
@@ -145,6 +145,7 @@ import {
|
||||
getPaymentChannels,
|
||||
} from "@/api/product";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { reloadMenusAndDynamicRoutes } from "@/router";
|
||||
|
||||
interface FeatureNode {
|
||||
key: number;
|
||||
@@ -311,6 +312,8 @@ const checkOrder = async (silent = false) => {
|
||||
ElMessage.success("购买成功,功能已开通");
|
||||
payVisible.value = false;
|
||||
loadMyOrders();
|
||||
// 重建动态路由,把刚开通模块的「功能未开通」菜单占位页切换为真实页面
|
||||
reloadMenusAndDynamicRoutes().catch(() => {});
|
||||
return;
|
||||
}
|
||||
if (status === "paid") {
|
||||
|
||||
Reference in New Issue
Block a user