chore: initial commit

This commit is contained in:
2026-07-22 17:50:30 +08:00
parent d46cdd676e
commit 3abf272e33
190 changed files with 18073 additions and 0 deletions

View File

@@ -0,0 +1,66 @@
import { z } from 'zod'
import { MenuIconKey, MenuType, MenuTypeSchema, StatusSchema, type MenuIconKeyValues } from '@/enum'
const MenuIconKeySchema = z.custom<MenuIconKeyValues>(
(value) => Object.values(MenuIconKey).includes(value as MenuIconKeyValues),
{
message: '请选择菜单图标',
},
)
export const sysMenuSchema = z.object({
id: z.number().int(),
name: z.string(),
path: z.string(),
component: z.string(),
hidden: z.boolean(),
sort: z.number(),
type: MenuTypeSchema,
status: StatusSchema,
permission_code: z.string(),
parent_id: z.number().int().nullable(),
icon: MenuIconKeySchema.nullable(),
created_at: z.string(),
updated_at: z.string(),
})
export type SysMenu = z.infer<typeof sysMenuSchema>
export interface SysMenuTree extends SysMenu {
children?: SysMenuTree[]
}
export const sysMenuFormSchema = z
.object({
id: z.number().optional(),
name: z.string().min(1, '菜单名称不能为空').max(16, '菜单名称不能超过16个字符'),
path: z.string().min(1, '路径不能为空'),
component: z.string().optional(),
hidden: z.boolean(),
// https://www.reddit.com/r/reactjs/comments/1mmfnyt/typescript_error_when_using_zcoercenumberstring/
sort: z.coerce.number<number>().int().min(0, '排序值不能小于0'),
type: MenuTypeSchema.refine((val) => val !== undefined, {
message: '请选择菜单类型',
}),
status: StatusSchema.refine((val) => val !== undefined, {
message: '请选择状态',
}),
permission_code: z.string().min(1, '权限编码不能为空'),
parent_id: z.number().int().nullable().optional(),
icon: MenuIconKeySchema.nullable(),
})
.superRefine((data, ctx) => {
if (data.type === MenuType.menu && !data.component) {
ctx.addIssue({ code: 'custom', path: ['component'], message: '组件路径不能为空' })
}
})
.transform((data) => {
if (data.type !== MenuType.menu) {
data.component = ''
}
return data
})
export type SysMenuForm = z.infer<typeof sysMenuFormSchema>