新增项目打标状态联动实施计划
This commit is contained in:
@@ -0,0 +1,506 @@
|
||||
# Project Bank Tag Status Lock Backend Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 让项目在银行流水打标开始时进入“打标中”,在成功后进入“已完成”、失败后回退为“进行中”,并由后端统一拦截打标期间的上传、拉取本行信息和参数修改操作。
|
||||
|
||||
**Architecture:** 以 `ccdi_project.status` 作为唯一业务状态源,在项目模块中补充统一状态更新能力,由 `CcdiBankTagServiceImpl` 和 `ProjectBankTagRebuildCoordinator` 复用;上传与参数服务在进入写操作前统一校验项目状态;SQL 通过增量脚本补齐状态字典,并同步更新初始化脚本和单元测试。
|
||||
|
||||
**Tech Stack:** Java 21, Spring Boot 3, MyBatis Plus, JUnit 5, Mockito, Maven, MySQL SQL migration
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 补齐项目状态 SQL 与字典基线
|
||||
|
||||
**Files:**
|
||||
- Modify: `sql/ccdi_project.sql`
|
||||
- Create: `sql/migration/2026-03-18-add-project-tagging-status.sql`
|
||||
- Create: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/sql/CcdiProjectStatusSqlTest.java`
|
||||
|
||||
- [ ] **Step 1: Write the failing test**
|
||||
|
||||
先新增 `CcdiProjectStatusSqlTest`,锁定初始化脚本和增量脚本都必须包含 `3-打标中`:
|
||||
|
||||
```java
|
||||
class CcdiProjectStatusSqlTest {
|
||||
|
||||
@Test
|
||||
void shouldContainTaggingStatusInInitAndMigrationSql() throws Exception {
|
||||
String initSql = Files.readString(Path.of("sql/ccdi_project.sql"));
|
||||
String migrationSql = Files.readString(Path.of("sql/migration/2026-03-18-add-project-tagging-status.sql"));
|
||||
|
||||
assertTrue(initSql.contains("打标中"));
|
||||
assertTrue(initSql.contains("'3'"));
|
||||
assertTrue(migrationSql.contains("ccdi_project_status"));
|
||||
assertTrue(migrationSql.contains("打标中"));
|
||||
assertTrue(migrationSql.contains("'3'"));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-project -Dtest=CcdiProjectStatusSqlTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `FAIL`
|
||||
- 原因是测试类和增量 SQL 还不存在,初始化脚本也尚未包含状态 `3`
|
||||
|
||||
- [ ] **Step 3: Write minimal implementation**
|
||||
|
||||
最小实现包括两部分:
|
||||
|
||||
1. 在 `sql/ccdi_project.sql` 中把状态注释和状态字典更新为:
|
||||
|
||||
```sql
|
||||
`status` CHAR(1) NOT NULL DEFAULT '0' COMMENT '项目状态:0-进行中,1-已完成,2-已归档,3-打标中'
|
||||
```
|
||||
|
||||
```sql
|
||||
(4, '打标中', '3', 'ccdi_project_status', '', 'warning', 'N', '0', 'admin', NOW());
|
||||
```
|
||||
|
||||
2. 新增增量脚本 `sql/migration/2026-03-18-add-project-tagging-status.sql`,包含:
|
||||
|
||||
```sql
|
||||
ALTER TABLE ccdi_project
|
||||
MODIFY COLUMN status CHAR(1) NOT NULL DEFAULT '0' COMMENT '项目状态:0-进行中,1-已完成,2-已归档,3-打标中';
|
||||
|
||||
INSERT INTO sys_dict_data (...)
|
||||
SELECT ...
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM sys_dict_data WHERE dict_type = 'ccdi_project_status' AND dict_value = '3'
|
||||
);
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Run test to verify it passes**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-project -Dtest=CcdiProjectStatusSqlTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `PASS`
|
||||
- 说明新环境脚本和增量脚本都已统一包含“打标中”
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add sql/ccdi_project.sql sql/migration/2026-03-18-add-project-tagging-status.sql ccdi-project/src/test/java/com/ruoyi/ccdi/project/sql/CcdiProjectStatusSqlTest.java
|
||||
git commit -m "补充项目打标中状态SQL基线"
|
||||
```
|
||||
|
||||
### Task 2: 增加项目状态统一更新能力、写保护能力与状态统计扩展
|
||||
|
||||
**Files:**
|
||||
- Create: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/constants/CcdiProjectStatusConstants.java`
|
||||
- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/CcdiProject.java`
|
||||
- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectStatusCountsVO.java`
|
||||
- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectService.java`
|
||||
- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectServiceImpl.java`
|
||||
- Create: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectServiceImplTest.java`
|
||||
|
||||
- [ ] **Step 1: Write the failing test**
|
||||
|
||||
新增 `CcdiProjectServiceImplTest`,先锁定三个核心行为:状态统计要包含 `status3`,已归档项目不能重新进入打标,打标中项目不能继续写入上传/参数数据。
|
||||
|
||||
```java
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CcdiProjectServiceImplTest {
|
||||
|
||||
@InjectMocks
|
||||
private CcdiProjectServiceImpl service;
|
||||
|
||||
@Mock
|
||||
private CcdiProjectMapper projectMapper;
|
||||
|
||||
@Test
|
||||
void shouldCountTaggingProjectsSeparately() {
|
||||
when(projectMapper.selectCount(any())).thenReturn(10L, 3L, 4L, 2L, 1L);
|
||||
|
||||
CcdiProjectStatusCountsVO counts = service.getStatusCounts();
|
||||
|
||||
assertEquals(1L, counts.getStatus3());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectUpdatingArchivedProjectToTagging() {
|
||||
CcdiProject archived = new CcdiProject();
|
||||
archived.setProjectId(99L);
|
||||
archived.setStatus("2");
|
||||
when(projectMapper.selectById(99L)).thenReturn(archived);
|
||||
|
||||
assertThrows(ServiceException.class,
|
||||
() -> service.updateProjectStatus(99L, "3", "system"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectWritingWhenProjectIsTagging() {
|
||||
CcdiProject tagging = new CcdiProject();
|
||||
tagging.setProjectId(40L);
|
||||
tagging.setStatus("3");
|
||||
when(projectMapper.selectById(40L)).thenReturn(tagging);
|
||||
|
||||
assertThrows(ServiceException.class,
|
||||
() -> service.ensureProjectWritable(40L, "当前项目正在进行银行流水打标,暂不允许修改参数"));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-project -Dtest=CcdiProjectServiceImplTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `FAIL`
|
||||
- 原因是 `status3` 统计字段和统一状态更新方法尚未实现
|
||||
|
||||
- [ ] **Step 3: Write minimal implementation**
|
||||
|
||||
最小实现建议:
|
||||
|
||||
1. 新增状态常量类:
|
||||
|
||||
```java
|
||||
public final class CcdiProjectStatusConstants {
|
||||
public static final String PROCESSING = "0";
|
||||
public static final String COMPLETED = "1";
|
||||
public static final String ARCHIVED = "2";
|
||||
public static final String TAGGING = "3";
|
||||
}
|
||||
```
|
||||
|
||||
2. 在 `ICcdiProjectService` / `CcdiProjectServiceImpl` 中新增 3 个统一能力:
|
||||
|
||||
```java
|
||||
void updateProjectStatus(Long projectId, String status, String operator);
|
||||
void ensureProjectCanStartTagging(Long projectId);
|
||||
void ensureProjectWritable(Long projectId, String message);
|
||||
```
|
||||
|
||||
```java
|
||||
public void updateProjectStatus(Long projectId, String status, String operator) {
|
||||
CcdiProject project = getRequiredProject(projectId);
|
||||
if (CcdiProjectStatusConstants.ARCHIVED.equals(project.getStatus())
|
||||
&& !CcdiProjectStatusConstants.ARCHIVED.equals(status)) {
|
||||
throw new ServiceException("已归档项目不允许重新进入打标流程");
|
||||
}
|
||||
project.setStatus(status);
|
||||
project.setUpdateBy(operator);
|
||||
projectMapper.updateById(project);
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
public void ensureProjectCanStartTagging(Long projectId) {
|
||||
CcdiProject project = getRequiredProject(projectId);
|
||||
if (CcdiProjectStatusConstants.ARCHIVED.equals(project.getStatus())) {
|
||||
throw new ServiceException("已归档项目不允许重新进入打标流程");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
public void ensureProjectWritable(Long projectId, String message) {
|
||||
CcdiProject project = getRequiredProject(projectId);
|
||||
if (CcdiProjectStatusConstants.TAGGING.equals(project.getStatus())) {
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. 扩展状态统计:
|
||||
|
||||
```java
|
||||
private Long status3;
|
||||
```
|
||||
|
||||
```java
|
||||
vo.setStatus3(projectMapper.selectCount(
|
||||
new LambdaQueryWrapper<CcdiProject>().eq(CcdiProject::getStatus, CcdiProjectStatusConstants.TAGGING)
|
||||
));
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Run test to verify it passes**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-project -Dtest=CcdiProjectServiceImplTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `PASS`
|
||||
- 说明统一状态更新能力和 `打标中` 统计口径已成立
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/constants/CcdiProjectStatusConstants.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/CcdiProject.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectStatusCountsVO.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectService.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectServiceImpl.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectServiceImplTest.java
|
||||
git commit -m "新增项目状态统一更新能力"
|
||||
```
|
||||
|
||||
### Task 3: 将打标任务状态流转接入项目状态
|
||||
|
||||
**Files:**
|
||||
- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiBankTagServiceImpl.java`
|
||||
- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/ProjectBankTagRebuildCoordinator.java`
|
||||
- Modify: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiBankTagServiceImplTest.java`
|
||||
- Modify: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/ProjectBankTagRebuildCoordinatorTest.java`
|
||||
|
||||
- [ ] **Step 1: Write the failing test**
|
||||
|
||||
先在 `CcdiBankTagServiceImplTest` 中锁定成功与失败两条状态流转,再在协调器测试里锁定已归档项目不能重入:
|
||||
|
||||
```java
|
||||
@Test
|
||||
void shouldMarkProjectTaggingBeforeExecutingAndCompletedAfterSuccess() {
|
||||
...
|
||||
service.rebuildProject(40L, null, "tester", TriggerType.MANUAL);
|
||||
|
||||
InOrder inOrder = inOrder(projectService, taskMapper);
|
||||
inOrder.verify(projectService).updateProjectStatus(40L, "3", "tester");
|
||||
inOrder.verify(taskMapper).updateTask(argThat(task -> "SUCCESS".equals(task.getStatus())));
|
||||
inOrder.verify(projectService).updateProjectStatus(40L, "1", "tester");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRollbackProjectStatusToProcessingWhenRebuildFails() {
|
||||
...
|
||||
assertThrows(RuntimeException.class,
|
||||
() -> service.rebuildProject(40L, null, "tester", TriggerType.MANUAL));
|
||||
|
||||
verify(projectService).updateProjectStatus(40L, "0", "tester");
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
@Test
|
||||
void shouldRejectSubmittingRebuildForArchivedProject() {
|
||||
doThrow(new ServiceException("已归档项目不允许重新进入打标流程"))
|
||||
.when(projectService).ensureProjectCanStartTagging(40L);
|
||||
|
||||
assertThrows(ServiceException.class,
|
||||
() -> coordinator.submitManual(40L, null, "tester"));
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-project -Dtest=CcdiBankTagServiceImplTest,ProjectBankTagRebuildCoordinatorTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `FAIL`
|
||||
- 原因是打标服务还没有调用项目状态更新能力
|
||||
|
||||
- [ ] **Step 3: Write minimal implementation**
|
||||
|
||||
实现要点:
|
||||
|
||||
1. 在 `CcdiBankTagServiceImpl` 注入项目服务,并在 `rebuildProject(...)` 中按顺序调用:
|
||||
|
||||
```java
|
||||
projectService.updateProjectStatus(projectId, CcdiProjectStatusConstants.TAGGING, operator);
|
||||
```
|
||||
|
||||
```java
|
||||
projectService.updateProjectStatus(projectId, CcdiProjectStatusConstants.COMPLETED, operator);
|
||||
```
|
||||
|
||||
```java
|
||||
projectService.updateProjectStatus(projectId, CcdiProjectStatusConstants.PROCESSING, operator);
|
||||
```
|
||||
|
||||
2. 在 `ProjectBankTagRebuildCoordinator` 中增加前置校验,避免已归档项目进入重算:
|
||||
|
||||
```java
|
||||
projectService.ensureProjectCanStartTagging(projectId);
|
||||
```
|
||||
|
||||
3. 保持 `needRerun` 机制不变,但不要在补跑期间把状态提前切回非 `3`
|
||||
|
||||
- [ ] **Step 4: Run test to verify it passes**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-project -Dtest=CcdiBankTagServiceImplTest,ProjectBankTagRebuildCoordinatorTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `PASS`
|
||||
- 说明手工与自动打标共用的重算主链路已经接入项目状态流转
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiBankTagServiceImpl.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/ProjectBankTagRebuildCoordinator.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiBankTagServiceImplTest.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/ProjectBankTagRebuildCoordinatorTest.java
|
||||
git commit -m "接入项目打标状态流转"
|
||||
```
|
||||
|
||||
### Task 4: 在上传与参数保存链路中拦截“打标中”写操作
|
||||
|
||||
**Files:**
|
||||
- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiFileUploadServiceImpl.java`
|
||||
- Modify: `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImpl.java`
|
||||
- Modify: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiFileUploadServiceImplTest.java`
|
||||
- Modify: `ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImplTest.java`
|
||||
|
||||
- [ ] **Step 1: Write the failing test**
|
||||
|
||||
先补两组服务层测试:
|
||||
|
||||
```java
|
||||
@Test
|
||||
void shouldRejectPullBankInfoWhenProjectIsTagging() {
|
||||
CcdiProject project = new CcdiProject();
|
||||
project.setProjectId(40L);
|
||||
project.setStatus("3");
|
||||
when(projectMapper.selectById(40L)).thenReturn(project);
|
||||
|
||||
assertThrows(ServiceException.class,
|
||||
() -> service.submitPullBankInfo(40L, List.of("3301"), "2026-01-01", "2026-01-31", 1L, "tester"));
|
||||
}
|
||||
```
|
||||
|
||||
```java
|
||||
@Test
|
||||
void shouldRejectSaveAllParamsWhenProjectIsTagging() {
|
||||
CcdiProject project = new CcdiProject();
|
||||
project.setProjectId(40L);
|
||||
project.setStatus("3");
|
||||
when(projectMapper.selectById(40L)).thenReturn(project);
|
||||
|
||||
assertThrows(ServiceException.class, () -> service.saveAllParams(buildSaveAllDto()));
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run test to verify it fails**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-project -Dtest=CcdiFileUploadServiceImplTest,CcdiModelParamServiceImplTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `FAIL`
|
||||
- 原因是当前上传和参数服务没有“打标中”拦截
|
||||
|
||||
- [ ] **Step 3: Write minimal implementation**
|
||||
|
||||
在两个服务中增加统一状态校验,优先复用项目服务:
|
||||
|
||||
```java
|
||||
projectService.ensureProjectWritable(projectId, "当前项目正在进行银行流水打标,暂不允许上传或拉取数据");
|
||||
```
|
||||
|
||||
```java
|
||||
projectService.ensureProjectWritable(projectId, "当前项目正在进行银行流水打标,暂不允许修改参数");
|
||||
```
|
||||
|
||||
若不额外新增专门方法,至少要抽一个私有校验函数,避免状态字符串判断散落在多个类中。
|
||||
|
||||
- [ ] **Step 4: Run test to verify it passes**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-project -Dtest=CcdiFileUploadServiceImplTest,CcdiModelParamServiceImplTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `PASS`
|
||||
- 说明后端已经能兜底拒绝打标期间的输入变更
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiFileUploadServiceImpl.java ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImpl.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiFileUploadServiceImplTest.java ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiModelParamServiceImplTest.java
|
||||
git commit -m "拦截项目打标中的上传与参数修改"
|
||||
```
|
||||
|
||||
### Task 5: 完成回归验证、SQL 执行说明与实施记录
|
||||
|
||||
**Files:**
|
||||
- Create: `docs/tests/records/2026-03-18-project-bank-tag-status-lock-backend-verification.md`
|
||||
- Create: `docs/reports/implementation/2026-03-18-project-bank-tag-status-lock-backend-implementation.md`
|
||||
|
||||
- [ ] **Step 1: Prepare backend verification record**
|
||||
|
||||
先创建验证记录,至少包含以下检查项:
|
||||
|
||||
```markdown
|
||||
# 项目打标状态联动后端验证记录
|
||||
|
||||
## 验证项
|
||||
- [ ] 状态 `3-打标中` SQL 已同步
|
||||
- [ ] 打标成功后状态为 `1`
|
||||
- [ ] 打标失败后状态回退为 `0`
|
||||
- [ ] 打标中拒绝上传/拉取本行信息
|
||||
- [ ] 打标中拒绝参数保存
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run focused backend regression**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
mvn -pl ccdi-project -Dtest=CcdiProjectServiceImplTest,CcdiBankTagServiceImplTest,ProjectBankTagRebuildCoordinatorTest,CcdiFileUploadServiceImplTest,CcdiModelParamServiceImplTest,CcdiProjectStatusSqlTest test
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- 所有相关测试 `PASS`
|
||||
|
||||
如需在联调环境执行 SQL,必须使用:
|
||||
|
||||
```bash
|
||||
bin/mysql_utf8_exec.sh sql/migration/2026-03-18-add-project-tagging-status.sql
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Write implementation report**
|
||||
|
||||
在实施报告中记录:
|
||||
|
||||
- 新增状态 `3-打标中`
|
||||
- 打标状态流转接入的主链路
|
||||
- 上传/参数保存拦截点
|
||||
- 测试结果与 SQL 执行方式
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add docs/tests/records/2026-03-18-project-bank-tag-status-lock-backend-verification.md docs/reports/implementation/2026-03-18-project-bank-tag-status-lock-backend-implementation.md
|
||||
git commit -m "补充项目打标状态联动后端验证记录"
|
||||
```
|
||||
|
||||
## Backend Exit Criteria
|
||||
|
||||
- `ccdi_project.status` 和 `ccdi_project_status` 字典都支持 `3-打标中`
|
||||
- 所有银行流水打标入口都会先把项目置为 `3`
|
||||
- 打标成功后落为 `1`,失败后回退为 `0`
|
||||
- 打标期间上传、拉取本行信息、参数保存都会被后端拒绝
|
||||
- 后端测试、SQL 说明、实施记录都已补齐
|
||||
@@ -0,0 +1,317 @@
|
||||
# Project Bank Tag Status Lock Frontend Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 在项目列表与项目详情中展示“打标中”状态,并在项目打标期间禁用上传数据页的拉取/上传入口以及参数模型页的修改入口。
|
||||
|
||||
**Architecture:** 以前端现有的 `projectInfo.projectStatus` 为统一判断条件,扩展列表页、详情页和状态统计对状态 `3` 的展示;在 `UploadData.vue` 和 `ParamConfig.vue` 中基于同一状态进入受限/只读态;同时补一个轻量的项目详情刷新链路,确保提交上传或拉取任务后页面能够尽快拿到后端返回的最新状态。仓库当前没有现成的 Vue 单测基建,本计划以 `npm run build:prod` 加手工联调记录替代自动化前端单测。
|
||||
|
||||
**Tech Stack:** Vue 2, Element UI, Axios request wrapper, Node.js, npm
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 扩展项目列表、详情页与状态统计对“打标中”的展示
|
||||
|
||||
**Files:**
|
||||
- Modify: `ruoyi-ui/src/views/ccdiProject/detail.vue`
|
||||
- Modify: `ruoyi-ui/src/views/ccdiProject/index.vue`
|
||||
- Modify: `ruoyi-ui/src/views/ccdiProject/components/ProjectTable.vue`
|
||||
- Modify: `ruoyi-ui/src/views/ccdiProject/components/SearchBar.vue`
|
||||
- Create: `docs/tests/records/2026-03-18-project-bank-tag-status-lock-frontend-verification.md`
|
||||
|
||||
- [ ] **Step 1: Write the verification record skeleton**
|
||||
|
||||
先创建联调记录,明确本次前端验证点:
|
||||
|
||||
```markdown
|
||||
# 项目打标状态联动前端验证记录
|
||||
|
||||
## 验证范围
|
||||
- 列表页状态与统计显示
|
||||
- 详情页状态标签
|
||||
- 上传数据页禁用
|
||||
- 参数模型页只读
|
||||
|
||||
## 验证结果
|
||||
- [ ] 列表页出现“打标中”
|
||||
- [ ] 顶部统计出现“打标中”
|
||||
- [ ] 详情页出现“打标中”
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run baseline build check before edits**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd ruoyi-ui
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- 当前前端代码可以正常构建
|
||||
- 作为后续改动的基线
|
||||
|
||||
- [ ] **Step 3: Write minimal implementation**
|
||||
|
||||
按最小范围扩展前端状态映射:
|
||||
|
||||
1. `detail.vue` 中把状态映射补到 `3`
|
||||
|
||||
```js
|
||||
const statusMap = {
|
||||
0: "进行中",
|
||||
1: "已完成",
|
||||
2: "已归档",
|
||||
3: "打标中"
|
||||
}
|
||||
```
|
||||
|
||||
2. `ProjectTable.vue` 中补充 `3` 的颜色和操作显隐
|
||||
3. `index.vue` / `SearchBar.vue` 中把 `tabCounts` 和 tabs 扩展到 `3`
|
||||
|
||||
- [ ] **Step 4: Run build to verify it passes**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd ruoyi-ui
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `PASS`
|
||||
- 说明新增状态展示不会破坏现有页面构建
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ui/src/views/ccdiProject/detail.vue ruoyi-ui/src/views/ccdiProject/index.vue ruoyi-ui/src/views/ccdiProject/components/ProjectTable.vue ruoyi-ui/src/views/ccdiProject/components/SearchBar.vue docs/tests/records/2026-03-18-project-bank-tag-status-lock-frontend-verification.md
|
||||
git commit -m "补充前端项目打标中状态展示"
|
||||
```
|
||||
|
||||
### Task 2: 让上传数据页在“打标中”进入受限态
|
||||
|
||||
**Files:**
|
||||
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
|
||||
- Modify: `ruoyi-ui/src/views/ccdiProject/detail.vue`
|
||||
|
||||
- [ ] **Step 1: Define the failing interaction expectation**
|
||||
|
||||
先把联调记录里的受限行为补完整,锁定以下结果必须成立:
|
||||
|
||||
```markdown
|
||||
- [ ] 打标中时“拉取本行信息”按钮禁用
|
||||
- [ ] 打标中时“上传流水”按钮禁用
|
||||
- [ ] 打标中时仍可查看上传记录列表
|
||||
- [ ] 页面有明确提示文案
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Reproduce current behavior manually**
|
||||
|
||||
手工确认当前页面在 `projectStatus = '3'` 时仍然可以点击:
|
||||
|
||||
1. 打开项目详情页“上传数据”
|
||||
2. 通过 mock `projectInfo.projectStatus = '3'` 或联调真实数据观察页面
|
||||
3. 记录当前“拉取本行信息”和“上传流水”仍可点击的现状
|
||||
|
||||
Expected:
|
||||
|
||||
- 当前行为与需求不符,作为修改前基线
|
||||
|
||||
- [ ] **Step 3: Write minimal implementation**
|
||||
|
||||
在 `UploadData.vue` 中增加统一计算属性,例如:
|
||||
|
||||
```js
|
||||
computed: {
|
||||
isProjectTagging() {
|
||||
return String(this.projectInfo.projectStatus) === "3";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
再基于同一条件处理:
|
||||
|
||||
- 顶部 `拉取本行信息` 按钮 `:disabled="isProjectTagging"`
|
||||
- 流水导入卡片 `disabled: this.isProjectTagging`
|
||||
- 打开弹窗前再次短路返回,避免旧状态下已打开页面绕过按钮禁用
|
||||
- 页面顶部补一句提示,例如:
|
||||
|
||||
```html
|
||||
<div v-if="isProjectTagging" class="tagging-lock-tip">
|
||||
项目正在进行银行流水打标,暂不可上传或拉取数据。
|
||||
</div>
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Run build to verify it passes**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd ruoyi-ui
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `PASS`
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue ruoyi-ui/src/views/ccdiProject/detail.vue docs/tests/records/2026-03-18-project-bank-tag-status-lock-frontend-verification.md
|
||||
git commit -m "限制前端打标中的上传数据操作"
|
||||
```
|
||||
|
||||
### Task 3: 让参数模型页在“打标中”进入只读态
|
||||
|
||||
**Files:**
|
||||
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/ParamConfig.vue`
|
||||
|
||||
- [ ] **Step 1: Define the failing interaction expectation**
|
||||
|
||||
在联调记录中增加参数页检查项:
|
||||
|
||||
```markdown
|
||||
- [ ] 打标中时参数输入框禁用
|
||||
- [ ] 打标中时“保存所有修改”按钮禁用
|
||||
- [ ] 参数页有只读提示文案
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Reproduce current editable behavior**
|
||||
|
||||
手工确认当前 `projectStatus = '3'` 时:
|
||||
|
||||
- 参数输入框仍可编辑
|
||||
- 保存按钮仍可点击
|
||||
|
||||
Expected:
|
||||
|
||||
- 当前行为与需求不符
|
||||
|
||||
- [ ] **Step 3: Write minimal implementation**
|
||||
|
||||
在 `ParamConfig.vue` 中增加:
|
||||
|
||||
```js
|
||||
computed: {
|
||||
isProjectTagging() {
|
||||
return String(this.projectInfo.projectStatus) === "3";
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
并将其接到:
|
||||
|
||||
- 参数输入框 `:disabled="isProjectTagging"`
|
||||
- 保存按钮 `:disabled="isProjectTagging || saving"`
|
||||
- 顶部/底部提示文案:
|
||||
|
||||
```html
|
||||
<div v-if="isProjectTagging" class="readonly-tip">
|
||||
项目正在进行银行流水打标,参数暂不可修改。
|
||||
</div>
|
||||
```
|
||||
|
||||
- [ ] **Step 4: Run build to verify it passes**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd ruoyi-ui
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
Expected:
|
||||
|
||||
- `PASS`
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ui/src/views/ccdiProject/components/detail/ParamConfig.vue docs/tests/records/2026-03-18-project-bank-tag-status-lock-frontend-verification.md
|
||||
git commit -m "限制前端打标中的参数修改"
|
||||
```
|
||||
|
||||
### Task 4: 补项目状态刷新链路并完成联调验证
|
||||
|
||||
**Files:**
|
||||
- Modify: `ruoyi-ui/src/views/ccdiProject/detail.vue`
|
||||
- Modify: `ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue`
|
||||
- Modify: `docs/tests/records/2026-03-18-project-bank-tag-status-lock-frontend-verification.md`
|
||||
- Create: `docs/reports/implementation/2026-03-18-project-bank-tag-status-lock-frontend-implementation.md`
|
||||
|
||||
- [ ] **Step 1: Write the refresh expectation**
|
||||
|
||||
先在验证记录里加上刷新口径:
|
||||
|
||||
```markdown
|
||||
- [ ] 提交上传或拉取任务后,详情页能重新获取项目状态
|
||||
- [ ] 文件轮询期间如后端状态切为“打标中”,页面会同步受限
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Write minimal implementation**
|
||||
|
||||
建议增加一个轻量的父子联动:
|
||||
|
||||
1. `detail.vue` 监听子组件的 `refresh-project` 事件:
|
||||
|
||||
```html
|
||||
<component
|
||||
...
|
||||
@refresh-project="handleRefresh"
|
||||
/>
|
||||
```
|
||||
|
||||
2. `UploadData.vue` 在这些时机 `this.$emit("refresh-project")`:
|
||||
|
||||
- 批量上传提交成功后
|
||||
- 拉取本行信息提交成功后
|
||||
- 轮询到文件状态变化后
|
||||
- 手工刷新文件列表后
|
||||
|
||||
目标不是做实时推送,而是复用现有轮询时机把 `projectInfo` 更新到最新。
|
||||
|
||||
- [ ] **Step 3: Run build and manual verification**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd ruoyi-ui
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
手工联调建议:
|
||||
|
||||
1. 启动后端、前端、Mock 服务
|
||||
2. 打开一个项目详情页
|
||||
3. 触发上传流水或拉取本行信息
|
||||
4. 等待后端进入打标流程
|
||||
5. 验证页面状态变为“打标中”,上传/拉取被禁用,参数页只读
|
||||
6. 验证列表页和顶部统计刷新后可显示“打标中”
|
||||
|
||||
完成验证后,按仓库要求关闭测试过程中启动的前后端进程。
|
||||
|
||||
- [ ] **Step 4: Write implementation report and commit**
|
||||
|
||||
实施报告至少记录:
|
||||
|
||||
- 哪些页面补了 `3-打标中`
|
||||
- 哪些按钮/输入框在打标中被禁用
|
||||
- 项目状态刷新是如何接入的
|
||||
- `npm run build:prod` 和手工联调结果
|
||||
|
||||
```bash
|
||||
git add ruoyi-ui/src/views/ccdiProject/detail.vue ruoyi-ui/src/views/ccdiProject/components/detail/UploadData.vue docs/tests/records/2026-03-18-project-bank-tag-status-lock-frontend-verification.md docs/reports/implementation/2026-03-18-project-bank-tag-status-lock-frontend-implementation.md
|
||||
git commit -m "补充前端项目打标状态联动验证"
|
||||
```
|
||||
|
||||
## Frontend Exit Criteria
|
||||
|
||||
- 列表页、详情页、状态统计都能正确展示 `3-打标中`
|
||||
- 上传数据页在 `3` 状态下禁用上传/拉取入口并给出提示
|
||||
- 参数模型页在 `3` 状态下进入只读态
|
||||
- 提交上传或拉取任务后,详情页能重新拿到最新项目状态
|
||||
- 前端构建通过,联调记录与实施报告已补齐
|
||||
@@ -0,0 +1,18 @@
|
||||
# 项目银行流水打标状态联动实施计划产出记录
|
||||
|
||||
## 变更概述
|
||||
|
||||
- 基于已确认的“项目银行流水打标状态联动设计”文档,新增后端实施计划与前端实施计划各一份。
|
||||
- 后端计划聚焦状态 `3-打标中` 的 SQL、项目状态流转主链路、以及打标期间的服务端拦截。
|
||||
- 前端计划聚焦列表/详情/统计的状态展示、上传数据页禁用、参数模型页只读,以及详情页状态刷新联动。
|
||||
|
||||
## 新增文件
|
||||
|
||||
- `docs/plans/backend/2026-03-18-project-bank-tag-status-lock-backend-implementation.md`
|
||||
- `docs/plans/frontend/2026-03-18-project-bank-tag-status-lock-frontend-implementation.md`
|
||||
|
||||
## 说明
|
||||
|
||||
- 两份计划均按仓库规范拆分到 `docs/plans/backend/` 与 `docs/plans/frontend/`。
|
||||
- 前端计划已明确说明当前仓库缺少现成 Vue 单测基建,因此以构建验证与联调记录替代自动化单测。
|
||||
- 后续按计划实施时,仍需继续补测试记录和实施报告。
|
||||
Reference in New Issue
Block a user