130 lines
3.6 KiB
TypeScript
130 lines
3.6 KiB
TypeScript
import { dashboardSummary, menuRoutes, USER_STATUS, users, type MockUser } from './data'
|
|
|
|
export interface MockContext {
|
|
url: string
|
|
params: string[]
|
|
query: Record<string, string>
|
|
body: Record<string, unknown>
|
|
}
|
|
|
|
export interface MockRule {
|
|
method: 'GET' | 'POST' | 'PUT' | 'DELETE'
|
|
pattern: RegExp
|
|
handler: (ctx: MockContext) => unknown
|
|
}
|
|
|
|
const toNumber = (value: unknown, fallback = 0) => {
|
|
const n = Number(value)
|
|
return Number.isFinite(n) ? n : fallback
|
|
}
|
|
|
|
const pickString = (value: unknown, fallback = '') => (typeof value === 'string' ? value : fallback)
|
|
|
|
export const mockRules: MockRule[] = [
|
|
{
|
|
method: 'POST',
|
|
pattern: /^\/api\/v1\/auth\/login$/,
|
|
handler: (ctx) => ({
|
|
accessToken: 'mock-access-token',
|
|
refreshToken: 'mock-refresh-token',
|
|
tokenType: 'Bearer',
|
|
expiresIn: 7200,
|
|
username: pickString(ctx.body.username, 'admin'),
|
|
}),
|
|
},
|
|
{
|
|
method: 'POST',
|
|
pattern: /^\/api\/v1\/auth\/logout$/,
|
|
handler: () => true,
|
|
},
|
|
{
|
|
method: 'GET',
|
|
pattern: /^\/api\/v1\/auth\/me$/,
|
|
handler: () => ({
|
|
userId: 1,
|
|
username: 'admin',
|
|
nickname: '超级管理员',
|
|
avatar: '',
|
|
roles: ['ADMIN'],
|
|
permissions: ['sys:user:add', 'sys:user:edit', 'sys:user:delete', 'sys:user:query'],
|
|
}),
|
|
},
|
|
{
|
|
method: 'GET',
|
|
pattern: /^\/api\/v1\/auth\/routes$/,
|
|
handler: () => menuRoutes,
|
|
},
|
|
{
|
|
method: 'GET',
|
|
pattern: /^\/api\/v1\/users\/page$/,
|
|
handler: (ctx) => {
|
|
const { username, status } = ctx.query
|
|
const pageNum = toNumber(ctx.query.pageNum, 1)
|
|
const pageSize = toNumber(ctx.query.pageSize, 10)
|
|
|
|
const filtered = users.filter((item) => {
|
|
const matchName = !username || item.username.includes(username)
|
|
const matchStatus = !status || String(item.status) === status
|
|
return matchName && matchStatus
|
|
})
|
|
|
|
const start = (pageNum - 1) * pageSize
|
|
return { list: filtered.slice(start, start + pageSize), total: filtered.length }
|
|
},
|
|
},
|
|
{
|
|
method: 'GET',
|
|
pattern: /^\/api\/v1\/users\/(\d+)$/,
|
|
handler: (ctx) => users.find((item) => item.id === toNumber(ctx.params[0])) ?? null,
|
|
},
|
|
{
|
|
method: 'POST',
|
|
pattern: /^\/api\/v1\/users$/,
|
|
handler: (ctx) => {
|
|
const id = users.length + 1
|
|
const created: MockUser = {
|
|
id,
|
|
username: pickString(ctx.body.username, `user${id}`),
|
|
nickname: pickString(ctx.body.nickname),
|
|
mobile: pickString(ctx.body.mobile),
|
|
email: pickString(ctx.body.email),
|
|
status: toNumber(ctx.body.status, USER_STATUS.ENABLED) === 0 ? 0 : 1,
|
|
deptName: pickString(ctx.body.deptName, '技术部'),
|
|
roleNames: Array.isArray(ctx.body.roleNames)
|
|
? (ctx.body.roleNames as string[])
|
|
: ['普通用户'],
|
|
createTime: new Date().toISOString(),
|
|
}
|
|
users.unshift(created)
|
|
return id
|
|
},
|
|
},
|
|
{
|
|
method: 'PUT',
|
|
pattern: /^\/api\/v1\/users\/(\d+)$/,
|
|
handler: (ctx) => {
|
|
const target = users.find((item) => item.id === toNumber(ctx.params[0]))
|
|
if (!target) return false
|
|
Object.assign(target, ctx.body)
|
|
return true
|
|
},
|
|
},
|
|
{
|
|
method: 'DELETE',
|
|
pattern: /^\/api\/v1\/users\/([\d,]+)$/,
|
|
handler: (ctx) => {
|
|
const ids = ctx.params[0].split(',').map((id) => toNumber(id))
|
|
ids.forEach((id) => {
|
|
const index = users.findIndex((item) => item.id === id)
|
|
if (index > -1) users.splice(index, 1)
|
|
})
|
|
return true
|
|
},
|
|
},
|
|
{
|
|
method: 'GET',
|
|
pattern: /^\/api\/v1\/dashboard\/summary$/,
|
|
handler: () => dashboardSummary,
|
|
},
|
|
]
|