feat(admin): 添加用户管理相关文件
添加用户管理视图、API和状态管理文件
This commit is contained in:
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
* 测试数据工厂
|
||||
* 生成各种测试数据,支持边界条件和异常数据
|
||||
*/
|
||||
|
||||
import { faker } from '@faker-js/faker';
|
||||
import { zh_CN } from '@faker-js/faker/locale/zh_CN';
|
||||
|
||||
faker.locale = zh_CN;
|
||||
|
||||
export interface UserData {
|
||||
id?: number;
|
||||
username: string;
|
||||
realName: string;
|
||||
email: string;
|
||||
phone: string;
|
||||
password: string;
|
||||
confirmPassword: string;
|
||||
gender: number;
|
||||
status: number;
|
||||
avatar?: string;
|
||||
createBy?: string;
|
||||
updateBy?: string;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface RoleData {
|
||||
id?: number;
|
||||
roleName: string;
|
||||
roleCode: string;
|
||||
description: string;
|
||||
status: number;
|
||||
permissions?: string[];
|
||||
createBy?: string;
|
||||
updateBy?: string;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface MenuData {
|
||||
id?: number;
|
||||
menuName: string;
|
||||
menuCode: string;
|
||||
path: string;
|
||||
icon: string;
|
||||
sortOrder: number;
|
||||
status: number;
|
||||
parentId: number;
|
||||
menuType: number;
|
||||
component?: string;
|
||||
permission?: string;
|
||||
createBy?: string;
|
||||
updateBy?: string;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
export interface AlmanacData {
|
||||
date: string;
|
||||
lunarDate: string;
|
||||
ganZhi: string;
|
||||
zodiac: string;
|
||||
yi: string[];
|
||||
ji: string[];
|
||||
jieQi?: string;
|
||||
sha?: string;
|
||||
jiShen?: string[];
|
||||
xiongShen?: string[];
|
||||
}
|
||||
|
||||
export interface CalendarData {
|
||||
year: number;
|
||||
month: number;
|
||||
day: number;
|
||||
lunarYear: number;
|
||||
lunarMonth: number;
|
||||
lunarDay: number;
|
||||
lunarMonthName: string;
|
||||
lunarDayName: string;
|
||||
ganZhiYear: string;
|
||||
ganZhiMonth: string;
|
||||
ganZhiDay: string;
|
||||
zodiac: string;
|
||||
isLeapMonth: boolean;
|
||||
isToday: boolean;
|
||||
}
|
||||
|
||||
class TestDataFactory {
|
||||
/**
|
||||
* 生成正常用户数据
|
||||
*/
|
||||
generateUserData(overrides: Partial<UserData> = {}): UserData {
|
||||
const timestamp = Date.now();
|
||||
const password = 'Test@123456';
|
||||
|
||||
return {
|
||||
username: `testuser_${timestamp}`,
|
||||
realName: faker.person.fullName(),
|
||||
email: `test_${timestamp}@example.com`,
|
||||
phone: `1${faker.string.numeric(10)}`,
|
||||
password,
|
||||
confirmPassword: password,
|
||||
gender: faker.number.int({ min: 0, max: 2 }),
|
||||
status: 1,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成边界条件用户数据
|
||||
*/
|
||||
generateBoundaryUserData(type: 'min' | 'max' | 'empty' | 'special'): Partial<UserData> {
|
||||
const timestamp = Date.now();
|
||||
|
||||
switch (type) {
|
||||
case 'min':
|
||||
return {
|
||||
username: 'abc',
|
||||
nickname: '测',
|
||||
email: 'test@example.com',
|
||||
phone: '13800138000',
|
||||
password: 'A1@aaaa',
|
||||
confirmPassword: 'A1@aaaa',
|
||||
roleIds: [1], // 添加默认角色
|
||||
};
|
||||
case 'max':
|
||||
return {
|
||||
username: 'a'.repeat(20),
|
||||
nickname: '测'.repeat(50),
|
||||
email: `test${timestamp}@example.com`,
|
||||
phone: '13800138000',
|
||||
password: 'A1@' + 'a'.repeat(17),
|
||||
confirmPassword: 'A1@' + 'a'.repeat(17),
|
||||
roleIds: [1],
|
||||
};
|
||||
case 'empty':
|
||||
return {
|
||||
username: '',
|
||||
nickname: '',
|
||||
email: '',
|
||||
phone: '',
|
||||
password: '',
|
||||
confirmPassword: '',
|
||||
roleIds: [],
|
||||
};
|
||||
case 'special':
|
||||
return {
|
||||
username: `test_${timestamp}`,
|
||||
nickname: '测试<script>alert(1)</script>',
|
||||
email: `test+${timestamp}@example.com`,
|
||||
phone: '13800138000',
|
||||
password: 'Test@123!@#$%^&*()',
|
||||
confirmPassword: 'Test@123!@#$%^&*()',
|
||||
roleIds: [1],
|
||||
};
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成异常用户数据
|
||||
*/
|
||||
generateInvalidUserData(type: 'duplicate' | 'invalid_email' | 'invalid_phone' | 'weak_password'): Partial<UserData> {
|
||||
const timestamp = Date.now();
|
||||
|
||||
switch (type) {
|
||||
case 'duplicate':
|
||||
return {
|
||||
username: 'admin',
|
||||
email: 'admin@example.com',
|
||||
};
|
||||
case 'invalid_email':
|
||||
return {
|
||||
email: 'invalid-email',
|
||||
};
|
||||
case 'invalid_phone':
|
||||
return {
|
||||
phone: '12345678901',
|
||||
};
|
||||
case 'weak_password':
|
||||
return {
|
||||
password: '123456',
|
||||
confirmPassword: '123456',
|
||||
};
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成角色数据
|
||||
*/
|
||||
generateRoleData(overrides: Partial<RoleData> = {}): RoleData {
|
||||
const timestamp = Date.now();
|
||||
|
||||
return {
|
||||
roleName: `测试角色_${timestamp}`,
|
||||
roleCode: `test_role_${timestamp}`,
|
||||
description: faker.lorem.sentence(),
|
||||
status: 1,
|
||||
permissions: [],
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成菜单数据
|
||||
*/
|
||||
generateMenuData(overrides: Partial<MenuData> = {}): MenuData {
|
||||
const timestamp = Date.now();
|
||||
|
||||
return {
|
||||
menuName: `测试菜单_${timestamp}`,
|
||||
menuCode: `test_menu_${timestamp}`,
|
||||
path: `/test-menu-${timestamp}`,
|
||||
icon: 'SettingOutlined',
|
||||
sortOrder: faker.number.int({ min: 1, max: 100 }),
|
||||
status: 0,
|
||||
parentId: 0,
|
||||
menuType: 1,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成黄历数据
|
||||
*/
|
||||
generateAlmanacData(date: string = new Date().toISOString().split('T')[0]): AlmanacData {
|
||||
return {
|
||||
date,
|
||||
lunarDate: '农历日期',
|
||||
ganZhi: '甲子年 丙寅月 戊辰日',
|
||||
zodiac: '鼠',
|
||||
yi: ['嫁娶', '祭祀', '祈福', '求嗣', '开光', '出行'],
|
||||
ji: ['开市', '立券', '交易', '纳财'],
|
||||
jieQi: '立春',
|
||||
sha: '南',
|
||||
jiShen: ['天德', '月德', '天恩'],
|
||||
xiongShen: ['月破', '大耗', '四击'],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成日历数据
|
||||
*/
|
||||
generateCalendarData(year: number = new Date().getFullYear(), month: number = new Date().getMonth() + 1): CalendarData {
|
||||
return {
|
||||
year,
|
||||
month,
|
||||
day: 15,
|
||||
lunarYear: year,
|
||||
lunarMonth: month,
|
||||
lunarDay: 15,
|
||||
lunarMonthName: '正月',
|
||||
lunarDayName: '十五',
|
||||
ganZhiYear: '甲子',
|
||||
ganZhiMonth: '丙寅',
|
||||
ganZhiDay: '戊辰',
|
||||
zodiac: '鼠',
|
||||
isLeapMonth: false,
|
||||
isToday: false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成批量测试数据
|
||||
*/
|
||||
generateBatchData<T>(
|
||||
generator: () => T,
|
||||
count: number,
|
||||
overrides: Partial<T> = {}
|
||||
): T[] {
|
||||
return Array.from({ length: count }, () => ({
|
||||
...generator(),
|
||||
...overrides,
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成测试日期范围
|
||||
*/
|
||||
generateDateRange(days: number = 30): { start: string; end: string } {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setDate(start.getDate() - days);
|
||||
|
||||
return {
|
||||
start: start.toISOString().split('T')[0],
|
||||
end: end.toISOString().split('T')[0],
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成特殊日期
|
||||
*/
|
||||
generateSpecialDates(): Record<string, string> {
|
||||
const year = new Date().getFullYear();
|
||||
return {
|
||||
newYear: `${year}-01-01`,
|
||||
springFestival: `${year}-02-10`, // 示例春节日期
|
||||
laborDay: `${year}-05-01`,
|
||||
nationalDay: `${year}-10-01`,
|
||||
leapYearFeb29: `${year % 4 === 0 ? year : year + 4}-02-29`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const testDataFactory = new TestDataFactory();
|
||||
Reference in New Issue
Block a user