1. 新增门店列表页(筛选/统计/表格/抽屉编辑),使用 mockjs 提供接口数据 2. 新增门店相关枚举、API 定义、路由配置 3. 修复 auth.ts loginApi 参数类型不匹配 4. 修复 merchant-center stores 属性路径错误及 merchant prop 类型不兼容 5. 修复 merchant-setting showSubmitButton 不存在于 VbenFormProps
254 lines
6.3 KiB
TypeScript
254 lines
6.3 KiB
TypeScript
import Mock from 'mockjs';
|
||
|
||
const Random = Mock.Random;
|
||
|
||
/** mockjs 请求回调参数 */
|
||
interface MockRequestOptions {
|
||
url: string;
|
||
type: string;
|
||
body: null | string;
|
||
}
|
||
|
||
/** 门店筛选参数 */
|
||
interface StoreFilterParams {
|
||
keyword?: string;
|
||
businessStatus?: string;
|
||
auditStatus?: string;
|
||
serviceType?: string;
|
||
page?: string;
|
||
pageSize?: string;
|
||
}
|
||
|
||
// 预定义门店数据,保证每次请求返回一致的数据
|
||
const storePool = generateStores(23);
|
||
|
||
function generateStores(count: number) {
|
||
const districts = [
|
||
'朝阳区建国路88号',
|
||
'海淀区中关村大街66号',
|
||
'朝阳区望京西路50号',
|
||
'通州区新华大街120号',
|
||
'丰台区丰台路18号',
|
||
'西城区西单北大街100号',
|
||
'东城区王府井大街200号',
|
||
'大兴区黄村镇兴华路30号',
|
||
'昌平区回龙观东大街15号',
|
||
'顺义区府前街8号',
|
||
'石景山区石景山路22号',
|
||
'房山区良乡拱辰大街55号',
|
||
'密云区鼓楼东大街10号',
|
||
'怀柔区青春路6号',
|
||
'平谷区府前街12号',
|
||
'门头沟区新桥大街3号',
|
||
'延庆区妫水北街9号',
|
||
'亦庄经济开发区荣华南路1号',
|
||
'望京SOHO T1-2层',
|
||
'三里屯太古里南区B1',
|
||
'国贸商城3层',
|
||
'五道口华联商厦1层',
|
||
'中关村食宝街B1层',
|
||
];
|
||
|
||
const managerNames = [
|
||
'张伟',
|
||
'李娜',
|
||
'王磊',
|
||
'赵敏',
|
||
'刘洋',
|
||
'陈静',
|
||
'杨帆',
|
||
'周杰',
|
||
'吴芳',
|
||
'孙涛',
|
||
'马丽',
|
||
'朱军',
|
||
'胡明',
|
||
'郭强',
|
||
'何欢',
|
||
'林峰',
|
||
'徐婷',
|
||
'高远',
|
||
'罗斌',
|
||
'梁宇',
|
||
'宋佳',
|
||
'唐亮',
|
||
'韩雪',
|
||
];
|
||
|
||
const storeNames = [
|
||
'老三家外卖(朝阳店)',
|
||
'老三家外卖(海淀店)',
|
||
'老三家外卖(望京店)',
|
||
'老三家外卖(通州店)',
|
||
'老三家外卖(丰台店)',
|
||
'老三家外卖(西单店)',
|
||
'老三家外卖(王府井店)',
|
||
'老三家外卖(大兴店)',
|
||
'老三家外卖(回龙观店)',
|
||
'老三家外卖(顺义店)',
|
||
'老三家外卖(石景山店)',
|
||
'老三家外卖(良乡店)',
|
||
'老三家外卖(密云店)',
|
||
'老三家外卖(怀柔店)',
|
||
'老三家外卖(平谷店)',
|
||
'老三家外卖(门头沟店)',
|
||
'老三家外卖(延庆店)',
|
||
'老三家外卖(亦庄店)',
|
||
'老三家外卖(望京SOHO店)',
|
||
'老三家外卖(三里屯店)',
|
||
'老三家外卖(国贸店)',
|
||
'老三家外卖(五道口店)',
|
||
'老三家外卖(中关村店)',
|
||
];
|
||
|
||
const avatarColors = [
|
||
'#3b82f6',
|
||
'#f59e0b',
|
||
'#8b5cf6',
|
||
'#ef4444',
|
||
'#22c55e',
|
||
'#06b6d4',
|
||
'#ec4899',
|
||
'#f97316',
|
||
'#14b8a6',
|
||
'#6366f1',
|
||
];
|
||
|
||
const stores = [];
|
||
for (let i = 0; i < count; i++) {
|
||
// 1. 按索引分配营业状态,模拟真实分布
|
||
let businessStatus = 1;
|
||
if (i >= 21) {
|
||
businessStatus = Random.pick([1, 2, 3]);
|
||
} else if (i >= 18) {
|
||
businessStatus = 3;
|
||
} else if (i >= 14) {
|
||
businessStatus = 2;
|
||
}
|
||
|
||
// 2. 按索引分配审核状态
|
||
let auditStatus = 2;
|
||
if (i < 20) {
|
||
auditStatus = 1;
|
||
} else if (i < 22) {
|
||
auditStatus = 0;
|
||
}
|
||
|
||
// 3. 循环分配服务方式组合
|
||
const serviceTypeCombos = [[1], [1, 2], [1, 2, 3], [1, 3], [2, 3]];
|
||
|
||
stores.push({
|
||
id: Random.guid(),
|
||
name: storeNames[i] || `老三家外卖(分店${i + 1})`,
|
||
code: `ST2025${String(i + 1).padStart(4, '0')}`,
|
||
contactPhone: `138****${String(8001 + i).slice(-4)}`,
|
||
managerName: managerNames[i] || Random.cname(),
|
||
address: `北京市${districts[i] || `朝阳区某路${i + 1}号`}`,
|
||
coverImage: '',
|
||
businessStatus,
|
||
auditStatus,
|
||
serviceTypes: serviceTypeCombos[i % serviceTypeCombos.length],
|
||
createdAt: Random.datetime('yyyy-MM-dd'),
|
||
_avatarColor: avatarColors[i % avatarColors.length],
|
||
});
|
||
}
|
||
return stores;
|
||
}
|
||
|
||
function filterStores(params: StoreFilterParams) {
|
||
let list = [...storePool];
|
||
|
||
// 1. 关键词模糊匹配(名称/编码/电话)
|
||
if (params.keyword) {
|
||
const kw = params.keyword.toLowerCase();
|
||
list = list.filter(
|
||
(s) =>
|
||
s.name.toLowerCase().includes(kw) ||
|
||
s.code.toLowerCase().includes(kw) ||
|
||
s.contactPhone.includes(kw),
|
||
);
|
||
}
|
||
|
||
// 2. 营业状态筛选
|
||
if (params.businessStatus) {
|
||
const status = Number(params.businessStatus);
|
||
list = list.filter((s) => s.businessStatus === status);
|
||
}
|
||
|
||
// 3. 审核状态筛选
|
||
if (params.auditStatus !== undefined && params.auditStatus !== '') {
|
||
const status = Number(params.auditStatus);
|
||
list = list.filter((s) => s.auditStatus === status);
|
||
}
|
||
|
||
// 4. 服务方式筛选
|
||
if (params.serviceType) {
|
||
const type = Number(params.serviceType);
|
||
list = list.filter((s) => (s.serviceTypes ?? []).includes(type));
|
||
}
|
||
|
||
return list;
|
||
}
|
||
|
||
/** 从 URL 中解析查询参数 */
|
||
function parseUrlParams(url: string): StoreFilterParams {
|
||
const parsed = new URL(url, 'http://localhost');
|
||
const params: Record<string, string> = {};
|
||
parsed.searchParams.forEach((value, key) => {
|
||
params[key] = value;
|
||
});
|
||
return params;
|
||
}
|
||
|
||
// 门店列表
|
||
Mock.mock(/\/store\/list/, 'get', (options: MockRequestOptions) => {
|
||
const params = parseUrlParams(options.url);
|
||
|
||
const page = Number(params.page) || 1;
|
||
const pageSize = Number(params.pageSize) || 10;
|
||
const filtered = filterStores(params);
|
||
const start = (page - 1) * pageSize;
|
||
const items = filtered.slice(start, start + pageSize);
|
||
|
||
return {
|
||
code: 200,
|
||
data: {
|
||
items,
|
||
total: filtered.length,
|
||
page,
|
||
pageSize,
|
||
},
|
||
};
|
||
});
|
||
|
||
// 门店统计
|
||
Mock.mock(/\/store\/stats/, 'get', () => {
|
||
return {
|
||
code: 200,
|
||
data: {
|
||
total: storePool.length,
|
||
operating: storePool.filter((s) => s.businessStatus === 1).length,
|
||
resting: storePool.filter((s) => s.businessStatus === 2).length,
|
||
pendingAudit: storePool.filter((s) => s.auditStatus === 0).length,
|
||
},
|
||
};
|
||
});
|
||
|
||
// 创建门店
|
||
Mock.mock(/\/store\/create/, 'post', () => {
|
||
return { code: 200, data: null };
|
||
});
|
||
|
||
// 更新门店
|
||
Mock.mock(/\/store\/update/, 'post', () => {
|
||
return { code: 200, data: null };
|
||
});
|
||
|
||
// 删除门店
|
||
Mock.mock(/\/store\/delete/, 'post', () => {
|
||
return { code: 200, data: null };
|
||
});
|
||
|
||
// 设置 mock 响应延迟
|
||
Mock.setup({ timeout: '200-400' });
|