|
|
|
|
@ -0,0 +1,150 @@
|
|
|
|
|
# 产品开发关键因素第 4 步 Implementation Plan
|
|
|
|
|
|
|
|
|
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
|
|
|
|
|
|
|
|
**Goal:** 实现学生端产品开发关键因素第 4 步总结与最终任务提交,并提供后端非空校验。
|
|
|
|
|
|
|
|
|
|
**Architecture:** 前端在现有四步页面中增加两个总结文本框,把数据独立持久化到 `step4Answer`。后端延续前三步校验模式,新增 DTO、服务和控制器路由;校验通过后由前端以 `SUBMIT` 终结任务。
|
|
|
|
|
|
|
|
|
|
**Tech Stack:** Vue 3 Composition API、Element Plus、Spring Boot、JUnit 5、Mockito、Maven。
|
|
|
|
|
|
|
|
|
|
## Global Constraints
|
|
|
|
|
|
|
|
|
|
- 仅修改学生端和学生答案校验接口,不修改教师端或任务配置。
|
|
|
|
|
- 沿用当前隔离分支,最终分支同时包含第 3、4 步。
|
|
|
|
|
- 不新增数据库字段,使用 `step4Answer` 与 `currentStep: 4`。
|
|
|
|
|
- 最终保存使用 `saveAction: "SUBMIT"`、`submitted: true`,两个因素字段必须非空。
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
### Task 1: 第 4 步后端校验服务与路由
|
|
|
|
|
|
|
|
|
|
**Files:**
|
|
|
|
|
- Create: `src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepFourValidationRequest.java`
|
|
|
|
|
- Create: `src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepFourValidationResult.java`
|
|
|
|
|
- Create: `src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepFourService.java`
|
|
|
|
|
- Create: `src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepFourServiceImpl.java`
|
|
|
|
|
- Modify: `src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java`
|
|
|
|
|
- Test: `src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepFourServiceImplTest.java`
|
|
|
|
|
- Test: `src/test/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerControllerTest.java`
|
|
|
|
|
|
|
|
|
|
**Interfaces:**
|
|
|
|
|
- Produces: `POST /api/student-training-answers/product-development-factors/step-4/validate`。
|
|
|
|
|
- Request: `{ successFactors: String, failedFactors: String }`。
|
|
|
|
|
- Response: `{ valid: boolean, message: String }`。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 1: 写失败服务测试并验证红灯**
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
@Test void acceptsCompleteStudentSummary() {
|
|
|
|
|
assertTrue(new ProductDevelopmentFactorsStepFourServiceImpl().validate(valid(), student()).isValid());
|
|
|
|
|
}
|
|
|
|
|
@Test void rejectsBlankSummaryOrNonStudent() {
|
|
|
|
|
ProductDevelopmentFactorsStepFourValidationRequest blank = valid();
|
|
|
|
|
blank.setFailedFactors(" ");
|
|
|
|
|
assertThrows(ServiceException.class, () -> service.validate(blank, student()));
|
|
|
|
|
assertThrows(ServiceException.class, () -> service.validate(valid(), teacher()));
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Run: `mvn -B -Dtest=ProductDevelopmentFactorsStepFourServiceImplTest test`
|
|
|
|
|
|
|
|
|
|
Expected: FAIL,因为第 4 步类型与服务尚未创建。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 2: 实现最小 DTO 与服务**
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
if (user == null || StringUtils.isBlank(user.getUserId())) throw new ServiceException(HttpStatus.UNAUTHORIZED, "请先登录后再提交");
|
|
|
|
|
if (user.getRoleId() != 4) throw new ServiceException(HttpStatus.FORBIDDEN, "仅学生可提交实训答案");
|
|
|
|
|
if (!StringUtils.isNotBlank(request.getSuccessFactors())) throw badRequest("请填写产品成功的关键因素");
|
|
|
|
|
if (!StringUtils.isNotBlank(request.getFailedFactors())) throw badRequest("请填写产品失败的关键因素");
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 3: 写失败控制器测试、实现路由并验证绿灯**
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
@PostMapping("/product-development-factors/step-4/validate")
|
|
|
|
|
public ResultEntity<ProductDevelopmentFactorsStepFourValidationResult> validateProductDevelopmentFactorsStepFour(
|
|
|
|
|
@RequestBody ProductDevelopmentFactorsStepFourValidationRequest answer, HttpServletRequest request) {
|
|
|
|
|
return new ResultEntity<>(HttpStatus.OK, "校验通过", productDevelopmentFactorsStepFourService.validate(answer, TokenProvider.getJWTUser(request)));
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Run: `mvn -B "-Dtest=StudentTrainingAnswerControllerTest,ProductDevelopmentFactorsStepFourServiceImplTest" test`
|
|
|
|
|
|
|
|
|
|
Expected: PASS。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 4: 提交后端改动**
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepFourValidationRequest.java src/main/java/com/sztzjy/linkCommerce/entity/dto/ProductDevelopmentFactorsStepFourValidationResult.java src/main/java/com/sztzjy/linkCommerce/service/ProductDevelopmentFactorsStepFourService.java src/main/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepFourServiceImpl.java src/main/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerController.java src/test/java/com/sztzjy/linkCommerce/service/impl/ProductDevelopmentFactorsStepFourServiceImplTest.java src/test/java/com/sztzjy/linkCommerce/controller/stu/StudentTrainingAnswerControllerTest.java
|
|
|
|
|
git commit -m "feat: validate product factors step four"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Task 2: 第 4 步学生页面与最终提交
|
|
|
|
|
|
|
|
|
|
**Files:**
|
|
|
|
|
- Modify: `src/views/foundation/product-development-factors.vue`
|
|
|
|
|
- Modify: `src/api/studentTrainingAnswer.js`
|
|
|
|
|
- Modify: `tests/product-development-factors-step-one.static.test.cjs`
|
|
|
|
|
|
|
|
|
|
**Interfaces:**
|
|
|
|
|
- Consumes: `checkProductDevelopmentFactorsStepFour(payload)`。
|
|
|
|
|
- Produces: `step4Answer`、`submitTraining()` 和最终 `SUBMIT` 保存。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 1: 写失败前端契约测试并验证红灯**
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
assert.match(page, /v-else-if="currentStep === 3"/);
|
|
|
|
|
assert.match(page, /产品成功的关键因素/);
|
|
|
|
|
assert.match(page, /产品失败的关键因素/);
|
|
|
|
|
assert.match(page, /step4Answer/);
|
|
|
|
|
assert.match(page, /await checkProductDevelopmentFactorsStepFour\(buildStepFourValidationPayload\(\)\)/);
|
|
|
|
|
assert.match(page, /buildStepFourAnswerPayload\("SUBMIT", 4\)/);
|
|
|
|
|
assert.match(api, /product-development-factors\/step-4\/validate/);
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Run: `node tests/product-development-factors-step-one.static.test.cjs`
|
|
|
|
|
|
|
|
|
|
Expected: FAIL,因为第 4 步表单、校验和提交动作尚不存在。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 2: 实现页面、恢复与演示校验**
|
|
|
|
|
|
|
|
|
|
```js
|
|
|
|
|
function buildStepFourAnswerPayload(saveAction = "SUBMIT", persistedStep = 4) {
|
|
|
|
|
return { step4Answer: JSON.stringify(buildStepFourOutcome()), currentStep: persistedStep, submitted: true, saveAction };
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
增加 `stepFourForm`、草稿恢复、导出和清空;演示模式与正式接口都要求 `successFactors`、`failedFactors` 非空。`submitTraining` 校验成功后保存、清理草稿并提示“任务提交成功”。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 3: 运行前端验证并提交**
|
|
|
|
|
|
|
|
|
|
Run: `node tests/product-development-factors-step-one.static.test.cjs; npm run build:prod`
|
|
|
|
|
|
|
|
|
|
Expected: PASS。
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
git add src/views/foundation/product-development-factors.vue src/api/studentTrainingAnswer.js tests/product-development-factors-step-one.static.test.cjs
|
|
|
|
|
git commit -m "feat: add product factors step four summary"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Task 3: 全量回归与交付
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 1: 运行后端全量测试**
|
|
|
|
|
|
|
|
|
|
Run: `mvn -B test`
|
|
|
|
|
|
|
|
|
|
Expected: BUILD SUCCESS。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 2: 运行前端测试和生产构建**
|
|
|
|
|
|
|
|
|
|
Run: `node tests/product-development-factors-step-one.static.test.cjs; npm run build:prod`
|
|
|
|
|
|
|
|
|
|
Expected: PASS。
|
|
|
|
|
|
|
|
|
|
- [ ] **Step 3: 核对提交范围并等待集成指令**
|
|
|
|
|
|
|
|
|
|
Run: `git status --short; git log --oneline -6`
|
|
|
|
|
|
|
|
|
|
Expected: 仅第 3、4 步的预期提交;不修改主工作区的已有未跟踪文件。
|