Files
ccdi/doc/plans/2026-02-06-ccdi_purchase_transaction-deployment.md
2026-02-06 17:22:59 +08:00

16 KiB
Raw Blame History

员工采购交易信息管理功能 - 部署清单

功能状态: 开发完成,待部署

完成日期: 2026-02-06

实施方式: Subagent-Driven Development (21个任务全部完成)


📋 功能概览

核心功能

  • CRUD操作: 新增、修改、删除、查询采购交易信息
  • 分页查询: 支持多条件组合查询 + 日期范围筛选
  • 异步导入: 基于@Async + Redis的异步批量导入支持更新模式
  • 数据导出: 带字典下拉框的Excel导出
  • 模板下载: 带数据验证的导入模板
  • 批量删除: 支持多选删除
  • 失败记录: 导入失败记录存储7天支持查询

技术特性

  • 后端: Spring Boot 3.5.8 + MyBatis Plus 3.5.10 + EasyExcel + Redis
  • 前端: Vue 2.6.12 + Element UI 2.15.14 + Axios轮询
  • 数据库: MySQL 8.2.0 (4个业务索引优化)
  • 验证: Jakarta Validation + 自定义业务验证
  • 性能: 批量操作(500条/批) + 异步处理

📂 已创建文件清单

后端文件 (13个)

1. 实体层

ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/
├── domain/
│   ├── CcdiPurchaseTransaction.java                    # 实体类 (36字段)
│   ├── dto/
│   │   ├── CcdiPurchaseTransactionAddDTO.java          # 新增DTO (带验证)
│   │   ├── CcdiPurchaseTransactionEditDTO.java         # 编辑DTO (带验证)
│   │   └── CcdiPurchaseTransactionQueryDTO.java        # 查询DTO
│   ├── vo/
│   │   ├── CcdiPurchaseTransactionVO.java              # 返回VO
│   │   └── PurchaseTransactionImportFailureVO.java     # 导入失败VO (11字段)
│   └── excel/
│       └── CcdiPurchaseTransactionExcel.java           # Excel导入导出类

2. 持久层

ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/
├── mapper/
│   ├── CcdiPurchaseTransactionMapper.java              # Mapper接口
│   └── resources/mapper/ccdi/
│       └── CcdiPurchaseTransactionMapper.xml           # MyBatis XML映射

3. 服务层

ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/
├── service/
│   ├── ICcdiPurchaseTransactionService.java            # Service接口
│   ├── ICcdiPurchaseTransactionImportService.java     # 异步导入Service接口
│   └── impl/
│       ├── CcdiPurchaseTransactionServiceImpl.java     # Service实现 (Redis初始化已修复)
│       └── CcdiPurchaseTransactionImportServiceImpl.java # 异步导入实现

4. 控制层

ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/
└── controller/
    └── CcdiPurchaseTransactionController.java          # REST Controller (10接口)

前端文件 (2个)

ruoyi-ui/src/
├── api/
│   └── ccdiPurchaseTransaction.js                      # API封装 (10方法)
└── views/
    └── ccdiPurchaseTransaction/
        └── index.vue                                   # 页面组件 (1037行,含轮询)

数据库文件 (2个)

sql/
├── ccdi_purchase_transaction.sql                       # 表结构 (36字段 + 4索引)
└── ccdi_purchase_transaction_menu.sql                  # 菜单权限配置

文档文件 (4个)

doc/
├── api/
│   └── ccdi_purchase_transaction_api.md                # API文档 (752行)
├── plans/
│   ├── 2026-02-06-ccdi_purchase_transaction.md         # 实施计划
│   └── 2026-02-06-ccdi_purchase_transaction-verification.md # 验证清单 (888行)
└── test-data/
    └── purchase_transaction/
        └── README.md                                   # 测试指南 (379行)

🚀 部署步骤

Step 1: 数据库部署

# 1. 连接到MySQL数据库
mysql -u root -p

# 2. 选择数据库
use ruoyi;

# 3. 执行表创建脚本
source D:/ccdi/ccdi/sql/ccdi_purchase_transaction.sql;

# 4. 验证表是否创建成功
SHOW TABLES LIKE 'ccdi_purchase_transaction';

# 5. 查看表结构
DESC ccdi_purchase_transaction;

# 6. 查看索引
SHOW INDEX FROM ccdi_purchase_transaction;

预期输出:

  • 表包含36个字段
  • 4个业务索引: idx_applicant_id, idx_apply_date, idx_supplier_uscc, idx_category_method

