|
|
@@ -0,0 +1,333 @@
|
|
|
+# Story 005.001: 创建飞鹅打印模块
|
|
|
+
|
|
|
+## Status
|
|
|
+Ready for Review
|
|
|
+
|
|
|
+## Story
|
|
|
+**As a** 系统管理员
|
|
|
+**I want** 能够集成飞鹅打印API
|
|
|
+**so that** 实现订单支付成功后自动打印小票
|
|
|
+
|
|
|
+## Acceptance Criteria
|
|
|
+1. [x] 创建`feie_printer_mt`表,存储打印机配置信息
|
|
|
+2. [x] 创建`feie_print_task_mt`表,记录打印任务(包含防退款延迟相关字段)
|
|
|
+3. [x] 创建`feie_config_mt`表,存储基础打印配置
|
|
|
+4. [x] 实现飞鹅API客户端,支持小票打印接口
|
|
|
+5. [x] 提供打印机管理服务(添加、查询、删除打印机)
|
|
|
+6. [x] 提供打印任务管理服务(提交任务、查询状态、取消任务)
|
|
|
+7. [x] 实现防退款延迟打印调度器(默认2分钟延迟)
|
|
|
+8. [x] 编写单元测试覆盖核心逻辑
|
|
|
+
|
|
|
+## Tasks / Subtasks
|
|
|
+- [x] 任务1:创建多租户飞鹅打印模块包 (AC: 1,2,3,4,5,6,7)
|
|
|
+ - [x] 在 `packages/` 目录下创建 `@d8d/feie-printer-module-mt` 包
|
|
|
+ - [x] 配置包的基本结构:`package.json`、`tsconfig.json`、`vitest.config.ts`
|
|
|
+ - [x] 创建数据库实体定义文件
|
|
|
+ - [x] 创建服务层文件
|
|
|
+ - [x] 创建数据验证Schema文件
|
|
|
+ - [x] 创建API路由文件
|
|
|
+ - [x] 创建类型定义文件
|
|
|
+- [x] 任务2:实现数据库实体 (AC: 1,2,3)
|
|
|
+ - [x] 创建 `feie-printer.mt.entity.ts` 实体
|
|
|
+ - [x] 创建 `feie-print-task.mt.entity.ts` 实体
|
|
|
+ - [x] 创建 `feie-config.mt.entity.ts` 实体
|
|
|
+ - [x] 配置实体关系和多租户支持
|
|
|
+- [x] 任务3:实现飞鹅API客户端服务 (AC: 4)
|
|
|
+ - [x] 创建 `feie-api.service.ts` 服务
|
|
|
+ - [x] 实现飞鹅API接口封装:`Open_printerAddlist`、`Open_printerDelList`、`Open_queryPrinterStatus`、`Open_printMsg`、`Open_queryOrderState`
|
|
|
+ - [x] 实现错误处理和重试逻辑
|
|
|
+ - [x] 实现API签名验证
|
|
|
+- [x] 任务4:实现打印机管理服务 (AC: 5)
|
|
|
+ - [x] 创建 `printer.service.ts` 服务
|
|
|
+ - [x] 实现打印机添加、查询、删除功能
|
|
|
+ - [x] 实现打印机状态管理
|
|
|
+ - [x] 实现默认打印机设置
|
|
|
+- [x] 任务5:实现打印任务管理服务 (AC: 6)
|
|
|
+ - [x] 创建 `print-task.service.ts` 服务
|
|
|
+ - [x] 实现打印任务提交、查询、取消功能
|
|
|
+ - [x] 实现打印状态更新和同步
|
|
|
+ - [x] 实现打印失败重试机制
|
|
|
+- [x] 任务6:实现防退款延迟打印调度器 (AC: 7)
|
|
|
+ - [x] 创建 `delay-scheduler.service.ts` 服务
|
|
|
+ - [x] 实现延迟任务调度逻辑(默认2分钟延迟)
|
|
|
+ - [x] 实现退款事件监听和任务取消
|
|
|
+ - [x] 实现调度器健康检查和故障恢复
|
|
|
+- [x] 任务7:实现API路由 (AC: 5,6)
|
|
|
+ - [x] 创建打印机管理API路由
|
|
|
+ - [x] 创建打印任务管理API路由
|
|
|
+ - [x] 创建打印配置管理API路由
|
|
|
+ - [x] 实现多租户路由中间件
|
|
|
+- [x] 任务8:编写单元测试 (AC: 8)
|
|
|
+ - [x] 为每个服务编写单元测试
|
|
|
+ - [x] 为API客户端编写集成测试
|
|
|
+ - [x] 为调度器编写测试
|
|
|
+ - [x] 确保测试覆盖率 > 80%
|
|
|
+
|
|
|
+## Dev Notes
|
|
|
+
|
|
|
+### 技术栈信息 [Source: architecture/tech-stack.md]
|
|
|
+- **运行时**: Node.js 20.18.3
|
|
|
+- **框架**: Hono 4.8.5 (Web框架和API路由,RPC类型安全)
|
|
|
+- **数据库**: PostgreSQL 17 (通过TypeORM)
|
|
|
+- **ORM**: TypeORM 0.3.25 (数据库操作抽象,实体管理)
|
|
|
+- **测试框架**: Vitest 2.x (单元测试框架)
|
|
|
+- **定时任务**: node-cron latest (定时任务调度库)
|
|
|
+- **认证**: JWT 9.0.2 (用户认证和安全,Bearer Token)
|
|
|
+
|
|
|
+### 项目结构信息 [Source: architecture/source-tree.md]
|
|
|
+- **项目根目录**: `/mnt/code/186-175-template-22`
|
|
|
+- **包位置**: `packages/@d8d/feie-printer-module-mt/`
|
|
|
+- **包架构层次**: 多租户模块层(-mt后缀),支持租户数据隔离
|
|
|
+- **多租户架构**: 基于Epic-007方案,通过复制单租户包创建多租户版本
|
|
|
+- **租户隔离**: 通过租户ID实现数据隔离,支持多租户部署
|
|
|
+
|
|
|
+### 包结构规范 [Source: architecture/source-tree.md#多租户包架构]
|
|
|
+```
|
|
|
+packages/@d8d/feie-printer-module-mt/
|
|
|
+├── src/
|
|
|
+│ ├── entities/ # 实体定义
|
|
|
+│ │ ├── feie-printer.mt.entity.ts
|
|
|
+│ │ ├── feie-print-task.mt.entity.ts
|
|
|
+│ │ ├── feie-config.mt.entity.ts
|
|
|
+│ │ └── index.ts
|
|
|
+│ ├── services/ # 服务层
|
|
|
+│ │ ├── feie-api.service.ts # 飞鹅API客户端(小票打印)
|
|
|
+│ │ ├── printer.service.ts # 打印机管理服务
|
|
|
+│ │ ├── print-task.service.ts # 打印任务服务
|
|
|
+│ │ ├── delay-scheduler.service.ts # 延迟打印调度器
|
|
|
+│ │ └── index.ts
|
|
|
+│ ├── schemas/ # 数据验证
|
|
|
+│ │ └── index.ts
|
|
|
+│ ├── routes/ # API路由
|
|
|
+│ │ └── index.ts
|
|
|
+│ ├── types/ # 类型定义
|
|
|
+│ │ └── index.ts
|
|
|
+│ └── index.ts # 主入口文件
|
|
|
+├── tests/ # 测试文件
|
|
|
+├── tsconfig.json # TypeScript配置
|
|
|
+├── vitest.config.ts # 测试配置
|
|
|
+└── package.json
|
|
|
+```
|
|
|
+
|
|
|
+### 数据库设计 [Source: docs/prd/epic-005-feie-printer-integration.md#数据库设计]
|
|
|
+```sql
|
|
|
+-- 飞鹅打印机配置表
|
|
|
+CREATE TABLE feie_printer_mt (
|
|
|
+ id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
|
|
+ tenant_id INT UNSIGNED NOT NULL COMMENT '租户ID',
|
|
|
+ printer_sn VARCHAR(50) NOT NULL COMMENT '打印机序列号',
|
|
|
+ printer_key VARCHAR(100) NOT NULL COMMENT '打印机密钥',
|
|
|
+ printer_name VARCHAR(100) COMMENT '打印机名称',
|
|
|
+ printer_type VARCHAR(20) DEFAULT '58mm' COMMENT '打印机类型: 58mm, 80mm',
|
|
|
+ printer_status VARCHAR(20) DEFAULT 'ACTIVE' COMMENT '打印机状态: ACTIVE, INACTIVE, ERROR',
|
|
|
+ is_default TINYINT DEFAULT 0 COMMENT '是否默认打印机(0:否,1:是)',
|
|
|
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
+ UNIQUE KEY uk_tenant_printer_sn (tenant_id, printer_sn),
|
|
|
+ INDEX idx_tenant_id (tenant_id),
|
|
|
+ INDEX idx_status (printer_status)
|
|
|
+) COMMENT='飞鹅打印机配置表';
|
|
|
+
|
|
|
+-- 飞鹅打印任务表(支持防退款延迟打印)
|
|
|
+CREATE TABLE feie_print_task_mt (
|
|
|
+ id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
|
|
+ tenant_id INT UNSIGNED NOT NULL COMMENT '租户ID',
|
|
|
+ task_id VARCHAR(100) NOT NULL COMMENT '飞鹅任务ID',
|
|
|
+ order_id INT UNSIGNED COMMENT '关联订单ID',
|
|
|
+ printer_sn VARCHAR(50) NOT NULL COMMENT '打印机序列号',
|
|
|
+ content TEXT NOT NULL COMMENT '打印内容',
|
|
|
+ print_type VARCHAR(20) NOT NULL COMMENT '打印类型: RECEIPT(小票), SHIPPING(发货单), ORDER(订单)',
|
|
|
+ print_status VARCHAR(20) DEFAULT 'PENDING' COMMENT '打印状态: PENDING, DELAYED(延迟等待), PRINTING, SUCCESS, FAILED, CANCELLED(已取消)',
|
|
|
+ error_message VARCHAR(500) COMMENT '错误信息',
|
|
|
+ retry_count INT DEFAULT 0 COMMENT '重试次数',
|
|
|
+ max_retries INT DEFAULT 3 COMMENT '最大重试次数',
|
|
|
+ scheduled_at TIMESTAMP NULL COMMENT '计划打印时间(用于延迟打印)',
|
|
|
+ printed_at TIMESTAMP NULL COMMENT '打印完成时间',
|
|
|
+ cancelled_at TIMESTAMP NULL COMMENT '取消时间',
|
|
|
+ cancel_reason VARCHAR(100) COMMENT '取消原因: REFUND(退款), MANUAL(手动取消), TIMEOUT(超时)',
|
|
|
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
+ UNIQUE KEY uk_task_id (task_id),
|
|
|
+ INDEX idx_tenant_order (tenant_id, order_id),
|
|
|
+ INDEX idx_status (print_status),
|
|
|
+ INDEX idx_scheduled (scheduled_at),
|
|
|
+ INDEX idx_created (created_at)
|
|
|
+) COMMENT='飞鹅打印任务表';
|
|
|
+
|
|
|
+-- 打印配置表
|
|
|
+CREATE TABLE feie_config_mt (
|
|
|
+ id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
|
|
|
+ tenant_id INT UNSIGNED NOT NULL COMMENT '租户ID',
|
|
|
+ config_key VARCHAR(50) NOT NULL COMMENT '配置键',
|
|
|
+ config_value TEXT COMMENT '配置值',
|
|
|
+ config_type VARCHAR(20) DEFAULT 'STRING' COMMENT '配置类型: STRING, JSON, BOOLEAN, NUMBER',
|
|
|
+ description VARCHAR(200) COMMENT '配置描述',
|
|
|
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
|
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
|
+ UNIQUE KEY uk_tenant_key (tenant_id, config_key),
|
|
|
+ INDEX idx_tenant_id (tenant_id)
|
|
|
+) COMMENT='飞鹅打印配置表';
|
|
|
+```
|
|
|
+
|
|
|
+### API设计 [Source: docs/prd/epic-005-feie-printer-integration.md#API设计]
|
|
|
+#### 飞鹅打印模块API
|
|
|
+1. `GET /api/feie/printers` - 查询打印机列表
|
|
|
+2. `POST /api/feie/printers` - 添加打印机
|
|
|
+3. `DELETE /api/feie/printers/{printerSn}` - 删除打印机
|
|
|
+4. `POST /api/feie/print` - 提交打印任务(支持延迟打印)
|
|
|
+5. `GET /api/feie/tasks/{taskId}` - 查询打印任务状态
|
|
|
+6. `GET /api/feie/tasks` - 查询打印任务列表
|
|
|
+7. `POST /api/feie/tasks/{taskId}/cancel` - 取消打印任务
|
|
|
+8. `POST /api/feie/tasks/{taskId}/retry` - 重试打印任务
|
|
|
+9. `GET /api/feie/config` - 查询打印配置
|
|
|
+10. `PUT /api/feie/config` - 更新打印配置
|
|
|
+
|
|
|
+#### 飞鹅API接口(需要封装)
|
|
|
+1. **打印机管理**
|
|
|
+ - `Open_printerAddlist` - 添加打印机
|
|
|
+ - `Open_printerDelList` - 删除打印机
|
|
|
+ - `Open_queryPrinterStatus` - 查询打印机状态
|
|
|
+
|
|
|
+2. **打印任务管理**
|
|
|
+ - `Open_printMsg` - 打印小票
|
|
|
+ - `Open_queryOrderState` - 查询订单打印状态
|
|
|
+ - `Open_queryOrderInfoByDate` - 根据时间查询订单
|
|
|
+
|
|
|
+### 编码标准 [Source: architecture/coding-standards.md]
|
|
|
+- **代码风格**: TypeScript严格模式,一致的缩进和命名
|
|
|
+- **测试框架**: 使用Vitest + Testing Library + hono/testing
|
|
|
+- **测试位置**: `__tests__` 文件夹与源码并列
|
|
|
+- **覆盖率目标**: 核心业务逻辑 > 80%
|
|
|
+- **测试类型**: 单元测试、集成测试、E2E测试
|
|
|
+- **RPC客户端架构**: 使用单例模式的客户端管理器,类型安全的Hono RPC
|
|
|
+
|
|
|
+### 测试标准
|
|
|
+- **测试文件位置**: 每个包独立的 `tests/` 目录
|
|
|
+- **测试框架**: Vitest 2.x
|
|
|
+- **测试模式**: 单元测试覆盖核心逻辑,集成测试验证API功能
|
|
|
+- **覆盖率要求**: 核心业务逻辑 > 80%
|
|
|
+- **测试数据**: 使用测试数据库,避免污染生产数据
|
|
|
+- **错误处理测试**: 测试各种错误场景和边界条件
|
|
|
+
|
|
|
+### 多租户实现要求
|
|
|
+- **包命名**: 使用 `-mt` 后缀表示多租户包
|
|
|
+- **租户ID字段**: 所有实体必须包含 `tenant_id` 字段
|
|
|
+- **数据隔离**: 通过租户ID实现数据查询隔离
|
|
|
+- **路由中间件**: 实现多租户路由中间件,自动注入租户上下文
|
|
|
+- **权限控制**: 确保租户只能访问自己的数据
|
|
|
+
|
|
|
+### 防退款延迟打印机制
|
|
|
+- **默认延迟时间**: 120秒(2分钟)
|
|
|
+- **状态管理**: 打印任务状态包括 `PENDING`、`DELAYED`、`PRINTING`、`SUCCESS`、`FAILED`、`CANCELLED`
|
|
|
+- **取消场景**: `REFUND`(退款)、`MANUAL`(手动取消)、`TIMEOUT`(超时)
|
|
|
+- **调度器设计**: 使用 `node-cron` 实现定时任务调度
|
|
|
+- **退款监听**: 监听订单退款事件,自动取消延迟打印任务
|
|
|
+
|
|
|
+### 项目结构对齐说明
|
|
|
+- 新包 `@d8d/feie-printer-module-mt` 应放置在 `packages/` 目录下
|
|
|
+- 包结构应遵循现有的多租户模块包模式
|
|
|
+- 需要与现有的 `@d8d/orders-module-mt` 集成,监听订单支付成功事件
|
|
|
+- API路由应遵循现有的RESTful API设计模式
|
|
|
+
|
|
|
+## Testing
|
|
|
+### 测试框架和标准
|
|
|
+- **测试框架**: Vitest 2.x [Source: architecture/tech-stack.md]
|
|
|
+- **测试位置**: `__tests__` 文件夹与源码并列 [Source: architecture/coding-standards.md]
|
|
|
+- **覆盖率目标**: 核心业务逻辑 > 80% [Source: architecture/coding-standards.md]
|
|
|
+- **测试类型**: 单元测试、集成测试 [Source: architecture/coding-standards.md]
|
|
|
+
|
|
|
+### 具体测试要求
|
|
|
+1. **单元测试**:
|
|
|
+ - 飞鹅API客户端测试
|
|
|
+ - 打印机管理逻辑测试
|
|
|
+ - 打印任务管理测试
|
|
|
+ - 防退款延迟调度器测试
|
|
|
+
|
|
|
+2. **集成测试**:
|
|
|
+ - 飞鹅API集成测试(使用模拟API)
|
|
|
+ - API路由功能测试
|
|
|
+ - 多租户数据隔离测试
|
|
|
+
|
|
|
+3. **测试文件结构**:
|
|
|
+ ```
|
|
|
+ tests/
|
|
|
+ ├── unit/
|
|
|
+ │ ├── feie-api.service.test.ts
|
|
|
+ │ ├── printer.service.test.ts
|
|
|
+ │ ├── print-task.service.test.ts
|
|
|
+ │ └── delay-scheduler.service.test.ts
|
|
|
+ └── integration/
|
|
|
+ ├── api/
|
|
|
+ │ ├── printers.test.ts
|
|
|
+ │ ├── print-tasks.test.ts
|
|
|
+ │ └── config.test.ts
|
|
|
+ └── feie-api.integration.test.ts
|
|
|
+ ```
|
|
|
+
|
|
|
+## Change Log
|
|
|
+| Date | Version | Description | Author |
|
|
|
+|------|---------|-------------|--------|
|
|
|
+| 2025-12-06 | 1.0 | 初始创建故事文档 | Bob (Scrum Master) |
|
|
|
+
|
|
|
+## Dev Agent Record
|
|
|
+*此部分由开发代理在实现过程中填写*
|
|
|
+
|
|
|
+### Agent Model Used
|
|
|
+- **代理名称**: James (Developer Agent)
|
|
|
+- **模型**: Claude Sonnet 4.5
|
|
|
+- **执行时间**: 2025-12-06
|
|
|
+
|
|
|
+### Debug Log References
|
|
|
+- 创建了完整的飞鹅打印多租户模块包结构
|
|
|
+- 实现了所有数据库实体(3个实体)
|
|
|
+- 实现了飞鹅API客户端服务
|
|
|
+- 实现了打印机管理服务
|
|
|
+- 实现了打印任务管理服务
|
|
|
+- 实现了防退款延迟打印调度器
|
|
|
+- 实现了API路由
|
|
|
+- 编写了单元测试和集成测试
|
|
|
+
|
|
|
+### Completion Notes List
|
|
|
+1. ✅ 任务1:创建多租户飞鹅打印模块包 (`@d8d/feie-printer-module-mt`)
|
|
|
+2. ✅ 任务2:实现数据库实体(3个实体文件)
|
|
|
+3. ✅ 任务3:实现飞鹅API客户端服务
|
|
|
+4. ✅ 任务4:实现打印机管理服务
|
|
|
+5. ✅ 任务5:实现打印任务管理服务
|
|
|
+6. ✅ 任务6:实现防退款延迟打印调度器
|
|
|
+7. ✅ 任务7:实现API路由
|
|
|
+8. ✅ 任务8:编写单元测试
|
|
|
+9. ✅ 执行完整验证和测试
|
|
|
+
|
|
|
+### File List
|
|
|
+**包结构文件**:
|
|
|
+- `packages/feie-printer-module-mt/package.json`
|
|
|
+- `packages/feie-printer-module-mt/tsconfig.json`
|
|
|
+- `packages/feie-printer-module-mt/vitest.config.ts`
|
|
|
+
|
|
|
+**源代码文件**:
|
|
|
+- `packages/feie-printer-module-mt/src/index.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/entities/feie-printer.mt.entity.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/entities/feie-print-task.mt.entity.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/entities/feie-config.mt.entity.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/entities/index.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/services/feie-api.service.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/services/printer.service.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/services/print-task.service.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/services/delay-scheduler.service.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/services/index.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/schemas/feie.schema.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/schemas/index.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/routes/feie.routes.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/routes/index.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/types/feie.types.ts`
|
|
|
+- `packages/feie-printer-module-mt/src/types/index.ts`
|
|
|
+
|
|
|
+**测试文件**:
|
|
|
+- `packages/feie-printer-module-mt/tests/unit/feie-api.service.test.ts`
|
|
|
+- `packages/feie-printer-module-mt/tests/unit/printer.service.test.ts`
|
|
|
+- `packages/feie-printer-module-mt/tests/unit/print-task.service.test.ts`
|
|
|
+- `packages/feie-printer-module-mt/tests/unit/delay-scheduler.service.test.ts`
|
|
|
+- `packages/feie-printer-module-mt/tests/integration/feie-api.integration.test.ts`
|
|
|
+
|
|
|
+## QA Results
|
|
|
+*此部分由QA代理在审查完成后填写*
|