order-goods.schema.ts 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. import { z } from '@hono/zod-openapi';
  2. // 订单商品状态枚举
  3. export const OrderGoodsStatus = {
  4. UN_SHIPPED: 0, // 未发货
  5. SHIPPED: 1, // 已发货
  6. } as const;
  7. // 商品类型枚举
  8. export const GoodsType = {
  9. PHYSICAL: 1, // 实物产品
  10. VIRTUAL: 2, // 虚拟订单
  11. } as const;
  12. // 订单商品基础Schema
  13. export const OrderGoodsSchema = z.object({
  14. id: z.number().int().positive().openapi({
  15. description: '订单商品ID',
  16. example: 1
  17. }),
  18. orderId: z.number().int().positive().openapi({
  19. description: '订单ID',
  20. example: 1
  21. }),
  22. orderNo: z.string().max(50, '订单号最多50个字符').nullable().optional().openapi({
  23. description: '订单号',
  24. example: 'ORD20240101123456'
  25. }),
  26. goodsId: z.number().int().positive().openapi({
  27. description: '商品ID',
  28. example: 1
  29. }),
  30. goodsName: z.string().max(255, '商品名称最多255个字符').nullable().optional().openapi({
  31. description: '商品名称',
  32. example: '苹果手机'
  33. }),
  34. goodsType: z.coerce.number().int().min(1, '商品类型最小为1').max(2, '商品类型最大为2').default(1).openapi({
  35. description: '1实物产品2虚拟订单',
  36. example: 1
  37. }),
  38. supplierId: z.coerce.number().int().positive().default(0).openapi({
  39. description: '供货商ID',
  40. example: 1
  41. }),
  42. costPrice: z.coerce.number().min(0, '成本价不能小于0').max(999999.99, '成本价不能超过999999.99').default(0).openapi({
  43. description: '成本价',
  44. example: 50.00
  45. }),
  46. price: z.coerce.number().min(0, '售价不能小于0').max(999999.99, '售价不能超过999999.99').default(0).openapi({
  47. description: '售价',
  48. example: 99.99
  49. }),
  50. num: z.coerce.number().int().min(0, '数量不能小于0').max(99999, '数量不能超过99999').default(0).openapi({
  51. description: '数量',
  52. example: 2
  53. }),
  54. freightAmount: z.coerce.number().min(0, '运费不能小于0').max(999999.99, '运费不能超过999999.99').default(0).optional().openapi({
  55. description: '运费',
  56. example: 10.00
  57. }),
  58. state: z.coerce.number().int().min(0, '状态最小为0').max(1, '状态最大为1').default(0).openapi({
  59. description: '状态(0未发货、1已发货)',
  60. example: 0
  61. }),
  62. expressName: z.string().max(255, '快递名称最多255个字符').nullable().optional().openapi({
  63. description: '快递名称',
  64. example: '顺丰快递'
  65. }),
  66. expressNo: z.coerce.number().int().positive().nullable().optional().openapi({
  67. description: '快递单号',
  68. example: 1234567890
  69. }),
  70. createdBy: z.number().int().positive().nullable().optional().openapi({
  71. description: '创建人ID',
  72. example: 1
  73. }),
  74. updatedBy: z.number().int().positive().nullable().optional().openapi({
  75. description: '更新人ID',
  76. example: 1
  77. }),
  78. createdAt: z.coerce.date().openapi({
  79. description: '创建时间',
  80. example: '2024-01-01T12:00:00Z'
  81. }),
  82. updatedAt: z.coerce.date().openapi({
  83. description: '更新时间',
  84. example: '2024-01-01T12:00:00Z'
  85. }),
  86. imageFileId: z.number().int().positive().nullable().openapi({
  87. example: 1,
  88. description: '商品图片文件ID'
  89. }),
  90. imageFile: z.object({
  91. id: z.number().int().positive().openapi({ description: '文件ID' }),
  92. name: z.string().max(255).openapi({ description: '文件名', example: 'goods.jpg' }),
  93. fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/goods.jpg' }),
  94. type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }),
  95. size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
  96. }).nullable().optional().openapi({
  97. description: '商品图片文件信息'
  98. }),
  99. // 关联实体
  100. order: z.object({
  101. id: z.number().int().positive().openapi({ description: '订单ID' }),
  102. orderNo: z.string().openapi({ description: '订单号', example: 'ORD20240101123456' })
  103. }).nullable().optional().openapi({
  104. description: '订单信息'
  105. }),
  106. goods: z.object({
  107. id: z.number().int().positive().openapi({ description: '商品ID' }),
  108. name: z.string().openapi({ description: '商品名称', example: '苹果手机' }),
  109. image: z.string().nullable().openapi({ description: '商品图片', example: 'https://example.com/goods.jpg' })
  110. }).nullable().optional().openapi({
  111. description: '商品信息'
  112. }),
  113. supplier: z.object({
  114. id: z.number().int().positive().openapi({ description: '供货商ID' }),
  115. name: z.string().openapi({ description: '供货商名称', example: '供货商A' })
  116. }).nullable().optional().openapi({
  117. description: '供货商信息'
  118. })
  119. });
  120. // 创建订单商品DTO
  121. export const CreateOrderGoodsDto = z.object({
  122. orderId: z.number().int().positive('订单ID必须是正整数').openapi({
  123. description: '订单ID',
  124. example: 1
  125. }),
  126. orderNo: z.string().max(50, '订单号最多50个字符').nullable().optional().openapi({
  127. description: '订单号',
  128. example: 'ORD20240101123456'
  129. }),
  130. goodsId: z.number().int().positive('商品ID必须是正整数').openapi({
  131. description: '商品ID',
  132. example: 1
  133. }),
  134. goodsName: z.string().max(255, '商品名称最多255个字符').nullable().optional().openapi({
  135. description: '商品名称',
  136. example: '苹果手机'
  137. }),
  138. goodsType: z.coerce.number().int().min(1, '商品类型最小为1').max(2, '商品类型最大为2').default(1).optional().openapi({
  139. description: '1实物产品2虚拟订单',
  140. example: 1
  141. }),
  142. supplierId: z.coerce.number().int().positive().default(0).optional().openapi({
  143. description: '供货商ID',
  144. example: 1
  145. }),
  146. costPrice: z.coerce.number().min(0, '成本价不能小于0').max(999999.99, '成本价不能超过999999.99').default(0).optional().openapi({
  147. description: '成本价',
  148. example: 50.00
  149. }),
  150. price: z.coerce.number().min(0, '售价不能小于0').max(999999.99, '售价不能超过999999.99').default(0).optional().openapi({
  151. description: '售价',
  152. example: 99.99
  153. }),
  154. num: z.coerce.number().int().min(0, '数量不能小于0').max(99999, '数量不能超过99999').default(0).optional().openapi({
  155. description: '数量',
  156. example: 2
  157. }),
  158. freightAmount: z.coerce.number().min(0, '运费不能小于0').max(999999.99, '运费不能超过999999.99').default(0).optional().openapi({
  159. description: '运费',
  160. example: 10.00
  161. }),
  162. state: z.coerce.number().int().min(0, '状态最小为0').max(1, '状态最大为1').default(0).optional().openapi({
  163. description: '状态(0未发货、1已发货)',
  164. example: 0
  165. }),
  166. expressName: z.string().max(255, '快递名称最多255个字符').nullable().optional().openapi({
  167. description: '快递名称',
  168. example: '顺丰快递'
  169. }),
  170. expressNo: z.coerce.number().int().positive().nullable().optional().openapi({
  171. description: '快递单号',
  172. example: 1234567890
  173. }),
  174. imageFileId: z.number().int().positive().nullable().optional().openapi({
  175. description: '商品图片文件ID',
  176. example: 1
  177. })
  178. });
  179. // 更新订单商品DTO
  180. export const UpdateOrderGoodsDto = z.object({
  181. orderId: z.number().int().positive('订单ID必须是正整数').optional().openapi({
  182. description: '订单ID',
  183. example: 1
  184. }),
  185. orderNo: z.string().max(50, '订单号最多50个字符').nullable().optional().openapi({
  186. description: '订单号',
  187. example: 'ORD20240101123456'
  188. }),
  189. goodsId: z.number().int().positive('商品ID必须是正整数').optional().openapi({
  190. description: '商品ID',
  191. example: 1
  192. }),
  193. goodsName: z.string().max(255, '商品名称最多255个字符').nullable().optional().openapi({
  194. description: '商品名称',
  195. example: '苹果手机'
  196. }),
  197. goodsType: z.coerce.number().int().min(1, '商品类型最小为1').max(2, '商品类型最大为2').optional().openapi({
  198. description: '1实物产品2虚拟订单',
  199. example: 1
  200. }),
  201. supplierId: z.coerce.number().int().positive().optional().openapi({
  202. description: '供货商ID',
  203. example: 1
  204. }),
  205. costPrice: z.coerce.number().min(0, '成本价不能小于0').max(999999.99, '成本价不能超过999999.99').optional().openapi({
  206. description: '成本价',
  207. example: 50.00
  208. }),
  209. price: z.coerce.number().min(0, '售价不能小于0').max(999999.99, '售价不能超过999999.99').optional().openapi({
  210. description: '售价',
  211. example: 99.99
  212. }),
  213. num: z.coerce.number().int().min(0, '数量不能小于0').max(99999, '数量不能超过99999').optional().openapi({
  214. description: '数量',
  215. example: 2
  216. }),
  217. freightAmount: z.coerce.number().min(0, '运费不能小于0').max(999999.99, '运费不能超过999999.99').optional().openapi({
  218. description: '运费',
  219. example: 10.00
  220. }),
  221. state: z.coerce.number().int().min(0, '状态最小为0').max(1, '状态最大为1').optional().openapi({
  222. description: '状态(0未发货、1已发货)',
  223. example: 0
  224. }),
  225. expressName: z.string().max(255, '快递名称最多255个字符').nullable().optional().openapi({
  226. description: '快递名称',
  227. example: '顺丰快递'
  228. }),
  229. expressNo: z.coerce.number().int().positive().nullable().optional().openapi({
  230. description: '快递单号',
  231. example: 1234567890
  232. }),
  233. imageFileId: z.number().int().positive().nullable().optional().openapi({
  234. description: '商品图片文件ID',
  235. example: 1
  236. })
  237. });
  238. // 订单商品状态类型
  239. export type OrderGoodsStatusType = typeof OrderGoodsStatus[keyof typeof OrderGoodsStatus];
  240. export type GoodsTypeType = typeof GoodsType[keyof typeof GoodsType];