浏览代码

🚀 feat(订单模块多租户): 完成实体和服务多租户化

yourname 1 月之前
父节点
当前提交
8c56e4c542
共有 49 个文件被更改,包括 8242 次插入32 次删除
  1. 50 32
      docs/stories/007.010.orders-module-multi-tenant-replication.md
  2. 93 0
      packages/orders-module-mt/package.json
  3. 7 0
      packages/orders-module-mt/src/entities/index.ts
  4. 82 0
      packages/orders-module-mt/src/entities/order-goods.entity.ts
  5. 90 0
      packages/orders-module-mt/src/entities/order-goods.mt.entity.ts
  6. 40 0
      packages/orders-module-mt/src/entities/order-refund.entity.ts
  7. 47 0
      packages/orders-module-mt/src/entities/order-refund.mt.entity.ts
  8. 139 0
      packages/orders-module-mt/src/entities/order.entity.ts
  9. 148 0
      packages/orders-module-mt/src/entities/order.mt.entity.ts
  10. 5 0
      packages/orders-module-mt/src/index.ts
  11. 24 0
      packages/orders-module-mt/src/routes/admin/order-items.ts
  12. 24 0
      packages/orders-module-mt/src/routes/admin/orders.ts
  13. 24 0
      packages/orders-module-mt/src/routes/admin/refunds.ts
  14. 63 0
      packages/orders-module-mt/src/routes/create-order.ts
  15. 10 0
      packages/orders-module-mt/src/routes/index.ts
  16. 296 0
      packages/orders-module-mt/src/routes/user/order-items.ts
  17. 27 0
      packages/orders-module-mt/src/routes/user/orders.ts
  18. 305 0
      packages/orders-module-mt/src/routes/user/refunds.ts
  19. 66 0
      packages/orders-module-mt/src/schemas/create-order.schema.ts
  20. 4 0
      packages/orders-module-mt/src/schemas/index.ts
  21. 255 0
      packages/orders-module-mt/src/schemas/order-goods.schema.ts
  22. 129 0
      packages/orders-module-mt/src/schemas/order-refund.schema.ts
  23. 497 0
      packages/orders-module-mt/src/schemas/order.schema.ts
  24. 136 0
      packages/orders-module-mt/src/schemas/user-order.schema.ts
  25. 9 0
      packages/orders-module-mt/src/services/index.ts
  26. 11 0
      packages/orders-module-mt/src/services/order-goods.mt.service.ts
  27. 9 0
      packages/orders-module-mt/src/services/order-goods.service.ts
  28. 11 0
      packages/orders-module-mt/src/services/order-refund.mt.service.ts
  29. 9 0
      packages/orders-module-mt/src/services/order-refund.service.ts
  30. 185 0
      packages/orders-module-mt/src/services/order.mt.service.ts
  31. 180 0
      packages/orders-module-mt/src/services/order.service.ts
  32. 121 0
      packages/orders-module-mt/src/services/user-order-goods.mt.service.ts
  33. 114 0
      packages/orders-module-mt/src/services/user-order-goods.service.ts
  34. 169 0
      packages/orders-module-mt/src/services/user-refunds.mt.service.ts
  35. 151 0
      packages/orders-module-mt/src/services/user-refunds.service.ts
  36. 1 0
      packages/orders-module-mt/src/types/index.ts
  37. 65 0
      packages/orders-module-mt/src/types/order.types.ts
  38. 555 0
      packages/orders-module-mt/tests/integration/admin-order-items.integration.test.ts
  39. 706 0
      packages/orders-module-mt/tests/integration/admin-orders.integration.test.ts
  40. 416 0
      packages/orders-module-mt/tests/integration/admin-refunds.integration.test.ts
  41. 515 0
      packages/orders-module-mt/tests/integration/create-order.integration.test.ts
  42. 36 0
      packages/orders-module-mt/tests/integration/entity-configuration.integration.test.ts
  43. 708 0
      packages/orders-module-mt/tests/integration/user-order-items.integration.test.ts
  44. 628 0
      packages/orders-module-mt/tests/integration/user-orders.integration.test.ts
  45. 661 0
      packages/orders-module-mt/tests/integration/user-refunds.integration.test.ts
  46. 314 0
      packages/orders-module-mt/tests/utils/test-data-factory.ts
  47. 16 0
      packages/orders-module-mt/tsconfig.json
  48. 21 0
      packages/orders-module-mt/vitest.config.ts
  49. 70 0
      pnpm-lock.yaml

+ 50 - 32
docs/stories/007.010.orders-module-multi-tenant-replication.md

@@ -24,32 +24,32 @@ Draft
 
 ## 任务 / 子任务
 
-- [ ] 复制订单管理模块为多租户版本 (AC: 1)
-  - [ ] 复制 `packages/orders-module` 为 `packages/orders-module-mt`
-  - [ ] 更新包配置为 `@d8d/orders-module-mt`
-  - [ ] 更新依赖:
-    - [ ] 将 `@d8d/user-module` 替换为 `@d8d/user-module-mt`
-    - [ ] 将 `@d8d/auth-module` 替换为 `@d8d/auth-module-mt`
-    - [ ] 将 `@d8d/file-module` 替换为 `@d8d/file-module-mt`
-    - [ ] 将 `@d8d/merchant-module` 替换为 `@d8d/merchant-module-mt`
-    - [ ] 将 `@d8d/supplier-module` 替换为 `@d8d/supplier-module-mt`
-    - [ ] 将 `@d8d/delivery-address-module` 替换为 `@d8d/delivery-address-module-mt`
-    - [ ] 将 `@d8d/goods-module` 替换为 `@d8d/goods-module-mt`
-
-- [ ] 更新多租户订单实体 (AC: 2)
-  - [ ] 创建 `OrderMt` 实体,表名为 `orders_mt`
-  - [ ] 创建 `OrderGoodsMt` 实体,表名为 `orders_goods_mt`
-  - [ ] 创建 `RefundMt` 实体,表名为 `refunds_mt`
-  - [ ] 为所有实体添加 `tenantId` 字段和正确的TypeORM配置
-  - [ ] 保持其他字段与单租户版本一致
-  - [ ] 更新关联关系指向多租户实体
-
-- [ ] 更新多租户订单服务 (AC: 3, 4)
-  - [ ] 使用共享CRUD库的GenericCrudService
-  - [ ] 所有查询操作自动添加租户过滤
-  - [ ] 创建操作自动设置租户ID
-  - [ ] 更新关联查询支持租户隔离
-  - [ ] 确保订单与订单商品、退款等关联实体的租户一致性
+- [x] 复制订单管理模块为多租户版本 (AC: 1)
+  - [x] 复制 `packages/orders-module` 为 `packages/orders-module-mt`
+  - [x] 更新包配置为 `@d8d/orders-module-mt`
+  - [x] 更新依赖:
+    - [x] 将 `@d8d/user-module` 替换为 `@d8d/user-module-mt`
+    - [x] 将 `@d8d/auth-module` 替换为 `@d8d/auth-module-mt`
+    - [x] 将 `@d8d/file-module` 替换为 `@d8d/file-module-mt`
+    - [x] 将 `@d8d/merchant-module` 替换为 `@d8d/merchant-module-mt`
+    - [x] 将 `@d8d/supplier-module` 替换为 `@d8d/supplier-module-mt`
+    - [x] 将 `@d8d/delivery-address-module` 替换为 `@d8d/delivery-address-module-mt`
+    - [x] 将 `@d8d/goods-module` 替换为 `@d8d/goods-module-mt`
+
+- [x] 更新多租户订单实体 (AC: 2)
+  - [x] 创建 `OrderMt` 实体,表名为 `orders_mt`
+  - [x] 创建 `OrderGoodsMt` 实体,表名为 `orders_goods_mt`
+  - [x] 创建 `OrderRefundMt` 实体,表名为 `orders_refund_mt`
+  - [x] 为所有实体添加 `tenantId` 字段和正确的TypeORM配置
+  - [x] 保持其他字段与单租户版本一致
+  - [x] 更新关联关系指向多租户实体
+
+- [x] 更新多租户订单服务 (AC: 3, 4)
+  - [x] 使用共享CRUD库的GenericCrudService
+  - [x] 所有查询操作自动添加租户过滤
+  - [x] 创建操作自动设置租户ID
+  - [x] 更新关联查询支持租户隔离
+  - [x] 确保订单与订单商品、退款等关联实体的租户一致性
 
 - [ ] 更新多租户路由配置 (AC: 3)
   - [ ] 更新用户订单路由使用多租户实体和服务
@@ -79,10 +79,10 @@ Draft
   - [ ] 验证单租户API接口不受影响
   - [ ] 确认单租户数据库表结构不变
 
-- [ ] 在创建复制的代码修改完后先运行安装
-  - [ ] 在复制模块后运行 `pnpm install` 安装依赖
-  - [ ] 验证新包已正确添加到工作区
-  - [ ] 确认所有依赖解析正确
+- [x] 在创建复制的代码修改完后先运行安装
+  - [x] 在复制模块后运行 `pnpm install` 安装依赖
+  - [x] 验证新包已正确添加到工作区
+  - [x] 确认所有依赖解析正确
 
 - [ ] 执行性能基准测试 (AC: 8)
   - [ ] 运行多租户订单管理模块性能测试
@@ -212,10 +212,28 @@ Draft
 - 2025-11-14: 基于先前故事经验教训创建订单模块多租户复制故事
 
 ### Completion Notes List
-*此部分将在开发过程中由开发代理填充*
+- ✅ 成功复制订单管理模块为多租户版本 `@d8d/orders-module-mt`
+- ✅ 更新包配置和依赖关系,将所有单租户模块替换为多租户模块
+- ✅ 创建多租户订单实体:`OrderMt`、`OrderGoodsMt`、`OrderRefundMt`
+- ✅ 为所有实体添加 `tenantId` 字段和复合索引配置
+- ✅ 更新关联关系指向多租户实体
+- ✅ 创建多租户订单服务:`OrderMtService`、`OrderGoodsMtService`、`OrderRefundMtService`
+- ✅ 创建多租户用户服务:`UserOrderGoodsMtService`、`UserRefundsMtService`
+- ✅ 所有服务启用租户选项:`tenantOptions: { enabled: true, tenantIdField: 'tenantId' }`
+- ✅ 更新服务导出文件包含所有多租户服务
 
 ### File List
-*此部分将在开发过程中由开发代理填充*
+- `packages/orders-module-mt/package.json` - 更新包配置和依赖
+- `packages/orders-module-mt/src/entities/order.mt.entity.ts` - 多租户订单实体
+- `packages/orders-module-mt/src/entities/order-goods.mt.entity.ts` - 多租户订单商品实体
+- `packages/orders-module-mt/src/entities/order-refund.mt.entity.ts` - 多租户退款实体
+- `packages/orders-module-mt/src/entities/index.ts` - 更新实体导出
+- `packages/orders-module-mt/src/services/order.mt.service.ts` - 多租户订单服务
+- `packages/orders-module-mt/src/services/order-goods.mt.service.ts` - 多租户订单商品服务
+- `packages/orders-module-mt/src/services/order-refund.mt.service.ts` - 多租户退款服务
+- `packages/orders-module-mt/src/services/user-order-goods.mt.service.ts` - 多租户用户订单商品服务
+- `packages/orders-module-mt/src/services/user-refunds.mt.service.ts` - 多租户用户退款服务
+- `packages/orders-module-mt/src/services/index.ts` - 更新服务导出
 
 ## QA结果
 

+ 93 - 0
packages/orders-module-mt/package.json

@@ -0,0 +1,93 @@
+{
+  "name": "@d8d/orders-module-mt",
+  "version": "1.0.0",
+  "description": "订单管理多租户模块 - 提供订单、订单商品和退款的完整CRUD功能,包括订单创建、状态管理、库存更新等业务逻辑,支持租户数据隔离",
+  "type": "module",
+  "main": "src/index.ts",
+  "types": "src/index.ts",
+  "exports": {
+    ".": {
+      "types": "./src/index.ts",
+      "import": "./src/index.ts",
+      "require": "./src/index.ts"
+    },
+    "./services": {
+      "types": "./src/services/index.ts",
+      "import": "./src/services/index.ts",
+      "require": "./src/services/index.ts"
+    },
+    "./schemas": {
+      "types": "./src/schemas/index.ts",
+      "import": "./src/schemas/index.ts",
+      "require": "./src/schemas/index.ts"
+    },
+    "./routes": {
+      "types": "./src/routes/index.ts",
+      "import": "./src/routes/index.ts",
+      "require": "./src/routes/index.ts"
+    },
+    "./entities": {
+      "types": "./src/entities/index.ts",
+      "import": "./src/entities/index.ts",
+      "require": "./src/entities/index.ts"
+    },
+    "./types": {
+      "types": "./src/types/index.ts",
+      "import": "./src/types/index.ts",
+      "require": "./src/types/index.ts"
+    }
+  },
+  "files": [
+    "src"
+  ],
+  "scripts": {
+    "build": "tsc",
+    "dev": "tsc --watch",
+    "test": "vitest run",
+    "test:watch": "vitest",
+    "test:coverage": "vitest run --coverage",
+    "test:integration": "vitest run tests/integration",
+    "lint": "eslint src --ext .ts,.tsx",
+    "typecheck": "tsc --noEmit"
+  },
+  "dependencies": {
+    "@d8d/shared-types": "workspace:*",
+    "@d8d/shared-utils": "workspace:*",
+    "@d8d/shared-crud": "workspace:*",
+    "@d8d/auth-module-mt": "workspace:*",
+    "@d8d/user-module-mt": "workspace:*",
+    "@d8d/goods-module-mt": "workspace:*",
+    "@d8d/delivery-address-module-mt": "workspace:*",
+    "@d8d/merchant-module-mt": "workspace:*",
+    "@d8d/supplier-module-mt": "workspace:*",
+    "@d8d/file-module-mt": "workspace:*",
+    "@d8d/geo-areas": "workspace:*",
+    "@hono/zod-openapi": "^1.0.2",
+    "typeorm": "^0.3.20",
+    "zod": "^4.1.12"
+  },
+  "devDependencies": {
+    "@types/node": "^22.10.2",
+    "typescript": "^5.8.3",
+    "vitest": "^3.2.4",
+    "@d8d/shared-test-util": "workspace:*",
+    "@typescript-eslint/eslint-plugin": "^8.18.1",
+    "@typescript-eslint/parser": "^8.18.1",
+    "eslint": "^9.17.0"
+  },
+  "peerDependencies": {
+    "hono": "^4.8.5"
+  },
+  "keywords": [
+    "orders",
+    "order-management",
+    "e-commerce",
+    "crud",
+    "api",
+    "management",
+    "multi-tenant",
+    "tenant-isolation"
+  ],
+  "author": "D8D Team",
+  "license": "MIT"
+}

+ 7 - 0
packages/orders-module-mt/src/entities/index.ts

@@ -0,0 +1,7 @@
+export { Order } from './order.entity';
+export { OrderGoods } from './order-goods.entity';
+export { OrderRefund } from './order-refund.entity';
+
+export { OrderMt } from './order.mt.entity';
+export { OrderGoodsMt } from './order-goods.mt.entity';
+export { OrderRefundMt } from './order-refund.mt.entity';

+ 82 - 0
packages/orders-module-mt/src/entities/order-goods.entity.ts

@@ -0,0 +1,82 @@
+import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn } from 'typeorm';
+import { Order } from './order.entity';
+import { Goods } from '@d8d/goods-module';
+import { Supplier } from '@d8d/supplier-module';
+import { File } from '@d8d/file-module';
+
+@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_type', type: 'int', default: 1, comment: '1实物产品2虚拟订单' })
+  goodsType!: number;
+
+  @Column({ name: 'supplier_id', type: 'int', unsigned: true, nullable: true, comment: '供货商id' })
+  supplierId!: number | null;
+
+  @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;
+
+  @Column({ name: 'image_file_id', type: 'int', unsigned: true, nullable: true, comment: '商品图片文件ID' })
+  imageFileId!: 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;
+
+  @ManyToOne(() => File, { nullable: true })
+  @JoinColumn({ name: 'image_file_id', referencedColumnName: 'id' })
+  imageFile!: File | null;
+}

+ 90 - 0
packages/orders-module-mt/src/entities/order-goods.mt.entity.ts

@@ -0,0 +1,90 @@
+import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn, Index } from 'typeorm';
+import { OrderMt } from './order.mt.entity';
+import { GoodsMt } from '@d8d/goods-module-mt';
+import { SupplierMt } from '@d8d/supplier-module-mt';
+import { FileMt } from '@d8d/file-module-mt';
+
+@Entity('orders_goods_mt')
+@Index(['tenantId'])
+@Index(['tenantId', 'id'])
+@Index(['tenantId', 'orderId'])
+@Index(['tenantId', 'goodsId'])
+@Index(['tenantId', 'supplierId'])
+export class OrderGoodsMt {
+  @PrimaryGeneratedColumn({ unsigned: true })
+  id!: number;
+
+  @Column({ name: 'tenant_id', type: 'int', unsigned: true, comment: '租户ID' })
+  tenantId!: 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_type', type: 'int', default: 1, comment: '1实物产品2虚拟订单' })
+  goodsType!: number;
+
+  @Column({ name: 'supplier_id', type: 'int', unsigned: true, nullable: true, comment: '供货商id' })
+  supplierId!: number | null;
+
+  @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;
+
+  @Column({ name: 'image_file_id', type: 'int', unsigned: true, nullable: true, comment: '商品图片文件ID' })
+  imageFileId!: number | null;
+
+  // 关联关系
+  @ManyToOne(() => OrderMt)
+  @JoinColumn({ name: 'order_id', referencedColumnName: 'id' })
+  order!: OrderMt;
+
+  @ManyToOne(() => GoodsMt)
+  @JoinColumn({ name: 'goods_id', referencedColumnName: 'id' })
+  goods!: GoodsMt;
+
+  @ManyToOne(() => SupplierMt)
+  @JoinColumn({ name: 'supplier_id', referencedColumnName: 'id' })
+  supplier!: SupplierMt;
+
+  @ManyToOne(() => FileMt, { nullable: true })
+  @JoinColumn({ name: 'image_file_id', referencedColumnName: 'id' })
+  imageFile!: FileMt | null;
+}

+ 40 - 0
packages/orders-module-mt/src/entities/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;
+}

+ 47 - 0
packages/orders-module-mt/src/entities/order-refund.mt.entity.ts

@@ -0,0 +1,47 @@
+import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn, Index } from 'typeorm';
+import { OrderMt } from './order.mt.entity';
+
+@Entity('orders_refund_mt')
+@Index(['tenantId'])
+@Index(['tenantId', 'id'])
+@Index(['tenantId', 'orderNo'])
+@Index(['tenantId', 'refundOrderNo'])
+export class OrderRefundMt {
+  @PrimaryGeneratedColumn({ unsigned: true })
+  id!: number;
+
+  @Column({ name: 'tenant_id', type: 'int', unsigned: true, comment: '租户ID' })
+  tenantId!: 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(() => OrderMt)
+  @JoinColumn({ name: 'order_no', referencedColumnName: 'orderNo' })
+  order!: OrderMt;
+}

+ 139 - 0
packages/orders-module-mt/src/entities/order.entity.ts