Step 2: 菜单权限配置

# 执行菜单配置SQL
mysql -u root -p ruoyi < D:/ccdi/ccdi/sql/ccdi_purchase_transaction_menu.sql;

# 验证菜单是否插入成功
SELECT menu_id, menu_name, path, component
FROM sys_menu
WHERE menu_name = '采购交易管理';

预期输出:

  • 主菜单: 采购交易管理
  • 6个按钮权限: ccdi:purchaseTransaction:list/query/add/edit/remove/export/import

Step 3: 后端代码部署

方式A: 已有代码跳过 (推荐)

# 代码已存在于项目目录中,无需额外操作
cd ruoyi-ccdi
mvn clean compile  # 验证编译

方式B: 从Git拉取

git pull origin dev
cd ruoyi-ccdi
mvn clean compile

编译验证:

  • 无编译错误
  • 无警告信息
  • 所有依赖正常下载

Step 4: 后端服务启动

# 方式A: Maven启动 (开发环境)
cd ruoyi-admin
mvn spring-boot:run

# 方式B: JAR包启动 (生产环境)
mvn clean package
java -jar ruoyi-admin/target/ruoyi-admin.jar

# 方式C: IDEA启动
# 运行 RuoYiApplication.java

启动验证:

# 检查健康状态
curl http://localhost:8080/actuator/health

# 检查Swagger文档
# 浏览器访问: http://localhost:8080/swagger-ui/index.html

# 验证Controller接口
# 搜索 "采购交易信息管理" 标签应显示10个接口

Step 5: 前端代码部署

# 方式A: 开发环境启动
cd ruoyi-ui
npm install  # 首次需要安装依赖
npm run dev

# 方式B: 生产构建
npm run build:prod
# 生成的dist目录部署到Nginx

启动验证:

  • 前端地址: http://localhost (默认端口80)
  • 登录账号: admin / admin123
  • 检查左侧菜单是否显示 "采购交易管理"

Step 6: 功能测试验证

6.1 基础功能测试

测试项 操作 预期结果
页面访问 点击 "采购交易管理" 菜单 正常打开列表页面
查询功能 输入项目名称点击搜索 返回匹配数据
新增功能 点击新增,填写必填项提交 成功提示,列表刷新
编辑功能 修改某条记录,保存 成功提示,数据更新
删除功能 删除单条/多条记录 确认对话框,成功删除
导出功能 点击导出按钮 下载Excel文件
模板下载 点击导入→下载模板 下载带验证的模板

6.2 异步导入测试

# 1. 准备测试Excel文件 (包含5-10条测试数据)
#    - 必填字段: purchaseId, purchaseCategory, subjectName, purchaseQty, budgetAmount, purchaseMethod, applyDate, applicantId, applicantName, applyDepartment
#    - 工号格式: 7位数字 (如: 1234567)
#    - 金额: > 0

# 2. 测试纯新增导入
#    - 采购事项ID使用不存在的值 (如: TEST001, TEST002...)
#    - 不勾选 "更新支持"
#    - 预期: 全部成功导入

# 3. 测试更新导入
#    - 使用已存在的采购事项ID
#    - 勾选 "更新支持"
#    - 修改部分字段值
#    - 预期: 更新成功,旧数据被删除后重新插入

# 4. 测试失败记录
#    - 故意填错必填项 (如: 工号少于7位、金额<=0)
#    - 预期: 导入完成后显示失败记录列表

异步导入验证点:

  • 提交导入后立即返回taskId
  • 显示 "正在导入数据,请稍候..." 提示
  • 每2秒轮询一次状态
  • 导入完成后自动弹出结果对话框
  • 显示成功/失败数量统计
  • 失败记录显示详细错误信息
  • 列表自动刷新显示最新数据

6.3 Swagger接口测试

访问 http://localhost:8080/swagger-ui/index.html测试以下接口:

1. POST   /ccdi/purchaseTransaction                # 新增
2. PUT    /ccdi/purchaseTransaction                # 修改
3. GET    /ccdi/purchaseTransaction/{purchaseId}   # 查询详情
4. GET    /ccdi/purchaseTransaction/list           # 分页查询
5. DELETE /ccdi/purchaseTransaction/{purchaseIds}  # 删除
6. POST   /ccdi/purchaseTransaction/export         # 导出
7. POST   /ccdi/purchaseTransaction/importTemplate # 下载模板
8. POST   /ccdi/purchaseTransaction/importData     # 导入
9. GET    /ccdi/purchaseTransaction/importStatus/{taskId}      # 导入状态
10. GET   /ccdi/purchaseTransaction/importFailures/{taskId}    # 失败记录

