fix: 修复商户中心下拉跳转无匹配路由
启用 external 路由并注册 MerchantCenter 页面,补齐商户中心文案与页面实现,确保头像下拉点击可正常进入商户中心。
This commit is contained in:
41
apps/web-antd/src/api/merchant/index.ts
Normal file
41
apps/web-antd/src/api/merchant/index.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
/**
|
||||
* 商户信息 DTO
|
||||
*/
|
||||
export interface MerchantDto {
|
||||
/** 商户ID */
|
||||
id: string;
|
||||
/** 商户名称 */
|
||||
merchantName: string;
|
||||
/** 联系人 */
|
||||
contactName: string;
|
||||
/** 联系电话 */
|
||||
contactPhone: string;
|
||||
/** 商户地址 */
|
||||
address: string;
|
||||
/** 商户状态 (1: 正常, 2: 禁用) */
|
||||
status: number;
|
||||
/** 营业执照代码 */
|
||||
businessLicenseCode: string;
|
||||
/** 商户简介 */
|
||||
description: string;
|
||||
/** 创建时间 */
|
||||
createTime: string;
|
||||
/** 商户Logo */
|
||||
logo?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前商户信息
|
||||
*/
|
||||
export async function getMerchantInfoApi() {
|
||||
return requestClient.get<MerchantDto>('/merchant/info');
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新商户信息
|
||||
*/
|
||||
export async function updateMerchantInfoApi(data: Partial<MerchantDto>) {
|
||||
return requestClient.post('/merchant/update', data);
|
||||
}
|
||||
@@ -87,7 +87,7 @@ const showDot = computed(() =>
|
||||
const menus = computed(() => [
|
||||
{
|
||||
handler: () => {
|
||||
router.push({ name: 'Profile' });
|
||||
router.push({ name: 'MerchantCenter' });
|
||||
},
|
||||
icon: 'lucide:store',
|
||||
text: '商户中心',
|
||||
|
||||
@@ -11,5 +11,9 @@
|
||||
"title": "概览",
|
||||
"analytics": "分析页",
|
||||
"workspace": "工作台"
|
||||
},
|
||||
"merchant": {
|
||||
"title": "商户管理",
|
||||
"center": "商户中心"
|
||||
}
|
||||
}
|
||||
|
||||
29
apps/web-antd/src/router/routes/external/merchant.ts
vendored
Normal file
29
apps/web-antd/src/router/routes/external/merchant.ts
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
|
||||
import { BasicLayout } from '#/layouts';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
component: BasicLayout,
|
||||
meta: {
|
||||
hideInMenu: true,
|
||||
title: $t('page.merchant.title'),
|
||||
},
|
||||
name: 'MerchantLayout',
|
||||
path: '/merchant',
|
||||
children: [
|
||||
{
|
||||
name: 'MerchantCenter',
|
||||
path: 'center',
|
||||
component: () => import('#/views/merchant/center/index.vue'),
|
||||
meta: {
|
||||
hideInMenu: true,
|
||||
title: $t('page.merchant.center'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export default routes;
|
||||
@@ -9,17 +9,18 @@ const dynamicRouteFiles = import.meta.glob('./modules/**/*.ts', {
|
||||
});
|
||||
|
||||
// 有需要可以自行打开注释,并创建文件夹
|
||||
// const externalRouteFiles = import.meta.glob('./external/**/*.ts', { eager: true });
|
||||
const externalRouteFiles = import.meta.glob('./external/**/*.ts', {
|
||||
eager: true,
|
||||
});
|
||||
// const staticRouteFiles = import.meta.glob('./static/**/*.ts', { eager: true });
|
||||
|
||||
/** 动态路由 */
|
||||
const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles);
|
||||
|
||||
/** 外部路由列表,访问这些页面可以不需要Layout,可能用于内嵌在别的系统(不会显示在菜单中) */
|
||||
// const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles);
|
||||
// const staticRoutes: RouteRecordRaw[] = mergeRouteModules(staticRouteFiles);
|
||||
const staticRoutes: RouteRecordRaw[] = [];
|
||||
const externalRoutes: RouteRecordRaw[] = [];
|
||||
const externalRoutes: RouteRecordRaw[] = mergeRouteModules(externalRouteFiles);
|
||||
|
||||
/** 路由列表,由基本路由、外部路由和404兜底路由组成
|
||||
* 无需走权限验证(会一直显示在菜单中) */
|
||||
|
||||
112
apps/web-antd/src/views/merchant/center/index.vue
Normal file
112
apps/web-antd/src/views/merchant/center/index.vue
Normal file
@@ -0,0 +1,112 @@
|
||||
<script setup lang="ts">
|
||||
import type { MerchantDto } from '#/api/merchant';
|
||||
|
||||
import { computed, onMounted, ref } from 'vue';
|
||||
|
||||
import { Profile } from '@vben/common-ui';
|
||||
import { useUserStore } from '@vben/stores';
|
||||
|
||||
import { getMerchantInfoApi } from '#/api/merchant';
|
||||
|
||||
// 1. 状态定义
|
||||
const userStore = useUserStore();
|
||||
const merchantInfo = ref<MerchantDto | null>(null);
|
||||
const loading = ref(false);
|
||||
const tabsValue = ref('basic');
|
||||
|
||||
const tabs = [
|
||||
{
|
||||
label: '基本信息',
|
||||
value: 'basic',
|
||||
},
|
||||
{
|
||||
label: '资质信息',
|
||||
value: 'license',
|
||||
},
|
||||
];
|
||||
|
||||
// 2. 获取数据
|
||||
async function fetchMerchantInfo() {
|
||||
loading.value = true;
|
||||
try {
|
||||
const data = await getMerchantInfoApi();
|
||||
merchantInfo.value = data;
|
||||
} catch (error) {
|
||||
console.error('获取商户信息失败:', error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchMerchantInfo();
|
||||
});
|
||||
|
||||
// 3. 格式化显示
|
||||
const displayInfo = computed(() => [
|
||||
{ label: '商户名称', value: merchantInfo.value?.merchantName },
|
||||
{ label: '联系人', value: merchantInfo.value?.contactName },
|
||||
{ label: '联系电话', value: merchantInfo.value?.contactPhone },
|
||||
{ label: '商户地址', value: merchantInfo.value?.address },
|
||||
{ label: '创建时间', value: merchantInfo.value?.createTime },
|
||||
]);
|
||||
|
||||
const licenseInfo = computed(() => [
|
||||
{ label: '营业执照代码', value: merchantInfo.value?.businessLicenseCode },
|
||||
{ label: '商户简介', value: merchantInfo.value?.description },
|
||||
]);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-5">
|
||||
<Profile
|
||||
v-model:model-value="tabsValue"
|
||||
:title="$t('page.merchant.center')"
|
||||
:user-info="{
|
||||
realName: merchantInfo?.merchantName || '加载中...',
|
||||
avatar: merchantInfo?.logo || userStore.userInfo?.avatar || '',
|
||||
userId: userStore.userInfo?.userId || '',
|
||||
username: merchantInfo?.contactName || '',
|
||||
}"
|
||||
:tabs="tabs"
|
||||
>
|
||||
<template #content>
|
||||
<div v-loading="loading" class="rounded-lg bg-card p-6">
|
||||
<!-- 基本信息 -->
|
||||
<div v-if="tabsValue === 'basic'">
|
||||
<h3 class="mb-4 text-lg font-medium">基本信息</h3>
|
||||
<a-descriptions :column="1" bordered>
|
||||
<a-descriptions-item
|
||||
v-for="item in displayInfo"
|
||||
:key="item.label"
|
||||
:label="item.label"
|
||||
>
|
||||
{{ item.value || '-' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
|
||||
<!-- 资质信息 -->
|
||||
<div v-if="tabsValue === 'license'">
|
||||
<h3 class="mb-4 text-lg font-medium">资质信息</h3>
|
||||
<a-descriptions :column="1" bordered>
|
||||
<a-descriptions-item
|
||||
v-for="item in licenseInfo"
|
||||
:key="item.label"
|
||||
:label="item.label"
|
||||
>
|
||||
{{ item.value || '-' }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Profile>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.bg-card {
|
||||
background-color: var(--el-bg-color-overlay);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user