08ea5fbe98
添加用户管理视图、API和状态管理文件
311 lines
7.0 KiB
TypeScript
311 lines
7.0 KiB
TypeScript
/**
|
|
* 测试数据工厂
|
|
* 生成各种测试数据,支持边界条件和异常数据
|
|
*/
|
|
|
|
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();
|