93 lines
2.6 KiB
TypeScript
93 lines
2.6 KiB
TypeScript
import { z } from 'zod'
|
|
|
|
import { sysFileFormSchema } from './file'
|
|
import { sysMenuSchema } from './menu'
|
|
|
|
export const sysUserSchema = z.object({
|
|
id: z.number().int(),
|
|
account: z.string(),
|
|
username: z.string(),
|
|
created_at: z.string(),
|
|
updated_at: z.string(),
|
|
avatar_url: z.string().optional(),
|
|
avatar_id: z.number().int().optional(),
|
|
})
|
|
|
|
export type SysUser = z.infer<typeof sysUserSchema>
|
|
|
|
export const sysUserInfoSchema = sysUserSchema
|
|
.pick({
|
|
id: true,
|
|
account: true,
|
|
username: true,
|
|
created_at: true,
|
|
avatar_url: true,
|
|
})
|
|
.extend({
|
|
roles: z.array(z.string()),
|
|
menus: z.array(sysMenuSchema),
|
|
})
|
|
|
|
export type SysUserInfo = z.infer<typeof sysUserInfoSchema>
|
|
|
|
const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{5,16}$/
|
|
|
|
export const changePasswordFormSchema = z
|
|
.object({
|
|
password: z
|
|
.string()
|
|
.min(1, '密码为必填项')
|
|
.regex(passwordRegex, '密码需5-16位且包含字母和数字'),
|
|
confirmPassword: z.string().optional(),
|
|
})
|
|
.superRefine((data, ctx) => {
|
|
if (data.password !== data.confirmPassword) {
|
|
ctx.addIssue({ code: 'custom', path: ['confirmPassword'], message: '两次输入的密码不一致' })
|
|
}
|
|
})
|
|
|
|
export type ChangePasswordForm = z.infer<typeof changePasswordFormSchema>
|
|
|
|
export const sysUserFormSchema = z
|
|
.object({
|
|
id: z.number().optional(),
|
|
account: z
|
|
.string()
|
|
.min(4, '账号至少4个字符')
|
|
.regex(/^[a-zA-Z0-9_]+$/, '账号仅支持字母、数字和下划线'),
|
|
username: z
|
|
.string()
|
|
.min(2, '用户名称至少2个字符')
|
|
.max(16, '用户名称不能超过16个字符')
|
|
.optional(),
|
|
password: z.string().regex(passwordRegex, '密码需5-16位且包含字母和数字').optional(),
|
|
confirmPassword: z.string().optional(),
|
|
avatar: z.array(sysFileFormSchema).optional(),
|
|
})
|
|
.superRefine((data, ctx) => {
|
|
if (!data.id) {
|
|
if (!data.username) {
|
|
ctx.addIssue({ code: 'custom', path: ['username'], message: '用户名称为必填项' })
|
|
}
|
|
|
|
if (!data.password) {
|
|
ctx.addIssue({ code: 'custom', path: ['password'], message: '密码为必填项' })
|
|
}
|
|
|
|
if (data.password !== data.confirmPassword) {
|
|
ctx.addIssue({ code: 'custom', path: ['confirmPassword'], message: '两次输入的密码不一致' })
|
|
}
|
|
}
|
|
})
|
|
.transform((data) => {
|
|
const { avatar, ...rest } = data
|
|
return {
|
|
...rest,
|
|
avatar_id: avatar && avatar.length > 0 ? avatar[0].id : undefined,
|
|
}
|
|
})
|
|
|
|
export type SysUserFormInput = z.input<typeof sysUserFormSchema>
|
|
|
|
export type SysUserFormOutput = z.output<typeof sysUserFormSchema>
|