重构资产订阅功能,将弹窗模式改为外部页面跳转模式,移除AssetSubscribeDialog组件及其在App.vue中的引用,修改assetSubscribe工具类将showAssetSubscribeDialog方法替换为redirectToSubscribePage方法,当检测到402状态码时直接跳转到外部开通页面并携带资产ID和返回地址参数

This commit is contained in:
WUSIJIAN
2026-01-21 14:02:42 +08:00
parent aec7f3a017
commit af17d81422
5 changed files with 596 additions and 319 deletions

View File

@@ -6,3 +6,4 @@ VITE_API_URL = 'http://192.168.3.200:8808/'
# VITE_API_URL = 'http://192.168.3.11:8808/' # VITE_API_URL = 'http://192.168.3.11:8808/'

580
public/web/subscribe.html Normal file
View File

@@ -0,0 +1,580 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>服务开通 - 智能营销服务平台</title>
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="style.css">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700;800&display=swap" rel="stylesheet">
<style>
* {
box-sizing: border-box;
}
.subscribe-container {
max-width: 800px;
margin: 0 auto;
padding: 32px 24px;
}
.subscribe-header {
text-align: center;
margin-bottom: 32px;
}
.subscribe-header h1 {
font-size: 1.75rem;
font-weight: 700;
color: #1e293b;
margin: 0 0 8px 0;
}
.subscribe-header p {
color: #64748b;
font-size: 0.95rem;
margin: 0;
}
.asset-info {
background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
border-radius: 12px;
padding: 20px 24px;
margin-bottom: 28px;
border: 1px solid #bae6fd;
display: flex;
align-items: flex-start;
gap: 16px;
}
.asset-info .icon-wrapper {
width: 44px;
height: 44px;
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.asset-info .icon-wrapper svg {
width: 24px;
height: 24px;
color: #fff;
}
.asset-info .info-content {
flex: 1;
}
.asset-info .asset-name {
font-size: 1.1rem;
font-weight: 600;
color: #0c4a6e;
margin: 0 0 6px 0;
}
.asset-info .description {
color: #0369a1;
font-size: 0.875rem;
line-height: 1.5;
margin: 0;
}
.asset-info .description p {
margin: 0;
}
.sku-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
margin-bottom: 28px;
}
@media (max-width: 600px) {
.sku-grid {
grid-template-columns: 1fr;
}
}
.sku-card {
background: #fff;
border: 2px solid #e2e8f0;
border-radius: 12px;
padding: 20px;
cursor: pointer;
transition: all 0.2s ease;
position: relative;
display: flex;
flex-direction: column;
}
.sku-card:hover {
border-color: #3b82f6;
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.12);
}
.sku-card.selected {
border-color: #3b82f6;
background: #f8faff;
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);
}
.sku-card.selected::after {
content: '';
position: absolute;
top: 12px;
right: 12px;
width: 22px;
height: 22px;
background: #3b82f6 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z'/%3E%3C/svg%3E") center/14px no-repeat;
border-radius: 50%;
}
.sku-name {
font-size: 1rem;
font-weight: 600;
color: #334155;
margin-bottom: 12px;
padding-right: 30px;
}
.sku-content {
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.sku-specs {
display: flex;
align-items: baseline;
gap: 2px;
}
.sku-specs .count {
font-size: 2rem;
font-weight: 700;
color: #3b82f6;
line-height: 1;
}
.sku-specs .unit {
font-size: 0.875rem;
color: #64748b;
margin-left: 2px;
}
.sku-price {
text-align: right;
}
.sku-price .amount {
color: #ef4444;
font-size: 1.25rem;
font-weight: 700;
}
.sku-price .symbol {
font-size: 0.875rem;
}
.subscribe-actions {
display: flex;
gap: 12px;
justify-content: center;
padding-top: 8px;
}
.btn-subscribe {
padding: 12px 36px;
font-size: 1rem;
font-weight: 600;
border-radius: 8px;
border: none;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-subscribe.primary {
background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%);
color: #fff;
}
.btn-subscribe.primary:hover {
background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);
}
.btn-subscribe.primary:disabled {
background: #94a3b8;
cursor: not-allowed;
box-shadow: none;
}
.btn-subscribe.secondary {
background: #fff;
color: #64748b;
border: 1px solid #e2e8f0;
}
.btn-subscribe.secondary:hover {
border-color: #cbd5e1;
background: #f8fafc;
}
.loading-container {
text-align: center;
padding: 48px 20px;
}
.loading-spinner {
width: 40px;
height: 40px;
border: 3px solid #e2e8f0;
border-top-color: #3b82f6;
border-radius: 50%;
animation: spin 0.8s linear infinite;
margin: 0 auto 12px;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.empty-container {
text-align: center;
padding: 48px 20px;
color: #64748b;
}
.empty-container svg {
width: 56px;
height: 56px;
margin-bottom: 12px;
color: #cbd5e1;
}
.error-message {
background: #fef2f2;
border: 1px solid #fecaca;
color: #dc2626;
padding: 14px 20px;
border-radius: 8px;
margin-bottom: 20px;
text-align: center;
font-size: 0.95rem;
}
.success-message {
background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
border: 1px solid #86efac;
color: #166534;
padding: 32px;
border-radius: 12px;
text-align: center;
}
.success-message h3 {
font-size: 1.25rem;
margin: 0 0 8px 0;
}
.success-message p {
margin: 0;
color: #15803d;
}
</style>
</head>
<body class="auth-body">
<!-- 导航 -->
<nav class="auth-navbar">
<div class="auth-navbar-container">
<a href="index.html" class="auth-back-link">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path></svg>
返回首页
</a>
<span class="auth-title">服务开通</span>
</div>
</nav>
<main class="subscribe-container">
<div class="subscribe-header">
<h1>开通服务</h1>
<p>选择适合您的套餐,立即开通使用</p>
</div>
<!-- 加载中 -->
<div id="loading" class="loading-container">
<div class="loading-spinner"></div>
<p>正在加载套餐信息...</p>
</div>
<!-- 错误信息 -->
<div id="error" class="error-message" style="display: none;"></div>
<!-- 资产信息 -->
<div id="asset-info" class="asset-info" style="display: none;">
<div class="icon-wrapper">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
</div>
<div class="info-content">
<h3 id="asset-name" class="asset-name"></h3>
<div id="asset-description" class="description"></div>
</div>
</div>
<!-- SKU 列表 -->
<div id="sku-list" class="sku-grid" style="display: none;"></div>
<!-- 空状态 -->
<div id="empty" class="empty-container" style="display: none;">
<svg fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"></path></svg>
<p>暂无可用套餐</p>
</div>
<!-- 成功信息 -->
<div id="success" class="success-message" style="display: none;">
<h3>🎉 开通成功!</h3>
<p>正在返回...</p>
</div>
<!-- 操作按钮 -->
<div id="actions" class="subscribe-actions" style="display: none;">
<button class="btn-subscribe secondary" onclick="handleCancel()">取消</button>
<button id="btn-submit" class="btn-subscribe primary" onclick="handleSubscribe()" disabled>立即开通</button>
</div>
</main>
<script>
// API 基础地址
const API_BASE = 'http://192.168.3.11:8000';
// 页面状态
let assetId = '';
let returnUrl = '';
let selectedSku = null;
let assetData = null;
// 初始化
window.addEventListener('DOMContentLoaded', () => {
const params = new URLSearchParams(window.location.search);
assetId = params.get('assetId') || '';
returnUrl = params.get('returnUrl') || '/index.html';
if (!assetId) {
showError('缺少资产ID参数');
return;
}
loadAssetAndSku();
});
// 加载资产和SKU信息
async function loadAssetAndSku() {
showLoading(true);
try {
const token = getToken();
console.log('[subscribe] token:', token);
const headers = {
'Content-Type': 'application/json'
};
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
const response = await fetch(`${API_BASE}/assets/asset/getAssetAndSku?assetId=${assetId}`, {
headers: headers
});
// 先获取文本检查是否为有效JSON
const text = await response.text();
console.log('[subscribe] response text:', text);
let result;
try {
result = JSON.parse(text);
} catch (e) {
throw new Error('服务器返回数据格式错误');
}
if (result.code !== 0) {
throw new Error(result.message || '加载失败');
}
assetData = result.data;
renderAssetInfo(assetData);
renderSkuList(assetData.skus || []);
} catch (error) {
console.error('加载失败:', error);
showError(error.message || '加载套餐信息失败,请稍后重试');
} finally {
showLoading(false);
}
}
// 渲染资产信息
function renderAssetInfo(data) {
document.getElementById('asset-name').textContent = data.name || '服务';
document.getElementById('asset-description').innerHTML = data.description || '';
document.getElementById('asset-info').style.display = 'block';
}
// 渲染SKU列表
function renderSkuList(skus) {
const container = document.getElementById('sku-list');
const actions = document.getElementById('actions');
const empty = document.getElementById('empty');
if (!skus || skus.length === 0) {
empty.style.display = 'block';
return;
}
container.innerHTML = skus.map(sku => `
<div class="sku-card" data-sku-id="${sku.id}" onclick="selectSku('${sku.id}')">
<div class="sku-name">${sku.skuName}</div>
<div class="sku-content">
<div class="sku-specs">
<span class="count">${sku.specsCount}</span>
<span class="unit">${sku.specsUnit?.value || ''}</span>
</div>
<div class="sku-price">
<span class="amount"><span class="symbol">¥</span>${(sku.price / 100).toFixed(2)}</span>
</div>
</div>
</div>
`).join('');
container.style.display = 'grid';
actions.style.display = 'flex';
// 默认选中第一个
if (skus.length > 0) {
selectSku(skus[0].id);
}
}
// 选择SKU
function selectSku(skuId) {
// 移除之前的选中状态
document.querySelectorAll('.sku-card').forEach(card => {
card.classList.remove('selected');
});
// 添加选中状态
const card = document.querySelector(`.sku-card[data-sku-id="${skuId}"]`);
if (card) {
card.classList.add('selected');
}
// 保存选中的SKU
selectedSku = assetData?.skus?.find(s => s.id === skuId) || null;
// 更新按钮状态
document.getElementById('btn-submit').disabled = !selectedSku;
}
// 开通服务
async function handleSubscribe() {
if (!selectedSku) {
alert('请选择套餐');
return;
}
const btn = document.getElementById('btn-submit');
btn.disabled = true;
btn.textContent = '开通中...';
try {
const token = getToken();
const response = await fetch(`${API_BASE}/assets/asset/subscribe`, {
method: 'POST',
headers: {
'Authorization': token ? `Bearer ${token}` : '',
'Content-Type': 'application/json'
},
body: JSON.stringify({
skuId: selectedSku.id,
assetId: selectedSku.assetId
})
});
const result = await response.json();
if (result.code !== 0) {
throw new Error(result.message || '开通失败');
}
// 显示成功
document.getElementById('sku-list').style.display = 'none';
document.getElementById('actions').style.display = 'none';
document.getElementById('asset-info').style.display = 'none';
document.getElementById('success').style.display = 'block';
// 延迟跳转回原页面
setTimeout(() => {
window.location.href = decodeURIComponent(returnUrl);
}, 1500);
} catch (error) {
console.error('开通失败:', error);
alert(error.message || '开通失败,请稍后重试');
btn.disabled = false;
btn.textContent = '立即开通';
}
}
// 取消
function handleCancel() {
if (returnUrl) {
window.location.href = decodeURIComponent(returnUrl);
} else {
window.location.href = 'index.html';
}
}
// 获取Token从Cookie获取
function getToken() {
try {
const cookies = document.cookie.split(';');
for (let cookie of cookies) {
const parts = cookie.trim().split('=');
const name = parts[0];
// token 值可能包含 = 号,所以用 slice 获取剩余部分
const value = parts.slice(1).join('=');
if (name === 'token' && value) {
// Cookie 中的值可能被 URL 编码,需要解码
try {
return decodeURIComponent(value);
} catch (e) {
return value;
}
}
}
} catch (e) {
console.error('获取token失败:', e);
}
return '';
}
// 显示/隐藏加载
function showLoading(show) {
document.getElementById('loading').style.display = show ? 'block' : 'none';
}
// 显示错误
function showError(message) {
const errorEl = document.getElementById('error');
errorEl.textContent = message;
errorEl.style.display = 'block';
document.getElementById('loading').style.display = 'none';
}
</script>
</body>
</html>

View File

@@ -4,12 +4,6 @@
<LockScreen v-if="themeConfig.isLockScreen" /> <LockScreen v-if="themeConfig.isLockScreen" />
<Setings ref="setingsRef" v-show="themeConfig.lockScreenTime > 1" /> <Setings ref="setingsRef" v-show="themeConfig.lockScreenTime > 1" />
<CloseFull v-if="!themeConfig.isLockScreen" /> <CloseFull v-if="!themeConfig.isLockScreen" />
<!-- 模块未开通弹窗 -->
<AssetSubscribeDialog
v-model="assetSubscribeState.visible"
:assetId="assetSubscribeState.assetId"
:serviceName="assetSubscribeState.serviceName"
/>
</el-config-provider> </el-config-provider>
</template> </template>
@@ -25,12 +19,10 @@ import setIntroduction from '/@/utils/setIconfont';
import LockScreen from '/@/layout/lockScreen/index.vue'; import LockScreen from '/@/layout/lockScreen/index.vue';
import Setings from '/@/layout/navBars/breadcrumb/setings.vue'; import Setings from '/@/layout/navBars/breadcrumb/setings.vue';
import CloseFull from '/@/layout/navBars/breadcrumb/closeFull.vue'; import CloseFull from '/@/layout/navBars/breadcrumb/closeFull.vue';
import AssetSubscribeDialog from '/@/components/assetSubscribe/index.vue';
import { assetSubscribeState } from '/@/utils/assetSubscribe';
export default defineComponent({ export default defineComponent({
name: 'app', name: 'app',
components: { LockScreen, Setings, CloseFull, AssetSubscribeDialog }, components: { LockScreen, Setings, CloseFull },
setup() { setup() {
const { proxy } = <any>getCurrentInstance(); const { proxy } = <any>getCurrentInstance();
const setingsRef = ref(); const setingsRef = ref();
@@ -97,7 +89,6 @@ export default defineComponent({
themeConfig, themeConfig,
setingsRef, setingsRef,
getGlobalComponentSize, getGlobalComponentSize,
assetSubscribeState,
...toRefs(state), ...toRefs(state),
}; };
}, },

View File

@@ -1,277 +0,0 @@
<template>
<el-dialog
v-model="dialogVisible"
title="开通服务"
width="600px"
:close-on-click-modal="false"
@close="handleClose"
>
<div class="subscribe-container">
<div class="service-info">
<el-icon class="warning-icon"><WarningFilled /></el-icon>
<span class="service-name">{{ serviceName }}</span>
<span class="service-tip">服务未开通请选择套餐进行开通</span>
</div>
<div v-if="loading" class="loading-container">
<el-skeleton :rows="3" animated />
</div>
<div v-else-if="skuList.length === 0" class="empty-container">
<el-empty description="暂无可用套餐" />
</div>
<div v-else class="sku-list">
<div
v-for="sku in skuList"
:key="sku.id"
class="sku-item"
:class="{ active: selectedSku?.id === sku.id }"
@click="selectSku(sku)"
>
<div class="sku-header">
<span class="sku-name">{{ sku.skuName }}</span>
<el-tag v-if="sku.unlimitedStock" type="success" size="small">不限库存</el-tag>
</div>
<div class="sku-body">
<div class="sku-specs">
<span class="specs-count">{{ sku.specsCount }}</span>
<span class="specs-unit">{{ sku.specsUnit?.value || '' }}</span>
</div>
<div class="sku-price">
<span class="price-symbol">¥</span>
<span class="price-value">{{ (sku.price / 100).toFixed(2) }}</span>
</div>
</div>
</div>
</div>
</div>
<template #footer>
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" :disabled="!selectedSku" :loading="submitLoading" @click="handleSubscribe">
立即开通
</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue';
import { WarningFilled } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { getAssetAndSku, subscribeAsset } from '/@/api/assets/asset/index';
interface SkuItem {
id: string;
assetId: string;
assetName: string;
skuName: string;
price: number;
specsCount: number;
specsUnit: { key: string; value: string } | null;
unlimitedStock: boolean;
stock: number;
status: number;
}
interface Props {
modelValue: boolean;
assetId: string;
serviceName: string;
}
const props = withDefaults(defineProps<Props>(), {
modelValue: false,
assetId: '',
serviceName: '',
});
const emit = defineEmits<{
(e: 'update:modelValue', value: boolean): void;
(e: 'success', sku: SkuItem): void;
}>();
const dialogVisible = computed({
get: () => props.modelValue,
set: (val) => emit('update:modelValue', val),
});
const loading = ref(false);
const submitLoading = ref(false);
const skuList = ref<SkuItem[]>([]);
const selectedSku = ref<SkuItem | null>(null);
// 监听弹窗打开加载SKU列表
watch(
() => props.modelValue,
(val) => {
if (val && props.assetId) {
loadSkuList();
}
}
);
// 加载SKU列表
const loadSkuList = async () => {
loading.value = true;
selectedSku.value = null;
try {
const res = await getAssetAndSku({
assetId: props.assetId,
});
skuList.value = res.data?.skuList || res.data?.list || [];
// 默认选中第一个
if (skuList.value.length > 0) {
selectedSku.value = skuList.value[0];
}
} catch (error) {
console.error('加载套餐列表失败:', error);
skuList.value = [];
} finally {
loading.value = false;
}
};
// 选择SKU
const selectSku = (sku: SkuItem) => {
selectedSku.value = sku;
};
// 开通服务
const handleSubscribe = async () => {
if (!selectedSku.value) {
ElMessage.warning('请选择套餐');
return;
}
submitLoading.value = true;
try {
await subscribeAsset({
skuId: selectedSku.value.id,
assetId: selectedSku.value.assetId,
});
ElMessage.success('开通成功');
emit('success', selectedSku.value);
handleClose();
// 刷新页面以重新加载数据
window.location.reload();
} catch (error) {
console.error('开通失败:', error);
} finally {
submitLoading.value = false;
}
};
// 关闭弹窗
const handleClose = () => {
dialogVisible.value = false;
selectedSku.value = null;
skuList.value = [];
};
</script>
<style scoped lang="scss">
.subscribe-container {
.service-info {
display: flex;
align-items: center;
gap: 8px;
padding: 16px;
background: #fff7e6;
border-radius: 8px;
margin-bottom: 20px;
.warning-icon {
font-size: 20px;
color: #fa8c16;
}
.service-name {
font-weight: 600;
color: #333;
}
.service-tip {
color: #666;
font-size: 14px;
}
}
.loading-container,
.empty-container {
padding: 40px 0;
}
.sku-list {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
.sku-item {
border: 2px solid #e8e8e8;
border-radius: 12px;
padding: 16px;
cursor: pointer;
transition: all 0.3s;
&:hover {
border-color: #409eff;
box-shadow: 0 2px 12px rgba(64, 158, 255, 0.2);
}
&.active {
border-color: #409eff;
background: #ecf5ff;
}
.sku-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 12px;
.sku-name {
font-size: 16px;
font-weight: 600;
color: #333;
}
}
.sku-body {
display: flex;
justify-content: space-between;
align-items: flex-end;
.sku-specs {
.specs-count {
font-size: 24px;
font-weight: 700;
color: #409eff;
}
.specs-unit {
font-size: 14px;
color: #666;
margin-left: 4px;
}
}
.sku-price {
color: #f56c6c;
.price-symbol {
font-size: 14px;
}
.price-value {
font-size: 20px;
font-weight: 700;
}
}
}
}
}
}
</style>

View File

@@ -1,4 +1,5 @@
import { ref } from 'vue'; // 开通页面地址public/web/subscribe.html
const SUBSCRIBE_PAGE_URL = '/web/subscribe.html';
// 路由路径与 assetId 的映射关系 // 路由路径与 assetId 的映射关系
const ROUTE_ASSET_MAP: Record<string, { assetId: string; serviceName: string }> = { const ROUTE_ASSET_MAP: Record<string, { assetId: string; serviceName: string }> = {
@@ -10,21 +11,8 @@ const ROUTE_ASSET_MAP: Record<string, { assetId: string; serviceName: string }>
// 聚合电商业务(资产管理) // 聚合电商业务(资产管理)
'/assets': { assetId: '696b4acd1be1c8b76c4b4c15', serviceName: '资产管理' }, '/assets': { assetId: '696b4acd1be1c8b76c4b4c15', serviceName: '资产管理' },
// 订单
// '/order': { assetId: '696b4acd1be1c8b76c4b4c15', serviceName: '资产管理' },
// AI数字人
// '/digitalHuman': { assetId: '696f421205e496ba4ccbe662', serviceName: 'AI客服' },
}; };
// 当前弹窗状态(响应式,供组件使用)
export const assetSubscribeState = ref({
visible: false,
assetId: '',
serviceName: '',
});
/** /**
* 根据路由路径获取对应的 assetId 和服务名称 * 根据路由路径获取对应的 assetId 和服务名称
*/ */
@@ -45,26 +33,20 @@ export function getAssetInfoByRoute(routePath: string): { assetId: string; servi
} }
/** /**
* 显示服务开通弹窗 * 跳转到外部开通页面
* @param assetId 资产ID
*/ */
export function showAssetSubscribeDialog(assetId: string, serviceName: string) { export function redirectToSubscribePage(assetId: string) {
console.log('[showAssetSubscribeDialog] 显示弹窗:', { assetId, serviceName }); // 当前页面地址作为返回地址
console.log('[showAssetSubscribeDialog] 修改前状态:', JSON.stringify(assetSubscribeState.value)); const returnUrl = encodeURIComponent(window.location.href);
assetSubscribeState.value.visible = true; // 构建跳转URL
assetSubscribeState.value.assetId = assetId; const url = `${SUBSCRIBE_PAGE_URL}?assetId=${assetId}&returnUrl=${returnUrl}`;
assetSubscribeState.value.serviceName = serviceName; console.log('[redirectToSubscribePage] 跳转到开通页面:', url);
console.log('[showAssetSubscribeDialog] 修改后状态:', JSON.stringify(assetSubscribeState.value)); window.location.href = url;
} }
/** /**
* 关闭服务开通弹窗 * 处理 402 错误码(模块未开通)
*/
export function closeAssetSubscribeDialog() {
assetSubscribeState.value.visible = false;
}
/**
* 处理 403 错误码(模块未开通)
*/ */
export function handleModuleNotEnabled(routePath: string): boolean { export function handleModuleNotEnabled(routePath: string): boolean {
console.log('[模块未开通] 当前路由路径:', routePath); console.log('[模块未开通] 当前路由路径:', routePath);
@@ -72,12 +54,12 @@ export function handleModuleNotEnabled(routePath: string): boolean {
console.log('[模块未开通] 匹配到的资产信息:', assetInfo); console.log('[模块未开通] 匹配到的资产信息:', assetInfo);
if (assetInfo) { if (assetInfo) {
showAssetSubscribeDialog(assetInfo.assetId, assetInfo.serviceName); redirectToSubscribePage(assetInfo.assetId);
return true; return true;
} }
// 如果没有匹配到路由,尝试使用默认的资产管理 // 如果没有匹配到路由,尝试使用默认的资产管理
console.warn('[模块未开通] 未匹配到路由,使用默认资产管理'); console.warn('[模块未开通] 未匹配到路由,使用默认资产管理');
showAssetSubscribeDialog('696b4acd1be1c8b76c4b4c15', '资产管理'); redirectToSubscribePage('696b4acd1be1c8b76c4b4c15');
return true; return true;
} }