Explorar el Código

✨ feat(orders): 新增订单系统核心实体和Schema定义

- 创建OrderGoods实体和Schema用于订单商品关联管理
- 创建OrderRefund实体和Schema用于订单退款流程
- 创建Order主实体和Schema包含完整的订单生命周期字段
- 支持实物商品和虚拟商品两种订单类型
- 包含支付状态、物流状态、退款状态等完整状态流转
yourname hace 4 meses
padre
commit
8dfac67ea7

+ 77 - 0
src/server/modules/orders/order-goods.entity.ts

@@ -0,0 +1,77 @@
+import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn } from 'typeorm';
+import { Order } from './order.entity';
+import { Goods } from '@/server/modules/goods/goods.entity';
+import { Supplier } from '@/server/modules/supplier/supplier.entity';
+
+@Entity('orders_goods')
+export class OrderGoods {
+  @PrimaryGeneratedColumn({ unsigned: true })
+  id!: number;
+
+  @Column({ name: 'order_id', type: 'int', unsigned: true, comment: '订单表id' })
+  orderId!: number;
+
+  @Column({ name: 'order_no', type: 'varchar', length: 50, nullable: true, comment: '订单号' })
+  orderNo!: string | null;
+
+  @Column({ name: 'goods_id', type: 'int', unsigned: true, comment: '商品id' })
+  goodsId!: number;
+
+  @Column({ name: 'goods_name', type: 'varchar', length: 255, nullable: true, comment: '商品名称' })
+  goodsName!: string | null;
+
+  @Column({ name: 'goods_image', type: 'varchar', length: 255, nullable: true, comment: '商品图片' })
+  goodsImage!: string | null;
+
+  @Column({ name: 'goods_type', type: 'int', default: 1, comment: '1实物产品2虚拟订单' })
+  goodsType!: number;
+
+  @Column({ name: 'supplier_id', type: 'int', unsigned: true, default: 0, comment: '供货商id' })
+  supplierId!: number;
+
+  @Column({ name: 'cost_price', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '成本价' })
+  costPrice!: number;
+
+  @Column({ name: 'price', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '售价' })
+  price!: number;
+
+  @Column({ name: 'num', type: 'int', default: 0, comment: '数量' })
+  num!: number;
+
+  @Column({ name: 'freight_amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '运费' })
+  freightAmount!: number;
+
+  @Column({ name: 'state', type: 'int', default: 0, comment: '状态(0未发货、1已发货)' })
+  state!: number;
+
+  @Column({ name: 'express_name', type: 'varchar', length: 255, nullable: true, comment: '快递名称' })
+  expressName!: string | null;
+
+  @Column({ name: 'express_no', type: 'int', nullable: true, comment: '单号' })
+  expressNo!: number | null;
+
+  @CreateDateColumn({ name: 'created_at', type: 'timestamp' })
+  createdAt!: Date;
+
+  @UpdateDateColumn({ name: 'updated_at', type: 'timestamp' })
+  updatedAt!: Date;
+
+  @Column({ name: 'created_by', type: 'int', unsigned: true, nullable: true, comment: '创建人ID' })
+  createdBy!: number | null;
+
+  @Column({ name: 'updated_by', type: 'int', unsigned: true, nullable: true, comment: '更新人ID' })
+  updatedBy!: number | null;
+
+  // 关联关系
+  @ManyToOne(() => Order)
+  @JoinColumn({ name: 'order_id', referencedColumnName: 'id' })
+  order!: Order;
+
+  @ManyToOne(() => Goods)
+  @JoinColumn({ name: 'goods_id', referencedColumnName: 'id' })
+  goods!: Goods;
+
+  @ManyToOne(() => Supplier)
+  @JoinColumn({ name: 'supplier_id', referencedColumnName: 'id' })
+  supplier!: Supplier;
+}

+ 161 - 0
src/server/modules/orders/order-goods.schema.ts

@@ -0,0 +1,161 @@
+import { z } from '@hono/zod-openapi';
+
+// 订单商品状态枚举
+export const OrderGoodsStatus = {
+  UN_SHIPPED: 0, // 未发货
+  SHIPPED: 1, // 已发货
+} as const;
+
+// 商品类型枚举
+export const GoodsType = {
+  PHYSICAL: 1, // 实物产品
+  VIRTUAL: 2, // 虚拟订单
+} as const;
+
+// 订单商品基础Schema
+export const OrderGoodsSchema = z.object({
+  id: z.number().int().positive().openapi({
+    description: '订单商品ID',
+    example: 1
+  }),
+  orderId: z.number().int().positive().openapi({
+    description: '订单ID',
+    example: 1
+  }),
+  orderNo: z.string().max(50, '订单号最多50个字符').nullable().optional().openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  goodsId: z.number().int().positive().openapi({
+    description: '商品ID',
+    example: 1
+  }),
+  goodsName: z.string().max(255, '商品名称最多255个字符').nullable().optional().openapi({
+    description: '商品名称',
+    example: '苹果手机'
+  }),
+  goodsImage: z.string().max(255, '商品图片最多255个字符').nullable().optional().openapi({
+    description: '商品图片',
+    example: 'https://example.com/goods.jpg'
+  }),
+  goodsType: z.coerce.number().int().min(1, '商品类型最小为1').max(2, '商品类型最大为2').default(1).openapi({
+    description: '1实物产品2虚拟订单',
+    example: 1
+  }),
+  supplierId: z.coerce.number().int().positive().default(0).openapi({
+    description: '供货商ID',
+    example: 1
+  }),
+  costPrice: z.coerce.number().min(0, '成本价不能小于0').max(999999.99, '成本价不能超过999999.99').default(0).openapi({
+    description: '成本价',
+    example: 50.00
+  }),
+  price: z.coerce.number().min(0, '售价不能小于0').max(999999.99, '售价不能超过999999.99').default(0).openapi({
+    description: '售价',
+    example: 99.99
+  }),
+  num: z.coerce.number().int().min(0, '数量不能小于0').max(99999, '数量不能超过99999').default(0).openapi({
+    description: '数量',
+    example: 2
+  }),
+  freightAmount: z.coerce.number().min(0, '运费不能小于0').max(999999.99, '运费不能超过999999.99').default(0).optional().openapi({
+    description: '运费',
+    example: 10.00
+  }),
+  state: z.coerce.number().int().min(0, '状态最小为0').max(1, '状态最大为1').default(0).openapi({
+    description: '状态(0未发货、1已发货)',
+    example: 0
+  }),
+  expressName: z.string().max(255, '快递名称最多255个字符').nullable().optional().openapi({
+    description: '快递名称',
+    example: '顺丰快递'
+  }),
+  expressNo: z.coerce.number().int().positive().nullable().optional().openapi({
+    description: '快递单号',
+    example: 1234567890
+  }),
+  createdBy: z.number().int().positive().nullable().optional().openapi({
+    description: '创建人ID',
+    example: 1
+  }),
+  updatedBy: z.number().int().positive().nullable().optional().openapi({
+    description: '更新人ID',
+    example: 1
+  }),
+  createdAt: z.coerce.date().openapi({
+    description: '创建时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  updatedAt: z.coerce.date().openapi({
+    description: '更新时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  // 关联实体
+  order: z.object({
+    id: z.number().int().positive().openapi({ description: '订单ID' }),
+    orderNo: z.string().openapi({ description: '订单号', example: 'ORD20240101123456' })
+  }).nullable().optional().openapi({
+    description: '订单信息'
+  }),
+  goods: z.object({
+    id: z.number().int().positive().openapi({ description: '商品ID' }),
+    name: z.string().openapi({ description: '商品名称', example: '苹果手机' }),
+    image: z.string().nullable().openapi({ description: '商品图片', example: 'https://example.com/goods.jpg' })
+  }).nullable().optional().openapi({
+    description: '商品信息'
+  }),
+  supplier: z.object({
+    id: z.number().int().positive().openapi({ description: '供货商ID' }),
+    name: z.string().openapi({ description: '供货商名称', example: '供货商A' })
+  }).nullable().optional().openapi({
+    description: '供货商信息'
+  })
+});
+
+// 创建订单商品DTO
+export const CreateOrderGoodsDto = z.object({
+  orderId: z.number().int().positive('订单ID必须是正整数').openapi({
+    description: '订单ID',
+    example: 1
+  }),
+  orderNo: z.string().max(50, '订单号最多50个字符').nullable().optional().openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  goodsId: z.number().int().positive('商品ID必须是正整数').openapi({
+    description: '商品ID',
+    example: 1
+  }),
+  goodsName: z.string().max(255, '商品名称最多255个字符').nullable().optional().openapi({
+    description: '商品名称',
+    example: '苹果手机'
+  }),
+  goodsImage: z.string().max(255, '商品图片最多255个字符').nullable().optional().openapi({
+    description: '商品图片',
+    example: 'https://example.com/goods.jpg'
+  }),
+  goodsType: z.coerce.number().int().min(1, '商品类型最小为1').max(2, '商品类型最大为2').default(1).optional().openapi({
+    description: '1实物产品2虚拟订单',
+    example: 1
+  }),
+  supplierId: z.coerce.number().int().positive().default(0).optional().openapi({
+    description: '供货商ID',
+    example: 1
+  }),
+  costPrice: z.coerce.number().min(0, '成本价不能小于0').max(999999.99, '成本价不能超过999999.99').default(0).optional().openapi({
+    description: '成本价',
+    example: 50.00
+  }),
+  price: z.coerce.number().min(0, '售价不能小于0').max(999999.99, '售价不能超过999999.99').default(0).optional().openapi({
+    description: '售价',
+    example: 99.99
+  }),
+  num: z.coerce.number().int().min(0, '数量不能小于0').max(99999, '数量不能超过99999').default(0).optional().openapi({
+    description: '数量',
+    example: 2
+  }),
+  freightAmount: z.coerce.number().min(0, '运费不能小于0').max(999999.99, '运费不能超过999999.99').default(0).optional().openapi({
+    description: '运费',
+    example: 10.00
+  }),
+  state: z.coerce.number().int().min(0, '状态

+ 40 - 0
src/server/modules/orders/order-refund.entity.ts

@@ -0,0 +1,40 @@
+import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn } from 'typeorm';
+import { Order } from './order.entity';
+
+@Entity('orders_refund')
+export class OrderRefund {
+  @PrimaryGeneratedColumn({ unsigned: true })
+  id!: number;
+
+  @Column({ name: 'order_no', type: 'varchar', length: 32, nullable: true, comment: '订单号' })
+  orderNo!: string | null;
+
+  @Column({ name: 'refund_order_no', type: 'varchar', length: 32, nullable: true, comment: '退款订单号' })
+  refundOrderNo!: string | null;
+
+  @Column({ name: 'refund_amount', type: 'decimal', precision: 10, scale: 2, nullable: true, comment: '退款金额' })
+  refundAmount!: number | null;
+
+  @Column({ name: 'state', type: 'int', default: 0, comment: '0未退款1退款中2退款成功3退款失败' })
+  state!: number;
+
+  @Column({ name: 'remark', type: 'varchar', length: 255, nullable: true, comment: '备注' })
+  remark!: string | null;
+
+  @Column({ name: 'created_by', type: 'int', unsigned: true, nullable: true, comment: '创建人ID' })
+  createdBy!: number | null;
+
+  @Column({ name: 'updated_by', type: 'int', unsigned: true, nullable: true, comment: '更新人ID' })
+  updatedBy!: number | null;
+
+  @CreateDateColumn({ name: 'created_at', type: 'timestamp' })
+  createdAt!: Date;
+
+  @UpdateDateColumn({ name: 'updated_at', type: 'timestamp' })
+  updatedAt!: Date;
+
+  // 关联关系
+  @ManyToOne(() => Order)
+  @JoinColumn({ name: 'order_no', referencedColumnName: 'orderNo' })
+  order!: Order;
+}

+ 128 - 0
src/server/modules/orders/order-refund.schema.ts

@@ -0,0 +1,128 @@
+import { z } from '@hono/zod-openapi';
+
+// 退款状态枚举
+export const RefundStatus = {
+  PENDING: 0, // 未退款
+  PROCESSING: 1, // 退款中
+  SUCCESS: 2, // 退款成功
+  FAILED: 3, // 退款失败
+} as const;
+
+// 订单退款基础Schema
+export const OrderRefundSchema = z.object({
+  id: z.number().int().positive().openapi({
+    description: '退款记录ID',
+    example: 1
+  }),
+  orderNo: z.string().max(32, '订单号最多32个字符').nullable().optional().openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  refundOrderNo: z.string().max(32, '退款订单号最多32个字符').nullable().optional().openapi({
+    description: '退款订单号',
+    example: 'REF20240101123456'
+  }),
+  refundAmount: z.coerce.number().min(0, '退款金额不能小于0').max(999999.99, '退款金额不能超过999999.99').nullable().optional().openapi({
+    description: '退款金额',
+    example: 99.99
+  }),
+  state: z.coerce.number().int().min(0, '状态最小为0').max(3, '状态最大为3').default(0).openapi({
+    description: '0未退款1退款中2退款成功3退款失败',
+    example: 0
+  }),
+  remark: z.string().max(255, '备注最多255个字符').nullable().optional().openapi({
+    description: '备注',
+    example: '用户申请退款'
+  }),
+  createdBy: z.number().int().positive().nullable().optional().openapi({
+    description: '创建人ID',
+    example: 1
+  }),
+  updatedBy: z.number().int().positive().nullable().optional().openapi({
+    description: '更新人ID',
+    example: 1
+  }),
+  createdAt: z.coerce.date().openapi({
+    description: '创建时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  updatedAt: z.coerce.date().openapi({
+    description: '更新时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  // 关联实体
+  order: z.object({
+    id: z.number().int().positive().openapi({ description: '订单ID' }),
+    orderNo: z.string().openapi({ description: '订单号', example: 'ORD20240101123456' }),
+    amount: z.number().openapi({ description: '订单金额', example: 99.99 })
+  }).nullable().optional().openapi({
+    description: '订单信息'
+  })
+});
+
+// 创建订单退款DTO
+export const CreateOrderRefundDto = z.object({
+  orderNo: z.string().max(32, '订单号最多32个字符').nullable().optional().openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  refundOrderNo: z.string().max(32, '退款订单号最多32个字符').nullable().optional().openapi({
+    description: '退款订单号',
+    example: 'REF20240101123456'
+  }),
+  refundAmount: z.coerce.number().min(0, '退款金额不能小于0').max(999999.99, '退款金额不能超过999999.99').nullable().optional().openapi({
+    description: '退款金额',
+    example: 99.99
+  }),
+  state: z.coerce.number().int().min(0, '状态最小为0').max(3, '状态最大为3').default(0).optional().openapi({
+    description: '0未退款1退款中2退款成功3退款失败',
+    example: 0
+  }),
+  remark: z.string().max(255, '备注最多255个字符').nullable().optional().openapi({
+    description: '备注',
+    example: '用户申请退款'
+  })
+});
+
+// 更新订单退款DTO
+export const UpdateOrderRefundDto = z.object({
+  orderNo: z.string().max(32, '订单号最多32个字符').nullable().optional().openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  refundOrderNo: z.string().max(32, '退款订单号最多32个字符').nullable().optional().openapi({
+    description: '退款订单号',
+    example: 'REF20240101123456'
+  }),
+  refundAmount: z.coerce.number().min(0, '退款金额不能小于0').max(999999.99, '退款金额不能超过999999.99').nullable().optional().openapi({
+    description: '退款金额',
+    example: 99.99
+  }),
+  state: z.coerce.number().int().min(0, '状态最小为0').max(3, '状态最大为3').optional().openapi({
+    description: '0未退款1退款中2退款成功3退款失败',
+    example: 2
+  }),
+  remark: z.string().max(255, '备注最多255个字符').nullable().optional().openapi({
+    description: '备注',
+    example: '退款已完成'
+  })
+});
+
+// 订单退款列表响应
+export const OrderRefundListResponse = z.object({
+  data: z.array(OrderRefundSchema),
+  pagination: z.object({
+    total: z.number().openapi({
+      example: 100,
+      description: '总记录数'
+    }),
+    current: z.number().openapi({
+      example: 1,
+      description: '当前页码'
+    }),
+    pageSize: z.number().openapi({
+      example: 10,
+      description: '每页数量'
+    })
+  })
+});

+ 488 - 0
src/server/modules/orders/order.schema.ts

@@ -0,0 +1,488 @@
+import { z } from '@hono/zod-openapi';
+
+// 订单状态枚举
+export const OrderStatus = {
+  PENDING: 0, // 未发货
+  SHIPPED: 1, // 已发货
+  RECEIVED: 2, // 收货成功
+  RETURNED: 3, // 已退货
+} as const;
+
+// 支付状态枚举
+export const PayStatus = {
+  UNPAID: 0, // 未支付
+  PAYING: 1, // 支付中
+  SUCCESS: 2, // 支付成功
+  REFUNDED: 3, // 已退款
+  FAILED: 4, // 支付失败
+  CLOSED: 5, // 订单关闭
+} as const;
+
+// 订单类型枚举
+export const OrderType = {
+  PHYSICAL: 1, // 实物订单
+  VIRTUAL: 2, // 虚拟订单
+} as const;
+
+// 支付类型枚举
+export const PayType = {
+  POINTS: 1, // 积分
+  COUPON: 2, // 礼券
+} as const;
+
+// 订单基础Schema
+export const OrderSchema = z.object({
+  id: z.number().int().positive().openapi({
+    description: '订单ID',
+    example: 1
+  }),
+  orderNo: z.string().min(1, '订单号不能为空').max(50, '订单号最多50个字符').openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  userId: z.number().int().positive().openapi({
+    description: '用户ID',
+    example: 1
+  }),
+  authCode: z.string().max(32, '付款码最多32个字符').nullable().optional().openapi({
+    description: '付款码',
+    example: '12345678901234567890123456789012'
+  }),
+  cardNo: z.string().max(32, '卡号最多32个字符').nullable().optional().openapi({
+    description: '卡号',
+    example: '6222********1234'
+  }),
+  sjtCardNo: z.string().max(32, '盛京通卡号最多32个字符').nullable().optional().openapi({
+    description: '盛京通卡号',
+    example: 'SJT1234567890'
+  }),
+  amount: z.coerce.number().min(0, '订单金额不能小于0').max(999999.99, '订单金额不能超过999999.99').openapi({
+    description: '订单金额',
+    example: 99.99
+  }),
+  costAmount: z.coerce.number().min(0, '成本金额不能小于0').max(999999.99, '成本金额不能超过999999.99').default(0).openapi({
+    description: '成本金额',
+    example: 50.00
+  }),
+  freightAmount: z.coerce.number().min(0, '运费不能小于0').max(999999.99, '运费不能超过999999.99').default(0).openapi({
+    description: '运费',
+    example: 10.00
+  }),
+  discountAmount: z.coerce.number().min(0, '优惠金额不能小于0').max(999999.99, '优惠金额不能超过999999.99').default(0).openapi({
+    description: '优惠金额',
+    example: 5.00
+  }),
+  payAmount: z.coerce.number().min(0, '实际支付金额不能小于0').max(999999.99, '实际支付金额不能超过999999.99').default(0).openapi({
+    description: '实际支付金额',
+    example: 94.99
+  }),
+  deviceNo: z.string().max(255, '设备编号最多255个字符').nullable().optional().openapi({
+    description: '设备编号',
+    example: 'DEV001234'
+  }),
+  description: z.string().max(255, '订单描述最多255个字符').nullable().optional().openapi({
+    description: '订单描述',
+    example: '购买商品'
+  }),
+  goodsDetail: z.string().max(2000, '订单详情最多2000个字符').nullable().optional().openapi({
+    description: '订单详情(json格式)',
+    example: '[{"goodsId":1,"name":"商品1","price":99.99,"num":1}]'
+  }),
+  goodsTag: z.string().max(255, '订单优惠标记最多255个字符').nullable().optional().openapi({
+    description: '订单优惠标记',
+    example: '满100减5'
+  }),
+  address: z.string().max(255, '地址最多255个字符').nullable().optional().openapi({
+    description: '地址',
+    example: '北京市朝阳区xxx路xxx号'
+  }),
+  orderType: z.coerce.number().int().min(1, '订单类型最小为1').max(2, '订单类型最大为2').default(1).openapi({
+    description: '订单类型 1实物订单 2虚拟订单',
+    example: 1
+  }),
+  payType: z.coerce.number().int().min(0, '支付类型最小为0').max(2, '支付类型最大为2').default(0).openapi({
+    description: '支付类型1积分2礼券',
+    example: 1
+  }),
+  payState: z.coerce.number().int().min(0, '支付状态最小为0').max(5, '支付状态最大为5').default(0).openapi({
+    description: '支付状态 0未支付1支付中2支付成功3已退款4支付失败5订单关闭',
+    example: 2
+  }),
+  state: z.coerce.number().int().min(0, '订单状态最小为0').max(3, '订单状态最大为3').default(0).openapi({
+    description: '订单状态 0未发货1已发货2收货成功3已退货',
+    example: 0
+  }),
+  userPhone: z.string().max(50, '用户手机号最多50个字符').nullable().optional().openapi({
+    description: '用户手机号',
+    example: '13800138000'
+  }),
+  merchantId: z.coerce.number().int().positive().default(0).openapi({
+    description: '商户id',
+    example: 1
+  }),
+  merchantNo: z.coerce.number().int().positive().nullable().optional().openapi({
+    description: '商户号',
+    example: 1001
+  }),
+  supplierId: z.coerce.number().int().positive().default(0).openapi({
+    description: '供货商id',
+    example: 1
+  }),
+  addressId: z.coerce.number().int().positive().default(0).openapi({
+    description: '地址id',
+    example: 1
+  }),
+  receiverMobile: z.string().max(255, '收货人手机号最多255个字符').nullable().optional().openapi({
+    description: '收货人手机号',
+    example: '13800138000'
+  }),
+  recevierName: z.string().max(255, '收货人姓名最多255个字符').nullable().optional().openapi({
+    description: '收货人姓名',
+    example: '张三'
+  }),
+  recevierProvince: z.coerce.number().int().positive().default(0).openapi({
+    description: '收货人所在省',
+    example: 110000
+  }),
+  recevierCity: z.coerce.number().int().positive().default(0).openapi({
+    description: '收货人所在市',
+    example: 110100
+  }),
+  recevierDistrict: z.coerce.number().int().positive().default(0).openapi({
+    description: '收货人所在区',
+    example: 110105
+  }),
+  recevierTown: z.coerce.number().int().positive().default(0).openapi({
+    description: '收货人所在街道',
+    example: 110105001
+  }),
+  refundTime: z.coerce.date().nullable().optional().openapi({
+    description: '退款时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  closeTime: z.coerce.date().nullable().optional().openapi({
+    description: '订单关闭时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  remark: z.string().max(255, '管理员备注信息最多255个字符').nullable().optional().openapi({
+    description: '管理员备注信息',
+    example: '请尽快发货'
+  }),
+  createdBy: z.number().int().positive().nullable().optional().openapi({
+    description: '创建人ID',
+    example: 1
+  }),
+  updatedBy: z.number().int().positive().nullable().optional().openapi({
+    description: '更新人ID',
+    example: 1
+  }),
+  createdAt: z.coerce.date().openapi({
+    description: '创建时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  updatedAt: z.coerce.date().openapi({
+    description: '更新时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  // 关联实体
+  user: z.object({
+    id: z.number().int().positive().openapi({ description: '用户ID' }),
+    username: z.string().openapi({ description: '用户名', example: 'user123' }),
+    phone: z.string().nullable().openapi({ description: '手机号', example: '13800138000' })
+  }).nullable().optional().openapi({
+    description: '用户信息'
+  }),
+  merchant: z.object({
+    id: z.number().int().positive().openapi({ description: '商户ID' }),
+    name: z.string().openapi({ description: '商户名称', example: '商户A' })
+  }).nullable().optional().openapi({
+    description: '商户信息'
+  }),
+  supplier: z.object({
+    id: z.number().int().positive().openapi({ description: '供货商ID' }),
+    name: z.string().openapi({ description: '供货商名称', example: '供货商A' })
+  }).nullable().optional().openapi({
+    description: '供货商信息'
+  }),
+  deliveryAddress: z.object({
+    id: z.number().int().positive().openapi({ description: '地址ID' }),
+    name: z.string().openapi({ description: '收货人姓名', example: '张三' }),
+    phone: z.string().openapi({ description: '收货人电话', example: '13800138000' }),
+    address: z.string().openapi({ description: '详细地址', example: '北京市朝阳区xxx路xxx号' })
+  }).nullable().optional().openapi({
+    description: '收货地址信息'
+  })
+});
+
+// 创建订单DTO
+export const CreateOrderDto = z.object({
+  orderNo: z.string().min(1, '订单号不能为空').max(50, '订单号最多50个字符').openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  userId: z.number().int().positive('用户ID必须是正整数').openapi({
+    description: '用户ID',
+    example: 1
+  }),
+  authCode: z.string().max(32, '付款码最多32个字符').nullable().optional().openapi({
+    description: '付款码',
+    example: '12345678901234567890123456789012'
+  }),
+  cardNo: z.string().max(32, '卡号最多32个字符').nullable().optional().openapi({
+    description: '卡号',
+    example: '6222********1234'
+  }),
+  sjtCardNo: z.string().max(32, '盛京通卡号最多32个字符').nullable().optional().openapi({
+    description: '盛京通卡号',
+    example: 'SJT1234567890'
+  }),
+  amount: z.coerce.number().min(0, '订单金额不能小于0').max(999999.99, '订单金额不能超过999999.99').openapi({
+    description: '订单金额',
+    example: 99.99
+  }),
+  costAmount: z.coerce.number().min(0, '成本金额不能小于0').max(999999.99, '成本金额不能超过999999.99').default(0).optional().openapi({
+    description: '成本金额',
+    example: 50.00
+  }),
+  freightAmount: z.coerce.number().min(0, '运费不能小于0').max(999999.99, '运费不能超过999999.99').default(0).optional().openapi({
+    description: '运费',
+    example: 10.00
+  }),
+  discountAmount: z.coerce.number().min(0, '优惠金额不能小于0').max(999999.99, '优惠金额不能超过999999.99').default(0).optional().openapi({
+    description: '优惠金额',
+    example: 5.00
+  }),
+  payAmount: z.coerce.number().min(0, '实际支付金额不能小于0').max(999999.99, '实际支付金额不能超过999999.99').default(0).optional().openapi({
+    description: '实际支付金额',
+    example: 94.99
+  }),
+  deviceNo: z.string().max(255, '设备编号最多255个字符').nullable().optional().openapi({
+    description: '设备编号',
+    example: 'DEV001234'
+  }),
+  description: z.string().max(255, '订单描述最多255个字符').nullable().optional().openapi({
+    description: '订单描述',
+    example: '购买商品'
+  }),
+  goodsDetail: z.string().max(2000, '订单详情最多2000个字符').nullable().optional().openapi({
+    description: '订单详情(json格式)',
+    example: '[{"goodsId":1,"name":"商品1","price":99.99,"num":1}]'
+  }),
+  goodsTag: z.string().max(255, '订单优惠标记最多255个字符').nullable().optional().openapi({
+    description: '订单优惠标记',
+    example: '满100减5'
+  }),
+  address: z.string().max(255, '地址最多255个字符').nullable().optional().openapi({
+    description: '地址',
+    example: '北京市朝阳区xxx路xxx号'
+  }),
+  orderType: z.coerce.number().int().min(1, '订单类型最小为1').max(2, '订单类型最大为2').default(1).optional().openapi({
+    description: '订单类型 1实物订单 2虚拟订单',
+    example: 1
+  }),
+  payType: z.coerce.number().int().min(0, '支付类型最小为0').max(2, '支付类型最大为2').default(0).optional().openapi({
+    description: '支付类型1积分2礼券',
+    example: 1
+  }),
+  payState: z.coerce.number().int().min(0, '支付状态最小为0').max(5, '支付状态最大为5').default(0).optional().openapi({
+    description: '支付状态 0未支付1支付中2支付成功3已退款4支付失败5订单关闭',
+    example: 0
+  }),
+  state: z.coerce.number().int().min(0, '订单状态最小为0').max(3, '订单状态最大为3').default(0).optional().openapi({
+    description: '订单状态 0未发货1已发货2收货成功3已退货',
+    example: 0
+  }),
+  userPhone: z.string().max(50, '用户手机号最多50个字符').nullable().optional().openapi({
+    description: '用户手机号',
+    example: '13800138000'
+  }),
+  merchantId: z.coerce.number().int().positive().default(0).optional().openapi({
+    description: '商户id',
+    example: 1
+  }),
+  merchantNo: z.coerce.number().int().positive().nullable().optional().openapi({
+    description: '商户号',
+    example: 1001
+  }),
+  supplierId: z.coerce.number().int().positive().default(0).optional().openapi({
+    description: '供货商id',
+    example: 1
+  }),
+  addressId: z.coerce.number().int().positive().default(0).optional().openapi({
+    description: '地址id',
+    example: 1
+  }),
+  receiverMobile: z.string().max(255, '收货人手机号最多255个字符').nullable().optional().openapi({
+    description: '收货人手机号',
+    example: '13800138000'
+  }),
+  recevierName: z.string().max(255, '收货人姓名最多255个字符').nullable().optional().openapi({
+    description: '收货人姓名',
+    example: '张三'
+  }),
+  recevierProvince: z.coerce.number().int().positive().default(0).optional().openapi({
+    description: '收货人所在省',
+    example: 110000
+  }),
+  recevierCity: z.coerce.number().int().positive().default(0).optional().openapi({
+    description: '收货人所在市',
+    example: 110100
+  }),
+  recevierDistrict: z.coerce.number().int().positive().default(0).optional().openapi({
+    description: '收货人所在区',
+    example: 110105
+  }),
+  recevierTown: z.coerce.number().int().positive().default(0).optional().openapi({
+    description: '收货人所在街道',
+    example: 110105001
+  }),
+  refundTime: z.coerce.date().nullable().optional().openapi({
+    description: '退款时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  closeTime: z.coerce.date().nullable().optional().openapi({
+    description: '订单关闭时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  remark: z.string().max(255, '管理员备注信息最多255个字符').nullable().optional().openapi({
+    description: '管理员备注信息',
+    example: '请尽快发货'
+  }),
+  createdBy: z.number().int().positive().nullable().optional().openapi({
+    description: '创建人ID',
+    example: 1
+  })
+});
+
+// 更新订单DTO(通常仅包含可更新字段,这里示例保留大部分字段,实际可根据业务调整)
+export const UpdateOrderDto = z.object({
+  authCode: z.string().max(32, '付款码最多32个字符').nullable().optional().openapi({
+    description: '付款码',
+    example: '12345678901234567890123456789012'
+  }),
+  cardNo: z.string().max(32, '卡号最多32个字符').nullable().optional().openapi({
+    description: '卡号',
+    example: '6222********1234'
+  }),
+  sjtCardNo: z.string().max(32, '盛京通卡号最多32个字符').nullable().optional().openapi({
+    description: '盛京通卡号',
+    example: 'SJT1234567890'
+  }),
+  amount: z.coerce.number().min(0, '订单金额不能小于0').max(999999.99, '订单金额不能超过999999.99').optional().openapi({
+    description: '订单金额',
+    example: 99.99
+  }),
+  costAmount: z.coerce.number().min(0, '成本金额不能小于0').max(999999.99, '成本金额不能超过999999.99').optional().openapi({
+    description: '成本金额',
+    example: 50.00
+  }),
+  freightAmount: z.coerce.number().min(0, '运费不能小于0').max(999999.99, '运费不能超过999999.99').optional().openapi({
+    description: '运费',
+    example: 10.00
+  }),
+  discountAmount: z.coerce.number().min(0, '优惠金额不能小于0').max(999999.99, '优惠金额不能超过999999.99').optional().openapi({
+    description: '优惠金额',
+    example: 5.00
+  }),
+  payAmount: z.coerce.number().min(0, '实际支付金额不能小于0').max(999999.99, '实际支付金额不能超过999999.99').optional().openapi({
+    description: '实际支付金额',
+    example: 94.99
+  }),
+  deviceNo: z.string().max(255, '设备编号最多255个字符').nullable().optional().openapi({
+    description: '设备编号',
+    example: 'DEV001234'
+  }),
+  description: z.string().max(255, '订单描述最多255个字符').nullable().optional().openapi({
+    description: '订单描述',
+    example: '购买商品'
+  }),
+  goodsDetail: z.string().max(2000, '订单详情最多2000个字符').nullable().optional().openapi({
+    description: '订单详情(json格式)',
+    example: '[{"goodsId":1,"name":"商品1","price":99.99,"num":1}]'
+  }),
+  goodsTag: z.string().max(255, '订单优惠标记最多255个字符').nullable().optional().openapi({
+    description: '订单优惠标记',
+    example: '满100减5'
+  }),
+  address: z.string().max(255, '地址最多255个字符').nullable().optional().openapi({
+    description: '地址',
+    example: '北京市朝阳区xxx路xxx号'
+  }),
+  orderType: z.coerce.number().int().min(1, '订单类型最小为1').max(2, '订单类型最大为2').optional().openapi({
+    description: '订单类型 1实物订单 2虚拟订单',
+    example: 1
+  }),
+  payType: z.coerce.number().int().min(0, '支付类型最小为0').max(2, '支付类型最大为2').optional().openapi({
+    description: '支付类型1积分2礼券',
+    example: 1
+  }),
+  payState: z.coerce.number().int().min(0, '支付状态最小为0').max(5, '支付状态最大为5').optional().openapi({
+    description: '支付状态 0未支付1支付中2支付成功3已退款4支付失败5订单关闭',
+    example: 2
+  }),
+  state: z.coerce.number().int().min(0, '订单状态最小为0').max(3, '订单状态最大为3').optional().openapi({
+    description: '订单状态 0未发货1已发货2收货成功3已退货',
+    example: 1
+  }),
+  userPhone: z.string().max(50, '用户手机号最多50个字符').nullable().optional().openapi({
+    description: '用户手机号',
+    example: '13800138000'
+  }),
+  merchantId: z.coerce.number().int().positive().optional().openapi({
+    description: '商户id',
+    example: 1
+  }),
+  merchantNo: z.coerce.number().int().positive().nullable().optional().openapi({
+    description: '商户号',
+    example: 1001
+  }),
+  supplierId: z.coerce.number().int().positive().optional().openapi({
+    description: '供货商id',
+    example: 1
+  }),
+  addressId: z.coerce.number().int().positive().optional().openapi({
+    description: '地址id',
+    example: 1
+  }),
+  receiverMobile: z.string().max(255, '收货人手机号最多255个字符').nullable().optional().openapi({
+    description: '收货人手机号',
+    example: '13800138000'
+  }),
+  recevierName: z.string().max(255, '收货人姓名最多255个字符').nullable().optional().openapi({
+    description: '收货人姓名',
+    example: '张三'
+  }),
+  recevierProvince: z.coerce.number().int().positive().optional().openapi({
+    description: '收货人所在省',
+    example: 110000
+  }),
+  recevierCity: z.coerce.number().int().positive().optional().openapi({
+    description: '收货人所在市',
+    example: 110100
+  }),
+  recevierDistrict: z.coerce.number().int().positive().optional().openapi({
+    description: '收货人所在区',
+    example: 110105
+  }),
+  recevierTown: z.coerce.number().int().positive().optional().openapi({
+    description: '收货人所在街道',
+    example: 110105001
+  }),
+  refundTime: z.coerce.date().nullable().optional().openapi({
+    description: '退款时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  closeTime: z.coerce.date().nullable().optional().openapi({
+    description: '订单关闭时间',
+    example: '2024-01-01T12:00:00Z'
+  }),
+  remark: z.string().max(255, '管理员备注信息最多255个字符').nullable().optional().openapi({
+    description: '管理员备注信息',
+    example: '请尽快发货'
+  }),
+  updatedBy: z.number().int().positive().nullable().optional().openapi({
+    description: '更新人ID',
+    example: 1
+  })
+});
+