🔍 关键代码验证点

后端核心验证

1. 异步导入服务 (CcdiPurchaseTransactionImportServiceImpl.java:46-114)

验证点:

  • @Async 注解启用异步
  • @Transactional 注解保证事务
  • 批量查询已存在的purchaseId (line 52)
  • 数据分类: newRecords/updateRecords/failures (line 47-49)
  • 批量插入: 500条/批 (line 92)
  • 批量更新: insertOrUpdateBatch (line 97)
  • 失败记录存Redis: 7天TTL (line 102-103)
  • 最终状态更新: SUCCESS/PARTIAL_SUCCESS (line 112)

2. Redis状态初始化 (CcdiPurchaseTransactionServiceImpl.java)

验证点:

  • 生成UUID作为taskId
  • 初始化Redis Hash结构
  • 设置7天过期时间
  • 调用异步服务前完成状态初始化

3. Controller接口 (CcdiPurchaseTransactionController.java)

验证点:

  • 10个REST接口完整
  • @PreAuthorize权限注解正确
  • @Operation Swagger注解完整
  • 导入接口返回taskId
  • 失败记录接口使用PurchaseTransactionImportFailureVO

前端核心验证

1. 异步导入轮询 (index.vue:834-880)

验证点:

  • handleFileSuccess 检查response.data.taskId (line 816)
  • startImportPolling 启动轮询 (line 835)
  • 立即查询一次 + 每2秒轮询 (line 844, 847)
  • checkImportStatus 检查completed/failed状态 (line 856-872)
  • 完成后清理定时器 (line 858)
  • beforeDestroy清理定时器防止内存泄漏 (line 652-657)

2. 失败记录展示 (index.vue:882-920)

验证点:

  • 显示成功/失败数量 (line 885-886)
  • 失败记录>0时调用getImportFailures (line 894)
  • 显示详细错误信息 (line 897-900)
  • 支持滚动查看 (max-height: 300px) (line 891)

📊 数据库结构验证

表结构确认

-- 查看表字段
DESC ccdi_purchase_transaction;

-- 应显示36个字段:
-- purchase_id (主键, VARCHAR(32))
-- purchase_category, project_name, subject_name, subject_desc
-- purchase_qty (DECIMAL(12,4))
-- budget_amount, bid_amount, actual_amount, contract_amount, settlement_amount (DECIMAL(18,2))
-- purchase_method
-- supplier_name, contact_person, contact_phone, supplier_uscc, supplier_bank_account
-- apply_date, plan_approve_date, announce_date, bid_open_date, contract_sign_date
-- expected_delivery_date, actual_delivery_date, acceptance_date, settlement_date
-- applicant_id, applicant_name, apply_department
-- purchase_leader_id, purchase_leader_name, purchase_department
-- create_time, update_time, created_by, updated_by

索引验证

-- 查看索引
SHOW INDEX FROM ccdi_purchase_transaction;

-- 应显示5个索引:
-- PRIMARY (purchase_id)
-- idx_applicant_id
-- idx_apply_date
-- idx_supplier_uscc
-- idx_category_method (purchase_category, purchase_method)

⚠️ 常见问题排查

问题1: 菜单不显示

现象: 登录后左侧菜单没有 "采购交易管理"

排查步骤:

-- 1. 检查菜单是否存在
SELECT * FROM sys_menu WHERE menu_name = '采购交易管理';

-- 2. 检查角色权限
SELECT * FROM sys_role_menu WHERE menu_id IN (
    SELECT menu_id FROM sys_menu WHERE menu_name LIKE '%采购交易%'
);

-- 3. 手动分配权限 (如果缺失)
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT 1, menu_id FROM sys_menu WHERE menu_name LIKE '%采购交易%';

问题2: 导入按钮点击无响应

现象: 点击导入按钮没反应

排查步骤:

  1. 检查浏览器控制台是否有错误
  2. 检查权限: ccdi:purchaseTransaction:import
  3. 检查API地址: /ccdi/purchaseTransaction/importData
  4. 检查后端日志是否接收请求

问题3: 导入一直显示"正在导入"

现象: 导入后轮询一直不停止

排查步骤:

# 1. 检查Redis是否运行
redis-cli ping

