This commit is contained in:
andyesfly committed 2026-10-02 16:11:04 +08:00
commit 7b6fe46d10
21 files changed
+3856 -110

No files matched your search

@@ -0,0 +1,18 @@
# Checklist
- [x] 后端实体 RepairRequest / RepairDispatch 字段与 db_design D8 一致(表存在,未使用自动建表)
- [x] 报修派单接口:列表/详情/创建(事务+状态流转+单号)/更新/完成(状态0→1+completed_at)/删除 全部实现
- [x] 重复派单返回 400,已完成派单不可编辑
- [x] 后端实体 MaintenanceOrder / MaintenanceDetail 字段与 db_design D9 一致
- [x] 维保接口:主从创建/更新事务、列表/详情(含明细)、完成、删除 全部实现
- [x] 全部接口接入 JWT + RBAC(dispatch:repair / dispatch:maintenance),401/403 正确返回
- [x] 行级数据权限:非 ADMIN 按 customer_id 归属过滤;列表支持 workerId 筛选(APP 兼容)
- [x] 查询全部参数化(防 SQL 注入),排序白名单
- [x] 报修/维保创建/更新/完成/删除均写入 sys_operation_log
- [x] 前端 views/dispatch/repair、views/dispatch/maintenance 页面实现(搜索/表格/分页/弹窗/状态标签)
- [x] 前端无 v-html(防 XSS)
- [x] 菜单:db_seed.sql 与远程库均含 id=36 报修派单、id=37 维保派单,挂父菜单 id=3,ADMIN/SALESMAN 角色已绑定
- [x] 路由 /dispatch/repair、/dispatch/maintenance 注册且带 permission meta
- [x] server tsc --noEmit 通过
- [x] client vue-tsc --noEmit 通过
- [x] 核心接口 curl 冒烟通过(登录→列表→创建→详情→完成→删除,重复派单 400)
@@ -0,0 +1,77 @@
# 派单管理模块(报修派单 + 维保派单)Spec
## Why
运营派单模块目前仅有"安装派单"落地(项目管理下)。根据系统设计文档(db_design.html D8 报修域 / D9 维保域),报修派单、维保派单是运营核心业务(客户小程序报修 → 运营平台派单 → APP 电工接单处理 → 客户评分),当前 Web 端缺失完整实现。
## What Changes
- 后端新增报修派单全链路:报修单查询 + 报修派单 CRUD/派单/完成(`repair_request` / `repair_dispatch` 表已存在)
- 后端新增维保派单全链路:维保单主从(单头 `maintenance_order` + 明细 `maintenance_detail`)CRUD/完成
- 全部接口接入 JWT + RBAC 鉴权、防 SQL 注入(参数化)、操作日志埋点、统一响应格式兼容 APP
- 前端新增"报修派单"、"维保派单"两个台账页面(复用安装派单页面模式),挂载到"运营派单"菜单
- 菜单 seed 与远程库同步(父菜单 id=3 "运营派单" 下新增子菜单)
## Impact
- Affected specs: 运营派单域(D8 报修域、D9 维保域)
- Affected code:
- server: entity/ dto/ service/ controller/(新增 4 个实体域文件组)、middleware/rbac.middleware.ts、service/log.service.ts(复用)
- client: views/dispatch/repair、views/dispatch/maintenance、api/、router/index.ts
- database: db_seed.sql(菜单 seed)、远程库 sys_menu/sys_role_menu 同步
## ADDED Requirements
### Requirement: 报修单查询(repair_request)
系统 SHALL 提供报修单列表与详情查询接口,支持按客户、状态(0待处理 1已派单 2已完成)、报修时间范围、关键字(单号/报修人/报修电话)筛选。
#### Scenario: 查询报修单列表
- **WHEN** 运营人员带筛选条件 GET /api/repair-requests
- **THEN** 返回分页列表 {code,message,data:{list,total,page,pageSize}}
### Requirement: 报修派单(repair_dispatch)
系统 SHALL 支持从"待处理"报修单创建报修派单(选择共享电工),事务内将报修单状态置为"已派单",并自动生成派单号 `WH-REP-YYYY-NNNN`。报修派单支持 CRUD、标记完成(status 0→1,写 completed_at)、评分(rating)查看。已完成派单不可编辑。
#### Scenario: 报修单派单成功
- **WHEN** 运营人员对 status=0 的报修单提交派单(customer_id + worker_id + 报修信息)
- **THEN** 创建 repair_dispatch 记录,报修单 status 变为 1,返回新派单数据
#### Scenario: 重复派单被拒绝
- **WHEN** 对已派单(status=1/2)的报修单再次派单
- **THEN** 返回 400 错误"该报修单已派单"
### Requirement: 维保派单主从(maintenance_order + maintenance_detail)
系统 SHALL 支持维保单(手工录入单号 maintenance_no + 客户 + 维保人 + 维保日期 + 备注 + 状态)及其明细行(客户设备 equip_id/equip_name/equip_type、建筑/楼层/位置、配电间情况/回路情况/终端情况/维保情况说明、照片)的一体化创建、更新、列表、详情、完成、删除。
#### Scenario: 创建维保单(含明细)
- **WHEN** 运营人员提交维保单头 + ≥1 条明细
- **THEN** 事务内创建 maintenance_order 及 maintenance_detail 多条记录,返回主单详情
### Requirement: 接口鉴权
所有 `/api/repair-requests`、`/api/repair-dispatchs`、`/api/maintenance-orders` 接口 SHALL 经过 JWT 鉴权,并按权限码 `dispatch:repair` / `dispatch:maintenance` 做 RBAC 校验(ADMIN 放行,非 ADMIN 需菜单权限);未带 token 返回 401,无权限返回 403。
#### Scenario: 未登录访问
- **WHEN** 无 token 调用上述接口
- **THEN** 返回 401 "未登录"
### Requirement: 防 SQL 注入
后端查询 SHALL 全部使用 Sequelize 参数化查询(Op.like 绑定参数、排序白名单),禁止字符串拼接 SQL。
### Requirement: 行级数据权限
非 ADMIN 用户 SHALL 仅能访问其名下客户(customer_id 归属过滤)的数据,与 install_order 模式一致。列表 SHALL 支持按 workerId 筛选(供 APP 电工查本人派单)。
### Requirement: 操作日志
报修派单创建/更新/完成/删除、维保派单创建/更新/完成/删除 SHALL 写入 sys_operation_log(复用 log.service.logAction)。
### Requirement: 前端页面
系统 SHALL 提供"报修派单"(views/dispatch/repair/index.vue)与"维保派单"(views/dispatch/maintenance/index.vue)两个台账页面,复用安装派单页面的搜索区/表格/分页/弹窗表单模式;前端 SHALL 禁止 v-html(防 XSS),全部文本插值输出。
#### Scenario: 报修派单页操作
- **WHEN** 运营人员在报修派单页对报修单执行"派单"并选择电工
- **THEN** 提交成功提示"派单成功",列表刷新,报修单状态更新
### Requirement: 接口兼容 APP
所有接口 SHALL 返回统一结构 {code,message,data},分页参数统一 page/pageSize/total,时间字段 ISO 字符串,报修/维保列表支持 workerId 查询参数,便于 APP/小程序消费。
## MODIFIED Requirements
(无既有需求修改)
## REMOVED Requirements
(无)
@@ -0,0 +1,49 @@
# Tasks
- [x] Task 1: 后端报修模块(repair_request + repair_dispatch)
- [x] 1.1 实体:RepairRequest.entity.ts、RepairDispatch.entity.ts(对齐 db_design D8,表已存在,timestamps:false,索引对齐)
- [x] 1.2 DTO:repair_request.dto.ts(QueryRepairRequestDto)、repair_dispatch.dto.ts(Query/Create/Update/Complete,class-validator 全量校验)
- [x] 1.3 Service:RepairDispatchService(列表/详情/创建派单事务(报修单状态流转)/更新/完成/删除,行级权限,单号 WH-REP-YYYY-NNNN,防 SQL 注入,LogService 埋点)
- [x] 1.4 Controller:repair.controller.ts(GET /api/repair-requests、GET /api/repair-requests/:id、GET/POST/PUT/DELETE /api/repair-dispatchs、PUT /api/repair-dispatchs/:id/complete)
- [x] Task 2: 后端维保模块(maintenance_order + maintenance_detail)
- [x] 2.1 实体:MaintenanceOrder.entity.ts、MaintenanceDetail.entity.ts(对齐 db_design D9,表已存在)
- [x] 2.2 DTO:maintenance_order.dto.ts(Query/Create/Update 含明细数组校验)
- [x] 2.3 Service:MaintenanceService(主从事务创建/更新、列表/详情含明细、完成、删除,行级权限,LogService 埋点)
- [x] 2.4 Controller:maintenance.controller.ts(/api/maintenance-orders 全端点 + /:id/complete)
- [x] Task 3: 鉴权接入与菜单同步
- [x] 3.1 rbac.middleware.ts PERMISSION_MAP 增加 '/api/repair-requests'/'/api/repair-dispatchs' → 'dispatch:repair'、'/api/maintenance-orders' → 'dispatch:maintenance'
- [x] 3.2 db_seed.sql:父菜单 id=3 下新增子菜单 id=36 报修派单 /dispatch/repair、id=37 维保派单 /dispatch/maintenance(component views/dispatch/repair/index、views/dispatch/maintenance/index),sys_role_menu 绑定 ADMIN(1)/SALESMAN(2)
- [x] 3.3 远程库同步:INSERT/UPDATE sys_menu(36/37)+ sys_role_menu + 序列收敛
- [x] Task 4: 前端 API 封装
- [x] 4.1 client/src/api/repair.ts:repairRequestApi(列表/详情)、repairDispatchApi(列表/详情/创建/更新/完成/删除)
- [x] 4.2 client/src/api/maintenance.ts:maintenanceApi(列表/详情/创建/更新/完成/删除)
- [x] 4.3 确认/复用 worker 下拉接口与 customer 下拉接口(workerApi.getOptions、customerApi.getCustomerOptions 已存在复用)
- [x] Task 5: 前端报修派单页面
- [x] 5.1 views/dispatch/repair/index.vue:双页签(报修单 + 报修派单);搜索区(客户/状态/日期/关键字)、表格、分页
- [x] 5.2 派单弹窗:选报修单+选电工,提交调 POST /api/repair-dispatchs
- [x] 5.3 编辑/完成/删除弹窗与确认,状态标签,无 v-html
- [x] Task 6: 前端维保派单页面
- [x] 6.1 views/dispatch/maintenance/index.vue:搜索区/表格/分页
- [x] 6.2 创建/编辑弹窗:单头字段 + 明细行动态增删(设备/巡检项),主从提交
- [x] 6.3 完成/删除确认、状态标签,无 v-html
- [x] Task 7: 路由与菜单注册
- [x] 7.1 client/src/router/index.ts:/dispatch/repair、/dispatch/maintenance 路由(meta.permission = dispatch:repair / dispatch:maintenance)
- [x] Task 8: 构建与安全验证
- [x] 8.1 server npx tsc --noEmit 通过;client npx vue-tsc --noEmit 通过
- [x] 8.2 SQL 注入审查(全参数化)、前端 XSS 审查(无 v-html)
- [x] 8.3 接口鉴权验证(401)、核心接口冒烟(列表/创建/详情/完成/删除/重复派单 400)
# Task Dependencies
- Task 3 依赖 Task 1/2 的 controller 路由确定
- Task 4 依赖 Task 1/2 的接口定义
- Task 5 依赖 Task 4
- Task 6 依赖 Task 4
- Task 7 依赖 Task 5/6 的页面文件
- Task 8 依赖全部