import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
import { z } from '@hono/zod-openapi';
@Entity('table_name') // 使用小写下划线命名表名
export class EntityName {
// 字段定义...
}
@PrimaryGeneratedColumn({ unsigned: true }) // 必须使用无符号整数
id!: number; // 使用非空断言(!)和明确类型
@Column({
name: '字段名称', // 必须添加并与数据表字段名称一致
type: 'varchar', // 明确指定数据库类型
length: 255, // 字符串必须指定长度
nullable: true, // 明确是否可为空
default: undefined, // 默认值(可选)
comment: '字段说明' // 必须添加中文注释
})
fieldName!: FieldType; // 类型必须明确
| 业务类型 | 数据库类型 | TypeScript 类型 |
|---|---|---|
| 主键ID | int unsigned | number |
| 短文本 | varchar(length) | string |
| 长文本 | text | string |
| 整数 | int | number |
| 小数 | decimal(precision,scale) | number |
| 布尔状态 | tinyint | number (0/1) |
| 日期时间 | timestamp | Date |
// 禁用状态 (0启用 1禁用)
@Column({ name: 'is_disabled', type: 'tinyint', default: 1 })
isDisabled!: number;
// 删除状态 (0未删除 1已删除)
@Column({ name: 'is_deleted',type: 'tinyint', default: 0 })
isDeleted!: number;
// 创建时间 (自动设置)
@Column({
name: 'created_at',
type: 'timestamp',
default: () => 'CURRENT_TIMESTAMP'
})
createdAt!: Date;
// 更新时间 (自动更新)
@Column({
name: 'updated_at',
type: 'timestamp',
default: () => 'CURRENT_TIMESTAMP',
onUpdate: 'CURRENT_TIMESTAMP'
})
updatedAt!: Date;
export const EntitySchema = z.object({
id: z.number().int().positive().openapi({ description: 'ID说明' }),
// 字符串字段
fieldName: z.string()
.max(255)
.nullable()
.openapi({
description: '字段说明',
example: '示例值'
}),
// 数字字段
numberField: z.number()
.default(默认值)
.openapi({...}),
// 日期字段
dateField: z.date().openapi({...})
});
对于URL参数或表单数据中的数字类型,必须使用z.coerce.number()进行类型转换,以确保字符串到数字的正确转换:
// 整数类型
z.coerce.number().int().positive().openapi({
description: '正整数ID',
example: 1
});
// 小数类型
z.coerce.number().multipleOf(0.01).openapi({
description: '金额,保留两位小数',
example: 19.99
});
// 状态类型(0/1)
z.coerce.number().int().min(0).max(1).openapi({
description: '状态(0-禁用,1-启用)',
example: 1
});
对于日期时间类型,必须使用z.coerce.date()进行类型转换:
// 日期时间类型
z.coerce.date().openapi({
description: '创建时间',
example: '2023-10-01T12:00:00Z'
});
// 日期范围查询
const DateRangeSchema = z.object({
startDate: z.coerce.date().openapi({
description: '开始日期',
example: '2023-10-01T00:00:00Z'
}),
endDate: z.coerce.date().openapi({
description: '结束日期',
example: '2023-10-31T23:59:59Z'
})
});
对于布尔类型参数,必须使用z.coerce.boolean()进行类型转换:
// 布尔类型
z.coerce.boolean().openapi({
description: '是否启用',
example: true
});
创建(Create)和更新(Update)Schema必须遵循以下额外规范:
创建Schema:
id字段(由数据库自动生成)optional()必须使用适当的coerce方法处理非字符串类型
export const CreateEntityDto = z.object({
name: z.string().max(255).openapi({
description: '名称',
example: '示例名称'
}),
quantity: z.coerce.number().int().min(1).openapi({
description: '数量',
example: 10
}),
price: z.coerce.number().multipleOf(0.01).openapi({
description: '价格',
example: 99.99
}),
isActive: z.coerce.boolean().default(true).openapi({
description: '是否激活',
example: true
}),
expireDate: z.coerce.date().openapi({
description: '过期日期',
example: '2024-12-31T23:59:59Z'
})
});
更新Schema:
id字段(通过URL参数传递)optional()必须使用适当的coerce方法处理非字符串类型
export const UpdateEntityDto = z.object({
name: z.string().max(255).optional().openapi({
description: '名称',
example: '更新后的名称'
}),
quantity: z.coerce.number().int().min(1).optional().openapi({
description: '数量',
example: 20
}),
price: z.coerce.number().multipleOf(0.01).optional().openapi({
description: '价格',
example: 89.99
}),
isActive: z.coerce.boolean().optional().openapi({
description: '是否激活',
example: false
}),
expireDate: z.coerce.date().optional().openapi({
description: '过期日期',
example: '2025-12-31T23:59:59Z'
})
});
```