# 2. 检查Redis中的导入状态
redis-cli
> KEYS import:purchaseTransaction:*
> HGETALL import:purchaseTransaction:{taskId}

# 3. 检查异步方法是否正常执行
# 查看后端日志是否有异常堆栈

# 4. 检查@Async配置
# 确认 Spring Boot 主类有 @EnableAsync 注解

问题4: 导入失败记录不显示

现象: 导入部分成功,但不显示失败记录

排查步骤:

# 1. 检查Redis失败记录
redis-cli
> KEYS import:purchaseTransaction:*:failures
> GET import:purchaseTransaction:{taskId}:failures

# 2. 检查VO字段映射
# PurchaseTransactionImportFailureVO 应包含11个字段

# 3. 检查前端调用
# getImportFailures 是否正确传递taskId

问题5: 更新导入不生效

现象: 勾选"更新支持"后,数据仍不更新

排查步骤:

-- 1. 检查purchaseId是否存在
SELECT * FROM ccdi_purchase_transaction WHERE purchase_id = 'TEST001';

-- 2. 检查Mapper XML的insertOrUpdateBatch方法
-- 确认先DELETE后INSERT的逻辑

-- 3. 检查isUpdateSupport参数传递
-- 前端upload.updateSupport是否正确传递 (0或1)

验收清单

功能验收

  • 菜单正常显示
  • 列表查询正常
  • 新增功能正常
  • 修改功能正常
  • 删除功能正常 (单个/批量)
  • 导出功能正常
  • 导入模板下载正常
  • 纯新增导入正常
  • 更新导入正常 (先删后插)
  • 导入失败记录显示正常
  • 异步导入轮询正常
  • 金额格式化显示正常
  • 日期格式化显示正常
  • 表单验证正常
  • 权限控制正常

性能验收

  • 列表查询响应时间 < 1秒 (1000条数据)
  • 导入1000条数据 < 30秒
  • 导出1000条数据 < 10秒
  • 异步导入轮询不阻塞UI
  • 批量删除100条 < 2秒

安全验收

  • SQL注入防护 (MyBatis参数化查询)
  • XSS防护 (前端转义)
  • CSRF防护 (Token验证)
  • 权限验证 (@PreAuthorize)
  • 数据验证 (Jakarta Validation)
  • 审计日志 (@Log注解)

📝 部署后检查项

1. 数据库检查

-- 表是否存在
SHOW TABLES LIKE 'ccdi_purchase_transaction';

-- 记录数是否正常
SELECT COUNT(*) FROM ccdi_purchase_transaction;

-- 索引是否生效
SHOW INDEX FROM ccdi_purchase_transaction;

2. 后端服务检查

# 服务是否启动
curl http://localhost:8080/actuator/health

# Swagger文档是否可访问
curl http://localhost:8080/swagger-ui/index.html

# Controller是否注册
# 访问 /swagger-ui/index.html 搜索 "采购交易信息管理"

3. 前端页面检查

# 页面是否可访问
# 浏览器访问: http://localhost → 登录 → 点击 "采购交易管理"

# API请求是否正常
# 打开浏览器开发者工具 → Network → 查看XHR请求

4. Redis连接检查

# Redis是否运行
redis-cli ping

# 查看导入状态Key
redis-cli KEYS "import:purchaseTransaction:*"

📚 参考文档

  • 实施计划: doc/plans/2026-02-06-ccdi_purchase_transaction.md
  • 验证清单: doc/plans/2026-02-06-ccdi_purchase_transaction-verification.md
  • API文档: doc/api/ccdi_purchase_transaction_api.md
  • 测试指南: doc/test-data/purchase_transaction/README.md

🎯 部署成功标准

  1. 所有文件已创建并编译通过
  2. 数据库表和索引创建成功
  3. 菜单权限配置完成
  4. 后端服务启动成功
  5. 前端页面访问正常
  6. 10个REST接口测试通过
  7. 异步导入功能测试通过
  8. 所有验收检查项通过

📞 技术支持

问题反馈:

  • 查看后端日志: ruoyi-admin/logs/sys-info.log
  • 查看前端控制台: F12 → Console
  • 查看Redis状态: redis-cli monitor

关键文件位置:

  • Controller: ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/controller/CcdiPurchaseTransactionController.java
  • 异步Service: ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiPurchaseTransactionImportServiceImpl.java
  • 前端页面: ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue

部署完成后,请按照 doc/plans/2026-02-06-ccdi_purchase_transaction-verification.md 进行完整的验收测试。