596 lines
16 KiB
Markdown
596 lines
16 KiB
Markdown
# 员工采购交易信息管理功能 - 部署清单
|
||
|
||
> **功能状态**: ✅ 开发完成,待部署
|
||
>
|
||
> **完成日期**: 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: 数据库部署
|
||
|
||
```bash
|
||
# 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: 菜单权限配置
|
||
|
||
```bash
|
||
# 执行菜单配置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: 已有代码跳过 (推荐)
|
||
```bash
|
||
# 代码已存在于项目目录中,无需额外操作
|
||
cd ruoyi-ccdi
|
||
mvn clean compile # 验证编译
|
||
```
|
||
|
||
#### 方式B: 从Git拉取
|
||
```bash
|
||
git pull origin dev
|
||
cd ruoyi-ccdi
|
||
mvn clean compile
|
||
```
|
||
|
||
**编译验证**:
|
||
- 无编译错误
|
||
- 无警告信息
|
||
- 所有依赖正常下载
|
||
|
||
### Step 4: 后端服务启动
|
||
|
||
```bash
|
||
# 方式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
|
||
```
|
||
|
||
**启动验证**:
|
||
```bash
|
||
# 检查健康状态
|
||
curl http://localhost:8080/actuator/health
|
||
|
||
# 检查Swagger文档
|
||
# 浏览器访问: http://localhost:8080/swagger-ui/index.html
|
||
|
||
# 验证Controller接口
|
||
# 搜索 "采购交易信息管理" 标签,应显示10个接口
|
||
```
|
||
|
||
### Step 5: 前端代码部署
|
||
|
||
```bash
|
||
# 方式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 异步导入测试
|
||
|
||
```bash
|
||
# 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)
|
||
|
||
---
|
||
|
||
## 📊 数据库结构验证
|
||
|
||
### 表结构确认
|
||
|
||
```sql
|
||
-- 查看表字段
|
||
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
|
||
```
|
||
|
||
### 索引验证
|
||
|
||
```sql
|
||
-- 查看索引
|
||
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: 菜单不显示
|
||
|
||
**现象**: 登录后左侧菜单没有 "采购交易管理"
|
||
|
||
**排查步骤**:
|
||
```sql
|
||
-- 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: 导入一直显示"正在导入"
|
||
|
||
**现象**: 导入后轮询一直不停止
|
||
|
||
**排查步骤**:
|
||
```bash
|
||
# 1. 检查Redis是否运行
|
||
redis-cli ping
|
||
|
||
# 2. 检查Redis中的导入状态
|
||
redis-cli
|
||
> KEYS import:purchaseTransaction:*
|
||
> HGETALL import:purchaseTransaction:{taskId}
|
||
|
||
# 3. 检查异步方法是否正常执行
|
||
# 查看后端日志是否有异常堆栈
|
||
|
||
# 4. 检查@Async配置
|
||
# 确认 Spring Boot 主类有 @EnableAsync 注解
|
||
```
|
||
|
||
### 问题4: 导入失败记录不显示
|
||
|
||
**现象**: 导入部分成功,但不显示失败记录
|
||
|
||
**排查步骤**:
|
||
```bash
|
||
# 1. 检查Redis失败记录
|
||
redis-cli
|
||
> KEYS import:purchaseTransaction:*:failures
|
||
> GET import:purchaseTransaction:{taskId}:failures
|
||
|
||
# 2. 检查VO字段映射
|
||
# PurchaseTransactionImportFailureVO 应包含11个字段
|
||
|
||
# 3. 检查前端调用
|
||
# getImportFailures 是否正确传递taskId
|
||
```
|
||
|
||
### 问题5: 更新导入不生效
|
||
|
||
**现象**: 勾选"更新支持"后,数据仍不更新
|
||
|
||
**排查步骤**:
|
||
```sql
|
||
-- 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. 数据库检查
|
||
|
||
```sql
|
||
-- 表是否存在
|
||
SHOW TABLES LIKE 'ccdi_purchase_transaction';
|
||
|
||
-- 记录数是否正常
|
||
SELECT COUNT(*) FROM ccdi_purchase_transaction;
|
||
|
||
-- 索引是否生效
|
||
SHOW INDEX FROM ccdi_purchase_transaction;
|
||
```
|
||
|
||
### 2. 后端服务检查
|
||
|
||
```bash
|
||
# 服务是否启动
|
||
curl http://localhost:8080/actuator/health
|
||
|
||
# Swagger文档是否可访问
|
||
curl http://localhost:8080/swagger-ui/index.html
|
||
|
||
# Controller是否注册
|
||
# 访问 /swagger-ui/index.html 搜索 "采购交易信息管理"
|
||
```
|
||
|
||
### 3. 前端页面检查
|
||
|
||
```bash
|
||
# 页面是否可访问
|
||
# 浏览器访问: http://localhost → 登录 → 点击 "采购交易管理"
|
||
|
||
# API请求是否正常
|
||
# 打开浏览器开发者工具 → Network → 查看XHR请求
|
||
```
|
||
|
||
### 4. Redis连接检查
|
||
|
||
```bash
|
||
# 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` 进行完整的验收测试。**
|