feat: 对接角色权限与操作日志相关接口字段

This commit is contained in:
ZhuRui
2026-07-30 16:57:22 +08:00
parent 7276425abf
commit 1638643811
16 changed files with 930 additions and 533 deletions
+129 -141
View File
@@ -1,181 +1,169 @@
/**
* 操作日志假数据
* 类型内联定义,避免循环引用。
* 操作日志假数据
* 对应接口:GET /admin/sys/operation/page
*
* 支持按 type、nickname、dateBegin/dateEnd 前端筛选,
* 模拟后端分页行为。
*/
import type { SysOperationLogVO, OperationLogQueryParams, PageData } from '@/api/logs';
interface MockLogVO {
opName: string;
source: string;
nickname: string;
phone: string;
tournamentName: string;
obj: string;
createDate: string;
/** 操作内容详情(mock 扩展字段,API 暂无) */
content?: string;
}
const MOCK_LOGS: MockLogVO[] = [
const MOCK_LOGS: SysOperationLogVO[] = [
{
opName: '删除赛事',
source: '2',
type: 1,
nickname: '张三',
phone: '12345678989',
tournamentName: '第二十一届风林杯羽毛球大赛',
obj: '第二十一届风林杯羽毛球大赛',
createDate: '2026-05-26 08:00:00',
content: '删除赛事',
createDate: '2026-07-30 08:00:00',
content: '下架赛事"第二十一届贝格林羽毛球大赛"',
},
{
opName: '取消报名',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '张三',
createDate: '2026-05-27 10:12:00',
content: '选手"张三"取消报名',
type: 2,
nickname: '张三',
createDate: '2026-07-30 09:30:00',
content: '上架赛事"第二十一届贝格林羽毛球大赛"',
},
{
opName: '编辑选手',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '李四',
createDate: '2026-05-27 10:30:00',
content: '修改姓名,修改前:李四,修改后:张三',
type: 3,
nickname: '李四',
createDate: '2026-07-29 10:12:00',
content: '禁用用户"王五(1003"',
},
{
opName: '编辑选手',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '李四',
createDate: '2026-05-27 10:35:00',
content:
'修改手机号,修改前:1234567899,修改后:13425678997;修改组别,修改前:男子单打,修改后:男子双打',
type: 4,
nickname: '李四',
createDate: '2026-07-29 10:20:00',
content: '启用用户"王五(1003"',
},
{
opName: '批量生成对阵',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '男子小组A,男子小组B,男子小组C',
createDate: '2026-05-27 11:00:00',
content: '生成对阵',
type: 1,
nickname: '赵六',
createDate: '2026-07-28 14:00:00',
content: '下架赛事"春季马拉松大赛"',
},
{
opName: '生成对阵',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '男子小组A',
createDate: '2026-05-27 11:05:00',
content: '生成对阵',
type: 2,
nickname: '赵六',
createDate: '2026-07-28 15:00:00',
content: '上架赛事"春季马拉松大赛"',
},
{
opName: '批量删除对阵',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '男子小组A,男子小组B,男子小组C',
createDate: '2026-05-27 11:10:00',
content: '删除对阵',
type: 3,
nickname: '张三',
createDate: '2026-07-27 09:00:00',
content: '禁用用户"钱七(1005"',
},
{
opName: '删除对阵',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '男子小组A',
createDate: '2026-05-27 11:15:00',
content: '删除对阵',
type: 4,
nickname: '张三',
createDate: '2026-07-27 09:15:00',
content: '启用用户"钱七(1005"',
},
{
opName: '修改比分',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '男子小组A,张三李四,第一局',
createDate: '2026-05-27 12:00:00',
content: '修改前:比分"21:0",修改后:"0:21"',
type: 1,
nickname: '孙八',
createDate: '2026-07-26 16:30:00',
content: '下架赛事"夏季游泳锦标赛"',
},
{
opName: '弃权',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '男子淘汰1,第一轮,张三李四',
createDate: '2026-05-27 13:00:00',
content: '选手"张三"弃权',
type: 2,
nickname: '孙八',
createDate: '2026-07-26 17:00:00',
content: '上架赛事"夏季游泳锦标赛"',
},
{
opName: '弃权',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '男子小组A,张三李四',
createDate: '2026-05-27 13:10:00',
content: '双方弃权,选手"张三"、"李四"',
type: 1,
nickname: '李四',
createDate: '2026-07-25 11:00:00',
content: '下架赛事"秋季篮球邀请赛"',
},
{
opName: '修改对阵',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '男子小组A,张三李四,1',
createDate: '2026-05-27 14:00:00',
content: '修改前:比分"21:10",修改后:比分"21:0"',
type: 2,
nickname: '李四',
createDate: '2026-07-25 12:00:00',
content: '上架赛事"秋季篮球邀请赛"',
},
{
opName: '修改对阵',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '男子小组A,张三李四,双打名额,选手 场地名额',
createDate: '2026-05-27 14:30:00',
content:
'修改前:比分"21:0",对局状态已完成,对阵时间:08:50-09:00,场地号:羽1,修改后:比分"0:0",对局状态为未开始,对阵时间:08:50-09:00,场地号:羽2',
type: 3,
nickname: '周九',
createDate: '2026-07-24 08:30:00',
content: '禁用用户"吴十(1008"',
},
{
opName: '修改场地',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '羽1',
createDate: '2026-05-27 15:00:00',
content: '修改前:羽1,修改后:羽3',
type: 4,
nickname: '周九',
createDate: '2026-07-24 08:45:00',
content: '启用用户"吴十(1008"',
},
{
opName: '修改种子',
source: '1',
nickname: '',
phone: '',
tournamentName: '',
obj: '张某某,张三 场地名额',
createDate: '2026-05-27 15:30:00',
content: '修改前:1号种子,修改后:2号种子',
type: 1,
nickname: '张三',
createDate: '2026-07-23 13:00:00',
content: '下架赛事"冬季滑雪挑战赛"',
},
{
type: 2,
nickname: '张三',
createDate: '2026-07-23 14:00:00',
content: '上架赛事"冬季滑雪挑战赛"',
},
{
type: 3,
nickname: '郑十一',
createDate: '2026-07-22 10:00:00',
content: '禁用用户"冯十二(1012"',
},
{
type: 4,
nickname: '郑十一',
createDate: '2026-07-22 10:10:00',
content: '启用用户"冯十二(1012"',
},
{
type: 1,
nickname: '孙八',
createDate: '2026-07-21 15:30:00',
content: '下架赛事"元旦全民健身跑"',
},
{
type: 2,
nickname: '孙八',
createDate: '2026-07-21 16:00:00',
content: '上架赛事"元旦全民健身跑"',
},
];
interface MockPageData<T> {
total: number;
list: T[];
/** 按日期范围过滤(dateBegin / dateEnd 格式 yyyy-MM-dd */
function inDateRange(dateStr: string, begin?: string, end?: string): boolean {
if (!begin && !end) return true;
const d = dateStr.slice(0, 10); // yyyy-MM-dd
if (begin && d < begin) return false;
if (end && d > end) return false;
return true;
}
export function buildMockOperationLogPage(page: number, limit: number): MockPageData<MockLogVO> {
export function buildMockOperationLogPage(
page: number,
limit: number,
params: OperationLogQueryParams,
): PageData<SysOperationLogVO> {
let filtered = [...MOCK_LOGS];
// 按操作类型筛选(API 传 '1'/'2'/'3'/'4'
if (params.type) {
filtered = filtered.filter((item) => item.type === Number(params.type));
}
// 按操作人昵称模糊筛选
if (params.nickname) {
filtered = filtered.filter((item) => item.nickname.includes(params.nickname!));
}
// 按日期范围筛选
filtered = filtered.filter((item) =>
inDateRange(item.createDate, params.dateBegin, params.dateEnd),
);
const total = filtered.length;
const start = (page - 1) * limit;
return { total: MOCK_LOGS.length, list: MOCK_LOGS.slice(start, start + limit) };
const list = filtered.slice(start, start + limit);
return { total, list };
}
+213
View File
@@ -0,0 +1,213 @@
/**
* 角色权限树假数据
* 对应接口:GET /admin/sys/role/permissionList?roleId=xxx
*
* - 传 roleId=0 时返回全量未选中树(新增角色用)
* - 传已有角色ID时返回带 selected 的树,模拟后端已有权限
*
* 结构对齐 PermissionTreeNode: { id, pid, name, selected, children }
* selected 仅叶节点有值(true/false),父节点为 null
*/
import type { PermissionTreeNode } from '@/api/roles';
/**
* 全量权限树(所有节点的 selected=null,叶节点 selected=false
* 作为未授权角色的默认返回
*/
const FULL_UNSELECTED: PermissionTreeNode[] = [
{
id: 1,
pid: 0,
name: '赛事管理',
selected: null,
children: [
{
id: 11,
pid: 1,
name: '赛事列表',
selected: null,
children: [
{ id: 101, pid: 11, name: '赛事列表-查看', selected: false },
{ id: 102, pid: 11, name: '赛事列表-上架', selected: false },
{ id: 103, pid: 11, name: '赛事列表-下架', selected: false },
],
},
{
id: 12,
pid: 1,
name: '赛事规程',
selected: null,
children: [
{ id: 104, pid: 12, name: '赛事规程-查看', selected: false },
{ id: 105, pid: 12, name: '赛事规程-编辑', selected: false },
],
},
{
id: 13,
pid: 1,
name: '订单管理',
selected: null,
children: [
{ id: 106, pid: 13, name: '订单管理-查看', selected: false },
{ id: 107, pid: 13, name: '订单管理-退款', selected: false },
],
},
{
id: 14,
pid: 1,
name: '用户列表',
selected: null,
children: [{ id: 108, pid: 14, name: '用户列表-查看', selected: false }],
},
{
id: 15,
pid: 1,
name: 'Banner管理',
selected: null,
children: [
{ id: 109, pid: 15, name: 'Banner-查看', selected: false },
{ id: 110, pid: 15, name: 'Banner-新增', selected: false },
{ id: 111, pid: 15, name: 'Banner-编辑', selected: false },
{ id: 112, pid: 15, name: 'Banner-删除', selected: false },
],
},
{
id: 16,
pid: 1,
name: '赛事审核',
selected: null,
children: [
{ id: 113, pid: 16, name: '赛事审核-查看', selected: false },
{ id: 114, pid: 16, name: '赛事审核-通过', selected: false },
{ id: 115, pid: 16, name: '赛事审核-驳回', selected: false },
],
},
],
},
{
id: 2,
pid: 0,
name: '账务管理',
selected: null,
children: [
{
id: 21,
pid: 2,
name: '财务报表',
selected: null,
children: [{ id: 201, pid: 21, name: '财务报表-查看', selected: false }],
},
{
id: 22,
pid: 2,
name: '提现管理',
selected: null,
children: [
{ id: 202, pid: 22, name: '提现管理-查看', selected: false },
{ id: 203, pid: 22, name: '提现管理-审核', selected: false },
],
},
{
id: 23,
pid: 2,
name: '支付流水',
selected: null,
children: [{ id: 204, pid: 23, name: '支付流水-查看', selected: false }],
},
{
id: 24,
pid: 2,
name: '钱包管理',
selected: null,
children: [{ id: 205, pid: 24, name: '钱包管理-查看', selected: false }],
},
],
},
{
id: 3,
pid: 0,
name: '系统管理',
selected: null,
children: [
{
id: 31,
pid: 3,
name: '用户管理',
selected: null,
children: [
{ id: 301, pid: 31, name: '用户管理-查看', selected: false },
{ id: 302, pid: 31, name: '用户管理-新增', selected: false },
{ id: 303, pid: 31, name: '用户管理-编辑', selected: false },
{ id: 304, pid: 31, name: '用户管理-启用/禁用', selected: false },
{ id: 305, pid: 31, name: '用户管理-重置密码', selected: false },
],
},
{
id: 32,
pid: 3,
name: '角色权限',
selected: null,
children: [
{ id: 306, pid: 32, name: '角色权限-查看', selected: false },
{ id: 307, pid: 32, name: '角色权限-新增', selected: false },
{ id: 308, pid: 32, name: '角色权限-编辑', selected: false },
{ id: 309, pid: 32, name: '角色权限-删除', selected: false },
],
},
{
id: 33,
pid: 3,
name: '操作日志',
selected: null,
children: [{ id: 310, pid: 33, name: '操作日志-查看', selected: false }],
},
],
},
];
/**
* 根据角色已有权限ID集合,深拷贝全量树并标记叶节点 selected
*/
function applySelected(tree: PermissionTreeNode[], selectedIds: Set<number>): PermissionTreeNode[] {
return tree.map((node) => {
const isLeaf = !node.children || node.children.length === 0;
if (isLeaf) {
return { ...node, selected: selectedIds.has(node.id) };
}
// 父节点:递归处理子节点,自身 selected 保持 null
return {
...node,
selected: null,
children: applySelected(node.children!, selectedIds),
};
});
}
/**
* 构建权限树假数据
* @param roleId 角色ID,0 表示新增(返回全量未选中),其他值模拟该角色已有权限
*/
export function buildMockPermissionTree(roleId: number): PermissionTreeNode[] {
// roleId=0 → 新增角色,全量未选中
if (roleId === 0) {
return JSON.parse(JSON.stringify(FULL_UNSELECTED));
}
// 模拟不同角色拥有不同权限子集
const rolePermissions: Record<number, number[]> = {
// 超级管理员:全选(所有叶节点)
1: [
101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 201, 202, 203, 204,
205, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310,
],
// 赛事管理员:只有赛事管理模块
2: [101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112],
// 财务:只有账务管理模块
4: [201, 202, 203, 204, 205],
// 其他角色默认仅查看权限
};
const selectedIds = new Set<number>(rolePermissions[roleId] || [101, 201, 301, 306, 310]);
return applySelected(FULL_UNSELECTED, selectedIds);
}
+31
View File
@@ -0,0 +1,31 @@
/**
* 角色列表页假数据(类型内联,避免循环引用)
* 对应接口:GET /sys/role/page
*/
interface MockRoleVO {
roleId: number;
roleName: string;
userCount: number;
createTime: string;
}
interface MockPageData<T> {
total: number;
list: T[];
}
const MOCK_ROLES: MockRoleVO[] = [
{ roleId: 1, roleName: '超级管理员', userCount: 2, createTime: '2025-06-01 09:00:00' },
{ roleId: 2, roleName: '赛事管理员', userCount: 5, createTime: '2025-08-15 14:30:00' },
{ roleId: 3, roleName: '裁判', userCount: 8, createTime: '2025-10-10 10:15:00' },
{ roleId: 4, roleName: '财务', userCount: 3, createTime: '2026-01-20 16:00:00' },
{ roleId: 5, roleName: '运营管理员', userCount: 4, createTime: '2026-03-05 11:00:00' },
{ roleId: 6, roleName: '客服', userCount: 6, createTime: '2026-04-10 08:30:00' },
{ roleId: 7, roleName: '审核员', userCount: 3, createTime: '2026-05-18 13:45:00' },
{ roleId: 8, roleName: '内容编辑', userCount: 2, createTime: '2026-06-22 09:20:00' },
];
export function buildMockRoleListPage(page: number, limit: number): MockPageData<MockRoleVO> {
const start = (page - 1) * limit;
return { total: MOCK_ROLES.length, list: MOCK_ROLES.slice(start, start + limit) };
}
+33
View File
@@ -0,0 +1,33 @@
/**
* 角色下用户列表假数据
* 对应接口:GET /sys/role/usageUserPage
*/
interface MockUserVO {
realName: string;
phone: string;
createTime: string;
status: number;
}
interface MockPageData<T> {
total: number;
list: T[];
}
const MOCK_USERS: MockUserVO[] = [
{ realName: '张超管', phone: '13900000001', createTime: '2025-06-01 09:00:00', status: 1 },
{ realName: '李运营', phone: '15900000002', createTime: '2026-01-10 16:00:00', status: 0 },
{ realName: '王运营', phone: '15900000001', createTime: '2025-10-20 10:00:00', status: 1 },
{ realName: '张运营', phone: '13900000002', createTime: '2025-08-15 14:30:00', status: 1 },
{ realName: '赵裁判', phone: '13800000005', createTime: '2025-10-10 10:15:00', status: 1 },
{ realName: '钱裁判', phone: '13800000006', createTime: '2025-10-12 11:00:00', status: 1 },
{ realName: '孙财务', phone: '13700000007', createTime: '2026-01-20 16:00:00', status: 1 },
{ realName: '周客服', phone: '13700000008', createTime: '2026-01-21 09:30:00', status: 1 },
{ realName: '吴客服', phone: '13700000009', createTime: '2026-01-22 10:00:00', status: 0 },
{ realName: '郑客服', phone: '13700000010', createTime: '2026-01-23 14:00:00', status: 1 },
];
export function buildMockRoleUsageUserPage(page: number, limit: number): MockPageData<MockUserVO> {
const start = (page - 1) * limit;
return { total: MOCK_USERS.length, list: MOCK_USERS.slice(start, start + limit) };
}