@@ -0,0 +1,139 @@
+import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn } from 'typeorm';
+import { UserEntity as User } from '@d8d/user-module';
+import { Merchant } from '@d8d/merchant-module';
+import { Supplier } from '@d8d/supplier-module';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+
+@Entity('orders')
+export class Order {
+  @PrimaryGeneratedColumn({ unsigned: true })
+  id!: number;
+
+  @Column({ name: 'order_no', type: 'varchar', length: 50, unique: true, comment: '订单号' })
+  orderNo!: string;
+
+  @Column({ name: 'user_id', type: 'int', unsigned: true, comment: '用户ID' })
+  userId!: number;
+
+  @Column({ name: 'auth_code', type: 'varchar', length: 32, nullable: true, comment: '付款码' })
+  authCode!: string | null;
+
+  @Column({ name: 'card_no', type: 'varchar', length: 32, nullable: true, comment: '卡号' })
+  cardNo!: string | null;
+
+  @Column({ name: 'sjt_card_no', type: 'varchar', length: 32, nullable: true, comment: '盛京通卡号' })
+  sjtCardNo!: string | null;
+
+  @Column({ name: 'amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '订单金额' })
+  amount!: number;
+
+  @Column({ name: 'cost_amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '成本金额' })
+  costAmount!: number;
+
+  @Column({ name: 'freight_amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '运费' })
+  freightAmount!: number;
+
+  @Column({ name: 'discount_amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '优惠金额' })
+  discountAmount!: number;
+
+  @Column({ name: 'pay_amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '实际支付金额' })
+  payAmount!: number;
+
+  @Column({ name: 'device_no', type: 'varchar', length: 255, nullable: true, comment: '设备编号' })
+  deviceNo!: string | null;
+
+  @Column({ name: 'description', type: 'varchar', length: 255, nullable: true, comment: '订单描述' })
+  description!: string | null;
+
+  @Column({ name: 'goods_detail', type: 'varchar', length: 2000, nullable: true, comment: '订单详情 json' })
+  goodsDetail!: string | null;
+
+  @Column({ name: 'goods_tag', type: 'varchar', length: 255, nullable: true, comment: '订单优惠标记' })
+  goodsTag!: string | null;
+
+  @Column({ name: 'address', type: 'varchar', length: 255, nullable: true, comment: '地址' })
+  address!: string | null;
+
+  @Column({ name: 'order_type', type: 'int', default: 1, comment: '订单类型 1实物订单 2虚拟订单' })
+  orderType!: number;
+
+  @Column({ name: 'pay_type', type: 'int', default: 0, comment: '支付类型1积分2礼券' })
+  payType!: number;
+
+  @Column({ name: 'pay_state', type: 'int', default: 0, comment: '0未支付1支付中2支付成功3已退款4支付失败5订单关闭' })
+  payState!: number;
+
+  @Column({ name: 'state', type: 'int', default: 0, comment: '订单状态0未发货1已发货2收货成功3已退货' })
+  state!: number;
+
+  @Column({ name: 'user_phone', type: 'varchar', length: 50, nullable: true, comment: '用户手机号' })
+  userPhone!: string | null;
+
+  @Column({ name: 'merchant_id', type: 'int', unsigned: true, default: 0, comment: '商户id' })
+  merchantId!: number;
+
+  @Column({ name: 'merchant_no', type: 'int', unsigned: true, nullable: true, comment: '商户号' })
+  merchantNo!: number | null;
+
+  @Column({ name: 'supplier_id', type: 'int', unsigned: true, default: 0, comment: '供货商id' })
+  supplierId!: number;
+
+  @Column({ name: 'address_id', type: 'int', unsigned: true, default: 0, comment: '地址id' })
+  addressId!: number;
+
+  @Column({ name: 'receiver_mobile', type: 'varchar', length: 255, nullable: true, comment: '收货人手机号' })
+  receiverMobile!: string | null;
+
+  @Column({ name: 'recevier_name', type: 'varchar', length: 255, nullable: true, comment: '收货人姓名' })
+  recevierName!: string | null;
+
+  @Column({ name: 'recevier_province', type: 'bigint', default: 0, comment: '收货人所在省' })
+  recevierProvince!: number;
+
+  @Column({ name: 'recevier_city', type: 'bigint', default: 0, comment: '收货人所在市' })
+  recevierCity!: number;
+
+  @Column({ name: 'recevier_district', type: 'bigint', default: 0, comment: '收货人所在区' })
+  recevierDistrict!: number;
+
+  @Column({ name: 'recevier_town', type: 'bigint', default: 0, comment: '收货人所在街道' })
+  recevierTown!: number;
+
+  @Column({ name: 'refund_time', type: 'timestamp', nullable: true, comment: '退款时间' })
+  refundTime!: Date | null;
+
+  @Column({ name: 'close_time', type: 'timestamp', nullable: true, comment: '订单关闭时间' })
+  closeTime!: Date | null;
+
+  @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(() => User)
+  @JoinColumn({ name: 'user_id', referencedColumnName: 'id' })
+  user!: User;
+
+  @ManyToOne(() => Merchant)
+  @JoinColumn({ name: 'merchant_id', referencedColumnName: 'id' })
+  merchant!: Merchant;
+
+  @ManyToOne(() => Supplier)
+  @JoinColumn({ name: 'supplier_id', referencedColumnName: 'id' })
+  supplier!: Supplier;
+
+  @ManyToOne(() => DeliveryAddress)
+  @JoinColumn({ name: 'address_id', referencedColumnName: 'id' })
+  deliveryAddress!: DeliveryAddress;
+}

+ 148 - 0
packages/orders-module-mt/src/entities/order.mt.entity.ts

@@ -0,0 +1,148 @@
+import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToOne, JoinColumn, Index } from 'typeorm';
+import { UserMt } from '@d8d/user-module-mt';
+import { MerchantMt } from '@d8d/merchant-module-mt';
+import { SupplierMt } from '@d8d/supplier-module-mt';
+import { DeliveryAddressMt } from '@d8d/delivery-address-module-mt';
+
+@Entity('orders_mt')
+@Index(['tenantId'])
+@Index(['tenantId', 'id'])
+@Index(['tenantId', 'userId'])
+@Index(['tenantId', 'merchantId'])
+@Index(['tenantId', 'supplierId'])
+@Index(['tenantId', 'addressId'])
+export class OrderMt {
+  @PrimaryGeneratedColumn({ unsigned: true })
+  id!: number;
+
+  @Column({ name: 'tenant_id', type: 'int', unsigned: true, comment: '租户ID' })
+  tenantId!: number;
+
+  @Column({ name: 'order_no', type: 'varchar', length: 50, unique: true, comment: '订单号' })
+  orderNo!: string;
+
+  @Column({ name: 'user_id', type: 'int', unsigned: true, comment: '用户ID' })
+  userId!: number;
+
+  @Column({ name: 'auth_code', type: 'varchar', length: 32, nullable: true, comment: '付款码' })
+  authCode!: string | null;
+
+  @Column({ name: 'card_no', type: 'varchar', length: 32, nullable: true, comment: '卡号' })
+  cardNo!: string | null;
+
+  @Column({ name: 'sjt_card_no', type: 'varchar', length: 32, nullable: true, comment: '盛京通卡号' })
+  sjtCardNo!: string | null;
+
+  @Column({ name: 'amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '订单金额' })
+  amount!: number;
+
+  @Column({ name: 'cost_amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '成本金额' })
+  costAmount!: number;
+
+  @Column({ name: 'freight_amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '运费' })
+  freightAmount!: number;
+
+  @Column({ name: 'discount_amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '优惠金额' })
+  discountAmount!: number;
+
+  @Column({ name: 'pay_amount', type: 'decimal', precision: 10, scale: 2, default: 0.00, comment: '实际支付金额' })
+  payAmount!: number;
+
+  @Column({ name: 'device_no', type: 'varchar', length: 255, nullable: true, comment: '设备编号' })
+  deviceNo!: string | null;
+
+  @Column({ name: 'description', type: 'varchar', length: 255, nullable: true, comment: '订单描述' })
+  description!: string | null;
+
+  @Column({ name: 'goods_detail', type: 'varchar', length: 2000, nullable: true, comment: '订单详情 json' })
+  goodsDetail!: string | null;
+
+  @Column({ name: 'goods_tag', type: 'varchar', length: 255, nullable: true, comment: '订单优惠标记' })
+  goodsTag!: string | null;
+
+  @Column({ name: 'address', type: 'varchar', length: 255, nullable: true, comment: '地址' })
+  address!: string | null;
+
+  @Column({ name: 'order_type', type: 'int', default: 1, comment: '订单类型 1实物订单 2虚拟订单' })
+  orderType!: number;
+
+  @Column({ name: 'pay_type', type: 'int', default: 0, comment: '支付类型1积分2礼券' })
+  payType!: number;
+
+  @Column({ name: 'pay_state', type: 'int', default: 0, comment: '0未支付1支付中2支付成功3已退款4支付失败5订单关闭' })
+  payState!: number;
+
+  @Column({ name: 'state', type: 'int', default: 0, comment: '订单状态0未发货1已发货2收货成功3已退货' })
+  state!: number;
+
+  @Column({ name: 'user_phone', type: 'varchar', length: 50, nullable: true, comment: '用户手机号' })
+  userPhone!: string | null;
+
+  @Column({ name: 'merchant_id', type: 'int', unsigned: true, default: 0, comment: '商户id' })
+  merchantId!: number;
+
+  @Column({ name: 'merchant_no', type: 'int', unsigned: true, nullable: true, comment: '商户号' })
+  merchantNo!: number | null;
+
+  @Column({ name: 'supplier_id', type: 'int', unsigned: true, default: 0, comment: '供货商id' })
+  supplierId!: number;
+
+  @Column({ name: 'address_id', type: 'int', unsigned: true, default: 0, comment: '地址id' })
+  addressId!: number;
+
+  @Column({ name: 'receiver_mobile', type: 'varchar', length: 255, nullable: true, comment: '收货人手机号' })
+  receiverMobile!: string | null;
+
+  @Column({ name: 'recevier_name', type: 'varchar', length: 255, nullable: true, comment: '收货人姓名' })
+  recevierName!: string | null;
+
+  @Column({ name: 'recevier_province', type: 'bigint', default: 0, comment: '收货人所在省' })
+  recevierProvince!: number;
+
+  @Column({ name: 'recevier_city', type: 'bigint', default: 0, comment: '收货人所在市' })
+  recevierCity!: number;
+
+  @Column({ name: 'recevier_district', type: 'bigint', default: 0, comment: '收货人所在区' })
+  recevierDistrict!: number;
+
+  @Column({ name: 'recevier_town', type: 'bigint', default: 0, comment: '收货人所在街道' })
+  recevierTown!: number;
+
+  @Column({ name: 'refund_time', type: 'timestamp', nullable: true, comment: '退款时间' })
+  refundTime!: Date | null;
+
+  @Column({ name: 'close_time', type: 'timestamp', nullable: true, comment: '订单关闭时间' })
+  closeTime!: Date | null;
+
+  @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(() => UserMt)
+  @JoinColumn({ name: 'user_id', referencedColumnName: 'id' })
+  user!: UserMt;
+
+  @ManyToOne(() => MerchantMt)
+  @JoinColumn({ name: 'merchant_id', referencedColumnName: 'id' })
+  merchant!: MerchantMt;
+
+  @ManyToOne(() => SupplierMt)
+  @JoinColumn({ name: 'supplier_id', referencedColumnName: 'id' })
+  supplier!: SupplierMt;
+
+  @ManyToOne(() => DeliveryAddressMt)
+  @JoinColumn({ name: 'address_id', referencedColumnName: 'id' })
+  deliveryAddress!: DeliveryAddressMt;
+}

+ 5 - 0
packages/orders-module-mt/src/index.ts

@@ -0,0 +1,5 @@
+export * from './entities';
+export * from './services';
+export * from './schemas';
+export * from './routes';
+export * from './types';

+ 24 - 0
packages/orders-module-mt/src/routes/admin/order-items.ts

@@ -0,0 +1,24 @@
+import { createCrudRoutes } from '@d8d/shared-crud';
+import { OpenAPIHono } from '@hono/zod-openapi';
+import { OrderGoods } from '../../entities/order-goods.entity';
+import { OrderGoodsSchema, CreateOrderGoodsDto, UpdateOrderGoodsDto } from '../../schemas/order-goods.schema';
+import { authMiddleware } from '@d8d/auth-module';
+
+// 管理员订单商品路由 - 无数据权限限制,完整CRUD功能
+const adminOrderItemsRoutes = createCrudRoutes({
+  entity: OrderGoods,
+  createSchema: CreateOrderGoodsDto,
+  updateSchema: UpdateOrderGoodsDto,
+  getSchema: OrderGoodsSchema,
+  listSchema: OrderGoodsSchema,
+  searchFields: ['orderNo', 'goodsName'],
+  relations: ['order', 'goods', 'supplier', 'imageFile'],
+  middleware: [authMiddleware],
+  userTracking: {
+    createdByField: 'createdBy',
+    updatedByField: 'updatedBy'
+  }
+  // 管理员路由不设置dataPermission,可以访问所有数据
+});
+
+export default adminOrderItemsRoutes;

+ 24 - 0
packages/orders-module-mt/src/routes/admin/orders.ts

@@ -0,0 +1,24 @@
+import { createCrudRoutes } from '@d8d/shared-crud';
+import { OpenAPIHono } from '@hono/zod-openapi';
+import { Order } from '../../entities/order.entity';
+import { OrderSchema, CreateOrderDto, UpdateOrderDto } from '../../schemas/order.schema';
+import { authMiddleware } from '@d8d/auth-module';
+
+// 管理员订单路由 - 无数据权限限制,完整CRUD功能
+const adminOrderRoutes = createCrudRoutes({
+  entity: Order,
+  createSchema: CreateOrderDto,
+  updateSchema: UpdateOrderDto,
+  getSchema: OrderSchema,
+  listSchema: OrderSchema,
+  searchFields: ['orderNo', 'userPhone', 'recevierName'],
+  relations: ['user', 'merchant', 'supplier', 'deliveryAddress'],
+  middleware: [authMiddleware],
+  userTracking: {
+    createdByField: 'createdBy',
+    updatedByField: 'updatedBy'
+  }
+  // 管理员路由不设置dataPermission,可以访问所有数据
+});
+
+export default adminOrderRoutes;

+ 24 - 0
packages/orders-module-mt/src/routes/admin/refunds.ts

@@ -0,0 +1,24 @@
+import { createCrudRoutes } from '@d8d/shared-crud';
+import { OpenAPIHono } from '@hono/zod-openapi';
+import { OrderRefund } from '../../entities/order-refund.entity';
+import { OrderRefundSchema, CreateOrderRefundDto, UpdateOrderRefundDto } from '../../schemas/order-refund.schema';
+import { authMiddleware } from '@d8d/auth-module';
+
+// 管理员退款路由 - 无数据权限限制,完整CRUD功能
+const adminRefundsRoutes = createCrudRoutes({
+  entity: OrderRefund,
+  createSchema: CreateOrderRefundDto,
+  updateSchema: UpdateOrderRefundDto,
+  getSchema: OrderRefundSchema,
+  listSchema: OrderRefundSchema,
+  searchFields: ['orderNo', 'refundOrderNo'],
+  relations: ['order'],
+  middleware: [authMiddleware],
+  userTracking: {
+    createdByField: 'createdBy',
+    updatedByField: 'updatedBy'
+  }
+  // 管理员路由不设置dataPermission,可以访问所有数据
+});
+
+export default adminRefundsRoutes;

+ 63 - 0
packages/orders-module-mt/src/routes/create-order.ts

@@ -0,0 +1,63 @@
+import { OpenAPIHono } from '@hono/zod-openapi';
+import { authMiddleware } from '@d8d/auth-module';
+import { AppDataSource } from '@d8d/shared-utils';
+import { AuthContext } from '@d8d/shared-types';
+import { OrderService } from '../services';
+import { CreateOrderRequestDto, CreateOrderResponseDto } from '../schemas/create-order.schema';
+
+const createOrderRoutes = new OpenAPIHono<AuthContext>();
+
+// 应用认证中间件
+createOrderRoutes.use('*', authMiddleware);
+
+// 创建订单路由
+createOrderRoutes.openapi(
+  {
+    method: 'post',
+    path: '/',
+    request: {
+      body: {
+        content: {
+          'application/json': {
+            schema: CreateOrderRequestDto
+          }
+        }
+      }
+    },
+    responses: {
+      200: {
+        description: '订单创建成功',
+        content: {
+          'application/json': {
+            schema: CreateOrderResponseDto
+          }
+        }
+      },
+      400: {
+        description: '请求参数错误'
+      },
+      500: {
+        description: '服务器内部错误'
+      }
+    }
+  },
+  async (c) => {
+    const data = c.req.valid('json');
+    const user = c.get('user');
+
+    try {
+      const orderService = new OrderService(AppDataSource);
+      const result = await orderService.createOrder(data, user.id);
+
+      return c.json(result, 201);
+    } catch (error) {
+      console.error('创建订单失败:', error);
+      return c.json(
+        { error: error instanceof Error ? error.message : '创建订单失败' },
+        500
+      );
+    }
+  }
+);
+
+export default createOrderRoutes;

+ 10 - 0
packages/orders-module-mt/src/routes/index.ts

@@ -0,0 +1,10 @@
+// 导出所有路由
+export { default as adminOrderRoutes } from './admin/orders';
+export { default as adminOrderItemsRoutes } from './admin/order-items';
+export { default as adminRefundsRoutes } from './admin/refunds';
+
+export { default as userOrderRoutes } from './user/orders';
+export { default as userOrderItemsRoutes } from './user/order-items';
+export { default as userRefundsRoutes } from './user/refunds';
+
+export { default as createOrderRoutes } from './create-order';

+ 296 - 0
packages/orders-module-mt/src/routes/user/order-items.ts

@@ -0,0 +1,296 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from '@hono/zod-openapi';
+import { authMiddleware } from '@d8d/auth-module';
+import { AppDataSource, ErrorSchema, parseWithAwait } from '@d8d/shared-utils';
+import { AuthContext } from '@d8d/shared-types';
+import { OrderGoodsSchema, CreateOrderGoodsDto, UpdateOrderGoodsDto } from '../../schemas/order-goods.schema';
+import { UserOrderGoodsService } from '../../services/user-order-goods.service';
+
+// 获取当前用户订单商品列表路由
+const getUserOrderItemsRoute = createRoute({
+  method: 'get',
+  path: '/',
+  middleware: [authMiddleware],
+  request: {
+    query: z.object({
+      page: z.coerce.number().int().positive('页码必须是正整数').default(1).openapi({
+        example: 1,
+        description: '页码,从1开始'
+      }),
+      pageSize: z.coerce.number().int().positive('每页数量必须是正整数').default(10).openapi({
+        example: 10,
+        description: '每页数量'
+      }),
+      keyword: z.string().optional().openapi({
+        example: '搜索关键词',
+        description: '搜索关键词'
+      })
+    })
+  },
+  responses: {
+    200: {
+      description: '成功获取订单商品列表',
+      content: {
+        'application/json': {
+          schema: z.object({
+            data: z.array(OrderGoodsSchema),
+            pagination: z.object({
+              total: z.number(),
+              current: z.number(),
+              pageSize: z.number()
+            })
+          })
+        }
+      }
+    },
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// 获取当前用户订单商品详情路由
+const getUserOrderItemRoute = createRoute({
+  method: 'get',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: z.object({
+      id: z.coerce.number().int().positive('ID必须是正整数').openapi({
+        param: { name: 'id', in: 'path' },
+        example: 1,
+        description: '订单商品ID'
+      })
+    })
+  },
+  responses: {
+    200: {
+      description: '成功获取订单商品详情',
+      content: {
+        'application/json': { schema: OrderGoodsSchema }
+      }
+    },
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    403: {
+      description: '无权访问该订单商品',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    404: {
+      description: '订单商品不存在',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// 为当前用户创建订单商品路由
+const createUserOrderItemRoute = createRoute({
+  method: 'post',
+  path: '/',
+  middleware: [authMiddleware],
+  request: {
+    body: {
+      content: {
+        'application/json': { schema: CreateOrderGoodsDto }
+      }
+    }
+  },
+  responses: {
+    201: {
+      description: '成功创建订单商品',
+      content: {
+        'application/json': { schema: OrderGoodsSchema }
+      }
+    },
+    400: {
+      description: '请求参数验证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    403: {
+      description: '无权为该订单创建商品',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// 更新当前用户订单商品路由
+const updateUserOrderItemRoute = createRoute({
+  method: 'put',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: z.object({
+      id: z.coerce.number().int().positive('ID必须是正整数').openapi({
+        param: { name: 'id', in: 'path' },
+        example: 1,
+        description: '订单商品ID'
+      })
+    }),
+    body: {
+      content: {
+        'application/json': { schema: UpdateOrderGoodsDto }
+      }
+    }
+  },
+  responses: {
+    200: {
+      description: '成功更新订单商品',
+      content: {
+        'application/json': { schema: OrderGoodsSchema }
+      }
+    },
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    403: {
+      description: '无权更新该订单商品',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    404: {
+      description: '订单商品不存在',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// 删除当前用户订单商品路由
+const deleteUserOrderItemRoute = createRoute({
+  method: 'delete',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: z.object({
+      id: z.coerce.number().int().positive('ID必须是正整数').openapi({
+        param: { name: 'id', in: 'path' },
+        example: 1,
+        description: '订单商品ID'
+      })
+    })
+  },
+  responses: {
+    204: { description: '成功删除订单商品' },
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    403: {
+      description: '无权删除该订单商品',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    404: {
+      description: '订单商品不存在',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+const app = new OpenAPIHono<AuthContext>()
+  .openapi(getUserOrderItemsRoute, async (c) => {
+    const user = c.get('user');
+    const { page, pageSize, keyword } = c.req.valid('query');
+
+    const orderGoodsService = new UserOrderGoodsService(AppDataSource);
+    const [data, total] = await orderGoodsService.getUserOrderGoodsList(
+      page,
+      pageSize,
+      keyword,
+      user?.id
+    );
+
+    // 使用 parseWithAwait 确保数据格式正确
+    const validatedData = await parseWithAwait(z.array(OrderGoodsSchema), data);
+
+    return c.json({
+      data: validatedData,
+      pagination: { total, current: page, pageSize: pageSize }
+    }, 200);
+  })
+  .openapi(getUserOrderItemRoute, async (c) => {
+    const user = c.get('user');
+    const { id } = c.req.valid('param');
+
+    try {
+      const orderGoodsService = new UserOrderGoodsService(AppDataSource);
+      const orderGoods = await orderGoodsService.getUserOrderGoodsById(id, user?.id);
+      if (!orderGoods) {
+        return c.json({ code: 404, message: '订单商品不存在' }, 404);
+      }
+
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedData = await parseWithAwait(OrderGoodsSchema, orderGoods);
+      return c.json(validatedData, 200);
+    } catch (error) {
+      if (error instanceof Error && error.message.includes('无权')) {
+        return c.json({ code: 403, message: error.message }, 403);
+      }
+      throw error;
+    }
+  })
+  .openapi(createUserOrderItemRoute, async (c) => {
+    const user = c.get('user');
+    const data = c.req.valid('json');
+
+    try {
+      const orderGoodsService = new UserOrderGoodsService(AppDataSource);
+      const orderGoods = await orderGoodsService.createUserOrderGoods(data, user?.id);
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedData = await parseWithAwait(OrderGoodsSchema, orderGoods);
+      return c.json(validatedData, 201);
+    } catch (error) {
+      if (error instanceof Error && error.message.includes('无权')) {
+        return c.json({ code: 403, message: error.message }, 403);
+      }
+      throw error;
+    }
+  })
+  .openapi(updateUserOrderItemRoute, async (c) => {
+    const user = c.get('user');
+    const { id } = c.req.valid('param');
+    const data = c.req.valid('json');
+
+    try {
+      const orderGoodsService = new UserOrderGoodsService(AppDataSource);
+      const orderGoods = await orderGoodsService.updateUserOrderGoods(id, data, user?.id);
+      if (!orderGoods) {
+        return c.json({ code: 404, message: '订单商品不存在' }, 404);
+      }
+
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedData = await parseWithAwait(OrderGoodsSchema, orderGoods);
+      return c.json(validatedData, 200);
+    } catch (error) {
+      if (error instanceof Error && error.message.includes('无权')) {
+        return c.json({ code: 403, message: error.message }, 403);
+      }
+      throw error;
+    }
+  })
+  .openapi(deleteUserOrderItemRoute, async (c) => {
+    const user = c.get('user');
+    const { id } = c.req.valid('param');
+
+    try {
+      const orderGoodsService = new UserOrderGoodsService(AppDataSource);
+      const success = await orderGoodsService.deleteUserOrderGoods(id, user?.id);
+      if (!success) {
+        return c.json({ code: 404, message: '订单商品不存在' }, 404);
+      }
+
+      return c.body(null, 204);
+    } catch (error) {
+      if (error instanceof Error && error.message.includes('无权')) {
+        return c.json({ code: 403, message: error.message }, 403);
+      }
+      throw error;
+    }
+  });
+
+export default app;

+ 27 - 0
packages/orders-module-mt/src/routes/user/orders.ts

@@ -0,0 +1,27 @@
+import { createCrudRoutes } from '@d8d/shared-crud';
+import { Order } from '../../entities/order.entity';
+import { OrderSchema } from '../../schemas/order.schema';
+import { UserCreateOrderDto, UserUpdateOrderDto } from '../../schemas/user-order.schema';
+import { authMiddleware } from '@d8d/auth-module';
+
+// 用户订单路由 - 有数据权限限制,只能访问自己的订单
+const userOrderRoutes = createCrudRoutes({
+  entity: Order,
+  createSchema: UserCreateOrderDto,
+  updateSchema: UserUpdateOrderDto,
+  getSchema: OrderSchema,
+  listSchema: OrderSchema,
+  searchFields: ['orderNo', 'userPhone', 'recevierName'],
+  relations: ['user', 'merchant', 'supplier', 'deliveryAddress'],
+  middleware: [authMiddleware],
+  userTracking: {
+    createdByField: 'createdBy',
+    updatedByField: 'updatedBy'
+  },
+  dataPermission: {
+    enabled: true,
+    userIdField: 'userId'
+  }
+});
+
+export default userOrderRoutes;

+ 305 - 0
packages/orders-module-mt/src/routes/user/refunds.ts

@@ -0,0 +1,305 @@
+import { createRoute, OpenAPIHono } from '@hono/zod-openapi';
+import { z } from '@hono/zod-openapi';
+import { authMiddleware } from '@d8d/auth-module';
+import { AppDataSource, ErrorSchema, parseWithAwait } from '@d8d/shared-utils';
+import { AuthContext } from '@d8d/shared-types';
+import { OrderRefundSchema, CreateOrderRefundDto, UpdateOrderRefundDto } from '../../schemas/order-refund.schema';
+import { UserRefundsService } from '../../services/user-refunds.service';
+
+// 获取当前用户退款列表路由
+const getUserRefundsRoute = createRoute({
+  method: 'get',
+  path: '/',
+  middleware: [authMiddleware],
+  request: {
+    query: z.object({
+      page: z.coerce.number().int().positive('页码必须是正整数').default(1).openapi({
+        example: 1,
+        description: '页码,从1开始'
+      }),
+      pageSize: z.coerce.number().int().positive('每页数量必须是正整数').default(10).openapi({
+        example: 10,
+        description: '每页数量'
+      }),
+      keyword: z.string().optional().openapi({
+        example: '搜索关键词',
+        description: '搜索关键词'
+      }),
+      filters: z.string().optional().openapi({
+        example: '{"state": 0}',
+        description: '过滤条件JSON字符串'
+      })
+    })
+  },
+  responses: {
+    200: {
+      description: '成功获取退款列表',
+      content: {
+        'application/json': {
+          schema: z.object({
+            data: z.array(OrderRefundSchema),
+            pagination: z.object({
+              total: z.number(),
+              current: z.number(),
+              pageSize: z.number()
+            })
+          })
+        }
+      }
+    },
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// 获取当前用户退款详情路由
+const getUserRefundRoute = createRoute({
+  method: 'get',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: z.object({
+      id: z.coerce.number().int().positive('ID必须是正整数').openapi({
+        param: { name: 'id', in: 'path' },
+        example: 1,
+        description: '退款ID'
+      })
+    })
+  },
+  responses: {
+    200: {
+      description: '成功获取退款详情',
+      content: {
+        'application/json': { schema: OrderRefundSchema }
+      }
+    },
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    403: {
+      description: '无权访问该退款',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    404: {
+      description: '退款不存在',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// 为当前用户创建退款路由
+const createUserRefundRoute = createRoute({
+  method: 'post',
+  path: '/',
+  middleware: [authMiddleware],
+  request: {
+    body: {
+      content: {
+        'application/json': { schema: CreateOrderRefundDto }
+      }
+    }
+  },
+  responses: {
+    201: {
+      description: '成功创建退款',
+      content: {
+        'application/json': { schema: OrderRefundSchema }
+      }
+    },
+    400: {
+      description: '请求参数验证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    403: {
+      description: '无权为该订单创建退款',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// 更新当前用户退款路由
+const updateUserRefundRoute = createRoute({
+  method: 'put',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: z.object({
+      id: z.coerce.number().int().positive('ID必须是正整数').openapi({
+        param: { name: 'id', in: 'path' },
+        example: 1,
+        description: '退款ID'
+      })
+    }),
+    body: {
+      content: {
+        'application/json': { schema: UpdateOrderRefundDto }
+      }
+    }
+  },
+  responses: {
+    200: {
+      description: '成功更新退款',
+      content: {
+        'application/json': { schema: OrderRefundSchema }
+      }
+    },
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    403: {
+      description: '无权更新该退款',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    404: {
+      description: '退款不存在',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+// 删除当前用户退款路由
+const deleteUserRefundRoute = createRoute({
+  method: 'delete',
+  path: '/{id}',
+  middleware: [authMiddleware],
+  request: {
+    params: z.object({
+      id: z.coerce.number().int().positive('ID必须是正整数').openapi({
+        param: { name: 'id', in: 'path' },
+        example: 1,
+        description: '退款ID'
+      })
+    })
+  },
+  responses: {
+    204: { description: '成功删除退款' },
+    401: {
+      description: '认证失败',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    403: {
+      description: '无权删除该退款',
+      content: { 'application/json': { schema: ErrorSchema } }
+    },
+    404: {
+      description: '退款不存在',
+      content: { 'application/json': { schema: ErrorSchema } }
+    }
+  }
+});
+
+const app = new OpenAPIHono<AuthContext>()
+  .openapi(getUserRefundsRoute, async (c) => {
+    const user = c.get('user');
+    const { page, pageSize, keyword, filters } = c.req.valid('query');
+
+    const refundsService = new UserRefundsService(AppDataSource);
+    const [data, total] = await refundsService.getUserRefundsList(
+      page,
+      pageSize,
+      keyword,
+      user?.id,
+      filters ? JSON.parse(filters) : undefined
+    );
+
+    // 使用 parseWithAwait 确保数据格式正确
+    const validatedData = await parseWithAwait(z.array(OrderRefundSchema), data);
+
+    return c.json({
+      data: validatedData,
+      pagination: { total, current: page, pageSize: pageSize }
+    }, 200);
+  })
+  .openapi(getUserRefundRoute, async (c) => {
+    const user = c.get('user');
+    const { id } = c.req.valid('param');
+
+    try {
+      const refundsService = new UserRefundsService(AppDataSource);
+      const refund = await refundsService.getUserRefundById(id, user?.id);
+      if (!refund) {
+        return c.json({ code: 404, message: '退款记录不存在' }, 404);
+      }
+
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedRefund = await parseWithAwait(OrderRefundSchema, refund);
+
+      return c.json(validatedRefund, 200);
+    } catch (error) {
+      if (error instanceof Error && error.message.includes('无权')) {
+        return c.json({ code: 403, message: error.message }, 403);
+      }
+      throw error;
+    }
+  })
+  .openapi(createUserRefundRoute, async (c) => {
+    const user = c.get('user');
+    const data = c.req.valid('json');
+
+    try {
+      const refundsService = new UserRefundsService(AppDataSource);
+      const refund = await refundsService.createUserRefund(data, user?.id);
+
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedRefund = await parseWithAwait(OrderRefundSchema, refund);
+
+      return c.json(validatedRefund, 201);
+    } catch (error) {
+      if (error instanceof Error && error.message.includes('无权')) {
+        return c.json({ code: 403, message: error.message }, 403);
+      }
+      throw error;
+    }
+  })
+  .openapi(updateUserRefundRoute, async (c) => {
+    const user = c.get('user');
+    const { id } = c.req.valid('param');
+    const data = c.req.valid('json');
+
+    try {
+      const refundsService = new UserRefundsService(AppDataSource);
+      const refund = await refundsService.updateUserRefund(id, data, user?.id);
+      if (!refund) {
+        return c.json({ code: 404, message: '退款记录不存在' }, 404);
+      }
+
+      // 使用 parseWithAwait 确保数据格式正确
+      const validatedRefund = await parseWithAwait(OrderRefundSchema, refund);
+
+      return c.json(validatedRefund, 200);
+    } catch (error) {
+      if (error instanceof Error && error.message.includes('无权')) {
+        return c.json({ code: 403, message: error.message }, 403);
+      }
+      throw error;
+    }
+  })
+  .openapi(deleteUserRefundRoute, async (c) => {
+    const user = c.get('user');
+    const { id } = c.req.valid('param');
+
+    try {
+      const refundsService = new UserRefundsService(AppDataSource);
+      const success = await refundsService.deleteUserRefund(id, user?.id);
+      if (!success) {
+        return c.json({ code: 404, message: '退款记录不存在' }, 404);
+      }
+
+      return c.body(null, 204);
+    } catch (error) {
+      if (error instanceof Error && error.message.includes('无权')) {
+        return c.json({ code: 403, message: error.message }, 403);
+      }
+      throw error;
+    }
+  });
+
+export default app;

+ 66 - 0
packages/orders-module-mt/src/schemas/create-order.schema.ts

@@ -0,0 +1,66 @@
+import { z } from '@hono/zod-openapi';
+
+// 订单商品项DTO
+export const OrderItemDto = z.object({
+  id: z.number().int().positive('商品ID必须是正整数').openapi({
+    description: '商品ID',
+    example: 1
+  }),
+  num: z.number().int().min(1, '购买数量必须大于0').openapi({
+    description: '购买数量',
+    example: 2
+  })
+});
+
+// 创建订单请求DTO
+export const CreateOrderRequestDto = z.object({
+  addressId: z.number().int().positive('收货地址ID必须是正整数').optional().openapi({
+    description: '收货地址ID',
+    example: 1
+  }),
+  productOwn: z.string().min(1, '商品所属方不能为空').max(50, '商品所属方最多50个字符').openapi({
+    description: '商品所属方(如:自营、第三方等)',
+    example: '自营'
+  }),
+  consumeFrom: z.string().min(1, '消费来源不能为空').max(50, '消费来源最多50个字符').openapi({
+    description: '消费来源(如:积分兑换、礼券兑换等)',
+    example: '积分兑换'
+  }),
+  products: z.array(OrderItemDto).min(1, '商品列表不能为空').openapi({
+    description: '商品列表',
+    example: [{ id: 1, num: 2 }, { id: 3, num: 1 }]
+  })
+});
+
+// 创建订单响应DTO
+export const CreateOrderResponseDto = z.object({
+  success: z.boolean().openapi({
+    description: '是否成功',
+    example: true
+  }),
+  orderId: z.number().int().positive().openapi({
+    description: '订单ID',
+    example: 1001
+  }),
+  orderNo: z.string().openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  amount: z.coerce.number().openapi({
+    description: '订单总金额',
+    example: 199.98
+  }),
+  payAmount: z.coerce.number().openapi({
+    description: '实际支付金额',
+    example: 199.98
+  }),
+  message: z.string().openapi({
+    description: '提示信息',
+    example: '订单创建成功'
+  })
+});
+
+// 导出类型
+export type CreateOrderRequest = z.infer<typeof CreateOrderRequestDto>;
+export type CreateOrderResponse = z.infer<typeof CreateOrderResponseDto>;
+export type OrderItem = z.infer<typeof OrderItemDto>;

+ 4 - 0
packages/orders-module-mt/src/schemas/index.ts

@@ -0,0 +1,4 @@
+export * from './order.schema';
+export * from './order-goods.schema';
+export * from './order-refund.schema';
+export * from './create-order.schema';

+ 255 - 0
packages/orders-module-mt/src/schemas/order-goods.schema.ts

@@ -0,0 +1,255 @@
+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: '苹果手机'
+  }),
+  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().nullable().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'
+  }),
+  imageFileId: z.number().int().positive().nullable().openapi({
+    example: 1,
+    description: '商品图片文件ID'
+  }),
+  imageFile: z.object({
+    id: z.number().int().positive().openapi({ description: '文件ID' }),
+    name: z.string().max(255).openapi({ description: '文件名', example: 'goods.jpg' }),
+    fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/goods.jpg' }),
+    type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }),
+    size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
+  }).nullable().optional().openapi({
+    description: '商品图片文件信息'
+  }),
+  // 关联实体
+  order: z.object({
+    id: z.number().int().positive().openapi({ description: '订单ID' }),
+    orderNo: z.string().openapi({ description: '订单号', example: 'ORD20240101123456' }),
+    userId: z.number().int().positive().openapi({ description: '用户ID' })
+  }).nullable().optional().openapi({
+    description: '订单信息'
+  }),
+  goods: z.object({
+    id: z.number().int().positive().openapi({ description: '商品ID' }),
+    name: z.string().openapi({ description: '商品名称', example: '苹果手机' }),
+    imageFile: z.object({
+      id: z.number().int().positive().openapi({ description: '文件ID' }),
+      name: z.string().max(255).openapi({ description: '文件名', example: 'goods.jpg' }),
+      fullUrl: z.string().openapi({ description: '文件完整URL', example: 'https://example.com/goods.jpg' }),
+      type: z.string().nullable().openapi({ description: '文件类型', example: 'image/jpeg' }),
+      size: z.number().nullable().openapi({ description: '文件大小(字节)', example: 102400 })
+    }).nullable().optional().openapi({
+      description: '商品图片文件信息'
+    })
+  }).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: '苹果手机'
+  }),
+  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().nullable().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, '状态最小为0').max(1, '状态最大为1').default(0).optional().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
+  }),
+  imageFileId: z.number().int().positive().nullable().optional().openapi({
+    description: '商品图片文件ID',
+    example: 1
+  })
+});
+
+// 更新订单商品DTO
+export const UpdateOrderGoodsDto = z.object({
+  orderId: z.number().int().positive('订单ID必须是正整数').optional().openapi({
+    description: '订单ID',
+    example: 1
+  }),
+  orderNo: z.string().max(50, '订单号最多50个字符').nullable().optional().openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  goodsId: z.number().int().positive('商品ID必须是正整数').optional().openapi({
+    description: '商品ID',
+    example: 1
+  }),
+  goodsName: z.string().max(255, '商品名称最多255个字符').nullable().optional().openapi({
+    description: '商品名称',
+    example: '苹果手机'
+  }),
+  goodsType: z.coerce.number().int().min(1, '商品类型最小为1').max(2, '商品类型最大为2').optional().openapi({
+    description: '1实物产品2虚拟订单',
+    example: 1
+  }),
+  supplierId: z.coerce.number().int().positive().nullable().optional().openapi({
+    description: '供货商ID',
+    example: 1
+  }),
+  costPrice: z.coerce.number().min(0, '成本价不能小于0').max(999999.99, '成本价不能超过999999.99').optional().openapi({
+    description: '成本价',
+    example: 50.00
+  }),
+  price: z.coerce.number().min(0, '售价不能小于0').max(999999.99, '售价不能超过999999.99').optional().openapi({
+    description: '售价',
+    example: 99.99
+  }),
+  num: z.coerce.number().int().min(0, '数量不能小于0').max(99999, '数量不能超过99999').optional().openapi({
+    description: '数量',
+    example: 2
+  }),
+  freightAmount: z.coerce.number().min(0, '运费不能小于0').max(999999.99, '运费不能超过999999.99').optional().openapi({
+    description: '运费',
+    example: 10.00
+  }),
+  state: z.coerce.number().int().min(0, '状态最小为0').max(1, '状态最大为1').optional().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
+  }),
+  imageFileId: z.number().int().positive().nullable().optional().openapi({
+    description: '商品图片文件ID',
+    example: 1
+  })
+});
+
+// 订单商品状态类型
+export type OrderGoodsStatusType = typeof OrderGoodsStatus[keyof typeof OrderGoodsStatus];
+export type GoodsTypeType = typeof GoodsType[keyof typeof GoodsType];

+ 129 - 0
packages/orders-module-mt/src/schemas/order-refund.schema.ts

@@ -0,0 +1,129 @@
+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' }),
+    userId: z.number().int().positive().openapi({ description: '用户ID', example: 1 }),
+    amount: z.coerce.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: '每页数量'
+    })
+  })
+});

+ 497 - 0
packages/orders-module-mt/src/schemas/order.schema.ts

@@ -0,0 +1,497 @@
+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().min(0, '不能小于0').default(0).openapi({
+    description: '商户id',
+    example: 1
+  }),
+  merchantNo: z.coerce.number().int().min(0, '不能小于0').nullable().optional().openapi({
+    description: '商户号',
+    example: 1001
+  }),
+  supplierId: z.coerce.number().int().min(0, '不能小于0').default(0).openapi({
+    description: '供货商id',
+    example: 1
+  }),
+  addressId: z.coerce.number().int().min(0, '不能小于0').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().min(0, '不能小于0').default(0).openapi({
+    description: '收货人所在省',
+    example: 110000
+  }),
+  recevierCity: z.coerce.number().int().min(0, '不能小于0').default(0).openapi({
+    description: '收货人所在市',
+    example: 110100
+  }),
+  recevierDistrict: z.coerce.number().int().min(0, '不能小于0').default(0).openapi({
+    description: '收货人所在区',
+    example: 110105
+  }),
+  recevierTown: z.coerce.number().int().min(0, '不能小于0').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).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().min(0, '不能小于0').default(0).openapi({
+    description: '商户id',
+    example: 1
+  }),
+  merchantNo: z.coerce.number().int().min(0, '不能小于0').nullable().optional().openapi({
+    description: '商户号',
+    example: 1001
+  }),
+  supplierId: z.coerce.number().int().min(0, '不能小于0').default(0).openapi({
+    description: '供货商id',
+    example: 1
+  }),
+  addressId: z.coerce.number().int().min(0, '不能小于0').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().min(0, '不能小于0').default(0).openapi({
+    description: '收货人所在省',
+    example: 110000
+  }),
+  recevierCity: z.coerce.number().int().min(0, '不能小于0').default(0).openapi({
+    description: '收货人所在市',
+    example: 110100
+  }),
+  recevierDistrict: z.coerce.number().int().min(0, '不能小于0').default(0).openapi({
+    description: '收货人所在区',
+    example: 110105
+  }),
+  recevierTown: z.coerce.number().int().min(0, '不能小于0').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: '请尽快发货'
+  })
+});
+
+// 更新订单DTO
+export const UpdateOrderDto = z.object({
+  orderNo: z.string().min(1, '订单号不能为空').max(50, '订单号最多50个字符').optional().openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  userId: z.number().int().positive('用户ID必须是正整数').optional().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').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: 0
+  }),
+  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().min(0, '不能小于0').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: '请尽快发货'
+  })
+});
+
+// 订单列表响应Schema
+export const OrderListResponse = z.object({
+  data: z.array(OrderSchema),
+  pagination: z.object({
+    total: z.number().openapi({ example: 100, description: '总记录数' }),
+    current: z.number().openapi({ example: 1, description: '当前页码' }),
+    pageSize: z.number().openapi({ example: 10, description: '每页数量' })
+  })
+});

+ 136 - 0
packages/orders-module-mt/src/schemas/user-order.schema.ts

@@ -0,0 +1,136 @@
+import { z } from 'zod';
+
+// 用户创建订单DTO - 不包含userId字段,用户ID从认证信息中自动设置
+export const UserCreateOrderDto = z.object({
+  orderNo: z.string().min(1, '订单号不能为空').max(50, '订单号最多50个字符').openapi({
+    description: '订单号',
+    example: 'ORD20240101123456'
+  }),
+  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').openapi({
+    description: '订单类型 1实物订单 2虚拟订单',
+    example: 1
+  }),
+  payType: z.coerce.number().int().min(0, '支付类型最小为0').max(2, '支付类型最大为2').openapi({
+    description: '支付类型1积分2礼券',
+    example: 1
+  }),
+  payState: z.coerce.number().int().min(0, '支付状态最小为0').max(5, '支付状态最大为5').openapi({
+    description: '支付状态 0未支付1支付中2支付成功3已退款4支付失败5订单关闭',
+    example: 0
+  }),
+  state: z.coerce.number().int().min(0, '订单状态最小为0').max(3, '订单状态最大为3').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('必须是正整数').openapi({
+    description: '商户id',
+    example: 1
+  }),
+  merchantNo: z.coerce.number().int().positive('必须是正整数').nullable().optional().openapi({
+    description: '商户号',
+    example: 1001
+  }),
+  supplierId: z.coerce.number().int().positive('必须是正整数').openapi({
+    description: '供货商id',
+    example: 1
+  }),
+  addressId: z.coerce.number().int().positive('必须是正整数').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: '请尽快发货'
+  })
+});
+
+// 用户更新订单DTO - 不包含userId字段
+export const UserUpdateOrderDto = UserCreateOrderDto.partial();

+ 9 - 0
packages/orders-module-mt/src/services/index.ts

@@ -0,0 +1,9 @@
+export { OrderService } from './order.service';
+export { OrderGoodsService } from './order-goods.service';
+export { OrderRefundService } from './order-refund.service';
+
+export { OrderMtService } from './order.mt.service';
+export { OrderGoodsMtService } from './order-goods.mt.service';
+export { OrderRefundMtService } from './order-refund.mt.service';
+export { UserOrderGoodsMtService } from './user-order-goods.mt.service';
+export { UserRefundsMtService } from './user-refunds.mt.service';

+ 11 - 0
packages/orders-module-mt/src/services/order-goods.mt.service.ts

@@ -0,0 +1,11 @@
+import { GenericCrudService } from '@d8d/shared-crud';
+import { DataSource } from 'typeorm';
+import { OrderGoodsMt } from '../entities/order-goods.mt.entity';
+
+export class OrderGoodsMtService extends GenericCrudService<OrderGoodsMt> {
+  constructor(dataSource: DataSource) {
+    super(dataSource, OrderGoodsMt, {
+      tenantOptions: { enabled: true, tenantIdField: 'tenantId' }
+    });
+  }
+}

+ 9 - 0
packages/orders-module-mt/src/services/order-goods.service.ts

@@ -0,0 +1,9 @@
+import { GenericCrudService } from '@d8d/shared-crud';
+import { DataSource } from 'typeorm';
+import { OrderGoods } from '../entities/order-goods.entity';
+
+export class OrderGoodsService extends GenericCrudService<OrderGoods> {
+  constructor(dataSource: DataSource) {
+    super(dataSource, OrderGoods);
+  }
+}

+ 11 - 0
packages/orders-module-mt/src/services/order-refund.mt.service.ts

@@ -0,0 +1,11 @@
+import { GenericCrudService } from '@d8d/shared-crud';
+import { DataSource } from 'typeorm';
+import { OrderRefundMt } from '../entities/order-refund.mt.entity';
+
+export class OrderRefundMtService extends GenericCrudService<OrderRefundMt> {
+  constructor(dataSource: DataSource) {
+    super(dataSource, OrderRefundMt, {
+      tenantOptions: { enabled: true, tenantIdField: 'tenantId' }
+    });
+  }
+}

+ 9 - 0
packages/orders-module-mt/src/services/order-refund.service.ts

@@ -0,0 +1,9 @@
+import { GenericCrudService } from '@d8d/shared-crud';
+import { DataSource } from 'typeorm';
+import { OrderRefund } from '../entities/order-refund.entity';
+
+export class OrderRefundService extends GenericCrudService<OrderRefund> {
+  constructor(dataSource: DataSource) {
+    super(dataSource, OrderRefund);
+  }
+}

+ 185 - 0
packages/orders-module-mt/src/services/order.mt.service.ts

@@ -0,0 +1,185 @@
+import { GenericCrudService } from '@d8d/shared-crud';
+import { DataSource, Repository } from 'typeorm';
+import { OrderMt } from '../entities/order.mt.entity';
+import { OrderGoodsMt } from '../entities/order-goods.mt.entity';
+import { GoodsMt } from '@d8d/goods-module-mt';
+import { DeliveryAddressMt } from '@d8d/delivery-address-module-mt';
+import type { CreateOrderRequest } from '../schemas/create-order.schema';
+
+export class OrderMtService extends GenericCrudService<OrderMt> {
+  private orderGoodsRepository: Repository<OrderGoodsMt>;
+  private goodsRepository: Repository<GoodsMt>;
+  private deliveryAddressRepository: Repository<DeliveryAddressMt>;
+
+  constructor(dataSource: DataSource) {
+    super(dataSource, OrderMt, {
+      tenantOptions: { enabled: true, tenantIdField: 'tenantId' }
+    });
+    this.orderGoodsRepository = dataSource.getRepository(OrderGoodsMt);
+    this.goodsRepository = dataSource.getRepository(GoodsMt);
+    this.deliveryAddressRepository = dataSource.getRepository(DeliveryAddressMt);
+  }
+
+  /**
+   * 创建订单
+   * @param data 创建订单请求数据
+   * @param userId 用户ID
+   * @param tenantId 租户ID
+   * @returns 创建的订单信息
+   */
+  async createOrder(data: CreateOrderRequest, userId: number, tenantId: number): Promise<{
+    orderId: number;
+    orderNo: string;
+    amount: number;
+    payAmount: number;
+  }> {
+    const queryRunner = this.dataSource.createQueryRunner();
+    await queryRunner.connect();
+    await queryRunner.startTransaction();
+
+    try {
+      const { addressId, productOwn, consumeFrom, products } = data;
+
+      // 验证商品信息并计算总价
+      let totalAmount = 0;
+      let totalCostAmount = 0;
+      const goodsInfo = [];
+
+      for (const item of products) {
+        const goods = await this.goodsRepository.findOne({
+          where: { id: item.id, tenantId }
+        });
+
+        if (!goods) {
+          throw new Error(`商品ID ${item.id} 不存在`);
+        }
+
+        if (goods.stock < item.num) {
+          throw new Error(`商品 ${goods.name} 库存不足`);
+        }
+
+        const itemAmount = goods.price * item.num;
+        const itemCostAmount = goods.costPrice * item.num;
+
+        totalAmount += itemAmount;
+        totalCostAmount += itemCostAmount;
+
+        goodsInfo.push({
+          goods,
+          quantity: item.num,
+          amount: itemAmount,
+          costAmount: itemCostAmount
+        });
+      }
+
+      // 获取收货地址信息
+      let deliveryAddress = null;
+      if (addressId) {
+        deliveryAddress = await this.deliveryAddressRepository.findOne({
+          where: { id: addressId, userId, tenantId }
+        });
+
+        if (!deliveryAddress) {
+          throw new Error('收货地址不存在');
+        }
+      }
+
+      // 生成订单号
+      const orderNo = this.generateOrderNo();
+
+      // 创建订单
+      const order = this.repository.create({
+        tenantId,
+        orderNo,
+        userId,
+        amount: totalAmount,
+        costAmount: totalCostAmount,
+        payAmount: totalAmount, // 这里可以根据优惠规则计算实际支付金额
+        orderType: 1, // 实物订单
+        payType: consumeFrom === '积分兑换' ? 1 : 2, // 根据消费来源设置支付类型
+        payState: 0, // 未支付
+        state: 0, // 未发货
+        addressId: addressId || 0,
+        merchantId: goodsInfo[0]?.goods.merchantId || 0,
+        supplierId: goodsInfo[0]?.goods.supplierId || 0,
+        createdBy: userId,
+        updatedBy: userId,
+        // 设置收货地址信息(如果提供)
+        ...(deliveryAddress && {
+          receiverMobile: deliveryAddress.phone,
+          recevierName: deliveryAddress.name,
+          recevierProvince: deliveryAddress.receiverProvince,
+          recevierCity: deliveryAddress.receiverCity,
+          recevierDistrict: deliveryAddress.receiverDistrict,
+          recevierTown: deliveryAddress.receiverTown,
+          address: deliveryAddress.address
+        })
+      });
+
+      const savedOrder = await queryRunner.manager.save(order);
+
+      // 创建订单商品明细
+      const orderGoodsList = goodsInfo.map(info => ({
+        tenantId,
+        orderId: savedOrder.id,
+        orderNo,
+        goodsId: info.goods.id,
+        goodsName: info.goods.name,
+        imageFileId: info.goods.imageFileId,
+        goodsType: info.goods.goodsType,
+        supplierId: info.goods.supplierId,
+        costPrice: info.goods.costPrice,
+        price: info.goods.price,
+        num: info.quantity,
+        freightAmount: 0,
+        state: 0,
+        createdBy: userId,
+        updatedBy: userId,
+        expressName: null,
+        expressNo: null
+      }));
+
+      await queryRunner.manager.save(OrderGoodsMt, orderGoodsList);
+
+      // 更新商品库存
+      for (const item of goodsInfo) {
+        await queryRunner.manager.update(GoodsMt, item.goods.id, {
+          stock: () => `stock - ${item.quantity}`,
+          salesNum: () => `sales_num + ${item.quantity}`
+        });
+      }
+
+      await queryRunner.commitTransaction();
+
+      return {
+        orderId: savedOrder.id,
+        orderNo: savedOrder.orderNo,
+        amount: savedOrder.amount,
+        payAmount: savedOrder.payAmount
+      };
+
+    } catch (error) {
+      await queryRunner.rollbackTransaction();
+      throw error;
+    } finally {
+      await queryRunner.release();
+    }
+  }
+
+  /**
+   * 生成订单号
+   * 格式:年月日时分秒 + 6位随机数
+   */
+  private generateOrderNo(): string {
+    const now = new Date();
+    const year = now.getFullYear();
+    const month = String(now.getMonth() + 1).padStart(2, '0');
+    const day = String(now.getDate()).padStart(2, '0');
+    const hour = String(now.getHours()).padStart(2, '0');
+    const minute = String(now.getMinutes()).padStart(2, '0');
+    const second = String(now.getSeconds()).padStart(2, '0');
+    const random = String(Math.floor(Math.random() * 1000000)).padStart(6, '0');
+
+    return `ORD${year}${month}${day}${hour}${minute}${second}${random}`;
+  }
+}

+ 180 - 0
packages/orders-module-mt/src/services/order.service.ts

@@ -0,0 +1,180 @@
+import { GenericCrudService } from '@d8d/shared-crud';
+import { DataSource, Repository } from 'typeorm';
+import { Order } from '../entities/order.entity';
+import { OrderGoods } from '../entities/order-goods.entity';
+import { Goods } from '@d8d/goods-module';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+import type { CreateOrderRequest } from '../schemas/create-order.schema';
+
+export class OrderService extends GenericCrudService<Order> {
+  private orderGoodsRepository: Repository<OrderGoods>;
+  private goodsRepository: Repository<Goods>;
+  private deliveryAddressRepository: Repository<DeliveryAddress>;
+
+  constructor(dataSource: DataSource) {
+    super(dataSource, Order);
+    this.orderGoodsRepository = dataSource.getRepository(OrderGoods);
+    this.goodsRepository = dataSource.getRepository(Goods);
+    this.deliveryAddressRepository = dataSource.getRepository(DeliveryAddress);
+  }
+
+  /**
+   * 创建订单
+   * @param data 创建订单请求数据
+   * @param userId 用户ID
+   * @returns 创建的订单信息
+   */
+  async createOrder(data: CreateOrderRequest, userId: number): Promise<{
+    orderId: number;
+    orderNo: string;
+    amount: number;
+    payAmount: number;
+  }> {
+    const queryRunner = this.dataSource.createQueryRunner();
+    await queryRunner.connect();
+    await queryRunner.startTransaction();
+
+    try {
+      const { addressId, productOwn, consumeFrom, products } = data;
+
+      // 验证商品信息并计算总价
+      let totalAmount = 0;
+      let totalCostAmount = 0;
+      const goodsInfo = [];
+
+      for (const item of products) {
+        const goods = await this.goodsRepository.findOne({
+          where: { id: item.id }
+        });
+
+        if (!goods) {
+          throw new Error(`商品ID ${item.id} 不存在`);
+        }
+
+        if (goods.stock < item.num) {
+          throw new Error(`商品 ${goods.name} 库存不足`);
+        }
+
+        const itemAmount = goods.price * item.num;
+        const itemCostAmount = goods.costPrice * item.num;
+
+        totalAmount += itemAmount;
+        totalCostAmount += itemCostAmount;
+
+        goodsInfo.push({
+          goods,
+          quantity: item.num,
+          amount: itemAmount,
+          costAmount: itemCostAmount
+        });
+      }
+
+      // 获取收货地址信息
+      let deliveryAddress = null;
+      if (addressId) {
+        deliveryAddress = await this.deliveryAddressRepository.findOne({
+          where: { id: addressId, userId }
+        });
+
+        if (!deliveryAddress) {
+          throw new Error('收货地址不存在');
+        }
+      }
+
+      // 生成订单号
+      const orderNo = this.generateOrderNo();
+
+      // 创建订单
+      const order = this.repository.create({
+        orderNo,
+        userId,
+        amount: totalAmount,
+        costAmount: totalCostAmount,
+        payAmount: totalAmount, // 这里可以根据优惠规则计算实际支付金额
+        orderType: 1, // 实物订单
+        payType: consumeFrom === '积分兑换' ? 1 : 2, // 根据消费来源设置支付类型
+        payState: 0, // 未支付
+        state: 0, // 未发货
+        addressId: addressId || 0,
+        merchantId: goodsInfo[0]?.goods.merchantId || 0,
+        supplierId: goodsInfo[0]?.goods.supplierId || 0,
+        createdBy: userId,
+        updatedBy: userId,
+        // 设置收货地址信息(如果提供)
+        ...(deliveryAddress && {
+          receiverMobile: deliveryAddress.phone,
+          recevierName: deliveryAddress.name,
+          recevierProvince: deliveryAddress.receiverProvince,
+          recevierCity: deliveryAddress.receiverCity,
+          recevierDistrict: deliveryAddress.receiverDistrict,
+          recevierTown: deliveryAddress.receiverTown,
+          address: deliveryAddress.address
+        })
+      });
+
+      const savedOrder = await queryRunner.manager.save(order);
+
+      // 创建订单商品明细
+      const orderGoodsList = goodsInfo.map(info => ({
+        orderId: savedOrder.id,
+        orderNo,
+        goodsId: info.goods.id,
+        goodsName: info.goods.name,
+        imageFileId: info.goods.imageFileId,
+        goodsType: info.goods.goodsType,
+        supplierId: info.goods.supplierId,
+        costPrice: info.goods.costPrice,
+        price: info.goods.price,
+        num: info.quantity,
+        freightAmount: 0,
+        state: 0,
+        createdBy: userId,
+        updatedBy: userId,
+        expressName: null,
+        expressNo: null
+      }));
+
+      await queryRunner.manager.save(OrderGoods, orderGoodsList);
+
+      // 更新商品库存
+      for (const item of goodsInfo) {
+        await queryRunner.manager.update(Goods, item.goods.id, {
+          stock: () => `stock - ${item.quantity}`,
+          salesNum: () => `sales_num + ${item.quantity}`
+        });
+      }
+
+      await queryRunner.commitTransaction();
+
+      return {
+        orderId: savedOrder.id,
+        orderNo: savedOrder.orderNo,
+        amount: savedOrder.amount,
+        payAmount: savedOrder.payAmount
+      };
+
+    } catch (error) {
+      await queryRunner.rollbackTransaction();
+      throw error;
+    } finally {
+      await queryRunner.release();
+    }
+  }
+
+  /**
+   * 生成订单号
+   * 格式:年月日时分秒 + 6位随机数
+   */
+  private generateOrderNo(): string {
+    const now = new Date();
+    const year = now.getFullYear();
+    const month = String(now.getMonth() + 1).padStart(2, '0');
+    const day = String(now.getDate()).padStart(2, '0');
+    const hour = String(now.getHours()).padStart(2, '0');
+    const minute = String(now.getMinutes()).padStart(2, '0');
+    const second = String(now.getSeconds()).padStart(2, '0');
+    const random = String(Math.floor(Math.random() * 1000000)).padStart(6, '0');
+
+    return `ORD${year}${month}${day}${hour}${minute}${second}${random}`;
+  }
+}

+ 121 - 0
packages/orders-module-mt/src/services/user-order-goods.mt.service.ts

@@ -0,0 +1,121 @@
+import { DataSource } from 'typeorm';
+import { OrderGoodsMt } from '../entities/order-goods.mt.entity';
+import { GenericCrudService } from '@d8d/shared-crud';
+
+export class UserOrderGoodsMtService extends GenericCrudService<OrderGoodsMt> {
+  constructor(dataSource: DataSource) {
+    super(dataSource, OrderGoodsMt, {
+      userTracking: {
+        createdByField: 'createdBy',
+        updatedByField: 'updatedBy'
+      },
+      tenantOptions: { enabled: true, tenantIdField: 'tenantId' }
+    });
+  }
+
+  /**
+   * 获取当前用户的订单商品列表
+   */
+  async getUserOrderGoodsList(
+    page: number = 1,
+    pageSize: number = 10,
+    keyword?: string,
+    userId?: string | number,
+    tenantId?: number
+  ): Promise<[OrderGoodsMt[], number]> {
+    const skip = (page - 1) * pageSize;
+    const query = this.repository.createQueryBuilder('orderGoods')
+      .leftJoinAndSelect('orderGoods.order', 'order')
+      .leftJoinAndSelect('orderGoods.goods', 'goods')
+      .leftJoinAndSelect('orderGoods.supplier', 'supplier')
+      .leftJoinAndSelect('orderGoods.imageFile', 'imageFile');
+
+    // 租户过滤
+    if (tenantId) {
+      query.andWhere('orderGoods.tenantId = :tenantId', { tenantId });
+    }
+
+    // 数据权限过滤:只返回当前用户订单的商品
+    if (userId) {
+      query.andWhere('order.userId = :userId', { userId });
+    }
+
+    // 关键词搜索
+    if (keyword) {
+      query.andWhere('(orderGoods.orderNo LIKE :keyword OR orderGoods.goodsName LIKE :keyword)', {
+        keyword: `%${keyword}%`
+      });
+    }
+
+    query.skip(skip).take(pageSize).orderBy('orderGoods.id', 'DESC');
+
+    return query.getManyAndCount();
+  }
+
+  /**
+   * 获取当前用户的订单商品详情
+   */
+  async getUserOrderGoodsById(id: number, userId?: string | number, tenantId?: number): Promise<OrderGoodsMt | null> {
+    const orderGoods = await this.repository.findOne({
+      where: { id, ...(tenantId && { tenantId }) },
+      relations: ['order', 'goods', 'supplier', 'imageFile']
+    });
+
+    if (!orderGoods) {
+      return null;
+    }
+
+    // 数据权限验证:检查订单是否属于当前用户
+    if (userId && orderGoods.order && orderGoods.order.userId !== userId) {
+      throw new Error('无权访问该订单商品');
+    }
+
+    return orderGoods;
+  }
+
+  /**
+   * 为当前用户创建订单商品
+   */
+  async createUserOrderGoods(data: Partial<OrderGoodsMt>, userId?: string | number, tenantId?: number): Promise<OrderGoodsMt> {
+    // 验证订单是否属于当前用户
+    if (userId && data.orderId) {
+      const orderRepository = this.dataSource.getRepository('OrderMt');
+      const order = await orderRepository.findOne({
+        where: { id: data.orderId, ...(tenantId && { tenantId }) },
+        select: ['userId']
+      });
+
+      if (!order || order.userId !== userId) {
+        throw new Error('无权为该订单创建商品');
+      }
+    }
+
+    return this.create(data, userId);
+  }
+
+  /**
+   * 更新当前用户的订单商品
+   */
+  async updateUserOrderGoods(id: number, data: Partial<OrderGoodsMt>, userId?: string | number, tenantId?: number): Promise<OrderGoodsMt | null> {
+    // 先验证权限
+    const existing = await this.getUserOrderGoodsById(id, userId, tenantId);
+    if (!existing) {
+      return null;
+    }
+
+    return this.update(id, data, userId);
+  }
+
+  /**
+   * 删除当前用户的订单商品
+   */
+  async deleteUserOrderGoods(id: number, userId?: string | number, tenantId?: number): Promise<boolean> {
+    // 先验证权限
+    const existing = await this.getUserOrderGoodsById(id, userId, tenantId);
+    if (!existing) {
+      return false;
+    }
+
+    return this.delete(id, userId);
+  }
+}

+ 114 - 0
packages/orders-module-mt/src/services/user-order-goods.service.ts

@@ -0,0 +1,114 @@
+import { DataSource } from 'typeorm';
+import { OrderGoods } from '../entities/order-goods.entity';
+import { GenericCrudService } from '@d8d/shared-crud';
+
+export class UserOrderGoodsService extends GenericCrudService<OrderGoods> {
+  constructor(dataSource: DataSource) {
+    super(dataSource, OrderGoods, {
+      userTracking: {
+        createdByField: 'createdBy',
+        updatedByField: 'updatedBy'
+      }
+    });
+  }
+
+  /**
+   * 获取当前用户的订单商品列表
+   */
+  async getUserOrderGoodsList(
+    page: number = 1,
+    pageSize: number = 10,
+    keyword?: string,
+    userId?: string | number
+  ): Promise<[OrderGoods[], number]> {
+    const skip = (page - 1) * pageSize;
+    const query = this.repository.createQueryBuilder('orderGoods')
+      .leftJoinAndSelect('orderGoods.order', 'order')
+      .leftJoinAndSelect('orderGoods.goods', 'goods')
+      .leftJoinAndSelect('orderGoods.supplier', 'supplier')
+      .leftJoinAndSelect('orderGoods.imageFile', 'imageFile');
+
+    // 数据权限过滤:只返回当前用户订单的商品
+    if (userId) {
+      query.andWhere('order.userId = :userId', { userId });
+    }
+
+    // 关键词搜索
+    if (keyword) {
+      query.andWhere('(orderGoods.orderNo LIKE :keyword OR orderGoods.goodsName LIKE :keyword)', {
+        keyword: `%${keyword}%`
+      });
+    }
+
+    query.skip(skip).take(pageSize).orderBy('orderGoods.id', 'DESC');
+
+    return query.getManyAndCount();
+  }
+
+  /**
+   * 获取当前用户的订单商品详情
+   */
+  async getUserOrderGoodsById(id: number, userId?: string | number): Promise<OrderGoods | null> {
+    const orderGoods = await this.repository.findOne({
+      where: { id },
+      relations: ['order', 'goods', 'supplier', 'imageFile']
+    });
+
+    if (!orderGoods) {
+      return null;
+    }
+
+    // 数据权限验证:检查订单是否属于当前用户
+    if (userId && orderGoods.order && orderGoods.order.userId !== userId) {
+      throw new Error('无权访问该订单商品');
+    }
+
+    return orderGoods;
+  }
+
+  /**
+   * 为当前用户创建订单商品
+   */
+  async createUserOrderGoods(data: Partial<OrderGoods>, userId?: string | number): Promise<OrderGoods> {
+    // 验证订单是否属于当前用户
+    if (userId && data.orderId) {
+      const orderRepository = this.dataSource.getRepository('Order');
+      const order = await orderRepository.findOne({
+        where: { id: data.orderId },
+        select: ['userId']
+      });
+
+      if (!order || order.userId !== userId) {
+        throw new Error('无权为该订单创建商品');
+      }
+    }
+
+    return this.create(data, userId);
+  }
+
+  /**
+   * 更新当前用户的订单商品
+   */
+  async updateUserOrderGoods(id: number, data: Partial<OrderGoods>, userId?: string | number): Promise<OrderGoods | null> {
+    // 先验证权限
+    const existing = await this.getUserOrderGoodsById(id, userId);
+    if (!existing) {
+      return null;
+    }
+
+    return this.update(id, data, userId);
+  }
+
+  /**
+   * 删除当前用户的订单商品
+   */
+  async deleteUserOrderGoods(id: number, userId?: string | number): Promise<boolean> {
+    // 先验证权限
+    const existing = await this.getUserOrderGoodsById(id, userId);
+    if (!existing) {
+      return false;
+    }
+
+    return this.delete(id, userId);
+  }
+}

+ 169 - 0
packages/orders-module-mt/src/services/user-refunds.mt.service.ts

@@ -0,0 +1,169 @@
+import { DataSource, Repository } from 'typeorm';
+import { OrderRefundMt } from '../entities/order-refund.mt.entity';
+import { OrderMt } from '../entities/order.mt.entity';
+import { CreateOrderRefundDto, UpdateOrderRefundDto } from '../schemas/order-refund.schema';
+import type { z } from 'zod';
+
+export class UserRefundsMtService {
+  private orderRefundRepository: Repository<OrderRefundMt>;
+  private orderRepository: Repository<OrderMt>;
+
+  constructor(dataSource: DataSource) {
+    this.orderRefundRepository = dataSource.getRepository(OrderRefundMt);
+    this.orderRepository = dataSource.getRepository(OrderMt);
+  }
+
+  /**
+   * 获取当前用户的退款列表
+   */
+  async getUserRefundsList(
+    page: number,
+    pageSize: number,
+    keyword?: string,
+    userId?: number,
+    tenantId?: number,
+    filters?: any
+  ): Promise<[OrderRefundMt[], number]> {
+    if (!userId) {
+      throw new Error('用户ID不能为空');
+    }
+
+    const queryBuilder = this.orderRefundRepository
+      .createQueryBuilder('refund')
+      .leftJoinAndSelect('refund.order', 'order')
+      .where('order.userId = :userId', { userId });
+
+    // 租户过滤
+    if (tenantId) {
+      queryBuilder.andWhere('refund.tenantId = :tenantId', { tenantId });
+    }
+
+    if (keyword) {
+      queryBuilder.andWhere(
+        '(refund.orderNo LIKE :keyword OR refund.refundOrderNo LIKE :keyword)',
+        { keyword: `%${keyword}%` }
+      );
+    }
+
+    // 处理状态过滤
+    if (filters && filters.state !== undefined) {
+      queryBuilder.andWhere('refund.state = :state', { state: filters.state });
+    }
+
+    const [data, total] = await queryBuilder
+      .orderBy('refund.createdAt', 'DESC')
+      .skip((page - 1) * pageSize)
+      .take(pageSize)
+      .getManyAndCount();
+
+    return [data, total];
+  }
+
+  /**
+   * 根据ID获取当前用户的退款详情
+   */
+  async getUserRefundById(id: number, userId?: number, tenantId?: number): Promise<OrderRefundMt | null> {
+    if (!userId) {
+      throw new Error('用户ID不能为空');
+    }
+
+    const queryBuilder = this.orderRefundRepository
+      .createQueryBuilder('refund')
+      .leftJoinAndSelect('refund.order', 'order')
+      .where('refund.id = :id', { id });
+
+    // 租户过滤
+    if (tenantId) {
+      queryBuilder.andWhere('refund.tenantId = :tenantId', { tenantId });
+    }
+
+    const refund = await queryBuilder.getOne();
+
+    if (!refund) {
+      return null;
+    }
+
+    // 检查权限
+    if (refund.order.userId !== userId) {
+      throw new Error('无权访问该退款记录');
+    }
+
+    return refund;
+  }
+
+  /**
+   * 为当前用户创建退款
+   */
+  async createUserRefund(data: z.infer<typeof CreateOrderRefundDto>, userId?: number, tenantId?: number): Promise<OrderRefundMt> {
+    if (!userId) {
+      throw new Error('用户ID不能为空');
+    }
+
+    // 验证订单是否属于当前用户
+    const order = await this.orderRepository.findOne({
+      where: {
+        orderNo: data.orderNo || undefined,
+        userId,
+        ...(tenantId && { tenantId })
+      }
+    });
+
+    if (!order) {
+      throw new Error('订单不存在或无权为该订单创建退款');
+    }
+
+    const refund = this.orderRefundRepository.create({
+      ...data,
+      tenantId,
+      createdBy: userId,
+      updatedBy: userId
+    });
+
+    return await this.orderRefundRepository.save(refund);
+  }
+
+  /**
+   * 更新当前用户的退款
+   */
+  async updateUserRefund(
+    id: number,
+    data: z.infer<typeof UpdateOrderRefundDto>,
+    userId?: number,
+    tenantId?: number
+  ): Promise<OrderRefundMt | null> {
+    if (!userId) {
+      throw new Error('用户ID不能为空');
+    }
+
+    // 验证退款是否属于当前用户
+    const existingRefund = await this.getUserRefundById(id, userId, tenantId);
+    if (!existingRefund) {
+      return null;
+    }
+
+    const updatedRefund = this.orderRefundRepository.merge(existingRefund, {
+      ...data,
+      updatedBy: userId
+    });
+
+    return await this.orderRefundRepository.save(updatedRefund);
+  }
+
+  /**
+   * 删除当前用户的退款
+   */
+  async deleteUserRefund(id: number, userId?: number, tenantId?: number): Promise<boolean> {
+    if (!userId) {
+      throw new Error('用户ID不能为空');
+    }
+
+    // 验证退款是否属于当前用户
+    const existingRefund = await this.getUserRefundById(id, userId, tenantId);
+    if (!existingRefund) {
+      return false;
+    }
+
+    await this.orderRefundRepository.remove(existingRefund);
+    return true;
+  }
+}

+ 151 - 0
packages/orders-module-mt/src/services/user-refunds.service.ts

@@ -0,0 +1,151 @@
+import { DataSource, Repository } from 'typeorm';
+import { OrderRefund } from '../entities/order-refund.entity';
+import { Order } from '../entities/order.entity';
+import { CreateOrderRefundDto, UpdateOrderRefundDto } from '../schemas/order-refund.schema';
+import type { z } from 'zod';
+
+export class UserRefundsService {
+  private orderRefundRepository: Repository<OrderRefund>;
+  private orderRepository: Repository<Order>;
+
+  constructor(dataSource: DataSource) {
+    this.orderRefundRepository = dataSource.getRepository(OrderRefund);
+    this.orderRepository = dataSource.getRepository(Order);
+  }
+
+  /**
+   * 获取当前用户的退款列表
+   */
+  async getUserRefundsList(
+    page: number,
+    pageSize: number,
+    keyword?: string,
+    userId?: number,
+    filters?: any
+  ): Promise<[OrderRefund[], number]> {
+    if (!userId) {
+      throw new Error('用户ID不能为空');
+    }
+
+    const queryBuilder = this.orderRefundRepository
+      .createQueryBuilder('refund')
+      .leftJoinAndSelect('refund.order', 'order')
+      .where('order.userId = :userId', { userId });
+
+    if (keyword) {
+      queryBuilder.andWhere(
+        '(refund.orderNo LIKE :keyword OR refund.refundOrderNo LIKE :keyword)',
+        { keyword: `%${keyword}%` }
+      );
+    }
+
+    // 处理状态过滤
+    if (filters && filters.state !== undefined) {
+      queryBuilder.andWhere('refund.state = :state', { state: filters.state });
+    }
+
+    const [data, total] = await queryBuilder
+      .orderBy('refund.createdAt', 'DESC')
+      .skip((page - 1) * pageSize)
+      .take(pageSize)
+      .getManyAndCount();
+
+    return [data, total];
+  }
+
+  /**
+   * 根据ID获取当前用户的退款详情
+   */
+  async getUserRefundById(id: number, userId?: number): Promise<OrderRefund | null> {
+    if (!userId) {
+      throw new Error('用户ID不能为空');
+    }
+
+    const refund = await this.orderRefundRepository
+      .createQueryBuilder('refund')
+      .leftJoinAndSelect('refund.order', 'order')
+      .where('refund.id = :id', { id })
+      .getOne();
+
+    if (!refund) {
+      return null;
+    }
+
+    // 检查权限
+    if (refund.order.userId !== userId) {
+      throw new Error('无权访问该退款记录');
+    }
+
+    return refund;
+  }
+
+  /**
+   * 为当前用户创建退款
+   */
+  async createUserRefund(data: z.infer<typeof CreateOrderRefundDto>, userId?: number): Promise<OrderRefund> {
+    if (!userId) {
+      throw new Error('用户ID不能为空');
+    }
+
+    // 验证订单是否属于当前用户
+    const order = await this.orderRepository.findOne({
+      where: { orderNo: data.orderNo || undefined, userId }
+    });
+
+    if (!order) {
+      throw new Error('订单不存在或无权为该订单创建退款');
+    }
+
+    const refund = this.orderRefundRepository.create({
+      ...data,
+      createdBy: userId,
+      updatedBy: userId
+    });
+
+    return await this.orderRefundRepository.save(refund);
+  }
+
+  /**
+   * 更新当前用户的退款
+   */
+  async updateUserRefund(
+    id: number,
+    data: z.infer<typeof UpdateOrderRefundDto>,
+    userId?: number
+  ): Promise<OrderRefund | null> {
+    if (!userId) {
+      throw new Error('用户ID不能为空');
+    }
+
+    // 验证退款是否属于当前用户
+    const existingRefund = await this.getUserRefundById(id, userId);
+    if (!existingRefund) {
+      return null;
+    }
+
+    const updatedRefund = this.orderRefundRepository.merge(existingRefund, {
+      ...data,
+      updatedBy: userId
+    });
+
+    return await this.orderRefundRepository.save(updatedRefund);
+  }
+
+  /**
+   * 删除当前用户的退款
+   */
+  async deleteUserRefund(id: number, userId?: number): Promise<boolean> {
+    if (!userId) {
+      throw new Error('用户ID不能为空');
+    }
+
+    // 验证退款是否属于当前用户
+    const existingRefund = await this.getUserRefundById(id, userId);
+    if (!existingRefund) {
+      return false;
+    }
+
+    await this.orderRefundRepository.remove(existingRefund);
+    return true;
+  }
+}

+ 1 - 0
packages/orders-module-mt/src/types/index.ts

@@ -0,0 +1 @@
+export * from './order.types';

+ 65 - 0
packages/orders-module-mt/src/types/order.types.ts

@@ -0,0 +1,65 @@
+import { OrderStatus, PayStatus, OrderType, PayType } from '../schemas/order.schema';
+import { OrderGoodsStatus, GoodsType } from '../schemas/order-goods.schema';
+import { RefundStatus } from '../schemas/order-refund.schema';
+
+// 订单状态类型
+export type OrderStatusType = typeof OrderStatus[keyof typeof OrderStatus];
+export type PayStatusType = typeof PayStatus[keyof typeof PayStatus];
+export type OrderTypeType = typeof OrderType[keyof typeof OrderType];
+export type PayTypeType = typeof PayType[keyof typeof PayType];
+
+// 订单商品状态类型
+// 这些类型已在 schemas 中导出,避免重复导出
+
+// 退款状态类型
+export type RefundStatusType = typeof RefundStatus[keyof typeof RefundStatus];
+
+// 订单相关类型
+export interface OrderQueryParams {
+  page?: number;
+  pageSize?: number;
+  userId?: number;
+  orderNo?: string;
+  state?: OrderStatusType;
+  payState?: PayStatusType;
+  startDate?: string;
+  endDate?: string;
+}
+
+// 订单统计类型
+export interface OrderStats {
+  totalOrders: number;
+  totalAmount: number;
+  pendingOrders: number;
+  completedOrders: number;
+  refundOrders: number;
+}
+
+// 订单创建结果类型
+export interface OrderCreateResult {
+  success: boolean;
+  orderId: number;
+  orderNo: string;
+  amount: number;
+  payAmount: number;
+  message: string;
+}
+
+// 订单商品信息类型
+export interface OrderGoodsInfo {
+  goodsId: number;
+  goodsName: string;
+  price: number;
+  num: number;
+  totalAmount: number;
+}
+
+// 订单详情类型
+export interface OrderDetail {
+  order: any; // Order 实体类型
+  orderGoods: any[]; // OrderGoods 实体类型数组
+  user?: any; // User 实体类型
+  merchant?: any; // Merchant 实体类型
+  supplier?: any; // Supplier 实体类型
+  deliveryAddress?: any; // DeliveryAddress 实体类型
+}

+ 555 - 0
packages/orders-module-mt/tests/integration/admin-order-items.integration.test.ts

@@ -0,0 +1,555 @@
+import { describe, it, expect, beforeEach } from 'vitest';
+import { testClient } from 'hono/testing';
+import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
+import { JWTUtil } from '@d8d/shared-utils';
+import { UserEntity, Role } from '@d8d/user-module';
+import { File } from '@d8d/file-module';
+import { Goods, GoodsCategory } from '@d8d/goods-module';
+import { Supplier } from '@d8d/supplier-module';
+import { Merchant } from '@d8d/merchant-module';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+import { AreaEntity } from '@d8d/geo-areas';
+import adminOrderItemsRoutes from '../../src/routes/admin/order-items';
+import { Order, OrderGoods } from '../../src/entities';
+
+// 设置集成测试钩子
+setupIntegrationDatabaseHooksWithEntities([
+  UserEntity, Role, Order, OrderGoods, Goods, GoodsCategory, File, Supplier, Merchant, DeliveryAddress, AreaEntity
+])
+
+describe('管理员订单商品管理API集成测试', () => {
+  let client: ReturnType<typeof testClient<typeof adminOrderItemsRoutes>>;
+  let adminToken: string;
+  let testUser: UserEntity;
+  let testAdmin: UserEntity;
+  let testOrder: Order;
+  let otherUserOrder: Order;
+  let testGoods: Goods;
+  let testSupplier: Supplier;
+  let testFile: File;
+
+  beforeEach(async () => {
+    // 创建测试客户端
+    client = testClient(adminOrderItemsRoutes);
+
+    // 获取数据源
+    const dataSource = await IntegrationTestDatabase.getDataSource();
+
+    // 创建测试用户
+    const userRepository = dataSource.getRepository(UserEntity);
+    testUser = userRepository.create({
+      username: `test_user_${Math.floor(Math.random() * 100000)}`,
+      password: 'test_password',
+      nickname: '测试用户',
+      registrationSource: 'web'
+    });
+    await userRepository.save(testUser);
+
+    // 创建测试管理员用户
+    testAdmin = userRepository.create({
+      username: `test_admin_${Math.floor(Math.random() * 100000)}`,
+      password: 'admin_password',
+      nickname: '测试管理员',
+      registrationSource: 'web'
+    });
+    await userRepository.save(testAdmin);
+
+    // 生成测试管理员的token
+    adminToken = JWTUtil.generateToken({
+      id: testAdmin.id,
+      username: testAdmin.username,
+      roles: [{name:'admin'}]
+    });
+
+    // 创建测试供应商
+    const supplierRepository = dataSource.getRepository(Supplier);
+    testSupplier = supplierRepository.create({
+      name: '测试供应商',
+      username: `test_supplier_${Math.floor(Math.random() * 100000)}`,
+      password: 'password123',
+      phone: '13800138000',
+      realname: '测试供应商',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await supplierRepository.save(testSupplier);
+
+    // 创建测试文件
+    const fileRepository = dataSource.getRepository(File);
+    testFile = fileRepository.create({
+      name: 'test_image.jpg',
+      type: 'image/jpeg',
+      size: 102400,
+      path: 'images/test_image.jpg',
+      uploadUserId: testUser.id,
+      uploadTime: new Date(),
+      createdAt: new Date(),
+      updatedAt: new Date()
+    });
+    await fileRepository.save(testFile);
+
+    // 创建测试商品分类
+    const categoryRepository = dataSource.getRepository(GoodsCategory);
+    const testCategory = categoryRepository.create({
+      name: '测试分类',
+      level: 1,
+      sort: 1,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await categoryRepository.save(testCategory);
+
+    // 创建测试商品
+    const goodsRepository = dataSource.getRepository(Goods);
+    testGoods = goodsRepository.create({
+      name: '测试商品',
+      price: 100.00,
+      costPrice: 80.00,
+      categoryId1: testCategory.id,
+      categoryId2: testCategory.id,
+      categoryId3: testCategory.id,
+      goodsType: 1,
+      supplierId: testSupplier.id,
+      imageFileId: testFile.id,
+      state: 1,
+      stock: 100,
+      lowestBuy: 1,
+      createdBy: testUser.id
+    });
+    await goodsRepository.save(testGoods);
+
+    // 创建测试商户
+    const merchantRepository = dataSource.getRepository(Merchant);
+    const testMerchant = merchantRepository.create({
+      name: '测试商户',
+      username: `test_merchant_${Math.floor(Math.random() * 100000)}`,
+      password: 'password123',
+      phone: '13900139000',
+      realname: '测试商户',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await merchantRepository.save(testMerchant);
+
+    // 创建测试地区数据
+    const areaRepository = dataSource.getRepository(AreaEntity);
+    const testProvince = areaRepository.create({
+      name: '广东省',
+      level: 1,
+      code: '44',
+      state: 1
+    });
+    await areaRepository.save(testProvince);
+
+    const testCity = areaRepository.create({
+      name: '广州市',
+      level: 2,
+      code: '4401',
+      state: 1
+    });
+    await areaRepository.save(testCity);
+
+    const testDistrict = areaRepository.create({
+      name: '天河区',
+      level: 3,
+      code: '440106',
+      state: 1
+    });
+    await areaRepository.save(testDistrict);
+
+    const testTown = areaRepository.create({
+      name: '天河南街道',
+      level: 4,
+      code: '440106001',
+      state: 1
+    });
+    await areaRepository.save(testTown);
+
+    // 创建测试配送地址
+    const addressRepository = dataSource.getRepository(DeliveryAddress);
+    const testDeliveryAddress = addressRepository.create({
+      userId: testUser.id,
+      name: '测试收货人',
+      phone: '13800138000',
+      address: '测试地址详情',
+      receiverProvince: testProvince.id,
+      receiverCity: testCity.id,
+      receiverDistrict: testDistrict.id,
+      receiverTown: testTown.id,
+      isDefault: 1,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await addressRepository.save(testDeliveryAddress);
+
+    // 创建测试用户的订单
+    const orderRepository = dataSource.getRepository(Order);
+    testOrder = orderRepository.create({
+      orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+      userId: testUser.id,
+      amount: 100.00,
+      costAmount: 80.00,
+      payAmount: 100.00,
+      orderType: 1,
+      payType: 1,
+      payState: 2,
+      state: 0,
+      addressId: testDeliveryAddress.id,
+      merchantId: testMerchant.id,
+      supplierId: testSupplier.id,
+      recevierProvince: testProvince.id,
+      recevierCity: testCity.id,
+      recevierDistrict: testDistrict.id,
+      recevierTown: testTown.id,
+      createdBy: testUser.id
+    });
+    await orderRepository.save(testOrder);
+
+    // 创建其他用户的订单
+    otherUserOrder = orderRepository.create({
+      orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+      userId: testAdmin.id,
+      amount: 200.00,
+      costAmount: 160.00,
+      payAmount: 200.00,
+      orderType: 1,
+      payType: 1,
+      payState: 2,
+      state: 0,
+      addressId: testDeliveryAddress.id,
+      merchantId: testMerchant.id,
+      supplierId: testSupplier.id,
+      recevierProvince: testProvince.id,
+      recevierCity: testCity.id,
+      recevierDistrict: testDistrict.id,
+      recevierTown: testTown.id,
+      createdBy: testAdmin.id
+    });
+    await orderRepository.save(otherUserOrder);
+  });
+
+  describe('GET /order-items', () => {
+    it('应该返回所有订单的商品列表', async () => {
+      // 为不同用户的订单创建商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+
+      const userOrderGoods = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        orderNo: testOrder.orderNo,
+        goodsId: testGoods.id,
+        goodsName: '测试用户商品',
+        price: 50.00,
+        num: 2,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(userOrderGoods);
+
+      const adminOrderGoods = orderGoodsRepository.create({
+        orderId: otherUserOrder.id,
+        orderNo: otherUserOrder.orderNo,
+        goodsId: testGoods.id,
+        goodsName: '管理员用户商品',
+        price: 100.00,
+        num: 1,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testAdmin.id
+      });
+      await orderGoodsRepository.save(adminOrderGoods);
+
+      const response = await client.index.$get({
+        query: {}
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员订单商品列表响应状态:', response.status);
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('管理员订单商品列表错误响应:', JSON.stringify(errorData, null, 2));
+      }
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data).toHaveProperty('data');
+        expect(Array.isArray(data.data)).toBe(true);
+
+        // 验证返回所有用户的订单商品(管理员可以访问所有数据)
+        const userOrderGoodsCount = data.data.filter((orderGoods: any) =>
+          orderGoods.order && orderGoods.order.userId === testUser.id
+        ).length;
+        const adminOrderGoodsCount = data.data.filter((orderGoods: any) =>
+          orderGoods.order && orderGoods.order.userId === testAdmin.id
+        ).length;
+
+        expect(userOrderGoodsCount).toBeGreaterThan(0);
+        expect(adminOrderGoodsCount).toBeGreaterThan(0);
+      }
+    });
+
+    it('应该拒绝未认证用户的访问', async () => {
+      const response = await client.index.$get({
+        query: {}
+      });
+      expect(response.status).toBe(401);
+    });
+  });
+
+  describe('POST /order-items', () => {
+    it('应该成功创建订单商品并可以指定权限', async () => {
+      const createData = {
+        orderId: testOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '管理员创建商品',
+        price: 75.00,
+        num: 3,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testAdmin.id // 管理员可以指定创建人
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员创建订单商品响应状态:', response.status);
+      if (response.status !== 201) {
+        const errorData = await response.json();
+        console.debug('管理员创建订单商品错误响应:', errorData);
+      }
+      expect(response.status).toBe(201);
+
+      if (response.status === 201) {
+        const data = await response.json();
+        expect(data).toHaveProperty('id');
+        expect(data.goodsName).toBe(createData.goodsName);
+        expect(parseFloat(data.price)).toBe(createData.price);
+        expect(data.num).toBe(createData.num);
+        expect(data.createdBy).toBe(testAdmin.id); // 验证可以指定创建人
+      }
+    });
+
+    it('应该验证创建订单商品的必填字段', async () => {
+      const invalidData = {
+        // 缺少必填字段
+        price: -1,
+        num: -1
+      };
+
+      const response = await client.index.$post({
+        json: invalidData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(400);
+    });
+  });
+
+  describe('GET /order-items/:id', () => {
+    it('应该返回指定订单商品的详情', async () => {
+      // 先为测试用户的订单创建一个商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+      const testOrderGoods = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        orderNo: testOrder.orderNo,
+        goodsId: testGoods.id,
+        goodsName: '测试订单商品详情',
+        price: 50.00,
+        num: 2,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(testOrderGoods);
+
+      const response = await client[':id'].$get({
+        param: { id: testOrderGoods.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员订单商品详情响应状态:', response.status);
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.id).toBe(testOrderGoods.id);
+        expect(data.goodsName).toBe(testOrderGoods.goodsName);
+        expect(data.order.userId).toBe(testUser.id); // 验证可以访问其他用户的订单商品
+      }
+    });
+
+    it('应该处理不存在的订单商品', async () => {
+      const response = await client[':id'].$get({
+        param: { id: 999999 }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(404);
+    });
+  });
+
+  describe('PUT /order-items/:id', () => {
+    it('应该成功更新任何订单商品', async () => {
+      // 先为测试用户的订单创建一个商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+      const testOrderGoods = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '测试更新订单商品',
+        price: 50.00,
+        num: 2,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(testOrderGoods);
+
+      const updateData = {
+        num: 5,
+        state: 1,
+        updatedBy: testAdmin.id // 管理员可以指定更新人
+      };
+
+      const response = await client[':id'].$put({
+        param: { id: testOrderGoods.id },
+        json: updateData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员更新订单商品响应状态:', response.status);
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.num).toBe(updateData.num);
+        expect(data.state).toBe(updateData.state);
+        expect(data.updatedBy).toBe(testAdmin.id); // 验证可以指定更新人
+      }
+    });
+  });
+
+  describe('DELETE /order-items/:id', () => {
+    it('应该成功删除任何订单商品', async () => {
+      // 先为测试用户的订单创建一个商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+      const testOrderGoods = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '测试删除订单商品',
+        price: 50.00,
+        num: 2,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(testOrderGoods);
+
+      const response = await client[':id'].$delete({
+        param: { id: testOrderGoods.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员删除订单商品响应状态:', response.status);
+      expect(response.status).toBe(204);
+    });
+  });
+
+  describe('管理员权限验证测试', () => {
+    it('应该验证管理员可以访问所有数据', async () => {
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+
+      // 创建不同用户的订单商品
+      const userOrderGoods = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        orderNo: testOrder.orderNo,
+        goodsId: testGoods.id,
+        goodsName: '用户订单商品',
+        price: 50.00,
+        num: 2,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(userOrderGoods);
+
+      const adminOrderGoods = orderGoodsRepository.create({
+        orderId: otherUserOrder.id,
+        orderNo: otherUserOrder.orderNo,
+        goodsId: testGoods.id,
+        goodsName: '管理员订单商品',
+        price: 100.00,
+        num: 1,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testAdmin.id
+      });
+      await orderGoodsRepository.save(adminOrderGoods);
+
+      // 使用管理员token获取列表
+      const response = await client.index.$get({
+        query: {}
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(200);
+      const data = await response.json();
+
+      // 类型检查确保data属性存在
+      if ('data' in data && Array.isArray(data.data)) {
+        // 验证返回所有用户的订单商品
+        const userOrderGoodsInResponse = data.data.filter((orderGoods: any) =>
+          orderGoods.order && orderGoods.order.userId === testUser.id
+        );
+        const adminOrderGoodsInResponse = data.data.filter((orderGoods: any) =>
+          orderGoods.order && orderGoods.order.userId === testAdmin.id
+        );
+
+        expect(userOrderGoodsInResponse.length).toBeGreaterThan(0);
+        expect(adminOrderGoodsInResponse.length).toBeGreaterThan(0);
+      } else {
+        // 如果响应是错误格式,应该失败
+        expect(data).toHaveProperty('data');
+      }
+    });
+  });
+});

+ 706 - 0
packages/orders-module-mt/tests/integration/admin-orders.integration.test.ts

@@ -0,0 +1,706 @@
+import { describe, it, expect, beforeEach } from 'vitest';
+import { testClient } from 'hono/testing';
+import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
+import { JWTUtil } from '@d8d/shared-utils';
+import { UserEntity, Role } from '@d8d/user-module';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+import { AreaEntity } from '@d8d/geo-areas';
+import { Merchant } from '@d8d/merchant-module';
+import { Supplier } from '@d8d/supplier-module';
+import { File } from '@d8d/file-module';
+import adminOrderRoutes from '../../src/routes/admin/orders';
+import { Order } from '../../src/entities';
+
+// 设置集成测试钩子
+setupIntegrationDatabaseHooksWithEntities([
+  UserEntity, Role, Order, DeliveryAddress, Merchant, Supplier, File, AreaEntity
+])
+
+describe('管理员订单管理API集成测试', () => {
+  let client: ReturnType<typeof testClient<typeof adminOrderRoutes>>;
+  let adminToken: string;
+  let testUser: UserEntity;
+  let testAdmin: UserEntity;
+  let testDeliveryAddress: DeliveryAddress;
+  let testMerchant: Merchant;
+  let testSupplier: Supplier;
+  let testProvince: AreaEntity;
+  let testCity: AreaEntity;
+  let testDistrict: AreaEntity;
+  let testTown: AreaEntity;
+
+  beforeEach(async () => {
+    // 创建测试客户端
+    client = testClient(adminOrderRoutes);
+
+    // 获取数据源
+    const dataSource = await IntegrationTestDatabase.getDataSource();
+
+    // 创建测试用户
+    const userRepository = dataSource.getRepository(UserEntity);
+    testUser = userRepository.create({
+      username: `test_user_${Math.floor(Math.random() * 100000)}`,
+      password: 'test_password',
+      nickname: '测试用户',
+      registrationSource: 'web'
+    });
+    await userRepository.save(testUser);
+
+    // 创建测试管理员用户
+    testAdmin = userRepository.create({
+      username: `test_admin_${Math.floor(Math.random() * 100000)}`,
+      password: 'admin_password',
+      nickname: '测试管理员',
+      registrationSource: 'web'
+    });
+    await userRepository.save(testAdmin);
+
+    // 生成测试管理员的token
+    adminToken = JWTUtil.generateToken({
+      id: testAdmin.id,
+      username: testAdmin.username,
+      roles: [{name:'admin'}]
+    });
+
+    // 创建测试地区数据
+    const areaRepository = dataSource.getRepository(AreaEntity);
+    testProvince = areaRepository.create({
+      name: '广东省',
+      level: 1,
+      code: '44',
+      state: 1
+    });
+    await areaRepository.save(testProvince);
+
+    testCity = areaRepository.create({
+      name: '深圳市',
+      level: 2,
+      code: '4403',
+      state: 1
+    });
+    await areaRepository.save(testCity);
+
+    testDistrict = areaRepository.create({
+      name: '南山区',
+      level: 3,
+      code: '440305',
+      state: 1
+    });
+    await areaRepository.save(testDistrict);
+
+    testTown = areaRepository.create({
+      name: '粤海街道',
+      level: 4,
+      code: '440305001',
+      state: 1
+    });
+    await areaRepository.save(testTown);
+
+    // 创建测试配送地址
+    const deliveryAddressRepository = dataSource.getRepository(DeliveryAddress);
+    testDeliveryAddress = deliveryAddressRepository.create({
+      userId: testUser.id,
+      name: '收货人姓名',
+      phone: '13800138000',
+      receiverProvince: testProvince.id,
+      receiverCity: testCity.id,
+      receiverDistrict: testDistrict.id,
+      receiverTown: testTown.id,
+      address: '测试地址',
+      isDefault: 1,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await deliveryAddressRepository.save(testDeliveryAddress);
+
+    // 创建测试商户
+    const merchantRepository = dataSource.getRepository(Merchant);
+    testMerchant = merchantRepository.create({
+      name: '测试商户',
+      username: `test_merchant_${Math.floor(Math.random() * 100000)}`,
+      password: 'password123',
+      phone: '13800138001',
+      realname: '测试商户',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await merchantRepository.save(testMerchant);
+
+    // 创建测试供应商
+    const supplierRepository = dataSource.getRepository(Supplier);
+    testSupplier = supplierRepository.create({
+      name: '测试供应商',
+      username: `test_supplier_${Math.floor(Math.random() * 100000)}`,
+      password: 'password123',
+      phone: '13800138002',
+      realname: '测试供应商',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await supplierRepository.save(testSupplier);
+  });
+
+  describe('GET /orders', () => {
+    it('应该返回所有订单列表', async () => {
+      // 创建多个用户的订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+
+      const userOrder1 = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(userOrder1);
+
+      const userOrder2 = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testAdmin.id,
+        amount: 200.00,
+        costAmount: 160.00,
+        payAmount: 200.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 1,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testAdmin.id
+      });
+      await orderRepository.save(userOrder2);
+
+      const response = await client.index.$get({
+        query: {}
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员订单列表响应状态:', response.status);
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data).toHaveProperty('data');
+        expect(Array.isArray(data.data)).toBe(true);
+
+        // 验证返回所有用户的订单(管理员可以访问所有数据)
+        const userOrderCount = data.data.filter((order: any) => order.userId === testUser.id).length;
+        const adminOrderCount = data.data.filter((order: any) => order.userId === testAdmin.id).length;
+
+        expect(userOrderCount).toBeGreaterThan(0);
+        expect(adminOrderCount).toBeGreaterThan(0);
+      }
+    });
+
+    it('应该拒绝未认证用户的访问', async () => {
+      const response = await client.index.$get({
+        query: {}
+      });
+      expect(response.status).toBe(401);
+    });
+  });
+
+  describe('POST /orders', () => {
+    it('应该成功创建订单并可以指定权限', async () => {
+      const createData = {
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 150.00,
+        costAmount: 120.00,
+        payAmount: 150.00,
+        orderType: 1,
+        payType: 1,
+        payState: 0,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id
+        // createdBy 由认证中间件自动设置
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员创建订单响应状态:', response.status);
+      if (response.status !== 201) {
+        const errorData = await response.json();
+        console.debug('管理员创建订单错误响应:', errorData);
+      }
+      expect(response.status).toBe(201);
+
+      if (response.status === 201) {
+        const data = await response.json();
+        expect(data).toHaveProperty('id');
+        expect(data.orderNo).toBe(createData.orderNo);
+        expect(parseFloat(data.amount)).toBe(createData.amount);
+        expect(data.userId).toBe(createData.userId); // 验证可以指定用户
+        expect(data.createdBy).toBe(testAdmin.id); // 验证创建人自动设置为当前管理员用户
+      }
+    });
+
+    it('应该验证创建订单的必填字段', async () => {
+      const invalidData = {
+        // 缺少必填字段
+        amount: -1,
+        orderType: -1
+      };
+
+      const response = await client.index.$post({
+        json: invalidData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(400);
+    });
+  });
+
+  describe('GET /orders/:id', () => {
+    it('应该返回指定订单的详情', async () => {
+      // 先创建一个订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+      const testOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(testOrder);
+
+      const response = await client[':id'].$get({
+        param: { id: testOrder.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员订单详情响应状态:', response.status);
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.id).toBe(testOrder.id);
+        expect(data.orderNo).toBe(testOrder.orderNo);
+        expect(data.userId).toBe(testUser.id);
+      }
+    });
+
+    it('应该处理不存在的订单', async () => {
+      const response = await client[':id'].$get({
+        param: { id: 999999 }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(404);
+    });
+  });
+
+  describe('PUT /orders/:id', () => {
+    it('应该成功更新任何订单', async () => {
+      // 先创建一个订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+      const testOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(testOrder);
+
+      const updateData = {
+        state: 1,
+        payState: 1,
+        updatedBy: testAdmin.id // 管理员可以指定更新人
+      };
+
+      const response = await client[':id'].$put({
+        param: { id: testOrder.id },
+        json: updateData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员更新订单响应状态:', response.status);
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.state).toBe(updateData.state);
+        expect(data.payState).toBe(updateData.payState);
+        expect(data.updatedBy).toBe(testAdmin.id); // 验证可以指定更新人
+      }
+    });
+  });
+
+  describe('DELETE /orders/:id', () => {
+    it('应该成功删除任何订单', async () => {
+      // 先创建一个订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+      const testOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(testOrder);
+
+      const response = await client[':id'].$delete({
+        param: { id: testOrder.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员删除订单响应状态:', response.status);
+      expect(response.status).toBe(204);
+    });
+  });
+
+  describe('订单状态管理测试', () => {
+    it('应该正确处理订单状态变更', async () => {
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+
+      // 创建不同状态的订单
+      const pendingOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0, // 未发货
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(pendingOrder);
+
+      const shippedOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 200.00,
+        costAmount: 160.00,
+        payAmount: 200.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 1, // 已发货
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(shippedOrder);
+
+      const completedOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 300.00,
+        costAmount: 240.00,
+        payAmount: 300.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 2, // 收货成功
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(completedOrder);
+
+      // 验证状态过滤
+      const response = await client.index.$get({
+        query: { filters: JSON.stringify({ state: 1 }) }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(200);
+      const data = await response.json();
+
+      // 类型检查确保data属性存在
+      if ('data' in data && Array.isArray(data.data)) {
+        // 应该只返回已发货状态的订单
+        const pendingOrdersInResponse = data.data.filter((order: any) => order.state === 0);
+        const shippedOrdersInResponse = data.data.filter((order: any) => order.state === 1);
+        const completedOrdersInResponse = data.data.filter((order: any) => order.state === 2);
+
+        expect(pendingOrdersInResponse.length).toBe(0);
+        expect(shippedOrdersInResponse.length).toBeGreaterThan(0);
+        expect(completedOrdersInResponse.length).toBe(0);
+      } else {
+        // 如果响应是错误格式,应该失败
+        expect(data).toHaveProperty('data');
+      }
+    });
+  });
+
+  describe('支付状态管理测试', () => {
+    it('应该正确处理支付状态变更', async () => {
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+
+      // 创建不同支付状态的订单
+      const unpaidOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 0, // 未支付
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(unpaidOrder);
+
+      const payingOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 200.00,
+        costAmount: 160.00,
+        payAmount: 200.00,
+        orderType: 1,
+        payType: 1,
+        payState: 1, // 支付中
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(payingOrder);
+
+      const paidOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 300.00,
+        costAmount: 240.00,
+        payAmount: 300.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2, // 支付成功
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(paidOrder);
+
+      // 验证支付状态过滤
+      const response = await client.index.$get({
+        query: { filters: JSON.stringify({ payState: 2 }) }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(200);
+      const data = await response.json();
+
+      // 类型检查确保data属性存在
+      if ('data' in data && Array.isArray(data.data)) {
+        // 应该只返回支付成功状态的订单
+        const unpaidOrdersInResponse = data.data.filter((order: any) => order.payState === 0);
+        const payingOrdersInResponse = data.data.filter((order: any) => order.payState === 1);
+        const paidOrdersInResponse = data.data.filter((order: any) => order.payState === 2);
+
+        expect(unpaidOrdersInResponse.length).toBe(0);
+        expect(payingOrdersInResponse.length).toBe(0);
+        expect(paidOrdersInResponse.length).toBeGreaterThan(0);
+      } else {
+        // 如果响应是错误格式,应该失败
+        expect(data).toHaveProperty('data');
+      }
+    });
+  });
+
+  describe('管理员权限验证测试', () => {
+    it('应该验证管理员可以访问所有数据', async () => {
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+
+      // 创建多个用户的订单
+      const userOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(userOrder);
+
+      const adminOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testAdmin.id,
+        amount: 200.00,
+        costAmount: 160.00,
+        payAmount: 200.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        recevierProvince: testProvince.id,
+        recevierCity: testCity.id,
+        recevierDistrict: testDistrict.id,
+        recevierTown: testTown.id,
+        createdBy: testAdmin.id
+      });
+      await orderRepository.save(adminOrder);
+
+      // 使用管理员token获取列表
+      const response = await client.index.$get({
+        query: {}
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(200);
+      const data = await response.json();
+
+      // 类型检查确保data属性存在
+      if ('data' in data && Array.isArray(data.data)) {
+        // 验证返回所有用户的订单
+        const userOrdersInResponse = data.data.filter((order: any) => order.userId === testUser.id);
+        const adminOrdersInResponse = data.data.filter((order: any) => order.userId === testAdmin.id);
+
+        expect(userOrdersInResponse.length).toBeGreaterThan(0);
+        expect(adminOrdersInResponse.length).toBeGreaterThan(0);
+      } else {
+        // 如果响应是错误格式,应该失败
+        expect(data).toHaveProperty('data');
+      }
+    });
+  });
+});

+ 416 - 0
packages/orders-module-mt/tests/integration/admin-refunds.integration.test.ts

@@ -0,0 +1,416 @@
+import { describe, it, expect, beforeEach } from 'vitest';
+import { testClient } from 'hono/testing';
+import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
+import { JWTUtil } from '@d8d/shared-utils';
+import { UserEntity, Role } from '@d8d/user-module';
+import { File } from '@d8d/file-module';
+import { Merchant } from '@d8d/merchant-module';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+import { AreaEntity } from '@d8d/geo-areas';
+import { Supplier } from '@d8d/supplier-module';
+import adminRefundsRoutes from '../../src/routes/admin/refunds';
+import { Order, OrderRefund } from '../../src/entities';
+import { OrdersTestDataFactory } from '../utils/test-data-factory';
+
+// 设置集成测试钩子
+setupIntegrationDatabaseHooksWithEntities([
+  UserEntity, Role, Order, OrderRefund, File, Merchant, DeliveryAddress, AreaEntity, Supplier
+])
+
+describe('管理员退款管理API集成测试', () => {
+  let client: ReturnType<typeof testClient<typeof adminRefundsRoutes>>;
+  let adminToken: string;
+  let testUser: UserEntity;
+  let testAdmin: UserEntity;
+  let testOrder: Order;
+  let otherUserOrder: Order;
+
+  beforeEach(async () => {
+    // 创建测试客户端
+    client = testClient(adminRefundsRoutes);
+
+    // 获取数据源
+    const dataSource = await IntegrationTestDatabase.getDataSource();
+
+    // 创建测试用户
+    testUser = await OrdersTestDataFactory.createTestUser(dataSource);
+
+    // 创建测试管理员用户
+    testAdmin = await OrdersTestDataFactory.createTestUser(dataSource, {
+      username: `test_admin_${Math.floor(Math.random() * 100000)}`,
+      nickname: '测试管理员'
+    });
+
+    // 生成测试管理员的token
+    adminToken = JWTUtil.generateToken({
+      id: testAdmin.id,
+      username: testAdmin.username,
+      roles: [{name:'admin'}]
+    });
+
+    // 为测试用户创建完整的订单环境
+    const testUserEnvironment = await OrdersTestDataFactory.createCompleteOrderEnvironment(dataSource, testUser.id);
+    testOrder = testUserEnvironment.order;
+
+    // 为管理员用户创建完整的订单环境
+    const adminEnvironment = await OrdersTestDataFactory.createCompleteOrderEnvironment(dataSource, testAdmin.id);
+    otherUserOrder = adminEnvironment.order;
+  });
+
+  describe('GET /refunds', () => {
+    it('应该返回所有订单的退款列表', async () => {
+      // 为不同用户的订单创建退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+
+      const userRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0,
+        createdBy: testUser.id,
+        order: testOrder // 设置关联的订单对象
+      });
+      await orderRefundRepository.save(userRefund);
+
+      const adminRefund = orderRefundRepository.create({
+        orderNo: otherUserOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 100.00,
+        state: 1,
+        createdBy: testAdmin.id,
+        order: otherUserOrder // 设置关联的订单对象
+      });
+      await orderRefundRepository.save(adminRefund);
+
+      const response = await client.index.$get({
+        query: {}
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员退款列表响应状态:', response.status);
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('管理员退款列表错误详情:', JSON.stringify(errorData, null, 2));
+      }
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data).toHaveProperty('data');
+        expect(Array.isArray(data.data)).toBe(true);
+
+        // 验证返回所有用户的退款(管理员可以访问所有数据)
+        const userRefundCount = data.data.filter((refund: any) =>
+          refund.order && refund.order.userId === testUser.id
+        ).length;
+        const adminRefundCount = data.data.filter((refund: any) =>
+          refund.order && refund.order.userId === testAdmin.id
+        ).length;
+
+        expect(userRefundCount).toBeGreaterThan(0);
+        expect(adminRefundCount).toBeGreaterThan(0);
+      }
+    });
+
+    it('应该拒绝未认证用户的访问', async () => {
+      const response = await client.index.$get({
+        query: {}
+      });
+      expect(response.status).toBe(401);
+    });
+  });
+
+  describe('POST /refunds', () => {
+    it('应该成功创建退款申请并可以指定权限', async () => {
+      const createData = {
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 75.00,
+        state: 0,
+        createdBy: testAdmin.id // 管理员可以指定创建人
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员创建退款申请响应状态:', response.status);
+      if (response.status !== 201) {
+        const errorData = await response.json();
+        console.debug('管理员创建退款申请错误响应:', errorData);
+      }
+      expect(response.status).toBe(201);
+
+      if (response.status === 201) {
+        const data = await response.json();
+        expect(data).toHaveProperty('id');
+        expect(data.refundOrderNo).toBe(createData.refundOrderNo);
+        expect(parseFloat(data.refundAmount)).toBe(createData.refundAmount);
+        expect(data.state).toBe(createData.state);
+        expect(data.createdBy).toBe(testAdmin.id); // 验证可以指定创建人
+      }
+    });
+
+    it('应该验证创建退款申请的必填字段', async () => {
+      const invalidData = {
+        // 缺少必填字段
+        refundAmount: -1
+      };
+
+      const response = await client.index.$post({
+        json: invalidData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(400);
+    });
+  });
+
+  describe('GET /refunds/:id', () => {
+    it('应该返回指定退款的详情', async () => {
+      // 先为测试用户的订单创建一个退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+      const testRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0,
+        createdBy: testUser.id,
+        order: testOrder // 设置关联的订单对象
+      });
+      await orderRefundRepository.save(testRefund);
+
+      const response = await client[':id'].$get({
+        param: { id: testRefund.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员退款详情响应状态:', response.status);
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.id).toBe(testRefund.id);
+        expect(data.refundOrderNo).toBe(testRefund.refundOrderNo);
+        expect(data.order.userId).toBe(testUser.id); // 验证可以访问其他用户的退款
+      }
+    });
+
+    it('应该处理不存在的退款', async () => {
+      const response = await client[':id'].$get({
+        param: { id: 999999 }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(404);
+    });
+  });
+
+  describe('PUT /refunds/:id', () => {
+    it('应该成功更新任何退款', async () => {
+      // 先为测试用户的订单创建一个退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+      const testRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0,
+        createdBy: testUser.id,
+        order: testOrder // 设置关联的订单对象
+      });
+      await orderRefundRepository.save(testRefund);
+
+      const updateData = {
+        state: 1,
+        updatedBy: testAdmin.id // 管理员可以指定更新人
+      };
+
+      const response = await client[':id'].$put({
+        param: { id: testRefund.id },
+        json: updateData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员更新退款响应状态:', response.status);
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.state).toBe(updateData.state);
+        expect(data.updatedBy).toBe(testAdmin.id); // 验证可以指定更新人
+      }
+    });
+  });
+
+  describe('DELETE /refunds/:id', () => {
+    it('应该成功删除任何退款', async () => {
+      // 先为测试用户的订单创建一个退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+      const testRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0,
+        createdBy: testUser.id,
+        order: testOrder // 设置关联的订单对象
+      });
+      await orderRefundRepository.save(testRefund);
+
+      const response = await client[':id'].$delete({
+        param: { id: testRefund.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      console.debug('管理员删除退款响应状态:', response.status);
+      expect(response.status).toBe(204);
+    });
+  });
+
+  describe('管理员权限验证测试', () => {
+    it('应该验证管理员可以访问所有数据', async () => {
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+
+      // 创建不同用户的退款
+      const userRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0,
+        createdBy: testUser.id,
+        order: testOrder // 设置关联的订单对象
+      });
+      await orderRefundRepository.save(userRefund);
+
+      const adminRefund = orderRefundRepository.create({
+        orderNo: otherUserOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 100.00,
+        state: 0,
+        createdBy: testAdmin.id,
+        order: otherUserOrder // 设置关联的订单对象
+      });
+      await orderRefundRepository.save(adminRefund);
+
+      // 使用管理员token获取列表
+      const response = await client.index.$get({
+        query: {}
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(200);
+      const data = await response.json();
+
+      // 类型检查确保data属性存在
+      if ('data' in data && Array.isArray(data.data)) {
+        // 验证返回所有用户的退款
+        const userRefundInResponse = data.data.filter((refund: any) =>
+          refund.order && refund.order.userId === testUser.id
+        );
+        const adminRefundInResponse = data.data.filter((refund: any) =>
+          refund.order && refund.order.userId === testAdmin.id
+        );
+
+        expect(userRefundInResponse.length).toBeGreaterThan(0);
+        expect(adminRefundInResponse.length).toBeGreaterThan(0);
+      } else {
+        // 如果响应是错误格式,应该失败
+        expect(data).toHaveProperty('data');
+      }
+    });
+  });
+
+  describe('退款状态管理测试', () => {
+    it('应该正确处理退款状态变更', async () => {
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+
+      // 创建不同状态的退款
+      const pendingRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0, // 未退款
+        createdBy: testUser.id,
+        order: testOrder // 设置关联的订单对象
+      });
+      await orderRefundRepository.save(pendingRefund);
+
+      const processingRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 25.00,
+        state: 1, // 退款中
+        createdBy: testUser.id,
+        order: testOrder // 设置关联的订单对象
+      });
+      await orderRefundRepository.save(processingRefund);
+
+      const completedRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 75.00,
+        state: 2, // 退款成功
+        createdBy: testUser.id,
+        order: testOrder // 设置关联的订单对象
+      });
+      await orderRefundRepository.save(completedRefund);
+
+      // 验证状态过滤
+      const response = await client.index.$get({
+        query: { filters: JSON.stringify({ state: 0 }) }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${adminToken}`
+        }
+      });
+
+      expect(response.status).toBe(200);
+      const data = await response.json();
+
+      // 类型检查确保data属性存在
+      if ('data' in data && Array.isArray(data.data)) {
+        // 应该只返回未退款状态的退款
+        const pendingRefundsInResponse = data.data.filter((refund: any) => refund.state === 0);
+        const processingRefundsInResponse = data.data.filter((refund: any) => refund.state === 1);
+        const completedRefundsInResponse = data.data.filter((refund: any) => refund.state === 2);
+
+        expect(pendingRefundsInResponse.length).toBeGreaterThan(0);
+        expect(processingRefundsInResponse.length).toBe(0);
+        expect(completedRefundsInResponse.length).toBe(0);
+      } else {
+        // 如果响应是错误格式,应该失败
+        expect(data).toHaveProperty('data');
+      }
+    });
+  });
+});

+ 515 - 0
packages/orders-module-mt/tests/integration/create-order.integration.test.ts

@@ -0,0 +1,515 @@
+import { describe, it, expect, beforeEach } from 'vitest';
+import { testClient } from 'hono/testing';
+import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
+import { JWTUtil } from '@d8d/shared-utils';
+import { UserEntity, Role } from '@d8d/user-module';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+import { AreaEntity } from '@d8d/geo-areas';
+import { Goods, GoodsCategory } from '@d8d/goods-module';
+import { Supplier } from '@d8d/supplier-module';
+import { File } from '@d8d/file-module';
+import { Merchant } from '@d8d/merchant-module';
+import createOrderRoutes from '../../src/routes/create-order';
+import { Order, OrderGoods } from '../../src/entities';
+
+// 设置集成测试钩子
+setupIntegrationDatabaseHooksWithEntities([
+  UserEntity, Role, Order, OrderGoods, Goods, GoodsCategory, File, Supplier, DeliveryAddress, Merchant, AreaEntity
+])
+
+describe('订单创建API集成测试', () => {
+  let client: ReturnType<typeof testClient<typeof createOrderRoutes>>;
+  let userToken: string;
+  let testUser: UserEntity;
+  let testGoods: Goods;
+  let testSupplier: Supplier;
+  let testFile: File;
+  let testDeliveryAddress: DeliveryAddress;
+
+  beforeEach(async () => {
+    // 创建测试客户端
+    client = testClient(createOrderRoutes);
+
+    // 获取数据源
+    const dataSource = await IntegrationTestDatabase.getDataSource();
+
+    // 创建测试用户
+    const userRepository = dataSource.getRepository(UserEntity);
+    testUser = userRepository.create({
+      username: `test_user_${Math.floor(Math.random() * 100000)}`,
+      password: 'test_password',
+      nickname: '测试用户',
+      registrationSource: 'web'
+    });
+    await userRepository.save(testUser);
+
+    // 生成测试用户的token
+    userToken = JWTUtil.generateToken({
+      id: testUser.id,
+      username: testUser.username,
+      roles: [{name:'user'}]
+    });
+
+    // 创建测试商品分类
+    const goodsCategoryRepository = dataSource.getRepository(GoodsCategory);
+    const testCategory1 = goodsCategoryRepository.create({
+      name: '一级分类',
+      level: 1,
+      sort: 1,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await goodsCategoryRepository.save(testCategory1);
+
+    const testCategory2 = goodsCategoryRepository.create({
+      name: '二级分类',
+      level: 2,
+      sort: 1,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await goodsCategoryRepository.save(testCategory2);
+
+    const testCategory3 = goodsCategoryRepository.create({
+      name: '三级分类',
+      level: 3,
+      sort: 1,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await goodsCategoryRepository.save(testCategory3);
+
+    // 创建测试供应商
+    const supplierRepository = dataSource.getRepository(Supplier);
+    testSupplier = supplierRepository.create({
+      name: '测试供应商',
+      username: `test_supplier_${Math.floor(Math.random() * 100000)}`,
+      password: 'password123',
+      phone: '13800138000',
+      realname: '测试供应商',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await supplierRepository.save(testSupplier);
+
+    // 创建测试商户
+    const merchantRepository = dataSource.getRepository(Merchant);
+    const testMerchant = merchantRepository.create({
+      name: '测试商户',
+      username: `test_merchant_${Math.floor(Math.random() * 100000)}`,
+      password: 'password123',
+      phone: '13800138000',
+      realname: '测试商户',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await merchantRepository.save(testMerchant);
+
+    // 创建测试商品
+    const goodsRepository = dataSource.getRepository(Goods);
+    testGoods = goodsRepository.create({
+      name: '测试商品',
+      price: 100.00,
+      costPrice: 80.00,
+      categoryId1: testCategory1.id,
+      categoryId2: testCategory2.id,
+      categoryId3: testCategory3.id,
+      goodsType: 1,
+      supplierId: testSupplier.id,
+      merchantId: testMerchant.id,
+      state: 1,
+      stock: 100,
+      lowestBuy: 1,
+      createdBy: testUser.id
+    });
+    await goodsRepository.save(testGoods);
+
+    // 创建测试文件
+    const fileRepository = dataSource.getRepository(File);
+    testFile = fileRepository.create({
+      name: 'test_image.jpg',
+      type: 'image/jpeg',
+      size: 102400,
+      path: 'images/test_image.jpg',
+      uploadUserId: testUser.id,
+      uploadTime: new Date(),
+      createdAt: new Date(),
+      updatedAt: new Date()
+    });
+    await fileRepository.save(testFile);
+
+    // 创建测试地区数据
+    const areaRepository = dataSource.getRepository(AreaEntity);
+    const testProvince = areaRepository.create({
+      name: '广东省',
+      level: 1,
+      code: '440000',
+      isDisabled: 0,
+      isDeleted: 0,
+      createdBy: testUser.id
+    });
+    await areaRepository.save(testProvince);
+
+    const testCity = areaRepository.create({
+      name: '深圳市',
+      level: 2,
+      code: '440300',
+      parentId: testProvince.id,
+      isDisabled: 0,
+      isDeleted: 0,
+      createdBy: testUser.id
+    });
+    await areaRepository.save(testCity);
+
+    const testDistrict = areaRepository.create({
+      name: '南山区',
+      level: 3,
+      code: '440305',
+      parentId: testCity.id,
+      isDisabled: 0,
+      isDeleted: 0,
+      createdBy: testUser.id
+    });
+    await areaRepository.save(testDistrict);
+
+    const testTown = areaRepository.create({
+      name: '粤海街道',
+      level: 4,
+      code: '440305001',
+      parentId: testDistrict.id,
+      isDisabled: 0,
+      isDeleted: 0,
+      createdBy: testUser.id
+    });
+    await areaRepository.save(testTown);
+
+    // 创建测试配送地址
+    const deliveryAddressRepository = dataSource.getRepository(DeliveryAddress);
+    testDeliveryAddress = deliveryAddressRepository.create({
+      userId: testUser.id,
+      name: '收货人姓名',
+      phone: '13800138000',
+      receiverProvince: testProvince.id,
+      receiverCity: testCity.id,
+      receiverDistrict: testDistrict.id,
+      receiverTown: testTown.id,
+      address: '测试地址',
+      isDefault: 1,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await deliveryAddressRepository.save(testDeliveryAddress);
+  });
+
+  describe('POST /create-order', () => {
+    it('应该成功创建订单并关联商品', async () => {
+      const createData = {
+        addressId: testDeliveryAddress.id,
+        productOwn: '自营',
+        consumeFrom: '积分兑换',
+        products: [
+          {
+            id: testGoods.id,
+            num: 2
+          },
+          {
+            id: testGoods.id,
+            num: 1
+          }
+        ]
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('订单创建响应状态:', response.status);
+      if (response.status !== 201) {
+        const errorData = await response.json();
+        console.debug('订单创建错误响应:', errorData);
+      }
+      expect(response.status).toBe(201);
+
+      if (response.status === 201) {
+        const data = await response.json();
+        expect(data).toHaveProperty('orderId');
+        expect(data).toHaveProperty('orderNo');
+        expect(data).toHaveProperty('amount');
+        expect(data).toHaveProperty('payAmount');
+
+        // 验证订单商品被正确创建(需要从数据库查询验证)
+        const dataSource = await IntegrationTestDatabase.getDataSource();
+        const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+        const createdOrderGoods = await orderGoodsRepository.find({
+          where: { orderId: data.orderId }
+        });
+
+        expect(createdOrderGoods).toBeDefined();
+        expect(Array.isArray(createdOrderGoods)).toBe(true);
+        expect(createdOrderGoods.length).toBe(2);
+
+        // 验证商品信息
+        createdOrderGoods.forEach((orderGoods: any, index: number) => {
+          expect(orderGoods.goodsName).toBe(testGoods.name);
+          expect(orderGoods.price).toBe(testGoods.price);
+          expect(orderGoods.num).toBe(createData.products[index].num);
+          expect(orderGoods.createdBy).toBe(testUser.id); // 验证商品创建用户
+        });
+      }
+    });
+
+    it('应该验证创建订单的必填字段', async () => {
+      const invalidData = {
+        // 缺少必填字段
+        amount: -1,
+        orderType: -1
+      };
+
+      const response = await client.index.$post({
+        json: invalidData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(400);
+    });
+
+    it('应该处理商品库存不足的情况', async () => {
+      // 创建一个库存为0的商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const goodsRepository = dataSource.getRepository(Goods);
+      const outOfStockGoods = goodsRepository.create({
+        name: '库存不足商品',
+        price: 100.00,
+        costPrice: 80.00,
+        categoryId1: 1,
+        categoryId2: 1,
+        categoryId3: 1,
+        goodsType: 1,
+        supplierId: 1,
+        state: 1,
+        stock: 0, // 库存为0
+        lowestBuy: 1,
+        createdBy: testUser.id
+      });
+      await goodsRepository.save(outOfStockGoods);
+
+      const createData = {
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 0,
+        state: 0,
+        deliveryAddressId: testDeliveryAddress.id,
+        merchantId: 1,
+        supplierId: testSupplier.id,
+        orderGoods: [
+          {
+            goodsId: outOfStockGoods.id,
+            goodsName: '库存不足商品',
+            price: 100.00,
+            num: 1,
+            state: 0,
+            supplierId: testSupplier.id,
+            imageFileId: testFile.id
+          }
+        ]
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      // 应该返回错误状态(库存不足)
+      expect(response.status).toBe(400);
+    });
+
+    it('应该拒绝未认证用户的访问', async () => {
+      const createData = {
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        amount: 150.00,
+        costAmount: 120.00,
+        payAmount: 150.00,
+        orderType: 1,
+        payType: 1,
+        payState: 0,
+        state: 0,
+        deliveryAddressId: testDeliveryAddress.id,
+        merchantId: 1,
+        supplierId: testSupplier.id,
+        orderGoods: [
+          {
+            goodsId: testGoods.id,
+            goodsName: '测试商品',
+            price: 50.00,
+            num: 3,
+            state: 0,
+            supplierId: testSupplier.id,
+            imageFileId: testFile.id
+          }
+        ]
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      });
+
+      expect(response.status).toBe(401);
+    });
+  });
+
+  describe('事务性测试', () => {
+    it('应该确保订单和商品创建的事务一致性', async () => {
+      const createData = {
+        addressId: testDeliveryAddress.id,
+        productOwn: '自营',
+        consumeFrom: '积分兑换',
+        products: [
+          {
+            id: testGoods.id,
+            num: 2
+          }
+        ]
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(201);
+
+      if (response.status === 201) {
+        const data = await response.json();
+
+        // 验证订单和商品都被正确创建
+        const dataSource = await IntegrationTestDatabase.getDataSource();
+        const orderRepository = dataSource.getRepository(Order);
+        const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+
+        // 验证订单存在
+        const createdOrder = await orderRepository.findOne({
+          where: { id: data.orderId }
+        });
+
+        expect(createdOrder).toBeDefined();
+        expect(createdOrder?.orderNo).toBe(data.orderNo);
+        expect(createdOrder?.userId).toBe(testUser.id);
+
+        // 验证订单商品存在
+        const createdOrderGoods = await orderGoodsRepository.find({
+          where: { orderId: data.orderId }
+        });
+
+        expect(createdOrderGoods.length).toBe(1);
+        expect(createdOrderGoods[0].goodsName).toBe(testGoods.name);
+        expect(createdOrderGoods[0].num).toBe(createData.products[0].num);
+      }
+    });
+
+    it('应该验证库存更新功能', async () => {
+      const initialStock = testGoods.stock;
+      const purchaseQuantity = 2;
+
+      const createData = {
+        addressId: testDeliveryAddress.id,
+        productOwn: '自营',
+        consumeFrom: '积分兑换',
+        products: [
+          {
+            id: testGoods.id,
+            num: purchaseQuantity
+          }
+        ]
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(201);
+
+      if (response.status === 201) {
+        // 验证商品库存被正确更新
+        const dataSource = await IntegrationTestDatabase.getDataSource();
+        const goodsRepository = dataSource.getRepository(Goods);
+        const updatedGoods = await goodsRepository.findOne({
+          where: { id: testGoods.id }
+        });
+
+        expect(updatedGoods).toBeDefined();
+        expect(Number(updatedGoods?.stock)).toBe(initialStock - purchaseQuantity);
+      }
+    });
+  });
+
+  describe('数据权限测试', () => {
+    it('应该自动设置当前用户权限', async () => {
+      const createData = {
+        addressId: testDeliveryAddress.id,
+        productOwn: '自营',
+        consumeFrom: '积分兑换',
+        products: [
+          {
+            id: testGoods.id,
+            num: 1
+          }
+        ]
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(201);
+
+      if (response.status === 201) {
+        const data = await response.json();
+
+        // 验证订单和商品都设置了正确的用户权限(需要从数据库查询验证)
+        const dataSource = await IntegrationTestDatabase.getDataSource();
+        const orderRepository = dataSource.getRepository(Order);
+        const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+
+        // 验证订单权限
+        const createdOrder = await orderRepository.findOne({
+          where: { id: data.orderId }
+        });
+        expect(createdOrder?.userId).toBe(testUser.id);
+        expect(createdOrder?.createdBy).toBe(testUser.id);
+
+        // 验证订单商品权限
+        const createdOrderGoods = await orderGoodsRepository.find({
+          where: { orderId: data.orderId }
+        });
+        createdOrderGoods.forEach((orderGoods: any) => {
+          expect(orderGoods.createdBy).toBe(testUser.id);
+        });
+      }
+    });
+  });
+});

+ 36 - 0
packages/orders-module-mt/tests/integration/entity-configuration.integration.test.ts

@@ -0,0 +1,36 @@
+import { describe, it, expect } from 'vitest';
+import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
+import { UserEntity, Role } from '@d8d/user-module';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+import { AreaEntity } from '@d8d/geo-areas';
+import { Merchant } from '@d8d/merchant-module';
+import { Supplier } from '@d8d/supplier-module';
+import { File } from '@d8d/file-module';
+import { Order } from '../../src/entities';
+
+// 设置集成测试钩子
+setupIntegrationDatabaseHooksWithEntities([
+  UserEntity, Role, Order, DeliveryAddress, Merchant, Supplier, File, AreaEntity
+])
+
+describe('简单实体配置测试', () => {
+  it('应该能够正确初始化所有实体', async () => {
+    const dataSource = await IntegrationTestDatabase.getDataSource();
+
+    // 验证数据源已正确初始化
+    expect(dataSource).toBeDefined();
+
+    // 验证所有实体都已正确注册
+    const entityMetadatas = dataSource.entityMetadatas;
+    const entityNames = entityMetadatas.map(metadata => metadata.name);
+
+    expect(entityNames).toContain('Order');
+    expect(entityNames).toContain('UserEntity');
+    expect(entityNames).toContain('DeliveryAddress');
+    expect(entityNames).toContain('AreaEntity');
+    expect(entityNames).toContain('Merchant');
+    expect(entityNames).toContain('Supplier');
+
+    console.log('所有实体已正确注册:', entityNames);
+  });
+});

+ 708 - 0
packages/orders-module-mt/tests/integration/user-order-items.integration.test.ts

@@ -0,0 +1,708 @@
+import { describe, it, expect, beforeEach } from 'vitest';
+import { testClient } from 'hono/testing';
+import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
+import { JWTUtil } from '@d8d/shared-utils';
+import { UserEntity, Role } from '@d8d/user-module';
+import { File } from '@d8d/file-module';
+import { Goods, GoodsCategory } from '@d8d/goods-module';
+import { Supplier } from '@d8d/supplier-module';
+import { Merchant } from '@d8d/merchant-module';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+import { AreaEntity } from '@d8d/geo-areas';
+import userOrderItemsRoutes from '../../src/routes/user/order-items';
+import { Order, OrderGoods } from '../../src/entities';
+
+// 设置集成测试钩子
+setupIntegrationDatabaseHooksWithEntities([
+  UserEntity, Role, Order, OrderGoods, Goods, GoodsCategory, File, Supplier, Merchant, DeliveryAddress, AreaEntity
+])
+
+describe('用户订单商品管理API集成测试', () => {
+  let client: ReturnType<typeof testClient<typeof userOrderItemsRoutes>>;
+  let userToken: string;
+  let otherUserToken: string;
+  let testUser: UserEntity;
+  let otherUser: UserEntity;
+  let testOrder: Order;
+  let otherUserOrder: Order;
+  let testGoods: Goods;
+  let testSupplier: Supplier;
+  let testFile: File;
+  let testGoodsCategory: GoodsCategory;
+  let testMerchant: Merchant;
+  let testDeliveryAddress: DeliveryAddress;
+  let testProvince: AreaEntity;
+  let testCity: AreaEntity;
+  let testDistrict: AreaEntity;
+  let testTown: AreaEntity;
+
+  beforeEach(async () => {
+    // 创建测试客户端
+    client = testClient(userOrderItemsRoutes);
+
+    // 获取数据源
+    const dataSource = await IntegrationTestDatabase.getDataSource();
+
+    // 创建测试用户
+    const userRepository = dataSource.getRepository(UserEntity);
+    testUser = userRepository.create({
+      username: `test_user_${Math.floor(Math.random() * 100000)}`,
+      password: 'test_password',
+      nickname: '测试用户',
+      registrationSource: 'web'
+    });
+    await userRepository.save(testUser);
+
+    // 创建其他用户
+    otherUser = userRepository.create({
+      username: `other_user_${Math.floor(Math.random() * 100000)}`,
+      password: 'other_password',
+      nickname: '其他用户',
+      registrationSource: 'web'
+    });
+    await userRepository.save(otherUser);
+
+    // 生成测试用户的token
+    userToken = JWTUtil.generateToken({
+      id: testUser.id,
+      username: testUser.username,
+      roles: [{name:'user'}]
+    });
+
+    // 生成其他用户的token
+    otherUserToken = JWTUtil.generateToken({
+      id: otherUser.id,
+      username: otherUser.username,
+      roles: [{name:'user'}]
+    });
+
+    // 先创建商品分类
+    const goodsCategoryRepository = dataSource.getRepository(GoodsCategory);
+    testGoodsCategory = goodsCategoryRepository.create({
+      name: '测试商品分类',
+      level: 1,
+      parentId: 0,
+      sort: 1,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await goodsCategoryRepository.save(testGoodsCategory);
+
+    // 创建测试供应商
+    const supplierRepository = dataSource.getRepository(Supplier);
+    testSupplier = supplierRepository.create({
+      name: '测试供应商',
+      username: `test_supplier_${Math.floor(Math.random() * 100000)}`,
+      password: 'password123',
+      phone: '13800138000',
+      realname: '测试供应商',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await supplierRepository.save(testSupplier);
+
+    // 创建测试商品
+    const goodsRepository = dataSource.getRepository(Goods);
+    testGoods = goodsRepository.create({
+      name: '测试商品',
+      price: 100.00,
+      costPrice: 80.00,
+      categoryId1: testGoodsCategory.id,
+      categoryId2: testGoodsCategory.id,
+      categoryId3: testGoodsCategory.id,
+      goodsType: 1,
+      supplierId: testSupplier.id,
+      state: 1,
+      stock: 100,
+      lowestBuy: 1,
+      createdBy: testUser.id
+    });
+    await goodsRepository.save(testGoods);
+
+    // 创建测试文件
+    const fileRepository = dataSource.getRepository(File);
+    testFile = fileRepository.create({
+      name: 'test_image.jpg',
+      type: 'image/jpeg',
+      size: 102400,
+      path: 'images/test_image.jpg',
+      uploadUserId: testUser.id,
+      uploadTime: new Date(),
+      createdAt: new Date(),
+      updatedAt: new Date()
+    });
+    await fileRepository.save(testFile);
+
+    // 创建测试商户
+    const merchantRepository = dataSource.getRepository(Merchant);
+    testMerchant = merchantRepository.create({
+      name: '测试商户',
+      username: `test_merchant_${Math.floor(Math.random() * 100000)}`,
+      password: 'password123',
+      phone: '13800138000',
+      realname: '测试商户',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await merchantRepository.save(testMerchant);
+
+    // 创建测试地区数据
+    const areaRepository = dataSource.getRepository(AreaEntity);
+    testProvince = areaRepository.create({
+      name: '测试省',
+      code: 110000,
+      level: 1,
+      parentCode: 0,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await areaRepository.save(testProvince);
+
+    testCity = areaRepository.create({
+      name: '测试市',
+      code: 110100,
+      level: 2,
+      parentCode: testProvince.code,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await areaRepository.save(testCity);
+
+    testDistrict = areaRepository.create({
+      name: '测试区',
+      code: 110105,
+      level: 3,
+      parentCode: testCity.code,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await areaRepository.save(testDistrict);
+
+    testTown = areaRepository.create({
+      name: '测试街道',
+      code: 110105001,
+      level: 4,
+      parentCode: testDistrict.code,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await areaRepository.save(testTown);
+
+    // 创建测试配送地址
+    const deliveryAddressRepository = dataSource.getRepository(DeliveryAddress);
+    testDeliveryAddress = deliveryAddressRepository.create({
+      name: '测试配送地址',
+      phone: '13800138000',
+      receiverProvince: testProvince.id,
+      receiverCity: testCity.id,
+      receiverDistrict: testDistrict.id,
+      receiverTown: testTown.id,
+      address: '测试地址详情',
+      userId: testUser.id,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await deliveryAddressRepository.save(testDeliveryAddress);
+
+    // 创建测试用户的订单
+    const orderRepository = dataSource.getRepository(Order);
+    testOrder = orderRepository.create({
+      orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+      userId: testUser.id,
+      amount: 100.00,
+      costAmount: 80.00,
+      payAmount: 100.00,
+      orderType: 1,
+      payType: 1,
+      payState: 2,
+      state: 0,
+      merchantId: testMerchant.id,
+      supplierId: testSupplier.id,
+      addressId: testDeliveryAddress.id,
+      createdBy: testUser.id
+    });
+    await orderRepository.save(testOrder);
+
+    // 创建其他用户的订单
+    otherUserOrder = orderRepository.create({
+      orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+      userId: otherUser.id,
+      amount: 200.00,
+      costAmount: 160.00,
+      payAmount: 200.00,
+      orderType: 1,
+      payType: 1,
+      payState: 2,
+      state: 0,
+      merchantId: testMerchant.id,
+      supplierId: testSupplier.id,
+      addressId: testDeliveryAddress.id,
+      createdBy: otherUser.id
+    });
+    await orderRepository.save(otherUserOrder);
+  });
+
+  describe('GET /order-items', () => {
+    it('应该返回当前用户订单的商品列表', async () => {
+      // 为测试用户的订单创建一些商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+
+      const userOrderGoods1 = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '测试商品1',
+        price: 50.00,
+        num: 2,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(userOrderGoods1);
+
+      const userOrderGoods2 = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '测试商品2',
+        price: 25.00,
+        num: 4,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(userOrderGoods2);
+
+      // 为其他用户的订单创建一个商品,确保不会返回
+      const otherUserOrderGoods = orderGoodsRepository.create({
+        orderId: otherUserOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '其他用户商品',
+        price: 100.00,
+        num: 1,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: otherUser.id
+      });
+      await orderGoodsRepository.save(otherUserOrderGoods);
+
+      const response = await client.index.$get({
+        query: {
+          page: 1,
+          pageSize: 10
+        }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户订单商品列表响应状态:', response.status);
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('用户订单商品列表错误响应:', errorData);
+      }
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data).toHaveProperty('data');
+        expect(Array.isArray(data.data)).toBe(true);
+
+        // 验证只返回当前用户订单的商品
+        data.data.forEach((orderGoods: any) => {
+          expect(orderGoods.order.userId).toBe(testUser.id);
+        });
+
+        // 验证不包含其他用户订单的商品
+        const otherUserOrderGoodsInResponse = data.data.find((orderGoods: any) =>
+          orderGoods.order && orderGoods.order.userId === otherUser.id
+        );
+        expect(otherUserOrderGoodsInResponse).toBeUndefined();
+      }
+    });
+
+    it('应该拒绝未认证用户的访问', async () => {
+      const response = await client.index.$get({
+        query: {
+          page: 1,
+          pageSize: 10
+        }
+      });
+      expect(response.status).toBe(401);
+    });
+  });
+
+  describe('POST /order-items', () => {
+    it('应该成功创建订单商品并自动设置当前用户权限', async () => {
+      const createData = {
+        orderId: testOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '用户创建商品',
+        price: 75.00,
+        num: 3,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户创建订单商品响应状态:', response.status);
+      if (response.status !== 201) {
+        const errorData = await response.json();
+        console.debug('用户创建订单商品错误响应:', errorData);
+      }
+      expect(response.status).toBe(201);
+
+      if (response.status === 201) {
+        const data = await response.json();
+        expect(data).toHaveProperty('id');
+        expect(data.goodsName).toBe(createData.goodsName);
+        expect(parseFloat(data.price)).toBe(createData.price);
+        expect(data.num).toBe(createData.num);
+        expect(data.createdBy).toBe(testUser.id); // 验证自动设置创建用户
+      }
+    });
+
+    it('应该验证创建订单商品的必填字段', async () => {
+      const invalidData = {
+        // 缺少必填字段
+        price: -1,
+        num: -1
+      };
+
+      const response = await client.index.$post({
+        json: invalidData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(400);
+    });
+
+    it('应该拒绝为其他用户的订单创建商品', async () => {
+      const createData = {
+        orderId: otherUserOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '尝试为其他用户订单创建商品',
+        price: 75.00,
+        num: 3,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403
+    });
+  });
+
+  describe('GET /order-items/:id', () => {
+    it('应该返回当前用户订单的商品详情', async () => {
+      // 先为测试用户的订单创建一个商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+      const testOrderGoods = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '测试订单商品详情',
+        price: 50.00,
+        num: 2,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(testOrderGoods);
+
+      const response = await client[':id'].$get({
+        param: { id: testOrderGoods.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户订单商品详情响应状态:', response.status);
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('用户订单商品详情错误响应:', errorData);
+      }
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.id).toBe(testOrderGoods.id);
+        expect(data.goodsName).toBe(testOrderGoods.goodsName);
+        expect(data.order.userId).toBe(testUser.id); // 验证订单属于当前用户
+      }
+    });
+
+    it('应该拒绝访问其他用户订单的商品', async () => {
+      // 为其他用户的订单创建一个商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+      const otherUserOrderGoods = orderGoodsRepository.create({
+        orderId: otherUserOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '其他用户订单商品',
+        price: 100.00,
+        num: 1,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: otherUser.id
+      });
+      await orderGoodsRepository.save(otherUserOrderGoods);
+
+      const response = await client[':id'].$get({
+        param: { id: otherUserOrderGoods.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403(权限不足)
+    });
+
+    it('应该处理不存在的订单商品', async () => {
+      const response = await client[':id'].$get({
+        param: { id: 999999 }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(404);
+    });
+  });
+
+  describe('PUT /order-items/:id', () => {
+    it('应该成功更新当前用户订单的商品', async () => {
+      // 先为测试用户的订单创建一个商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+      const testOrderGoods = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '测试更新订单商品',
+        price: 50.00,
+        num: 2,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(testOrderGoods);
+
+      const updateData = {
+        num: 5,
+        state: 1
+      };
+
+      const response = await client[':id'].$put({
+        param: { id: testOrderGoods.id },
+        json: updateData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户更新订单商品响应状态:', response.status);
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.num).toBe(updateData.num);
+        expect(data.state).toBe(updateData.state);
+        expect(data.updatedBy).toBe(testUser.id); // 验证自动设置更新用户
+      }
+    });
+
+    it('应该拒绝更新其他用户订单的商品', async () => {
+      // 为其他用户的订单创建一个商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+      const otherUserOrderGoods = orderGoodsRepository.create({
+        orderId: otherUserOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '其他用户订单商品',
+        price: 100.00,
+        num: 1,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: otherUser.id
+      });
+      await orderGoodsRepository.save(otherUserOrderGoods);
+
+      const updateData = {
+        num: 2
+      };
+
+      const response = await client[':id'].$put({
+        param: { id: otherUserOrderGoods.id },
+        json: updateData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403
+    });
+  });
+
+  describe('DELETE /order-items/:id', () => {
+    it('应该成功删除当前用户订单的商品', async () => {
+      // 先为测试用户的订单创建一个商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+      const testOrderGoods = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '测试删除订单商品',
+        price: 50.00,
+        num: 2,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(testOrderGoods);
+
+      const response = await client[':id'].$delete({
+        param: { id: testOrderGoods.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户删除订单商品响应状态:', response.status);
+      expect(response.status).toBe(204);
+    });
+
+    it('应该拒绝删除其他用户订单的商品', async () => {
+      // 为其他用户的订单创建一个商品
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+      const otherUserOrderGoods = orderGoodsRepository.create({
+        orderId: otherUserOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '其他用户订单商品',
+        price: 100.00,
+        num: 1,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: otherUser.id
+      });
+      await orderGoodsRepository.save(otherUserOrderGoods);
+
+      const response = await client[':id'].$delete({
+        param: { id: otherUserOrderGoods.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403
+    });
+  });
+
+  describe('数据权限配置测试', () => {
+    it('应该验证dataPermission配置正确工作', async () => {
+      // 这个测试验证数据权限配置是否正常工作
+      // 用户只能访问自己订单的商品
+
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderGoodsRepository = dataSource.getRepository(OrderGoods);
+
+      // 创建测试用户和其他用户订单的商品
+      const userOrderGoods = orderGoodsRepository.create({
+        orderId: testOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '用户订单商品',
+        price: 50.00,
+        num: 2,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: testUser.id
+      });
+      await orderGoodsRepository.save(userOrderGoods);
+
+      const otherUserOrderGoods = orderGoodsRepository.create({
+        orderId: otherUserOrder.id,
+        goodsId: testGoods.id,
+        goodsName: '其他用户订单商品',
+        price: 100.00,
+        num: 1,
+        state: 0,
+        supplierId: testSupplier.id,
+        imageFileId: testFile.id,
+        createdBy: otherUser.id
+      });
+      await orderGoodsRepository.save(otherUserOrderGoods);
+
+      // 使用测试用户token获取列表
+      const response = await client.index.$get({
+        query: {
+          page: 1,
+          pageSize: 10
+        }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('数据权限配置测试错误响应:', errorData);
+      }
+      expect(response.status).toBe(200);
+      const data = await response.json();
+
+      // 类型检查确保data属性存在
+      if ('data' in data && Array.isArray(data.data)) {
+        // 验证只返回测试用户订单的商品
+        const userOrderGoodsInResponse = data.data.filter((orderGoods: any) =>
+          orderGoods.order && orderGoods.order.userId === testUser.id
+        );
+        const otherUserOrderGoodsInResponse = data.data.filter((orderGoods: any) =>
+          orderGoods.order && orderGoods.order.userId === otherUser.id
+        );
+
+        expect(userOrderGoodsInResponse.length).toBeGreaterThan(0);
+        expect(otherUserOrderGoodsInResponse.length).toBe(0);
+      } else {
+        // 如果响应是错误格式,应该失败
+        expect(data).toHaveProperty('data');
+      }
+    });
+  });
+});

+ 628 - 0
packages/orders-module-mt/tests/integration/user-orders.integration.test.ts

@@ -0,0 +1,628 @@
+import { describe, it, expect, beforeEach } from 'vitest';
+import { testClient } from 'hono/testing';
+import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
+import { JWTUtil } from '@d8d/shared-utils';
+import { UserEntity, Role } from '@d8d/user-module';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+import { AreaEntity } from '@d8d/geo-areas';
+import { Merchant } from '@d8d/merchant-module';
+import { Supplier } from '@d8d/supplier-module';
+import { File } from '@d8d/file-module';
+import userOrderRoutes from '../../src/routes/user/orders';
+import { Order } from '../../src/entities';
+
+// 设置集成测试钩子
+setupIntegrationDatabaseHooksWithEntities([
+  UserEntity, Role, Order, DeliveryAddress, Merchant, Supplier, File, AreaEntity
+])
+
+describe('用户订单管理API集成测试', () => {
+  let client: ReturnType<typeof testClient<typeof userOrderRoutes>>;
+  let userToken: string;
+  let otherUserToken: string;
+  let testUser: UserEntity;
+  let otherUser: UserEntity;
+  let testDeliveryAddress: DeliveryAddress;
+  let testMerchant: Merchant;
+  let testSupplier: Supplier;
+
+  beforeEach(async () => {
+    // 创建测试客户端
+    client = testClient(userOrderRoutes);
+
+    // 获取数据源
+    const dataSource = await IntegrationTestDatabase.getDataSource();
+
+    // 创建测试用户
+    const userRepository = dataSource.getRepository(UserEntity);
+    testUser = userRepository.create({
+      username: `test_user_${Math.floor(Math.random() * 100000)}`,
+      password: 'test_password',
+      nickname: '测试用户',
+      registrationSource: 'web'
+    });
+    await userRepository.save(testUser);
+
+    // 创建其他用户
+    otherUser = userRepository.create({
+      username: `other_user_${Math.floor(Math.random() * 100000)}`,
+      password: 'other_password',
+      nickname: '其他用户',
+      registrationSource: 'web'
+    });
+    await userRepository.save(otherUser);
+
+    // 生成测试用户的token
+    userToken = JWTUtil.generateToken({
+      id: testUser.id,
+      username: testUser.username,
+      roles: [{name:'user'}]
+    });
+
+    // 生成其他用户的token
+    otherUserToken = JWTUtil.generateToken({
+      id: otherUser.id,
+      username: otherUser.username,
+      roles: [{name:'user'}]
+    });
+
+    // 创建测试区域数据
+    const areaRepository = dataSource.getRepository(AreaEntity);
+    const testProvince = areaRepository.create({
+      name: '广东省',
+      code: '440000',
+      level: 1,
+      parentId: null
+    });
+    await areaRepository.save(testProvince);
+
+    const testCity = areaRepository.create({
+      name: '深圳市',
+      code: '440300',
+      level: 2,
+      parentId: testProvince.id
+    });
+    await areaRepository.save(testCity);
+
+    const testDistrict = areaRepository.create({
+      name: '南山区',
+      code: '440305',
+      level: 3,
+      parentId: testCity.id
+    });
+    await areaRepository.save(testDistrict);
+
+    const testTown = areaRepository.create({
+      name: '粤海街道',
+      code: '440305001',
+      level: 3,
+      parentId: testDistrict.id
+    });
+    await areaRepository.save(testTown);
+
+    // 创建测试配送地址
+    const deliveryAddressRepository = dataSource.getRepository(DeliveryAddress);
+    testDeliveryAddress = deliveryAddressRepository.create({
+      userId: testUser.id,
+      name: '收货人姓名',
+      phone: '13800138000',
+      address: '测试地址',
+      receiverProvince: testProvince.id,
+      receiverCity: testCity.id,
+      receiverDistrict: testDistrict.id,
+      receiverTown: testTown.id,
+      isDefault: 1,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await deliveryAddressRepository.save(testDeliveryAddress);
+
+    // 创建测试商户
+    const merchantRepository = dataSource.getRepository(Merchant);
+    testMerchant = merchantRepository.create({
+      name: '测试商户',
+      username: `test_merchant_${Math.floor(Math.random() * 100000)}`,
+      password: 'password123',
+      phone: '13800138001',
+      realname: '测试商户',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await merchantRepository.save(testMerchant);
+
+    // 创建测试供应商
+    const supplierRepository = dataSource.getRepository(Supplier);
+    testSupplier = supplierRepository.create({
+      name: '测试供应商',
+      username: `test_supplier_${Math.floor(Math.random() * 100000)}`,
+      password: 'password123',
+      phone: '13800138002',
+      realname: '测试供应商',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await supplierRepository.save(testSupplier);
+  });
+
+  describe('GET /orders', () => {
+    it('应该返回当前用户的订单列表', async () => {
+      // 为测试用户创建一些订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+
+      const userOrder1 = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(userOrder1);
+
+      const userOrder2 = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 200.00,
+        costAmount: 160.00,
+        payAmount: 200.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 1,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(userOrder2);
+
+      // 为其他用户创建一个订单,确保不会返回
+      const otherUserOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: otherUser.id,
+        amount: 300.00,
+        costAmount: 240.00,
+        payAmount: 300.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: otherUser.id
+      });
+      await orderRepository.save(otherUserOrder);
+
+      const response = await client.index.$get({
+        query: {
+          page: 1,
+          pageSize: 10
+        }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户订单列表响应状态:', response.status);
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('用户订单列表错误响应:', errorData);
+      }
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data).toHaveProperty('data');
+        expect(Array.isArray(data.data)).toBe(true);
+
+        // 验证只返回当前用户的订单
+        data.data.forEach((order: any) => {
+          expect(order.userId).toBe(testUser.id);
+        });
+
+        // 验证不包含其他用户的订单
+        const otherUserOrderInResponse = data.data.find((order: any) => order.userId === otherUser.id);
+        expect(otherUserOrderInResponse).toBeUndefined();
+      }
+    });
+
+    it('应该拒绝未认证用户的访问', async () => {
+      const response = await client.index.$get({
+        query: {
+          page: 1,
+          pageSize: 10
+        }
+      });
+      expect(response.status).toBe(401);
+    });
+  });
+
+  describe('POST /orders', () => {
+    it('应该成功创建订单并自动设置当前用户权限', async () => {
+      const createData = {
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        amount: 150.00,
+        costAmount: 120.00,
+        payAmount: 150.00,
+        orderType: 1,
+        payType: 1,
+        payState: 0,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户创建订单响应状态:', response.status);
+      if (response.status !== 201) {
+        const errorData = await response.json();
+        console.debug('用户创建订单错误响应:', errorData);
+      }
+      expect(response.status).toBe(201);
+
+      if (response.status === 201) {
+        const data = await response.json();
+        expect(data).toHaveProperty('id');
+        expect(data.orderNo).toBe(createData.orderNo);
+        expect(parseFloat(data.amount)).toBe(createData.amount);
+        expect(data.userId).toBe(testUser.id); // 验证自动设置当前用户权限
+        expect(data.createdBy).toBe(testUser.id); // 验证自动设置创建用户
+      }
+    });
+
+    it('应该验证创建订单的必填字段', async () => {
+      const invalidData = {
+        // 缺少必填字段
+        amount: -1,
+        orderType: -1
+      };
+
+      const response = await client.index.$post({
+        json: invalidData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(400);
+    });
+  });
+
+  describe('GET /orders/:id', () => {
+    it('应该返回当前用户的订单详情', async () => {
+      // 先为测试用户创建一个订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+      const testOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(testOrder);
+
+      const response = await client[':id'].$get({
+        param: { id: testOrder.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户订单详情响应状态:', response.status);
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('用户订单详情错误响应:', errorData);
+      }
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.id).toBe(testOrder.id);
+        expect(data.orderNo).toBe(testOrder.orderNo);
+        expect(data.userId).toBe(testUser.id);
+      }
+    });
+
+    it('应该拒绝访问其他用户的订单', async () => {
+      // 为其他用户创建一个订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+      const otherUserOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: otherUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: otherUser.id
+      });
+      await orderRepository.save(otherUserOrder);
+
+      const response = await client[':id'].$get({
+        param: { id: otherUserOrder.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403(权限不足)
+    });
+
+    it('应该处理不存在的订单', async () => {
+      const response = await client[':id'].$get({
+        param: { id: 999999 }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(404);
+    });
+  });
+
+  describe('PUT /orders/:id', () => {
+    it('应该成功更新当前用户的订单', async () => {
+      // 先为测试用户创建一个订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+      const testOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(testOrder);
+
+      const updateData = {
+        state: 1,
+        payState: 1
+      };
+
+      const response = await client[':id'].$put({
+        param: { id: testOrder.id },
+        json: updateData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户更新订单响应状态:', response.status);
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.state).toBe(updateData.state);
+        expect(data.payState).toBe(updateData.payState);
+        expect(data.updatedBy).toBe(testUser.id); // 验证自动设置更新用户
+      }
+    });
+
+    it('应该拒绝更新其他用户的订单', async () => {
+      // 为其他用户创建一个订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+      const otherUserOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: otherUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: otherUser.id
+      });
+      await orderRepository.save(otherUserOrder);
+
+      const updateData = {
+        state: 1
+      };
+
+      const response = await client[':id'].$put({
+        param: { id: otherUserOrder.id },
+        json: updateData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403
+    });
+  });
+
+  describe('DELETE /orders/:id', () => {
+    it('应该成功删除当前用户的订单', async () => {
+      // 先为测试用户创建一个订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+      const testOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(testOrder);
+
+      const response = await client[':id'].$delete({
+        param: { id: testOrder.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户删除订单响应状态:', response.status);
+      expect(response.status).toBe(204);
+    });
+
+    it('应该拒绝删除其他用户的订单', async () => {
+      // 为其他用户创建一个订单
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+      const otherUserOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: otherUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: otherUser.id
+      });
+      await orderRepository.save(otherUserOrder);
+
+      const response = await client[':id'].$delete({
+        param: { id: otherUserOrder.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403
+    });
+  });
+
+  describe('数据权限配置测试', () => {
+    it('应该验证dataPermission配置正确工作', async () => {
+      // 这个测试验证数据权限配置是否正常工作
+      // 用户只能访问自己创建的订单
+
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRepository = dataSource.getRepository(Order);
+
+      // 创建测试用户和其他用户的订单
+      const userOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: testUser.id,
+        amount: 100.00,
+        costAmount: 80.00,
+        payAmount: 100.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: testUser.id
+      });
+      await orderRepository.save(userOrder);
+
+      const otherUserOrder = orderRepository.create({
+        orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+        userId: otherUser.id,
+        amount: 200.00,
+        costAmount: 160.00,
+        payAmount: 200.00,
+        orderType: 1,
+        payType: 1,
+        payState: 2,
+        state: 0,
+        addressId: testDeliveryAddress.id,
+        merchantId: testMerchant.id,
+        supplierId: testSupplier.id,
+        createdBy: otherUser.id
+      });
+      await orderRepository.save(otherUserOrder);
+
+      // 使用测试用户token获取列表
+      const response = await client.index.$get({
+        query: {
+          page: 1,
+          pageSize: 10
+        }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('数据权限配置测试错误响应:', errorData);
+      }
+      expect(response.status).toBe(200);
+      const data = await response.json();
+
+      // 类型检查确保data属性存在
+      if ('data' in data && Array.isArray(data.data)) {
+        // 验证只返回测试用户的订单
+        const userOrderInResponse = data.data.filter((order: any) => order.userId === testUser.id);
+        const otherUserOrderInResponse = data.data.filter((order: any) => order.userId === otherUser.id);
+
+        expect(userOrderInResponse.length).toBeGreaterThan(0);
+        expect(otherUserOrderInResponse.length).toBe(0);
+      } else {
+        // 如果响应是错误格式,应该失败
+        expect(data).toHaveProperty('data');
+      }
+    });
+  });
+});

+ 661 - 0
packages/orders-module-mt/tests/integration/user-refunds.integration.test.ts

@@ -0,0 +1,661 @@
+import { describe, it, expect, beforeEach } from 'vitest';
+import { testClient } from 'hono/testing';
+import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
+import { JWTUtil } from '@d8d/shared-utils';
+import { UserEntity, Role } from '@d8d/user-module';
+import { File } from '@d8d/file-module';
+import { Merchant } from '@d8d/merchant-module';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+import { AreaEntity } from '@d8d/geo-areas';
+import { Supplier } from '@d8d/supplier-module';
+import userRefundsRoutes from '../../src/routes/user/refunds';
+import { Order, OrderRefund } from '../../src/entities';
+
+// 设置集成测试钩子
+setupIntegrationDatabaseHooksWithEntities([
+  UserEntity, Role, Order, OrderRefund, File, Merchant, DeliveryAddress, AreaEntity, Supplier
+])
+
+describe('用户退款管理API集成测试', () => {
+  let client: ReturnType<typeof testClient<typeof userRefundsRoutes>>;
+  let userToken: string;
+  let otherUserToken: string;
+  let testUser: UserEntity;
+  let otherUser: UserEntity;
+  let testOrder: Order;
+  let otherUserOrder: Order;
+  let testDeliveryAddress: DeliveryAddress;
+  let testMerchant: Merchant;
+
+  beforeEach(async () => {
+    // 创建测试客户端
+    client = testClient(userRefundsRoutes);
+
+    // 获取数据源
+    const dataSource = await IntegrationTestDatabase.getDataSource();
+
+    // 创建测试用户
+    const userRepository = dataSource.getRepository(UserEntity);
+    testUser = userRepository.create({
+      username: `test_user_${Math.floor(Math.random() * 100000)}`,
+      password: 'test_password',
+      nickname: '测试用户',
+      registrationSource: 'web'
+    });
+    await userRepository.save(testUser);
+
+    // 创建其他用户
+    otherUser = userRepository.create({
+      username: `other_user_${Math.floor(Math.random() * 100000)}`,
+      password: 'other_password',
+      nickname: '其他用户',
+      registrationSource: 'web'
+    });
+    await userRepository.save(otherUser);
+
+    // 生成测试用户的token
+    userToken = JWTUtil.generateToken({
+      id: testUser.id,
+      username: testUser.username,
+      roles: [{name:'user'}]
+    });
+
+    // 生成其他用户的token
+    otherUserToken = JWTUtil.generateToken({
+      id: otherUser.id,
+      username: otherUser.username,
+      roles: [{name:'user'}]
+    });
+
+    // 创建测试地区
+    const areaRepository = dataSource.getRepository(AreaEntity);
+    const testProvince = areaRepository.create({
+      name: '广东省',
+      level: 1,
+      code: '440000',
+      state: 1
+    });
+    await areaRepository.save(testProvince);
+
+    const testCity = areaRepository.create({
+      name: '深圳市',
+      level: 2,
+      code: '440300',
+      state: 1
+    });
+    await areaRepository.save(testCity);
+
+    const testDistrict = areaRepository.create({
+      name: '南山区',
+      level: 3,
+      code: '440305',
+      state: 1
+    });
+    await areaRepository.save(testDistrict);
+
+    const testTown = areaRepository.create({
+      name: '粤海街道',
+      level: 4,
+      code: '440305001',
+      state: 1
+    });
+    await areaRepository.save(testTown);
+
+    // 创建测试配送地址
+    const deliveryAddressRepository = dataSource.getRepository(DeliveryAddress);
+    testDeliveryAddress = deliveryAddressRepository.create({
+      userId: testUser.id,
+      name: '收货人姓名',
+      phone: '13800138000',
+      receiverProvince: testProvince.id,
+      receiverCity: testCity.id,
+      receiverDistrict: testDistrict.id,
+      receiverTown: testTown.id,
+      address: '测试地址',
+      isDefault: 1,
+      state: 1,
+      createdBy: testUser.id
+    });
+    await deliveryAddressRepository.save(testDeliveryAddress);
+
+    // 创建测试商户
+    const merchantRepository = dataSource.getRepository(Merchant);
+    testMerchant = merchantRepository.create({
+      name: '测试商户',
+      username: `merchant_${Math.floor(Math.random() * 100000)}`,
+      password: 'test_password',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await merchantRepository.save(testMerchant);
+
+    // 创建测试供应商
+    const supplierRepository = dataSource.getRepository(Supplier);
+    const testSupplier = supplierRepository.create({
+      name: '测试供应商',
+      username: `supplier_${Math.floor(Math.random() * 100000)}`,
+      password: 'test_password',
+      state: 1,
+      createdBy: testUser.id
+    });
+    await supplierRepository.save(testSupplier);
+
+    // 创建测试用户的订单
+    const orderRepository = dataSource.getRepository(Order);
+    testOrder = orderRepository.create({
+      orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+      userId: testUser.id,
+      amount: 100.00,
+      costAmount: 80.00,
+      payAmount: 100.00,
+      orderType: 1,
+      payType: 1,
+      payState: 2,
+      state: 0,
+      deliveryAddressId: testDeliveryAddress.id,
+      addressId: testDeliveryAddress.id,
+      merchantId: testMerchant.id,
+      supplierId: testSupplier.id,
+      recevierProvince: testProvince.id,
+      recevierCity: testCity.id,
+      recevierDistrict: testDistrict.id,
+      recevierTown: testTown.id,
+      createdBy: testUser.id
+    });
+    await orderRepository.save(testOrder);
+
+    // 创建其他用户的订单
+    otherUserOrder = orderRepository.create({
+      orderNo: `ORDER_${Math.floor(Math.random() * 100000)}`,
+      userId: otherUser.id,
+      amount: 200.00,
+      costAmount: 160.00,
+      payAmount: 200.00,
+      orderType: 1,
+      payType: 1,
+      payState: 2,
+      state: 0,
+      deliveryAddressId: testDeliveryAddress.id,
+      addressId: testDeliveryAddress.id,
+      merchantId: testMerchant.id,
+      supplierId: testSupplier.id,
+      recevierProvince: testProvince.id,
+      recevierCity: testCity.id,
+      recevierDistrict: testDistrict.id,
+      recevierTown: testTown.id,
+      createdBy: otherUser.id
+    });
+    await orderRepository.save(otherUserOrder);
+  });
+
+  describe('GET /refunds', () => {
+    it('应该返回当前用户订单的退款列表', async () => {
+      // 为测试用户的订单创建一些退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+
+      const userRefund1 = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0,
+        createdBy: testUser.id
+      });
+      await orderRefundRepository.save(userRefund1);
+
+      const userRefund2 = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 25.00,
+        state: 1,
+        createdBy: testUser.id
+      });
+      await orderRefundRepository.save(userRefund2);
+
+      // 为其他用户的订单创建一个退款,确保不会返回
+      const otherUserRefund = orderRefundRepository.create({
+        orderNo: otherUserOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 100.00,
+        state: 0,
+        createdBy: otherUser.id
+      });
+      await orderRefundRepository.save(otherUserRefund);
+
+      const response = await client.index.$get({
+        query: {
+          page: 1,
+          pageSize: 10
+        }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户退款列表响应状态:', response.status);
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('用户退款列表错误响应:', errorData);
+      }
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data).toHaveProperty('data');
+        expect(Array.isArray(data.data)).toBe(true);
+
+        // 验证只返回当前用户订单的退款
+        data.data.forEach((refund: any) => {
+          expect(refund.order.userId).toBe(testUser.id);
+        });
+
+        // 验证不包含其他用户订单的退款
+        const otherUserRefundInResponse = data.data.find((refund: any) =>
+          refund.order && refund.order.userId === otherUser.id
+        );
+        expect(otherUserRefundInResponse).toBeUndefined();
+      }
+    });
+
+    it('应该拒绝未认证用户的访问', async () => {
+      const response = await client.index.$get({
+        query: {
+          page: 1,
+          pageSize: 10
+        }
+      });
+      expect(response.status).toBe(401);
+    });
+  });
+
+  describe('POST /refunds', () => {
+    it('应该成功创建退款申请并自动设置当前用户权限', async () => {
+      const createData = {
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 75.00,
+        state: 0
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户创建退款申请响应状态:', response.status);
+      if (response.status !== 201) {
+        const errorData = await response.json();
+        console.debug('用户创建退款申请错误响应:', errorData);
+      }
+      expect(response.status).toBe(201);
+
+      if (response.status === 201) {
+        const data = await response.json();
+        expect(data).toHaveProperty('id');
+        expect(data.refundOrderNo).toBe(createData.refundOrderNo);
+        expect(parseFloat(data.refundAmount)).toBe(createData.refundAmount);
+        expect(data.state).toBe(createData.state);
+        expect(data.createdBy).toBe(testUser.id); // 验证自动设置创建用户
+      }
+    });
+
+    it('应该验证创建退款申请的必填字段', async () => {
+      const invalidData = {
+        // 缺少必填字段
+        refundAmount: -1
+      };
+
+      const response = await client.index.$post({
+        json: invalidData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(400);
+    });
+
+    it('应该拒绝为其他用户的订单创建退款申请', async () => {
+      const createData = {
+        orderNo: otherUserOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 75.00,
+        state: 0
+      };
+
+      const response = await client.index.$post({
+        json: createData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403
+    });
+  });
+
+  describe('GET /refunds/:id', () => {
+    it('应该返回当前用户订单的退款详情', async () => {
+      // 先为测试用户的订单创建一个退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+      const testRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0,
+        createdBy: testUser.id
+      });
+      await orderRefundRepository.save(testRefund);
+
+      const response = await client[':id'].$get({
+        param: { id: testRefund.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户退款详情响应状态:', response.status);
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('用户退款详情错误响应:', errorData);
+      }
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.id).toBe(testRefund.id);
+        expect(data.refundOrderNo).toBe(testRefund.refundOrderNo);
+        expect(data.order.userId).toBe(testUser.id); // 验证订单属于当前用户
+      }
+    });
+
+    it('应该拒绝访问其他用户订单的退款', async () => {
+      // 为其他用户的订单创建一个退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+      const otherUserRefund = orderRefundRepository.create({
+        orderNo: otherUserOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 100.00,
+        state: 0,
+        createdBy: otherUser.id
+      });
+      await orderRefundRepository.save(otherUserRefund);
+
+      const response = await client[':id'].$get({
+        param: { id: otherUserRefund.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403(权限不足)
+    });
+
+    it('应该处理不存在的退款', async () => {
+      const response = await client[':id'].$get({
+        param: { id: 999999 }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(404);
+    });
+  });
+
+  describe('PUT /refunds/:id', () => {
+    it('应该成功更新当前用户订单的退款', async () => {
+      // 先为测试用户的订单创建一个退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+      const testRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0,
+        createdBy: testUser.id
+      });
+      await orderRefundRepository.save(testRefund);
+
+      const updateData = {
+        state: 1
+      };
+
+      const response = await client[':id'].$put({
+        param: { id: testRefund.id },
+        json: updateData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户更新退款响应状态:', response.status);
+      expect(response.status).toBe(200);
+
+      if (response.status === 200) {
+        const data = await response.json();
+        expect(data.state).toBe(updateData.state);
+        expect(data.updatedBy).toBe(testUser.id); // 验证自动设置更新用户
+      }
+    });
+
+    it('应该拒绝更新其他用户订单的退款', async () => {
+      // 为其他用户的订单创建一个退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+      const otherUserRefund = orderRefundRepository.create({
+        orderNo: otherUserOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 100.00,
+        state: 0,
+        createdBy: otherUser.id
+      });
+      await orderRefundRepository.save(otherUserRefund);
+
+      const updateData = {
+        state: 1
+      };
+
+      const response = await client[':id'].$put({
+        param: { id: otherUserRefund.id },
+        json: updateData
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403
+    });
+  });
+
+  describe('DELETE /refunds/:id', () => {
+    it('应该成功删除当前用户订单的退款', async () => {
+      // 先为测试用户的订单创建一个退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+      const testRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0,
+        createdBy: testUser.id
+      });
+      await orderRefundRepository.save(testRefund);
+
+      const response = await client[':id'].$delete({
+        param: { id: testRefund.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      console.debug('用户删除退款响应状态:', response.status);
+      expect(response.status).toBe(204);
+    });
+
+    it('应该拒绝删除其他用户订单的退款', async () => {
+      // 为其他用户的订单创建一个退款
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+      const otherUserRefund = orderRefundRepository.create({
+        orderNo: otherUserOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 100.00,
+        state: 0,
+        createdBy: otherUser.id
+      });
+      await orderRefundRepository.save(otherUserRefund);
+
+      const response = await client[':id'].$delete({
+        param: { id: otherUserRefund.id }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(403); // 数据权限控制返回403
+    });
+  });
+
+  describe('数据权限配置测试', () => {
+    it('应该验证dataPermission配置正确工作', async () => {
+      // 这个测试验证数据权限配置是否正常工作
+      // 用户只能访问自己订单的退款
+
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+
+      // 创建测试用户和其他用户订单的退款
+      const userRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0,
+        createdBy: testUser.id
+      });
+      await orderRefundRepository.save(userRefund);
+
+      const otherUserRefund = orderRefundRepository.create({
+        orderNo: otherUserOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 100.00,
+        state: 0,
+        createdBy: otherUser.id
+      });
+      await orderRefundRepository.save(otherUserRefund);
+
+      // 使用测试用户token获取列表
+      const response = await client.index.$get({
+        query: {
+          page: 1,
+          pageSize: 10
+        }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      if (response.status !== 200) {
+        const errorData = await response.json();
+        console.debug('数据权限配置测试错误响应:', errorData);
+      }
+      expect(response.status).toBe(200);
+      const data = await response.json();
+
+      // 类型检查确保data属性存在
+      if ('data' in data && Array.isArray(data.data)) {
+        // 验证只返回测试用户订单的退款
+        const userRefundInResponse = data.data.filter((refund: any) =>
+          refund.order && refund.order.userId === testUser.id
+        );
+        const otherUserRefundInResponse = data.data.filter((refund: any) =>
+          refund.order && refund.order.userId === otherUser.id
+        );
+
+        expect(userRefundInResponse.length).toBeGreaterThan(0);
+        expect(otherUserRefundInResponse.length).toBe(0);
+      } else {
+        // 如果响应是错误格式,应该失败
+        expect(data).toHaveProperty('data');
+      }
+    });
+  });
+
+  describe('退款状态管理测试', () => {
+    it('应该正确处理退款状态变更', async () => {
+      const dataSource = await IntegrationTestDatabase.getDataSource();
+      const orderRefundRepository = dataSource.getRepository(OrderRefund);
+
+      // 创建不同状态的退款
+      const pendingRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 50.00,
+        state: 0, // 未退款
+        createdBy: testUser.id
+      });
+      await orderRefundRepository.save(pendingRefund);
+
+      const processingRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 25.00,
+        state: 1, // 退款中
+        createdBy: testUser.id
+      });
+      await orderRefundRepository.save(processingRefund);
+
+      const completedRefund = orderRefundRepository.create({
+        orderNo: testOrder.orderNo,
+        refundOrderNo: `REFUND_${Math.floor(Math.random() * 100000)}`,
+        refundAmount: 75.00,
+        state: 2, // 退款成功
+        createdBy: testUser.id
+      });
+      await orderRefundRepository.save(completedRefund);
+
+      // 验证状态过滤
+      const response = await client.index.$get({
+        query: { filters: JSON.stringify({ state: 0 }) }
+      }, {
+        headers: {
+          'Authorization': `Bearer ${userToken}`
+        }
+      });
+
+      expect(response.status).toBe(200);
+      const data = await response.json();
+
+      // 类型检查确保data属性存在
+      if ('data' in data && Array.isArray(data.data)) {
+        // 应该只返回未退款状态的退款
+        const pendingRefundsInResponse = data.data.filter((refund: any) => refund.state === 0);
+        const processingRefundsInResponse = data.data.filter((refund: any) => refund.state === 1);
+        const completedRefundsInResponse = data.data.filter((refund: any) => refund.state === 2);
+
+        expect(pendingRefundsInResponse.length).toBeGreaterThan(0);
+        expect(processingRefundsInResponse.length).toBe(0);
+        expect(completedRefundsInResponse.length).toBe(0);
+      } else {
+        // 如果响应是错误格式,应该失败
+        expect(data).toHaveProperty('data');
+      }
+    });
+  });
+});

+ 314 - 0
packages/orders-module-mt/tests/utils/test-data-factory.ts

@@ -0,0 +1,314 @@
+import { DataSource } from 'typeorm';
+import { UserEntity } from '@d8d/user-module';
+import { AreaEntity } from '@d8d/geo-areas';
+import { DeliveryAddress } from '@d8d/delivery-address-module';
+import { Merchant } from '@d8d/merchant-module';
+import { Supplier } from '@d8d/supplier-module';
+import { Order, OrderRefund } from '../../src/entities';
+import { JWTUtil } from '@d8d/shared-utils';
+
+/**
+ * 订单模块测试数据工厂类
+ */
+export class OrdersTestDataFactory {
+  /**
+   * 创建测试用户数据
+   */
+  static createUserData(overrides: Partial<UserEntity> = {}): Partial<UserEntity> {
+    const timestamp = Math.floor(Math.random() * 100000);
+    return {
+      username: `test_user_${timestamp}`,
+      password: 'test_password',
+      nickname: '测试用户',
+      registrationSource: 'web',
+      ...overrides
+    };
+  }
+
+  /**
+   * 在数据库中创建测试用户
+   */
+  static async createTestUser(dataSource: DataSource, overrides: Partial<UserEntity> = {}): Promise<UserEntity> {
+    const userData = this.createUserData(overrides);
+    const userRepository = dataSource.getRepository(UserEntity);
+    const user = userRepository.create(userData);
+    return await userRepository.save(user);
+  }
+
+  /**
+   * 为测试用户生成JWT token
+   */
+  static generateUserToken(user: UserEntity): string {
+    return JWTUtil.generateToken({
+      id: user.id,
+      username: user.username,
+      roles: [{ name: 'user' }]
+    });
+  }
+
+  /**
+   * 创建测试地区数据
+   */
+  static createAreaData(overrides: Partial<AreaEntity> = {}): Partial<AreaEntity> {
+    const timestamp = Math.floor(Math.random() * 100000);
+    return {
+      name: '广东省',
+      level: 1,
+      code: `44${timestamp.toString().padStart(4, '0')}`,
+      state: 1,
+      ...overrides
+    };
+  }
+
+  /**
+   * 在数据库中创建测试地区
+   */
+  static async createTestArea(dataSource: DataSource, overrides: Partial<AreaEntity> = {}): Promise<AreaEntity> {
+    const areaData = this.createAreaData(overrides);
+    const areaRepository = dataSource.getRepository(AreaEntity);
+    const area = areaRepository.create(areaData);
+    return await areaRepository.save(area);
+  }
+
+  /**
+   * 创建完整的地区层级(省、市、区、街道)
+   */
+  static async createCompleteAreaHierarchy(dataSource: DataSource): Promise<{
+    province: AreaEntity;
+    city: AreaEntity;
+    district: AreaEntity;
+    town: AreaEntity;
+  }> {
+    const timestamp = Math.floor(Math.random() * 100000);
+
+    const province = await this.createTestArea(dataSource, {
+      name: '广东省',
+      level: 1,
+      code: `44${timestamp.toString().padStart(4, '0')}`
+    });
+
+    const city = await this.createTestArea(dataSource, {
+      name: '深圳市',
+      level: 2,
+      code: `44${(timestamp + 1).toString().padStart(4, '0')}`,
+      parentId: province.id
+    });
+
+    const district = await this.createTestArea(dataSource, {
+      name: '南山区',
+      level: 3,
+      code: `44${(timestamp + 2).toString().padStart(4, '0')}`,
+      parentId: city.id
+    });
+
+    const town = await this.createTestArea(dataSource, {
+      name: '粤海街道',
+      level: 4,
+      code: `44${(timestamp + 3).toString().padStart(4, '0')}`,
+      parentId: district.id
+    });
+
+    return { province, city, district, town };
+  }
+
+  /**
+   * 创建测试配送地址数据
+   */
+  static createDeliveryAddressData(
+    userId: number,
+    areaHierarchy: { province: AreaEntity; city: AreaEntity; district: AreaEntity; town: AreaEntity },
+    overrides: Partial<DeliveryAddress> = {}
+  ): Partial<DeliveryAddress> {
+    return {
+      userId,
+      name: '收货人姓名',
+      phone: '13800138000',
+      receiverProvince: areaHierarchy.province.id,
+      receiverCity: areaHierarchy.city.id,
+      receiverDistrict: areaHierarchy.district.id,
+      receiverTown: areaHierarchy.town.id,
+      address: '测试地址',
+      isDefault: 1,
+      state: 1,
+      createdBy: userId,
+      ...overrides
+    };
+  }
+
+  /**
+   * 在数据库中创建测试配送地址
+   */
+  static async createTestDeliveryAddress(
+    dataSource: DataSource,
+    userId: number,
+    areaHierarchy: { province: AreaEntity; city: AreaEntity; district: AreaEntity; town: AreaEntity },
+    overrides: Partial<DeliveryAddress> = {}
+  ): Promise<DeliveryAddress> {
+    const addressData = this.createDeliveryAddressData(userId, areaHierarchy, overrides);
+    const addressRepository = dataSource.getRepository(DeliveryAddress);
+    const address = addressRepository.create(addressData);
+    return await addressRepository.save(address);
+  }
+
+  /**
+   * 创建测试商户数据
+   */
+  static createMerchantData(overrides: Partial<Merchant> = {}): Partial<Merchant> {
+    const timestamp = Math.floor(Math.random() * 100000);
+    return {
+      name: '测试商户',
+      username: `merchant_${timestamp}`,
+      password: 'test_password',
+      state: 1,
+      createdBy: 1,
+      ...overrides
+    };
+  }
+
+  /**
+   * 在数据库中创建测试商户
+   */
+  static async createTestMerchant(dataSource: DataSource, overrides: Partial<Merchant> = {}): Promise<Merchant> {
+    const merchantData = this.createMerchantData(overrides);
+    const merchantRepository = dataSource.getRepository(Merchant);
+    const merchant = merchantRepository.create(merchantData);
+    return await merchantRepository.save(merchant);
+  }
+
+  /**
+   * 创建测试供应商数据
+   */
+  static createSupplierData(overrides: Partial<Supplier> = {}): Partial<Supplier> {
+    const timestamp = Math.floor(Math.random() * 100000);
+    return {
+      name: '测试供应商',
+      username: `supplier_${timestamp}`,
+      password: 'test_password',
+      state: 1,
+      createdBy: 1,
+      ...overrides
+    };
+  }
+
+  /**
+   * 在数据库中创建测试供应商
+   */
+  static async createTestSupplier(dataSource: DataSource, overrides: Partial<Supplier> = {}): Promise<Supplier> {
+    const supplierData = this.createSupplierData(overrides);
+    const supplierRepository = dataSource.getRepository(Supplier);
+    const supplier = supplierRepository.create(supplierData);
+    return await supplierRepository.save(supplier);
+  }
+
+  /**
+   * 创建测试订单数据
+   */
+  static createOrderData(
+    userId: number,
+    deliveryAddressId: number,
+    merchantId: number,
+    supplierId: number,
+    areaHierarchy: { province: AreaEntity; city: AreaEntity; district: AreaEntity; town: AreaEntity },
+    overrides: Partial<Order> = {}
+  ): Partial<Order> {
+    const timestamp = Math.floor(Math.random() * 100000);
+    return {
+      orderNo: `ORDER_${timestamp}`,
+      userId,
+      amount: 100.00,
+      costAmount: 80.00,
+      payAmount: 100.00,
+      orderType: 1,
+      payType: 1,
+      payState: 2,
+      state: 0,
+      deliveryAddressId,
+      addressId: deliveryAddressId,
+      merchantId,
+      supplierId,
+      recevierProvince: areaHierarchy.province.id,
+      recevierCity: areaHierarchy.city.id,
+      recevierDistrict: areaHierarchy.district.id,
+      recevierTown: areaHierarchy.town.id,
+      createdBy: userId,
+      ...overrides
+    };
+  }
+
+  /**
+   * 在数据库中创建测试订单
+   */
+  static async createTestOrder(
+    dataSource: DataSource,
+    userId: number,
+    deliveryAddressId: number,
+    merchantId: number,
+    supplierId: number,
+    areaHierarchy: { province: AreaEntity; city: AreaEntity; district: AreaEntity; town: AreaEntity },
+    overrides: Partial<Order> = {}
+  ): Promise<Order> {
+    const orderData = this.createOrderData(userId, deliveryAddressId, merchantId, supplierId, areaHierarchy, overrides);
+    const orderRepository = dataSource.getRepository(Order);
+    const order = orderRepository.create(orderData);
+    return await orderRepository.save(order);
+  }
+
+  /**
+   * 创建完整的测试订单环境(包含所有依赖实体)
+   */
+  static async createCompleteOrderEnvironment(dataSource: DataSource, userId?: number): Promise<{
+    user: UserEntity;
+    areaHierarchy: { province: AreaEntity; city: AreaEntity; district: AreaEntity; town: AreaEntity };
+    deliveryAddress: DeliveryAddress;
+    merchant: Merchant;
+    supplier: Supplier;
+    order: Order;
+  }> {
+    // 创建用户
+    const user = await this.createTestUser(dataSource, userId ? { id: userId } : {});
+
+    // 创建地区层级
+    const areaHierarchy = await this.createCompleteAreaHierarchy(dataSource);
+
+    // 创建商户和供应商
+    const merchant = await this.createTestMerchant(dataSource, { createdBy: user.id });
+    const supplier = await this.createTestSupplier(dataSource, { createdBy: user.id });
+
+    // 创建配送地址
+    const deliveryAddress = await this.createTestDeliveryAddress(dataSource, user.id, areaHierarchy);
+
+    // 创建订单
+    const order = await this.createTestOrder(dataSource, user.id, deliveryAddress.id, merchant.id, supplier.id, areaHierarchy);
+
+    return { user, areaHierarchy, deliveryAddress, merchant, supplier, order };
+  }
+
+  /**
+   * 创建测试退款数据
+   */
+  static createRefundData(orderNo: string, overrides: Partial<OrderRefund> = {}): Partial<OrderRefund> {
+    const timestamp = Math.floor(Math.random() * 100000);
+    return {
+      orderNo,
+      refundOrderNo: `REFUND_${timestamp}`,
+      refundAmount: 50.00,
+      state: 0,
+      createdBy: 1,
+      ...overrides
+    };
+  }
+
+  /**
+   * 在数据库中创建测试退款
+   */
+  static async createTestRefund(
+    dataSource: DataSource,
+    orderNo: string,
+    overrides: Partial<OrderRefund> = {}
+  ): Promise<OrderRefund> {
+    const refundData = this.createRefundData(orderNo, overrides);
+    const refundRepository = dataSource.getRepository(OrderRefund);
+    const refund = refundRepository.create(refundData);
+    return await refundRepository.save(refund);
+  }
+}

+ 16 - 0
packages/orders-module-mt/tsconfig.json

@@ -0,0 +1,16 @@
+{
+  "extends": "../../tsconfig.json",
+  "compilerOptions": {
+    "composite": true,
+    "rootDir": ".",
+    "outDir": "dist"
+  },
+  "include": [
+    "src/**/*",
+    "tests/**/*"
+  ],
+  "exclude": [
+    "node_modules",
+    "dist"
+  ]
+}

+ 21 - 0
packages/orders-module-mt/vitest.config.ts

@@ -0,0 +1,21 @@
+import { defineConfig } from 'vitest/config';
+
+export default defineConfig({
+  test: {
+    globals: true,
+    environment: 'node',
+    include: ['tests/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
+    coverage: {
+      provider: 'v8',
+      reporter: ['text', 'json', 'html'],
+      exclude: [
+        'tests/**',
+        '**/*.d.ts',
+        '**/*.config.*',
+        '**/dist/**'
+      ]
+    },
+    // 关闭并行测试以避免数据库连接冲突
+    fileParallelism: false
+  }
+});

+ 70 - 0
pnpm-lock.yaml

@@ -1106,6 +1106,76 @@ importers:
         specifier: ^3.2.4
         version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@18.0.1)(jiti@2.6.1)(jsdom@24.1.3)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.64.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
 
+  packages/orders-module-mt:
+    dependencies:
+      '@d8d/auth-module-mt':
+        specifier: workspace:*
+        version: link:../auth-module-mt
+      '@d8d/delivery-address-module-mt':
+        specifier: workspace:*
+        version: link:../delivery-address-module-mt
+      '@d8d/file-module-mt':
+        specifier: workspace:*
+        version: link:../file-module-mt
+      '@d8d/geo-areas':
+        specifier: workspace:*
+        version: link:../geo-areas
+      '@d8d/goods-module-mt':
+        specifier: workspace:*
+        version: link:../goods-module-mt
+      '@d8d/merchant-module-mt':
+        specifier: workspace:*
+        version: link:../merchant-module-mt
+      '@d8d/shared-crud':
+        specifier: workspace:*
+        version: link:../shared-crud
+      '@d8d/shared-types':
+        specifier: workspace:*
+        version: link:../shared-types
+      '@d8d/shared-utils':
+        specifier: workspace:*
+        version: link:../shared-utils
+      '@d8d/supplier-module-mt':
+        specifier: workspace:*
+        version: link:../supplier-module-mt
+      '@d8d/user-module-mt':
+        specifier: workspace:*
+        version: link:../user-module-mt
+      '@hono/zod-openapi':
+        specifier: ^1.0.2
+        version: 1.0.2(hono@4.8.5)(zod@4.1.12)
+      hono:
+        specifier: ^4.8.5
+        version: 4.8.5
+      typeorm:
+        specifier: ^0.3.20
+        version: 0.3.27(ioredis@5.8.2)(pg@8.16.3)(redis@4.7.1)(reflect-metadata@0.2.2)
+      zod:
+        specifier: ^4.1.12
+        version: 4.1.12
+    devDependencies:
+      '@d8d/shared-test-util':
+        specifier: workspace:*
+        version: link:../shared-test-util
+      '@types/node':
+        specifier: ^22.10.2
+        version: 22.19.0
+      '@typescript-eslint/eslint-plugin':
+        specifier: ^8.18.1
+        version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.8.3))(eslint@9.38.0(jiti@2.6.1))(typescript@5.8.3)
+      '@typescript-eslint/parser':
+        specifier: ^8.18.1
+        version: 8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.8.3)
+      eslint:
+        specifier: ^9.17.0
+        version: 9.38.0(jiti@2.6.1)
+      typescript:
+        specifier: ^5.8.3
+        version: 5.8.3
+      vitest:
+        specifier: ^3.2.4
+        version: 3.2.4(@types/debug@4.1.12)(@types/node@22.19.0)(happy-dom@18.0.1)(jiti@2.6.1)(jsdom@24.1.3)(lightningcss@1.30.2)(sass@1.93.2)(stylus@0.64.0)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)
+
   packages/server:
     dependencies:
       '@asteasolutions/zod-to-openapi':