diff --git a/docs/superpowers/plans/2026-05-25-remaining-work-wbs.md b/docs/superpowers/plans/2026-05-25-remaining-work-wbs.md new file mode 100644 index 0000000..fa4a304 --- /dev/null +++ b/docs/superpowers/plans/2026-05-25-remaining-work-wbs.md @@ -0,0 +1,425 @@ +# 原型完善 WBS 执行计划 — P0/P1/P2 任务拆解 + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** 基于原型复盘结论,按优先级分 5 个迭代完成全部 15 个遗留工作项 + +**Architecture:** 增量修改现有代码,不重构。后端 Spring Boot + MyBatis-Plus,前端 Vue 3 + Element Plus,遵循已有代码模式。每次迭代产出可编译、可运行的增量。 + +**Tech Stack:** Java 17, Spring Boot 3.4.5, MyBatis-Plus, Vue 3 (Composition API), Element Plus, Pinia, PostgreSQL 15 + +--- + +## 迭代路线图 + +| 迭代 | 周期 | 聚焦 | 任务数 | 估计工时 | +|------|------|------|--------|---------| +| **I10** | T0+1W | M1 字段补齐 + M4 批量导入 | 4 | 8.5h | +| **I11** | T0+2W | M2 增强 + M11 基础安全 | 5 | 10.5h | +| **I12** | T0+3W | M6 配置管理 | 2 | 7h | +| **I13** | T0+4W | M9 CSV + M10 审计 | 2 | 5h | +| **V2.0** | T0+6W | M11 角色模型重构 | 2 | 14h | + +--- + +## 迭代 I10:M1 字段补齐 + M4 批量导入(P0) + +### Task I10-1: M1 客户表加字段(行业/地址/开票信息) + +**Files:** +- Create: `services/delivery-platform-api/src/main/resources/db/migration/V9__m1_customer_fields.sql` +- Modify: `services/delivery-platform-api/src/main/java/.../persistence/customer/PlatformCustomer.java` +- Modify: `services/delivery-platform-api/src/main/java/.../customer/CustomerController.java` +- Modify: `services/delivery-platform-api/src/main/java/.../web/dto/CustomerRequest.java` +- Modify: `services/delivery-platform-api/src/main/java/.../web/dto/CustomerResponse.java` +- Modify: `web/delivery-platform-ui/src/views/CustomersView.vue` + +**DB Migration:** +```sql +-- V9__m1_customer_fields.sql +ALTER TABLE platform_customer + ADD COLUMN IF NOT EXISTS industry VARCHAR(128), + ADD COLUMN IF NOT EXISTS address TEXT, + ADD COLUMN IF NOT EXISTS billing_info TEXT, + ADD COLUMN IF NOT EXISTS customer_code VARCHAR(64); +``` + +**Backend:** +- `PlatformCustomer.java`: 添加 `industry`, `address`, `billingInfo`, `customerCode` 字段 (String, OffsetDateTime 无需) +- `CustomerRequest.java`: 添加 industry, address, billingInfo, customerCode 字段 + getters/setters +- `CustomerResponse.java`: 同前 +- `CustomerController.java`: 在 create/update 中透传新字段 + +**Frontend:** +- `CustomersView.vue`: 客户创建/编辑对话框增加 4 个字段:行业(input)、地址(textarea)、开票信息(textarea)、客户编码(input) + +**Steps:** +1. Create V9 migration SQL +2. Update PlatformCustomer entity +3. Update CustomerRequest/CustomerResponse DTOs +4. Update CustomersView.vue dialog +5. Compile & build +6. Commit + +--- + +### Task I10-2: M1 项目表加字段(计划起止/项目经理) + +**Files:** +- Modify: `services/.../db/migration/V9__m1_customer_fields.sql` (append) +- Modify: `services/.../persistence/project/PlatformProject.java` +- Modify: `services/.../project/ProjectController.java` +- Modify: `services/.../web/dto/ProjectRequest.java` +- Modify: `services/.../web/dto/ProjectResponse.java` +- Modify: `web/.../views/ProjectsView.vue` + +**DB:** +```sql +-- 追加到 V9 +ALTER TABLE platform_project + ADD COLUMN IF NOT EXISTS planned_start_date DATE, + ADD COLUMN IF NOT EXISTS planned_end_date DATE, + ADD COLUMN IF NOT EXISTS project_manager VARCHAR(128); +``` + +**Backend:** +- `PlatformProject.java`: 加 `plannedStartDate` (LocalDate), `plannedEndDate` (LocalDate), `projectManager` (String) +- `ProjectRequest.java` / `ProjectResponse.java`: 对应加字段 +- `ProjectController.java`: 透传 + +**Frontend:** +- `ProjectsView.vue`: 对话框加 计划开始日期(日期选择器)、计划结束日期(日期选择器)、项目经理(input) + +--- + +### Task I10-3: M1 客户详情聚合视图 + +**Files:** +- Create: `web/.../views/CustomerDetailView.vue` +- Modify: `web/.../router/index.js` +- Modify: `web/.../views/CustomersView.vue` (行操作加「详情」) +- Modify: `web/.../api/platform.js` + +**Backend:** +- `CustomerController.java`: 添加 `GET /api/v1/customers/{id}/summary` 返回聚合数据 +- `CustomerService.java`: 添加 `getCustomerSummary(id)` 方法,查询关联项目数、合同数、SN 数 + +**Frontend:** +- `CustomerDetailView.vue`: 展示客户基本信息 + 聚合卡片(关联项目数、在履约合同数、在途 SN 数) +- `CustomersView.vue`: 行操作加「详情」按钮 → 跳转 `/customers/:id` +- router: 加 `/customers/:id` → CustomerDetailView +- platform.js: 加 `getCustomerSummary(id)` + +--- + +### Task I10-4: M4 SN 批量导入 + +**Files:** +- Create: `services/.../api/web/dto/SnBatchImportRequest.java` +- Modify: `services/.../api/license/LicenseSnController.java` +- Modify: `services/.../api/service/LicenseSnService.java` +- Modify: `web/.../views/LicenseSnListView.vue` +- Modify: `web/.../api/platform.js` + +**Backend:** +- `LicenseSnController.java`: 添加 `POST /api/v1/license-sns/batch-import` +- `LicenseSnService.java`: 添加 `batchImport(List)` 方法,逐条校验并插入,返回成功数/失败数 +- `SnBatchImportRequest.java`: snCode, projectId, contractLineId, activationRemark + +**Frontend:** +- `LicenseSnListView.vue`: 加「批量导入」按钮 → 弹窗文本域(一行一个 SN) +- `platform.js`: 加 `batchImportLicenseSns(body)` + +--- + +## 迭代 I11:M2 增强 + M11 基础安全(P1) + +### Task I11-1: M2 合同附件上传 + +**Files:** +- Modify: `services/.../api/contracts/ContractController.java` +- Modify: `services/.../api/service/ContractService.java` +- Modify: `web/.../views/ContractDetailView.vue` +- Modify: `web/.../api/platform.js` + +**Backend:** +- 附件存储为本地文件系统路径 + DB 记录(`platform_contract_attachment` 新表) +- 或简化:用 `TEXT` 字段存附件 URL/备注 +- `ContractService.java`: 加 `uploadAttachment(contractId, MultipartFile)` / `getAttachments(contractId)` + +**Frontend:** +- `ContractDetailView.vue`: 加「附件」区块 + 上传按钮 + 文件列表 + +--- + +### Task I11-2: M2 合同变更版本 + +**Files:** +- Create: `services/.../db/migration/V10__contract_change_version.sql` +- Create: `services/.../api/contracts/ContractChangeController.java` +- Create: `services/.../api/web/dto/ContractChangeRequest.java` +- Modify: `services/.../api/service/ContractService.java` +- Modify: `web/.../views/ContractDetailView.vue` +- Modify: `web/.../router/index.js` + +**DB:** +```sql +CREATE TABLE platform_contract_change ( + id BIGSERIAL PRIMARY KEY, + contract_id BIGINT NOT NULL REFERENCES platform_contract(id), + version INT NOT NULL, + change_type VARCHAR(64) NOT NULL, + before_snapshot JSONB, + after_snapshot JSONB, + reason TEXT, + status VARCHAR(32) NOT NULL DEFAULT 'DRAFT', + created_by VARCHAR(256), + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); +``` + +**Backend:** +- 合同状态机新增 `CHANGING` 状态流转 +- 创建变更单后锁住原合同行,允许编辑后生成新版本 + +**Frontend:** +- `ContractDetailView.vue`: 状态操作条加「发起变更」「完成变更」按钮 +- 「变更历史」区块展示版本列表 + +--- + +### Task I11-3: M11 空闲超时自动登出 + +**Files:** +- Modify: `web/.../src/layout/MainLayout.vue` +- Possibly: `web/.../src/stores/auth.js` + +**Frontend:** +- `MainLayout.vue`: 监听用户活动事件(mousemove, keydown, click),空闲 N 分钟后自动调用 `auth.logout()` + 跳转登录页 +- 可配置超时时间(默认 30 分钟) +- 超时前 1 分钟弹窗提示 + +--- + +### Task I11-4: M11 登录失败锁定机制 + +**Files:** +- Modify: `services/.../api/auth/AuthController.java` +- Modify: `services/.../api/config/SecurityConfig.java` +- Possibly new table `platform_login_attempt` + +**Backend:** +- 记录登录失败次数(内存 Map 或 DB 表) +- 连续失败 N 次(默认 5 次)后锁定账号 X 分钟 +- 返回错误码 `ACCOUNT_LOCKED` + +--- + +### Task I11-5: M11 密码修改功能 + +**Files:** +- Modify: `services/.../api/auth/AuthController.java` +- Modify: `web/.../views/LoginView.vue` 或新建 `ProfileView.vue` +- Modify: `web/.../router/index.js` + +**Backend:** +- `POST /api/v1/auth/change-password` : body { oldPassword, newPassword } +- 校验旧密码正确性 + 新密码强度 + +**Frontend:** +- 用户菜单加「修改密码」入口 +- 弹窗表单:旧密码、新密码、确认新密码 + +--- + +## 迭代 I12:M6 配置管理(P1) + +### Task I12-1: M6 比特 ID 映射管理 + +**Files:** +- Create: `services/.../db/migration/V11__m6_id_mapping.sql` +- Create: `services/.../api/web/dto/BitanswerIdMappingRequest.java` +- Create: `services/.../api/web/dto/BitanswerIdMappingResponse.java` +- Create: `services/.../api/persistence/integration/PlatformBitanswerIdMapping.java` +- Create: `services/.../api/persistence/integration/PlatformBitanswerIdMappingMapper.java` +- Modify: `services/.../api/integration/IntegrationCatalogController.java` +- Modify: `services/.../api/service/IntegrationCatalogService.java` +- Create: `web/.../views/IntegrationIdMappingView.vue` +- Modify: `web/.../router/index.js` +- Modify: `web/.../api/platform.js` + +**DB:** +```sql +CREATE TABLE platform_bitanswer_id_mapping ( + id BIGSERIAL PRIMARY KEY, + product_line_id BIGINT NOT NULL REFERENCES platform_product_line(id), + environment_id BIGINT REFERENCES platform_integration_environment(id), + bitanswer_product_id VARCHAR(128), + bitanswer_template_id VARCHAR(128), + bitanswer_business_id VARCHAR(128), + feature_key VARCHAR(64), + bitanswer_feature_id VARCHAR(128), + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); +``` + +**Backend:** CRUD + +**Frontend:** 映射管理页面,按产品线+环境筛选,表格展示映射关系 + +--- + +### Task I12-2: M6 授权 JSON 模板管理 + +**Files:** +- Create: `services/.../db/migration/V12__m6_json_template.sql` +- Create: `services/.../api/persistence/integration/PlatformJsonTemplate.java` +- Create: `services/.../api/persistence/integration/PlatformJsonTemplateMapper.java` +- Create: `services/.../api/web/dto/JsonTemplateRequest.java` +- Modify: `services/.../api/service/IntegrationCatalogService.java` +- Modify: `services/.../api/integration/IntegrationCatalogController.java` +- Create: `web/.../views/IntegrationJsonTemplateView.vue` +- Modify: `web/.../router/index.js` + +**DB:** +```sql +CREATE TABLE platform_json_template ( + id BIGSERIAL PRIMARY KEY, + name VARCHAR(128) NOT NULL, + version INT NOT NULL DEFAULT 1, + template_content TEXT NOT NULL, + schema_version INT NOT NULL DEFAULT 1, + change_notes TEXT, + created_by VARCHAR(256), + created_at TIMESTAMPTZ NOT NULL DEFAULT now() +); +``` + +**Backend:** CRUD + JSON Schema 校验 + 版本递增 + +**Frontend:** 模板列表 + 创建/编辑页(JSON 编辑器 + 校验结果展示) + +--- + +## 迭代 I13:M9 CSV + M10 审计(P1-P2) + +### Task I13-1: M9 报表导出 CSV + +**Files:** +- Modify: `services/.../api/report/ReportController.java` +- Modify: `services/.../api/service/ReportService.java` +- Modify: `web/.../views/ContractSnReportView.vue` + +**Backend:** +- `ReportController.java`: 加 `GET /api/v1/reports/export?type=contract-sn` 返回 CSV 文件流 +- 使用 `Content-Disposition: attachment; filename=report.csv` +- `ReportService.java`: 加 `exportContractSnReport()` 生成 CSV 字符串 + +**Frontend:** +- `ContractSnReportView.vue`: 加「导出 CSV」按钮,调后端接口下载文件 + +--- + +### Task I13-2: M10 审计检索/导出 + +**Files:** +- Create: `web/.../views/AuditSearchView.vue` +- Modify: `web/.../router/index.js` +- Modify: `web/.../api/platform.js` +- Modify: `services/.../api/service/AuditService.java` +- Modify: `services/.../api/web/dto/AuditEventResponse.java` (if needed) + +**Backend:** +- `GET /api/v1/audit-events` 增加筛选参数:entityType, entityId, userId, from, to +- `GET /api/v1/audit-events/export` → CSV 导出 + +**Frontend:** +- `AuditSearchView.vue`: 筛选表单 + 审计日志表格 + 导出按钮 +- Router: `/audit` → AuditSearchView + +--- + +## V2.0:M11 角色模型重构(P2) + +### Task V2-1: M11 角色模型对齐产品定义 + +**Files:** (大量修改) +- Modify: `services/.../api/config/SecurityConfig.java` +- Modify: `services/.../api/security/PlatformRoles.java` +- Modify: 所有 Controller 的 `@PreAuthorize` 注解 +- Modify: `web/.../router/index.js` +- Modify: `web/.../layout/MainLayout.vue` +- Modify: `web/.../views/HomeView.vue` +- New seeds: `services/.../db/migration/V13__seed_roles.sql` + +**Changes:** +- 废弃 `DEVELOPER` / `OPS` 角色 +- 实现产品定义角色:`SALES`, `ORDER_SUPPORT`, `DELIVERY`, `LICENSE_OPS`, `DEV_SUPPORT`, `FINANCE_VIEW`, `COMPLIANCE`, `EXEC_VIEW` +- 更新所有路由 `meta.roles` +- 更新侧栏菜单 `roles` +- 更新后端所有 `@PreAuthorize` 注解 + +--- + +### Task V2-2: M11 按钮级权限码 + +**Files:** (大量修改) +- Create: `web/.../src/directives/permission.js` +- Modify: 所有 Vue 页面的操作按钮加 `v-permission` 指令 +- Modify: 后端 Controller 方法加细粒度 `@PreAuthorize` + +**Frontend:** +- 创建 `v-permission` 自定义指令 (类似 `v-permission="'contract:order:export'"`) +- Pinia store 存储用户权限码列表 +- 按钮级:`新建` + +**Backend:** +- 在 JWT token 中包含权限码列表 +- 每个 mutating 接口用 `@PreAuthorize("hasAuthority('license:sn:rw')")` + +--- + +## 任务依赖关系 + +```mermaid +flowchart LR + subgraph I10["I10 (P0聚焦)"] + T10_1[Task I10-1: M1客户字段] --> T10_3[Task I10-3: 客户详情页] + T10_2[Task I10-2: M1项目字段] + T10_4[Task I10-4: SN批量导入] + end + subgraph I11["I11 (M2+M11安全)"] + T11_1[Task I11-1: 合同附件] + T11_2[Task I11-2: 合同变更版本] + T11_3[Task I11-3: 空闲超时] + T11_4[Task I11-4: 登录锁定] + T11_5[Task I11-5: 密码修改] + end + subgraph I12["I12 (M6配置)"] + T12_1[Task I12-1: 比特ID映射] + T12_2[Task I12-2: JSON模板] + end + subgraph I13["I13 (报表+审计)"] + T13_1[Task I13-1: CSV导出] + T13_2[Task I13-2: 审计检索] + end + subgraph V2["V2.0 (架构债)"] + V2_1[Task V2-1: 角色模型] + V2_2[Task V2-2: 权限码] + end + I10 --> I11 --> I12 --> I13 --> V2 +``` + +--- + +## 工作量汇总 + +| 迭代 | 任务 | 后端文件 | 前端文件 | 迁移文件 | 估计工时 | +|------|------|---------|---------|---------|---------| +| **I10** | 4 | 8 | 4 | 1 | 8.5h | +| **I11** | 5 | 8 | 5 | 1 | 10.5h | +| **I12** | 2 | 10 | 3 | 2 | 7h | +| **I13** | 2 | 3 | 3 | 0 | 5h | +| **V2.0** | 2 | 10+ | 10+ | 1 | 14h | +| **总计** | **15** | **39+** | **25+** | **5** | **45h** |