order.schema.ts 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. import { z } from '@hono/zod-openapi';
  2. import { OrderStatus, WorkStatus } from '@d8d/allin-enums';
  3. import { DisabledPersonSchema } from '@d8d/allin-disability-module/schemas';
  4. // 资产类型枚举 - 从实体移到schema,供前端使用
  5. export enum AssetType {
  6. TAX = 'tax',
  7. SALARY = 'salary',
  8. JOB_RESULT = 'job_result',
  9. CONTRACT_SIGN = 'contract_sign',
  10. DISABILITY_CERT = 'disability_cert',
  11. OTHER = 'other',
  12. SALARY_VIDEO = 'salary_video',
  13. TAX_VIDEO = 'tax_video',
  14. CHECKIN_VIDEO = 'checkin_video',
  15. WORK_VIDEO = 'work_video',
  16. }
  17. // 资产文件类型枚举 - 从实体移到schema,供前端使用
  18. export enum AssetFileType {
  19. IMAGE = 'image',
  20. VIDEO = 'video',
  21. }
  22. // 用工订单实体Schema
  23. export const EmploymentOrderSchema = z.object({
  24. id: z.number().int().positive().openapi({
  25. description: '订单ID',
  26. example: 1
  27. }),
  28. orderName: z.string().max(50).nullable().optional().openapi({
  29. description: '订单名称',
  30. example: '2024年Q1用工订单'
  31. }),
  32. platformId: z.number().int().positive().openapi({
  33. description: '用人平台ID',
  34. example: 1
  35. }),
  36. companyId: z.number().int().positive().openapi({
  37. description: '用人单位ID',
  38. example: 1
  39. }),
  40. channelId: z.number().int().positive().nullable().optional().openapi({
  41. description: '渠道ID',
  42. example: 1
  43. }),
  44. expectedStartDate: z.coerce.date().nullable().optional().openapi({
  45. description: '预计开始日期',
  46. example: '2024-01-01T00:00:00Z'
  47. }),
  48. actualStartDate: z.coerce.date().nullable().optional().openapi({
  49. description: '实际开始日期',
  50. example: '2024-01-01T00:00:00Z'
  51. }),
  52. actualEndDate: z.coerce.date().nullable().optional().openapi({
  53. description: '实际结束日期',
  54. example: '2024-12-31T00:00:00Z'
  55. }),
  56. orderStatus: z.nativeEnum(OrderStatus).default(OrderStatus.DRAFT).openapi({
  57. description: '订单状态:draft-草稿, confirmed-已确认, in_progress-进行中, completed-已完成, cancelled-已取消',
  58. example: OrderStatus.DRAFT
  59. }),
  60. workStatus: z.nativeEnum(WorkStatus).default(WorkStatus.NOT_WORKING).openapi({
  61. description: '工作状态:not_working-未就业, pre_working-待就业, working-已就业, resigned-已离职',
  62. example: WorkStatus.NOT_WORKING
  63. }),
  64. createTime: z.coerce.date().openapi({
  65. description: '创建时间',
  66. example: '2024-01-01T00:00:00Z'
  67. }),
  68. updateTime: z.coerce.date().openapi({
  69. description: '更新时间',
  70. example: '2024-01-01T00:00:00Z'
  71. }),
  72. orderPersons: z.array(z.lazy(() => OrderPersonSchema)).optional().openapi({
  73. description: '订单关联人员列表',
  74. example: []
  75. })
  76. });
  77. // 创建用工订单DTO
  78. export const CreateEmploymentOrderSchema = z.object({
  79. orderName: z.string().max(50).optional().openapi({
  80. description: '订单名称',
  81. example: '2024年Q1用工订单'
  82. }),
  83. platformId: z.coerce.number().int().positive().openapi({
  84. description: '用人平台ID',
  85. example: 1
  86. }),
  87. companyId: z.coerce.number().int().positive().openapi({
  88. description: '用人单位ID',
  89. example: 1
  90. }),
  91. channelId: z.coerce.number().int().positive().optional().openapi({
  92. description: '渠道ID',
  93. example: 1
  94. }),
  95. expectedStartDate: z.coerce.date().optional().openapi({
  96. description: '预计开始日期',
  97. example: '2024-01-01T00:00:00Z'
  98. }),
  99. actualStartDate: z.coerce.date().optional().openapi({
  100. description: '实际开始日期',
  101. example: '2024-01-01T00:00:00Z'
  102. }),
  103. actualEndDate: z.coerce.date().optional().openapi({
  104. description: '实际结束日期',
  105. example: '2024-12-31T00:00:00Z'
  106. }),
  107. orderStatus: z.nativeEnum(OrderStatus).default(OrderStatus.DRAFT).optional().openapi({
  108. description: '订单状态:draft-草稿, confirmed-已确认, in_progress-进行中, completed-已完成, cancelled-已取消',
  109. example: OrderStatus.DRAFT
  110. }),
  111. workStatus: z.nativeEnum(WorkStatus).default(WorkStatus.NOT_WORKING).optional().openapi({
  112. description: '工作状态:not_working-未就业, pre_working-待就业, working-已就业, resigned-已离职',
  113. example: WorkStatus.NOT_WORKING
  114. })
  115. });
  116. // 更新用工订单DTO
  117. export const UpdateEmploymentOrderSchema = z.object({
  118. id: z.coerce.number().int().positive().openapi({
  119. description: '订单ID',
  120. example: 1
  121. }),
  122. orderName: z.string().max(50).optional().openapi({
  123. description: '订单名称',
  124. example: '2024年Q1用工订单'
  125. }),
  126. platformId: z.coerce.number().int().positive().optional().openapi({
  127. description: '用人平台ID',
  128. example: 1
  129. }),
  130. companyId: z.coerce.number().int().positive().optional().openapi({
  131. description: '用人单位ID',
  132. example: 1
  133. }),
  134. channelId: z.coerce.number().int().positive().optional().openapi({
  135. description: '渠道ID',
  136. example: 1
  137. }),
  138. expectedStartDate: z.coerce.date().optional().openapi({
  139. description: '预计开始日期',
  140. example: '2024-01-01T00:00:00Z'
  141. }),
  142. actualStartDate: z.coerce.date().optional().openapi({
  143. description: '实际开始日期',
  144. example: '2024-01-01T00:00:00Z'
  145. }),
  146. actualEndDate: z.coerce.date().optional().openapi({
  147. description: '实际结束日期',
  148. example: '2024-12-31T00:00:00Z'
  149. }),
  150. orderStatus: z.nativeEnum(OrderStatus).optional().openapi({
  151. description: '订单状态:draft-草稿, confirmed-已确认, in_progress-进行中, completed-已完成, cancelled-已取消',
  152. example: OrderStatus.DRAFT
  153. }),
  154. workStatus: z.nativeEnum(WorkStatus).optional().openapi({
  155. description: '工作状态:not_working-未就业, pre_working-待就业, working-已就业, resigned-已离职',
  156. example: WorkStatus.NOT_WORKING
  157. })
  158. });
  159. // 订单人员关联实体Schema
  160. export const OrderPersonSchema = z.object({
  161. id: z.number().int().positive().openapi({
  162. description: '关联ID',
  163. example: 1
  164. }),
  165. orderId: z.number().int().positive().openapi({
  166. description: '订单ID',
  167. example: 1
  168. }),
  169. personId: z.number().int().positive().openapi({
  170. description: '残疾人ID',
  171. example: 1
  172. }),
  173. joinDate: z.coerce.date().openapi({
  174. description: '入职日期',
  175. example: '2024-01-01T00:00:00Z'
  176. }),
  177. actualStartDate: z.coerce.date().nullable().optional().openapi({
  178. description: '实际入职日期',
  179. example: '2024-01-15T00:00:00Z'
  180. }),
  181. leaveDate: z.coerce.date().nullable().optional().openapi({
  182. description: '离职日期',
  183. example: '2024-12-31T00:00:00Z'
  184. }),
  185. workStatus: z.nativeEnum(WorkStatus).default(WorkStatus.NOT_WORKING).openapi({
  186. description: '工作状态:not_working-未就业, pre_working-待就业, working-已就业, resigned-已离职',
  187. example: WorkStatus.NOT_WORKING
  188. }),
  189. salaryDetail: z.coerce.number().positive().openapi({
  190. description: '个人薪资',
  191. example: 5000.00
  192. }),
  193. // 残疾人员的详细信息
  194. person: DisabledPersonSchema.pick({
  195. id: true,
  196. name: true,
  197. gender: true,
  198. disabilityType: true,
  199. phone: true,
  200. disabilityId: true
  201. }).partial().nullable().optional().openapi({
  202. description: '残疾人员详细信息'
  203. })
  204. });
  205. // 创建订单人员关联DTO
  206. export const CreateOrderPersonSchema = z.object({
  207. orderId: z.coerce.number().int().positive().openapi({
  208. description: '订单ID',
  209. example: 1
  210. }),
  211. personId: z.coerce.number().int().positive().openapi({
  212. description: '残疾人ID',
  213. example: 1
  214. }),
  215. joinDate: z.coerce.date().openapi({
  216. description: '入职日期',
  217. example: '2024-01-01T00:00:00Z'
  218. }),
  219. leaveDate: z.coerce.date().optional().openapi({
  220. description: '离职日期',
  221. example: '2024-12-31T00:00:00Z'
  222. }),
  223. workStatus: z.nativeEnum(WorkStatus).default(WorkStatus.NOT_WORKING).optional().openapi({
  224. description: '工作状态:not_working-未就业, pre_working-待就业, working-已就业, resigned-已离职',
  225. example: WorkStatus.NOT_WORKING
  226. }),
  227. salaryDetail: z.coerce.number().positive().openapi({
  228. description: '个人薪资',
  229. example: 5000.00
  230. })
  231. });
  232. // 批量添加人员DTO(不需要orderId,从URL参数获取)
  233. export const BatchAddPersonItemSchema = z.object({
  234. personId: z.coerce.number().int().positive().openapi({
  235. description: '残疾人ID',
  236. example: 1
  237. }),
  238. joinDate: z.coerce.date().openapi({
  239. description: '入职日期',
  240. example: '2024-01-01T00:00:00Z'
  241. }),
  242. leaveDate: z.coerce.date().optional().openapi({
  243. description: '离职日期',
  244. example: '2024-12-31T00:00:00Z'
  245. }),
  246. workStatus: z.nativeEnum(WorkStatus).default(WorkStatus.NOT_WORKING).optional().openapi({
  247. description: '工作状态:not_working-未就业, pre_working-待就业, working-已就业, resigned-已离职',
  248. example: WorkStatus.NOT_WORKING
  249. }),
  250. salaryDetail: z.coerce.number().positive().openapi({
  251. description: '个人薪资',
  252. example: 5000.00
  253. })
  254. });
  255. // 订单人员资产实体Schema
  256. export const OrderPersonAssetSchema = z.object({
  257. id: z.number().int().positive().openapi({
  258. description: '关联ID',
  259. example: 1
  260. }),
  261. orderId: z.number().int().positive().openapi({
  262. description: '订单ID',
  263. example: 1
  264. }),
  265. personId: z.number().int().positive().openapi({
  266. description: '残疾人ID',
  267. example: 1
  268. }),
  269. assetType: z.nativeEnum(AssetType).openapi({
  270. description: '资产类型:tax-税务, salary-薪资, job_result-工作成果, contract_sign-合同签署, disability_cert-残疾证明, other-其他, salary_video-工资视频, tax_video-个税视频, checkin_video-打卡视频, work_video-工作视频',
  271. example: AssetType.SALARY
  272. }),
  273. assetFileType: z.nativeEnum(AssetFileType).openapi({
  274. description: '资产文件类型:image-图片, video-视频',
  275. example: AssetFileType.IMAGE
  276. }),
  277. fileId: z.number().int().positive().openapi({
  278. description: '文件ID,引用files表',
  279. example: 1
  280. }),
  281. relatedTime: z.coerce.date().openapi({
  282. description: '关联时间',
  283. example: '2024-01-01T00:00:00Z'
  284. }),
  285. updateTime: z.coerce.date().openapi({
  286. description: '更新时间',
  287. example: '2024-01-01T00:00:00Z'
  288. })
  289. });
  290. // 创建订单人员资产DTO
  291. export const CreateOrderPersonAssetSchema = z.object({
  292. orderId: z.coerce.number().int().positive().openapi({
  293. description: '订单ID',
  294. example: 1
  295. }),
  296. personId: z.coerce.number().int().positive().openapi({
  297. description: '残疾人ID',
  298. example: 1
  299. }),
  300. assetType: z.nativeEnum(AssetType).openapi({
  301. description: '资产类型:tax-税务, salary-薪资, job_result-工作成果, contract_sign-合同签署, disability_cert-残疾证明, other-其他, salary_video-工资视频, tax_video-个税视频, checkin_video-打卡视频, work_video-工作视频',
  302. example: AssetType.SALARY
  303. }),
  304. assetFileType: z.nativeEnum(AssetFileType).openapi({
  305. description: '资产文件类型:image-图片, video-视频',
  306. example: AssetFileType.IMAGE
  307. }),
  308. fileId: z.coerce.number().int().positive().openapi({
  309. description: '文件ID,引用files表',
  310. example: 1
  311. }),
  312. relatedTime: z.coerce.date().optional().openapi({
  313. description: '关联时间',
  314. example: '2024-01-01T00:00:00Z'
  315. })
  316. });
  317. // 分页查询参数Schema
  318. export const PaginationQuerySchema = z.object({
  319. skip: z.coerce.number().int().min(0).default(0).optional().openapi({
  320. description: '跳过记录数',
  321. example: 0
  322. }),
  323. take: z.coerce.number().int().min(1).max(100).default(10).optional().openapi({
  324. description: '获取记录数',
  325. example: 10
  326. })
  327. });
  328. // 删除订单DTO
  329. export const DeleteOrderSchema = z.object({
  330. id: z.number().int().positive().openapi({
  331. description: '订单ID',
  332. example: 1
  333. })
  334. });
  335. // 删除订单人员DTO
  336. export const DeleteOrderPersonSchema = z.object({
  337. id: z.number().int().positive().openapi({
  338. description: '关联ID',
  339. example: 1
  340. })
  341. });
  342. // 删除订单人员资产DTO
  343. export const DeleteOrderPersonAssetSchema = z.object({
  344. id: z.number().int().positive().openapi({
  345. description: '关联ID',
  346. example: 1
  347. })
  348. });
  349. // 类型定义
  350. export type EmploymentOrder = z.infer<typeof EmploymentOrderSchema>;
  351. export type CreateEmploymentOrderDto = z.infer<typeof CreateEmploymentOrderSchema>;
  352. export type UpdateEmploymentOrderDto = z.infer<typeof UpdateEmploymentOrderSchema>;
  353. export type OrderPerson = z.infer<typeof OrderPersonSchema>;
  354. export type CreateOrderPersonDto = z.infer<typeof CreateOrderPersonSchema>;
  355. export type OrderPersonAsset = z.infer<typeof OrderPersonAssetSchema>;
  356. export type CreateOrderPersonAssetDto = z.infer<typeof CreateOrderPersonAssetSchema>;
  357. export type PaginationQuery = z.infer<typeof PaginationQuerySchema>;
  358. export type DeleteOrderDto = z.infer<typeof DeleteOrderSchema>;
  359. export type DeleteOrderPersonDto = z.infer<typeof DeleteOrderPersonSchema>;
  360. export type DeleteOrderPersonAssetDto = z.infer<typeof DeleteOrderPersonAssetSchema>;
  361. export type UpdatePersonWorkStatusDto = z.infer<typeof UpdatePersonWorkStatusSchema>;
  362. // 查询订单参数Schema
  363. export const QueryOrderSchema = z.object({
  364. orderName: z.string().optional().openapi({
  365. description: '订单名称',
  366. example: '2024年Q1用工订单'
  367. }),
  368. platformId: z.coerce.number().int().positive().optional().openapi({
  369. description: '用人平台ID',
  370. example: 1
  371. }),
  372. companyId: z.coerce.number().int().positive().optional().openapi({
  373. description: '用人单位ID',
  374. example: 1
  375. }),
  376. channelId: z.coerce.number().int().positive().optional().openapi({
  377. description: '渠道ID',
  378. example: 1
  379. }),
  380. orderStatus: z.nativeEnum(OrderStatus).optional().openapi({
  381. description: '订单状态',
  382. example: OrderStatus.DRAFT
  383. }),
  384. startDate: z.string().optional().openapi({
  385. description: '开始日期(YYYY-MM-DD格式)',
  386. example: '2024-01-01'
  387. }),
  388. endDate: z.string().optional().openapi({
  389. description: '结束日期(YYYY-MM-DD格式)',
  390. example: '2024-12-31'
  391. }),
  392. page: z.coerce.number().int().min(1).default(1).optional().openapi({
  393. description: '页码',
  394. example: 1
  395. }),
  396. limit: z.coerce.number().int().min(1).max(100).default(10).optional().openapi({
  397. description: '每页数量',
  398. example: 10
  399. })
  400. });
  401. // 查询订单人员资产参数Schema
  402. export const QueryOrderPersonAssetSchema = z.object({
  403. orderId: z.coerce.number().int().positive().optional().openapi({
  404. description: '订单ID',
  405. example: 1
  406. }),
  407. personId: z.coerce.number().int().positive().optional().openapi({
  408. description: '人员ID',
  409. example: 1
  410. }),
  411. assetType: z.nativeEnum(AssetType).optional().openapi({
  412. description: '资产类型:tax-税务, salary-薪资, job_result-工作成果, contract_sign-合同签署, disability_cert-残疾证明, other-其他, salary_video-工资视频, tax_video-个税视频, checkin_video-打卡视频, work_video-工作视频',
  413. example: AssetType.SALARY
  414. }),
  415. assetFileType: z.nativeEnum(AssetFileType).optional().openapi({
  416. description: '资产文件类型',
  417. example: AssetFileType.IMAGE
  418. }),
  419. page: z.coerce.number().int().min(1).default(1).optional().openapi({
  420. description: '页码',
  421. example: 1
  422. }),
  423. limit: z.coerce.number().int().min(1).max(100).default(10).optional().openapi({
  424. description: '每页数量',
  425. example: 10
  426. })
  427. });
  428. // 为兼容性添加别名导出
  429. export const CreateOrderSchema = CreateEmploymentOrderSchema;
  430. export const UpdateOrderSchema = UpdateEmploymentOrderSchema;
  431. export const BatchAddPersonsSchema = z.object({
  432. persons: z.array(BatchAddPersonItemSchema).openapi({
  433. description: '人员列表',
  434. example: [{ personId: 1, joinDate: '2024-01-01T00:00:00Z', salaryDetail: 5000 }]
  435. })
  436. });
  437. // 更新订单人员工作状态DTO
  438. export const UpdatePersonWorkStatusSchema = z.object({
  439. orderId: z.coerce.number().int().positive().openapi({
  440. description: '订单ID',
  441. example: 1
  442. }),
  443. personId: z.coerce.number().int().positive().openapi({
  444. description: '人员ID',
  445. example: 1
  446. }),
  447. workStatus: z.nativeEnum(WorkStatus).openapi({
  448. description: '工作状态:not_working-未就业, pre_working-待就业, working-已就业, resigned-已离职',
  449. example: WorkStatus.WORKING
  450. })
  451. });