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 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 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 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 export type SysUserFormOutput = z.output