import { z } from '@hono/zod-openapi'; export const LoginSchema = z.object({ username: z.string().min(3).openapi({ example: 'admin', description: '用户名' }), password: z.string().min(6).openapi({ example: 'admin123', description: '密码' }) }); export const RegisterSchema = z.object({ username: z.string().min(3).openapi({ example: 'john_doe', description: '用户名' }), password: z.string().min(6).openapi({ example: 'password123', description: '密码' }), email: z.string().email().openapi({ example: 'john@example.com', description: '邮箱' }).optional() }); export const MiniLoginSchema = z.object({ code: z.string().openapi({ example: '08123456789012345678901234567890', description: '小程序登录code' }), userInfo: z.object({ nickName: z.string().optional(), avatarUrl: z.string().optional() }).optional() }); export const UserResponseSchema = z.object({ id: z.number().int().positive().openapi({ description: '用户ID' }), tenantId: z.number().int().positive().openapi({ description: '租户ID' }), username: z.string().min(3, '用户名至少3个字符').max(255, '用户名最多255个字符').openapi({ example: 'admin', description: '用户名,3-255个字符' }), phone: z.string().max(255, '手机号最多255个字符').nullable().openapi({ example: '13800138000', description: '手机号' }), email: z.string().email('请输入正确的邮箱格式').max(255, '邮箱最多255个字符').nullable().openapi({ example: 'user@example.com', description: '邮箱' }), nickname: z.string().max(255, '昵称最多255个字符').nullable().openapi({ example: '昵称', description: '用户昵称' }), name: z.string().max(255, '姓名最多255个字符').nullable().openapi({ example: '张三', description: '真实姓名' }), avatarFileId: z.number().int().positive().nullable().openapi({ example: 1, description: '头像文件ID' }), avatarFile: z.object({ id: z.number().int().positive().openapi({ description: '文件ID' }), name: z.string().max(255).openapi({ description: '文件名', example: 'avatar.jpg' }), fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/avatar.jpg' }), type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }), size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 }) }).nullable().optional().openapi({ description: '头像文件信息' }), openid: z.string().max(255).nullable().optional().openapi({ example: 'oABCDEFGH123456789', description: '微信小程序openid' }), unionid: z.string().max(255).nullable().optional().openapi({ example: 'unionid123456789', description: '微信unionid' }), registrationSource: z.string().max(20).default('web').openapi({ example: 'miniapp', description: '注册来源: web, miniapp' }), isDisabled: z.number().int().min(0).max(1).default(0).openapi({ example: 0, description: '是否禁用(0:启用,1:禁用)' }), isDeleted: z.number().int().min(0).max(1).default(0).openapi({ example: 0, description: '是否删除(0:未删除,1:已删除)' }), roles: z.array(z.object({ id: z.number().int().positive().openapi({ description: '角色ID' }), tenantId: z.number().int().positive().openapi({ description: '租户ID' }), name: z.string().max(255).openapi({ description: '角色名称', example: 'admin' }), description: z.string().max(255).nullable().openapi({ description: '角色描述', example: '管理员' }), permissions: z.array(z.string()).openapi({ description: '权限列表', example: ['user:create'] }), createdAt: z.coerce.date().openapi({ description: '创建时间' }), updatedAt: z.coerce.date().openapi({ description: '更新时间' }) })).optional().openapi({ example: [ { id: 1, tenantId: 1, name: 'admin', description: '管理员', permissions: ['user:create'], createdAt: new Date(), updatedAt: new Date() } ], description: '用户角色列表' }), createdAt: z.coerce.date().openapi({ description: '创建时间' }), updatedAt: z.coerce.date().openapi({ description: '更新时间' }) }); export const TokenResponseSchema = z.object({ token: z.string().openapi({ example: 'jwt.token.here', description: 'JWT Token' }), user: UserResponseSchema }); export const MiniLoginResponseSchema = z.object({ token: z.string().openapi({ example: 'jwt.token.here', description: 'JWT Token' }), user: z.object({ id: z.number(), username: z.string(), nickname: z.string().nullable(), phone: z.string().nullable(), email: z.string().nullable(), avatarFileId: z.number().nullable(), registrationSource: z.string() }), isNewUser: z.boolean().openapi({ example: true, description: '是否为新注册用户' }) }); export const SuccessSchema = z.object({ message: z.string().openapi({ example: '登出成功' }) }); export const PhoneDecryptSchema = z.object({ encryptedData: z.string().openapi({ example: 'encrypted_phone_data_here', description: '微信小程序加密的手机号数据' }), iv: z.string().openapi({ example: 'encryption_iv_here', description: '加密算法的初始向量' }) }); export const PhoneDecryptResponseSchema = z.object({ phoneNumber: z.string().openapi({ example: '13800138000', description: '解密后的手机号' }), user: z.object({ id: z.number(), username: z.string(), nickname: z.string().nullable(), phone: z.string().nullable(), email: z.string().nullable(), avatarFileId: z.number().nullable(), registrationSource: z.string() }) });