更新项目管理模块中合同管理、项目安装、项目验收、回访记录等功能

This commit is contained in:
wk committed 2026-09-30 17:04:55 +08:00
1 parent 307e9cf1b9
commit b3cef22a54
32 files changed
+6094 -2600

No files matched your search

@@ -0,0 +1,31 @@
# Checklist
## 后端:安装派单
- [x] `install_order` entity 字段与 db_design.html D6 完全一致,含注释与索引
- [x] `POST /api/install-orders` 创建成功并自动生成唯一 install_no,返回统一结构
- [x] `GET /api/install-orders` 支持关键字/客户/状态/日期范围筛选与分页
- [x] `PUT /api/install-orders/:id/complete` 仅允许 0→1 流转,重复调用被拒绝
- [x] 非法入参(缺必填/超长/非法枚举)返回 422
## 后端:安全
- [x] 六个项目管理控制器全部端点:无 JWT 返回 401,无权限点返回 403
- [x] `sys_menu` 存在 `project:install` 权限点且 RBAC 匹配生效
- [x] 六个 service 无字符串拼接 SQL,模糊搜索全部绑定参数,排序字段白名单
- [x] 六个 DTO 对全部外部入参有 class-validator 校验
- [x] 创建/更新/删除/指派/流转/取消/复核/催办动作均写入 sys_operation_log
## 前端:页面
- [x] 勘察台账页含统计卡、状态Tab、高级筛选、台账列、批量指派/催办入口,数据与接口联通
- [x] 勘察派单页含报价联动、优先级、到场窗口、草稿/派发,提交与接口联通
- [x] 方案页含设备明细编辑,合同页含金额/支付周期/文件,验收页含关联合同,均为拜访台账式交互
- [x] 安装派单页 CRUD + 标记完成可用,路由 `/project/install` 与菜单项生效
- [x] 回访记录页列表/新建/编辑可用
## 前端:安全与兼容
- [x] `views/project/**` 无 `v-html` 渲染后端文本
- [x] 401 自动跳登录,403/422 有统一提示
- [x] 所有列表接口响应为 `{ code, message, data: { list, total, page, pageSize } }`
## 构建
- [x] `cd client && npx vue-tsc --noEmit` 通过(vue-tsc 无类型错误)
- [x] `cd server && npx tsc --noEmit` 通过(tsc 无类型错误)
@@ -0,0 +1,70 @@
# 项目管理模块全栈重建 Spec
## Why
项目管理模块(勘察派单/方案/合同/安装/验收/回访)后端代码已存在但前端页面未按系统设计稿实现,安装派单(install_order)全栈缺失;同时需要系统性补齐接口鉴权、SQL 注入防护、前端 XSS 防护与操作日志,并保证同一套 API 可被 APP 直接复用。
## What Changes
- **前端重建**:按设计稿重建勘察台账页(参考 `系统设计/UI/项目勘察台帐/code.html`)与勘察派单页(参考 `系统设计/UI/项目勘察派单/code.html`);方案/合同/验收/安装/回访页按客户拜访管理台账(`client/src/views/customer/visit/index.vue`)的交互与样式体系重建。
- **安装派单全栈新增**:install_order 的 entity / dto / service / controller / 前端台账页 / API / 路由,功能深度为台账式完整 CRUD + 状态流转(0已派发 → 1已完成)。
- **安全加固**:
- 接口鉴权补全:项目管理所有接口统一走 JWT 认证 + RBAC 权限点(复用现有 `RbacMiddleware`,按 path 匹配 permission code)。
- SQL 注入防护审查:全部查询走 Sequelize 参数化,禁止字符串拼接 SQL;DTO 层用 class-validator 全量校验入参。
- 前端 XSS 防护:用户输入的备注/说明/意见等文本字段渲染时禁止 `v-html`,统一文本插值;富文本场景如需 HTML 必须经白名单消毒。
- 操作日志埋点:创建/更新/删除/指派/状态流转/取消/复核等关键动作写入 `sys_operation_log`。
- **APP 兼容**:不新增命名空间,Web 与 APP 共用现有 `/api/project-*` 系列接口;统一响应结构 `{ code, message, data }`,分页结构统一为 `{ list, total, page, pageSize }`;字段命名与时间格式(ISO 8601)保持稳定。
## Impact
- Affected specs: 项目管理(新建)、系统安全(加固)
- Affected code:
- server:`src/entity/install_order.entity.ts`(新增)、`src/dto/install_order.dto.ts`(新增)、`src/service/install_order.service.ts`(新增)、`src/controller/install_order.controller.ts`(新增)、既有 project_plan / contract / survey_order / acceptance / visit_record 的 controller/service(安全审查与日志埋点)
- client:`src/views/project/**`(全部重建)、`src/api/installOrder.ts`(新增)、`src/router/index.ts`(补安装派单路由)、`src/layouts/index.vue`(菜单补项)
## ADDED Requirements
### Requirement: 安装派单管理(install_order 全栈)
系统 SHALL 提供安装派单的台账式完整 CRUD 与状态流转:列表分页筛选(关键字/客户/状态/派单日期范围)、新建、编辑、详情、删除、标记完成。单号自动生成(格式与勘察单号规则一致,如 `WH-INST-YYYY-NNNN`)。
#### Scenario: 创建安装派单
- **WHEN** 授权用户提交合法派单表单(customerId、planId、installer、dispatchDate 必填)
- **THEN** 系统生成唯一 install_no,状态为 0(已派发),写入操作日志,返回统一成功响应
#### Scenario: 状态流转
- **WHEN** 授权用户对已派发工单执行「标记完成」
- **THEN** 状态从 0 流转为 1,记录完成时间,写入操作日志;已完成工单禁止再次流转
### Requirement: 勘察台账页按设计稿重建
系统 SHALL 按 `系统设计/UI/项目勘察台帐/code.html` 重建勘察台账页:统计卡片(待指派/勘察中等待复核/已归档)、状态筛选 Tab、高级筛选(优先级/业务员/电工/时间窗口)、列表列(工单编号+优先级、关联客户与项目、空间位置、测绘回路规格、责任业务员、指派电工、期望时效/SLA、预估劳务费、状态、操作)、批量指派、催办、智能派单入口。
#### Scenario: 台账筛选
- **WHEN** 用户组合使用状态 Tab 与高级筛选条件
- **THEN** 列表与统计卡片按筛选结果刷新,分页保持统一响应结构
### Requirement: 勘察派单页按设计稿重建
系统 SHALL 按 `系统设计/UI/项目勘察派单/code.html` 重建派单表单页:关联客户选择、任务标题、空间位置、回路规格/数量、优先级(特急P1/加急P2/常规P3)、计划到场窗口、SLA、预估劳务费自动报价(复用 `/api/survey-orders/quote`)、指派电工、草稿保存与正式派发。
### Requirement: 方案/合同/验收/回访页重建
系统 SHALL 按客户拜访台账的交互体系(筛选区 + 表格 + 分页 + 新建/编辑弹窗或表单页 + 状态标签)重建项目方案(含设备明细)、合同(含金额/支付周期/合同文件)、项目验收(含验收意见/文件)、回访记录四个台账页。
### Requirement: 接口鉴权补全
系统 SHALL 保证 `/api/survey-orders`、`/api/project-plans`、`/api/contracts`、`/api/install-orders`、`/api/acceptances`、`/api/visit-records` 全部端点强制 JWT 认证并校验对应 RBAC 权限点(`project:survey`、`project:plan`、`project:contract`、`project:install`、`project:acceptance`、`project:visit`)。
#### Scenario: 未认证访问被拒
- **WHEN** 请求未携带有效 JWT
- **THEN** 返回 401 统一错误结构;无权限点返回 403
### Requirement: SQL 注入防护审查
系统 SHALL 保证项目管理模块所有数据库访问经由 Sequelize 参数化;关键字模糊搜索使用绑定参数的 `Op.like`,排序字段白名单校验,禁止任何字符串拼接 SQL。
### Requirement: 前端 XSS 防护
系统 SHALL 禁止对后端返回的用户输入文本使用 `v-html`;表格/详情中的备注、说明、意见字段使用文本插值渲染。
### Requirement: 操作日志埋点
系统 SHALL 在创建/更新/删除/指派/批量指派/状态流转/取消/复核/催办动作中写入 `sys_operation_log`(操作人、动作、目标单号、摘要)。
## MODIFIED Requirements
### Requirement: 统一响应结构(APP 兼容)
项目管理全部接口 SHALL 返回 `{ code, message, data }`;列表 data 统一为 `{ list, total, page, pageSize }`;时间字段序列化为 ISO 8601 字符串;错误码语义稳定(401 未认证 / 403 无权限 / 422 参数校验失败 / 500 服务器错误),供 APP 端直接消费。
@@ -0,0 +1,37 @@
# Tasks
## 后端:安装派单(新增)
- [x] Task 1: 新增 install_order 后端全栈
- [x] 1.1 创建 `src/entity/install_order.entity.ts`(字段对齐 db_design.html D6:install_no/customer_id/installer/worker_id/dispatch_date/start_date/end_date/plan_id/remark/status/created_at)
- [x] 1.2 创建 `src/dto/install_order.dto.ts`(class-validator:QueryDTO/CreateDTO/UpdateDTO,必填校验、长度限制、状态枚举校验)
- [x] 1.3 创建 `src/service/install_order.service.ts`(list 分页+筛选、detail、create 生成单号、update、delete、complete 状态流转;全程参数化查询)
- [x] 1.4 创建 `src/controller/install_order.controller.ts`(`/api/install-orders`:GET /、GET /:id、POST /、PUT /:id、PUT /:id/complete、DELETE /:id)
## 后端:安全加固(可并行)
- [x] Task 2: 接口鉴权补全
- [x] 2.1 核对六个项目管理控制器的 JWT + RbacMiddleware 挂载,确认 path→permission code 映射覆盖(project:survey/plan/contract/install/acceptance/visit)
- [x] 2.2 在 `sys_menu` 种子/迁移中补齐 `project:install` 权限点
- [x] Task 3: SQL 注入防护审查
- [x] 3.1 审查六个 service,确认无字符串拼接 SQL、模糊搜索均为绑定参数 `Op.like`、排序字段白名单
- [x] 3.2 审查六个 DTO,确认所有外部入参均有 class-validator 校验(类型/长度/枚举/范围)
- [x] Task 4: 操作日志埋点
- [x] 4.1 封装/复用操作日志写入方法(写 sys_operation_log:操作人、模块、动作、目标单号、摘要)
- [x] 4.2 在六个 service 的 create/update/delete/assign/batchAssign/状态流转/cancel/review/urge/complete 处埋点
## 前端:页面重建
- [x] Task 5: 重建勘察台账页 `views/project/survey/index.vue`(对齐 `系统设计/UI/项目勘察台帐/code.html`:统计卡、状态Tab、高级筛选、台账列、批量指派/催办/智能派单入口)
- [x] Task 6: 重建勘察派单页 `views/project/survey/form.vue`(对齐 `系统设计/UI/项目勘察派单/code.html`:客户选择、回路规格/数量、优先级、到场窗口、SLA、劳务费报价联动、草稿/派发)
- [x] Task 7: 重建方案管理页 `views/project/plan/index.vue`(拜访台账式:筛选+表格+分页+新建/编辑含设备明细+状态标签)
- [x] Task 8: 重建合同管理页 `views/project/contract/index.vue`(筛选+表格+新建/编辑含金额/支付周期/合同文件上传+状态标签)
- [x] Task 9: 重建项目验收页 `views/project/acceptance/index.vue`(筛选+表格+新建/编辑含验收意见/文件+关联合同)
- [x] Task 10: 新增安装派单页 `views/project/install/index.vue` + `src/api/installOrder.ts` + 路由 `/project/install` + 布局菜单项(台账式 CRUD + 标记完成)
- [x] Task 11: 重建回访记录页 `views/project/visit/index.vue` + 补齐 `src/api/visitRecord.ts`(如缺失)
- [x] Task 12: 前端 XSS 防护审查
- [x] 12.1 全量检查 `views/project/**` 无 `v-html` 渲染后端文本;备注/说明/意见统一文本插值
- [x] 12.2 确认 axios 拦截器对 401 跳登录、403/422 统一提示,响应结构与 APP 兼容约定一致
## Task Dependencies
- Task 5、6 依赖后端 survey_order 既有接口(不阻塞,可与 Task 1-4 并行)
- Task 10 依赖 Task 1(安装派单后端先行)
- Task 12 依赖 Task 5-11(在页面重建完成后统一审查)
- Task 4 依赖 Task 1(install service 一并埋点)