From 3c506e8ca6eaa79b6db364f4083dd6af9c97cb00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E6=96=87=E6=98=8A?= <15984991+wwh2328692301@user.noreply.gitee.com> Date: Sat, 11 Jul 2026 10:11:02 +0800 Subject: [PATCH] =?UTF-8?q?feat(crm,wms):=20=E9=87=8D=E6=9E=84=E5=AE=A2?= =?UTF-8?q?=E8=AF=89=E6=B5=81=E7=A8=8B=EF=BC=8C=E4=BC=98=E5=8C=96=E8=8A=82?= =?UTF-8?q?=E7=82=B9=E4=B8=8E=E5=B1=95=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 重构客诉受理流程:改为质量部+生产部并行处理,后续流转至陈总审批、吴部长处理 2. 移除原有的下发、驳回相关接口与逻辑 3. 更新全流程状态文案、标签与步骤展示 4. 调整页面筛选条件与操作按钮 5. 新增陈总审批表单与对应逻辑 --- .../TsComplaintAcceptController.java | 45 +----- .../service/ITsComplaintAcceptService.java | 17 +-- .../impl/TsComplaintAcceptServiceImpl.java | 141 +++--------------- .../impl/TsComplaintTaskServiceImpl.java | 81 ++++++++-- klp-ui/src/api/flow/complaintAccept.js | 12 -- .../views/crm/components/OrderObjection.vue | 6 +- klp-ui/src/views/crm/objection/index.vue | 6 +- klp-ui/src/views/wms/post/flow.vue | 25 ++-- .../objection/components/DeptOpinionForm.vue | 22 ++- .../components/FlowOverviewSection.vue | 24 +-- klp-ui/src/views/wms/post/objection/index.vue | 20 +-- .../src/views/wms/post/objection/opinion.vue | 26 +--- .../src/views/wms/post/objection/summary.vue | 81 +++++++--- 13 files changed, 213 insertions(+), 293 deletions(-) diff --git a/klp-flow/src/main/java/com/klp/flow/controller/TsComplaintAcceptController.java b/klp-flow/src/main/java/com/klp/flow/controller/TsComplaintAcceptController.java index 8ee89044a..e58610652 100644 --- a/klp-flow/src/main/java/com/klp/flow/controller/TsComplaintAcceptController.java +++ b/klp-flow/src/main/java/com/klp/flow/controller/TsComplaintAcceptController.java @@ -99,55 +99,14 @@ public class TsComplaintAcceptController extends BaseController { } /** - * 意见下发:修改flow_status=2,按字典部门创建代办任务 + * 发起流程:创建质量部+生产部并行任务 * * @param acceptId 受理单ID */ - @Log(title = "意见下发", businessType = BusinessType.UPDATE) + @Log(title = "发起流程", businessType = BusinessType.UPDATE) @PostMapping("/opinionDispatch/{acceptId}") public R opinionDispatch(@NotNull(message = "主键不能为空") @PathVariable Long acceptId) { return toAjax(iTsComplaintAcceptService.opinionDispatch(acceptId)); } - - /** - * 反馈下发:修改flow_status=4,按字典部门创建执行反馈记录 - * - * @param acceptId 受理单ID - */ - @Log(title = "反馈下发", businessType = BusinessType.UPDATE) - @PostMapping("/feedbackDispatch") - public R feedbackDispatch(@RequestParam Long acceptId, - @RequestParam String deptIds) { - List deptIdList = Arrays.stream(deptIds.split(",")).map(Long::parseLong).collect(Collectors.toList()); - return toAjax(iTsComplaintAcceptService.feedbackDispatch(acceptId, deptIdList)); - } - - /** - * 意见驳回:当前部门taskStatus→1、rejectMark→1,主表flowStatus→1,其他部门rejectMark→2 - * - * @param taskId 代办任务ID - * @param reason 驳回意见(填入deptOpinion) - */ - @Log(title = "意见驳回", businessType = BusinessType.UPDATE) - @PostMapping("/opinionReject/{taskId}") - public R opinionReject(@NotNull(message = "主键不能为空") - @PathVariable Long taskId, - @RequestParam String reason) { - return toAjax(iTsComplaintAcceptService.opinionReject(taskId, reason)); - } - - /** - * 反馈驳回:当前部门executeStatus→1、rejectMark→1,主表flowStatus→3,其他部门rejectMark→2 - * - * @param relId 执行反馈记录ID - * @param reason 驳回原因(填入executeResult) - */ - @Log(title = "反馈驳回", businessType = BusinessType.UPDATE) - @PostMapping("/feedbackReject/{relId}") - public R feedbackReject(@NotNull(message = "主键不能为空") - @PathVariable Long relId, - @RequestParam String reason) { - return toAjax(iTsComplaintAcceptService.feedbackReject(relId, reason)); - } } diff --git a/klp-flow/src/main/java/com/klp/flow/service/ITsComplaintAcceptService.java b/klp-flow/src/main/java/com/klp/flow/service/ITsComplaintAcceptService.java index dfb5e005f..603cfae1e 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/ITsComplaintAcceptService.java +++ b/klp-flow/src/main/java/com/klp/flow/service/ITsComplaintAcceptService.java @@ -48,22 +48,7 @@ public interface ITsComplaintAcceptService { Boolean deleteWithValidByIds(Collection ids, Boolean isValid); /** - * 意见下发:修改flow_status=2,按字典flow_coil_objection部门创建代办任务 + * 发起流程:创建质量部+生产部并行任务,更新flowStatus=1 */ Boolean opinionDispatch(Long acceptId); - - /** - * 反馈下发:修改flow_status=4,按传入部门创建执行反馈记录 - */ - Boolean feedbackDispatch(Long acceptId, List deptIds); - - /** - * 意见驳回:taskStatus→1、rejectMark→1,主表flowStatus→1,其他task的rejectMark→2 - */ - Boolean opinionReject(Long taskId, String reason); - - /** - * 反馈驳回:executeStatus→1、rejectMark→1,主表flowStatus→3,其他rel的rejectMark→2 - */ - Boolean feedbackReject(Long relId, String reason); } diff --git a/klp-flow/src/main/java/com/klp/flow/service/impl/TsComplaintAcceptServiceImpl.java b/klp-flow/src/main/java/com/klp/flow/service/impl/TsComplaintAcceptServiceImpl.java index fed46981b..178e01981 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/impl/TsComplaintAcceptServiceImpl.java +++ b/klp-flow/src/main/java/com/klp/flow/service/impl/TsComplaintAcceptServiceImpl.java @@ -96,7 +96,7 @@ public class TsComplaintAcceptServiceImpl implements ITsComplaintAcceptService { } /** - * 新增投诉受理单主 + * 新增投诉受理单主(创建后自动发起流程) */ @Override public Boolean insertByBo(TsComplaintAcceptBo bo) { @@ -115,6 +115,8 @@ public class TsComplaintAcceptServiceImpl implements ITsComplaintAcceptService { }).collect(java.util.stream.Collectors.toList()); tsAcceptCoilRelMapper.insertBatch(relList); } + // 自动创建质量部+生产部并行任务,发起流程 + opinionDispatch(add.getAcceptId()); } return flag; } @@ -130,133 +132,34 @@ public class TsComplaintAcceptServiceImpl implements ITsComplaintAcceptService { } /** - * 意见下发 - * 修改受理单flow_status=2,按字典flow_coil_objection的部门创建代办任务 + * 发起流程 + * 创建质量部(deptId=2) + 生产部(deptId=1) 两个并行代办任务 + * 更新受理单flow_status=1(质量部·生产部处理中) */ @Override public Boolean opinionDispatch(Long acceptId) { if (acceptId == null) { return false; } - // 从sys_dict_data直查,根据dict_type=flow_coil_objection获取部门ID列表 - List dictList = sysDictDataService.selectDictDataByTypeRealtime("flow_coil_objection"); - if (dictList == null || dictList.isEmpty()) { - return false; - } - // 更新受理单流程状态为2(部门意见填写中) + // 1. 创建质量部task deptId=2 + TsComplaintTask qaTask = new TsComplaintTask(); + qaTask.setAcceptId(acceptId); + qaTask.setDeptId(2L); + qaTask.setTaskStatus(0L); + qaTask.setRejectMark(0L); + tsComplaintTaskMapper.insert(qaTask); + // 2. 创建生产部task deptId=1 + TsComplaintTask prodTask = new TsComplaintTask(); + prodTask.setAcceptId(acceptId); + prodTask.setDeptId(1L); + prodTask.setTaskStatus(0L); + prodTask.setRejectMark(0L); + tsComplaintTaskMapper.insert(prodTask); + // 3. 更新受理单流程状态为1(质量部·生产部处理中) LambdaUpdateWrapper uw = Wrappers.lambdaUpdate(); uw.eq(TsComplaintAccept::getAcceptId, acceptId) - .set(TsComplaintAccept::getFlowStatus, 2L); - baseMapper.update(null, uw); - // 按部门创建代办任务 - for (SysDictData dict : dictList) { - TsComplaintTask task = new TsComplaintTask(); - task.setAcceptId(acceptId); - task.setDeptId(Long.valueOf(dict.getDictValue())); - task.setTaskStatus(0L); - tsComplaintTaskMapper.insert(task); - } - return true; - } - - /** - * 反馈下发 - * 修改受理单flow_status=4,按传入部门创建执行反馈记录 - */ - @Override - public Boolean feedbackDispatch(Long acceptId, List deptIds) { - if (acceptId == null || deptIds == null || deptIds.isEmpty()) { - return false; - } - // 更新受理单流程状态为4(方案下发执行反馈中) - LambdaUpdateWrapper uw = Wrappers.lambdaUpdate(); - uw.eq(TsComplaintAccept::getAcceptId, acceptId) - .set(TsComplaintAccept::getFlowStatus, 4L); - baseMapper.update(null, uw); - // 按部门创建执行反馈记录 - for (Long deptId : deptIds) { - TsPlanExecuteRel rel = new TsPlanExecuteRel(); - rel.setAcceptId(acceptId); - rel.setDeptId(deptId); - rel.setExecuteStatus(0L); - tsPlanExecuteRelMapper.insert(rel); - } - return true; - } - - /** - * 意见驳回 - * 当前task:taskStatus→1(已审核)、rejectMark→1(本部门驳回) - * 主表:flowStatus→1(待审核) - * 其他task:若rejectMark!=1则→2(存在部门驳回) - */ - @Override - public Boolean opinionReject(Long taskId, String reason) { - if (taskId == null) { - return false; - } - TsComplaintTask currentTask = tsComplaintTaskMapper.selectById(taskId); - if (currentTask == null) { - return false; - } - Long acceptId = currentTask.getAcceptId(); - // 1. 更新当前task:taskStatus=1, rejectMark=1 - LambdaUpdateWrapper taskUw = Wrappers.lambdaUpdate(); - taskUw.eq(TsComplaintTask::getTaskId, taskId) - .set(TsComplaintTask::getTaskStatus, 1L) - .set(TsComplaintTask::getRejectMark, 1L) - .set(TsComplaintTask::getDeptOpinion, reason); - tsComplaintTaskMapper.update(null, taskUw); - // 2. 主表flowStatus→1(待审核) - LambdaUpdateWrapper acceptUw = Wrappers.lambdaUpdate(); - acceptUw.eq(TsComplaintAccept::getAcceptId, acceptId) .set(TsComplaintAccept::getFlowStatus, 1L); - baseMapper.update(null, acceptUw); - // 3. 同acceptId下其他task:若rejectMark!=1则→2 - LambdaUpdateWrapper otherUw = Wrappers.lambdaUpdate(); - otherUw.eq(TsComplaintTask::getAcceptId, acceptId) - .ne(TsComplaintTask::getTaskId, taskId) - .ne(TsComplaintTask::getRejectMark, 1L) - .set(TsComplaintTask::getRejectMark, 2L); - tsComplaintTaskMapper.update(null, otherUw); - return true; - } - - /** - * 反馈驳回 - * 当前rel:executeStatus→1(已反馈)、rejectMark→1(本部门驳回) - * 主表:flowStatus→3(待总负责人汇总方案) - * 其他rel:若rejectMark!=1则→2(存在部门驳回) - */ - @Override - public Boolean feedbackReject(Long relId, String reason) { - if (relId == null) { - return false; - } - TsPlanExecuteRel currentRel = tsPlanExecuteRelMapper.selectById(relId); - if (currentRel == null) { - return false; - } - Long acceptId = currentRel.getAcceptId(); - // 1. 更新当前rel:executeStatus=1, rejectMark=1 - LambdaUpdateWrapper relUw = Wrappers.lambdaUpdate(); - relUw.eq(TsPlanExecuteRel::getRelId, relId) - .set(TsPlanExecuteRel::getExecuteStatus, 1L) - .set(TsPlanExecuteRel::getRejectMark, 1L) - .set(TsPlanExecuteRel::getExecuteResult, reason); - tsPlanExecuteRelMapper.update(null, relUw); - // 2. 主表flowStatus→3(待总负责人汇总方案) - LambdaUpdateWrapper acceptUw = Wrappers.lambdaUpdate(); - acceptUw.eq(TsComplaintAccept::getAcceptId, acceptId) - .set(TsComplaintAccept::getFlowStatus, 3L); - baseMapper.update(null, acceptUw); - // 3. 同acceptId下其他rel:若rejectMark!=1则→2 - LambdaUpdateWrapper otherUw = Wrappers.lambdaUpdate(); - otherUw.eq(TsPlanExecuteRel::getAcceptId, acceptId) - .ne(TsPlanExecuteRel::getRelId, relId) - .ne(TsPlanExecuteRel::getRejectMark, 1L) - .set(TsPlanExecuteRel::getRejectMark, 2L); - tsPlanExecuteRelMapper.update(null, otherUw); + baseMapper.update(null, uw); return true; } diff --git a/klp-flow/src/main/java/com/klp/flow/service/impl/TsComplaintTaskServiceImpl.java b/klp-flow/src/main/java/com/klp/flow/service/impl/TsComplaintTaskServiceImpl.java index 0df328de4..e3ee1a7a8 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/impl/TsComplaintTaskServiceImpl.java +++ b/klp-flow/src/main/java/com/klp/flow/service/impl/TsComplaintTaskServiceImpl.java @@ -157,10 +157,10 @@ public class TsComplaintTaskServiceImpl implements ITsComplaintTaskService { } /** - * 同步受理单流程状态 - * 查看当前受理单下所有代办任务: - * - 所有task_status都为1 → flow_status = 3(待总负责人汇总方案) - * (flow_status=2由意见下发接口设置,此处不再处理) + * 同步受理单流程状态 — 串行推进逻辑 + * Step 1: 质量部(deptId=2) + 生产部(deptId=1) 都完成 → 创建陈总task(deptId=4), flowStatus=2 + * Step 2: 陈总完成 → 创建吴部长task(deptId=3), flowStatus=3 + * Step 3: 吴部长完成 → flowStatus=4 已办结 */ private void syncAcceptFlowStatus(Long acceptId) { if (acceptId == null) { @@ -169,18 +169,71 @@ public class TsComplaintTaskServiceImpl implements ITsComplaintTaskService { // 查询该受理单下所有未删除的代办任务 List taskList = baseMapper.selectList( Wrappers.lambdaQuery() - .eq(TsComplaintTask::getAcceptId, acceptId).eq(TsComplaintTask::getRejectMark,0) + .eq(TsComplaintTask::getAcceptId, acceptId) ); - // 判断所有任务是否都已完成(taskStatus = 1) - boolean allCompleted = !taskList.isEmpty() && taskList.stream() - .allMatch(task -> task.getTaskStatus() != null && task.getTaskStatus() == 1L); - if (allCompleted) { - // 更新受理单流程状态为3(待总负责人汇总方案) - LambdaUpdateWrapper uw = Wrappers.lambdaUpdate(); - uw.eq(TsComplaintAccept::getAcceptId, acceptId) - .set(TsComplaintAccept::getFlowStatus, 3L); - tsComplaintAcceptMapper.update(null, uw); + if (taskList.isEmpty()) { + return; } + // 按 deptId 分组查询各节点状态 + Map> taskByDept = taskList.stream() + .collect(Collectors.groupingBy(TsComplaintTask::getDeptId)); + + // Step 1: 质量部(deptId=2) 和 生产部(deptId=1) 是否都完成 + boolean qaDone = taskByDept.containsKey(2L) && + taskByDept.get(2L).stream().allMatch(t -> t.getTaskStatus() != null && t.getTaskStatus() == 1L); + boolean prodDone = taskByDept.containsKey(1L) && + taskByDept.get(1L).stream().allMatch(t -> t.getTaskStatus() != null && t.getTaskStatus() == 1L); + + if (qaDone && prodDone) { + // 两者都完成 → 检查陈总节点(deptId=4)是否存在 + boolean chenExists = taskByDept.containsKey(4L); + if (!chenExists) { + // 创建陈总task deptId=4 + TsComplaintTask chenTask = new TsComplaintTask(); + chenTask.setAcceptId(acceptId); + chenTask.setDeptId(4L); + chenTask.setRejectMark(0L); + chenTask.setTaskStatus(0L); + baseMapper.insert(chenTask); + updateFlowStatus(acceptId, 2L); // 待陈总审批 + } else { + // 陈总节点已存在,检查是否完成 + boolean chenDone = taskByDept.get(4L).stream() + .allMatch(t -> t.getTaskStatus() != null && t.getTaskStatus() == 1L); + if (chenDone) { + // 陈总完成 → 检查吴部长节点(deptId=3)是否存在 + boolean wuExists = taskByDept.containsKey(3L); + if (!wuExists) { + // 创建吴部长task deptId=3 + TsComplaintTask wuTask = new TsComplaintTask(); + wuTask.setAcceptId(acceptId); + wuTask.setDeptId(3L); + wuTask.setRejectMark(0L); + wuTask.setTaskStatus(0L); + baseMapper.insert(wuTask); + updateFlowStatus(acceptId, 3L); // 待吴部长处理 + } else { + // 吴部长已完成 → 办结 + boolean wuDone = taskByDept.get(3L).stream() + .allMatch(t -> t.getTaskStatus() != null && t.getTaskStatus() == 1L); + if (wuDone) { + updateFlowStatus(acceptId, 4L); // 已办结 + } + } + } + } + } + // 质/产未全部完成时不做任何事,等待 + } + + /** + * 更新受理单流程状态 + */ + private void updateFlowStatus(Long acceptId, Long status) { + LambdaUpdateWrapper uw = Wrappers.lambdaUpdate(); + uw.eq(TsComplaintAccept::getAcceptId, acceptId) + .set(TsComplaintAccept::getFlowStatus, status); + tsComplaintAcceptMapper.update(null, uw); } /** diff --git a/klp-ui/src/api/flow/complaintAccept.js b/klp-ui/src/api/flow/complaintAccept.js index 73caf9ec9..cb78fbe7e 100644 --- a/klp-ui/src/api/flow/complaintAccept.js +++ b/klp-ui/src/api/flow/complaintAccept.js @@ -44,15 +44,3 @@ export function opinionDispatch(acceptId) { method: 'post' }) } - -export function feedbackDispatch(acceptId, deptIds) { - return request({ url: '/flow/complaintAccept/feedbackDispatch', method: 'post', params: { acceptId, deptIds } }) -} - -export function opinionReject(taskId, reason) { - return request({ url: '/flow/complaintAccept/opinionReject/' + taskId, method: 'post', params: { reason } }) -} - -export function feedbackReject(relId, reason) { - return request({ url: '/flow/complaintAccept/feedbackReject/' + relId, method: 'post', params: { reason } }) -} diff --git a/klp-ui/src/views/crm/components/OrderObjection.vue b/klp-ui/src/views/crm/components/OrderObjection.vue index bc244c2d5..a62e4b12b 100644 --- a/klp-ui/src/views/crm/components/OrderObjection.vue +++ b/klp-ui/src/views/crm/components/OrderObjection.vue @@ -37,9 +37,9 @@ diff --git a/klp-ui/src/views/crm/objection/index.vue b/klp-ui/src/views/crm/objection/index.vue index 4373fd7d4..ed7d05356 100644 --- a/klp-ui/src/views/crm/objection/index.vue +++ b/klp-ui/src/views/crm/objection/index.vue @@ -37,9 +37,9 @@ diff --git a/klp-ui/src/views/wms/post/flow.vue b/klp-ui/src/views/wms/post/flow.vue index db3ce6a13..08ad2b7ac 100644 --- a/klp-ui/src/views/wms/post/flow.vue +++ b/klp-ui/src/views/wms/post/flow.vue @@ -104,10 +104,10 @@ const NODE_EVENT_CONFIG = { ], afterSales: [ { id: 'A', label: '创建售后单', handler: 'handleOpen', params: { componentPath: 'wms/post/objection/index' } }, - { id: 'C', label: '生产部出具处理意见', handler: 'handleOpen', params: { componentPath: 'wms/post/objection/opinion' } }, - { id: 'D', label: '质量部出具处理意见', handler: 'handleOpen', params: { componentPath: 'wms/post/objection/opinion' } }, - { id: 'E', label: '销售部出具处理意见', handler: 'handleOpen', params: { componentPath: 'wms/post/objection/opinion' } }, - { id: 'G', label: '售后负责人汇总', handler: 'handleOpen', params: { componentPath: 'wms/post/objection/summary' } }, + { id: 'C', label: '质量部处理', handler: 'handleOpen', params: { componentPath: 'wms/post/objection/opinion' } }, + { id: 'D', label: '生产部处理', handler: 'handleOpen', params: { componentPath: 'wms/post/objection/opinion' } }, + { id: 'G', label: '陈总审批', handler: 'handleOpen', params: { componentPath: 'wms/post/objection/summary' } }, + { id: 'H', label: '吴部长(销售部)处理', handler: 'handleOpen', params: { componentPath: 'wms/post/objection/opinion' } }, ], inventoryCheck: [ { id: 'A', label: '创建盘库计划', handler: 'handleOpen', params: { componentPath: 'wms/post/InvCount/index' } }, @@ -245,16 +245,15 @@ graph TD afterSales: ` graph TD - A["创建售后单
填写基本信息
选择需售后处理的钢卷"]:::step - A --> B["多部门并行处理"]:::fork - B --> C["生产部
出具处理意见"]:::dept1 - B --> D["质量部
出具处理意见"]:::dept2 - B --> E["销售部
出具处理意见"]:::dept3 - C --> F{"三个部门
全部提交?"}:::decision + A["创建售后单
销售内勤发起"]:::step + A --> B["质量部·生产部
并行处理"]:::fork + B --> C["质量部
出具处理意见"]:::dept1 + B --> D["生产部
出具处理意见"]:::dept2 + C --> F{"两部门
均已完成?"}:::decision D --> F - E --> F - F -->|已全部提交| G["售后负责人
汇总各部门意见
直接办结归档"]:::approve - G --> J(["售后单封存
流程结束"]):::end + F -->|是| G["陈总审批"]:::dept3 + G --> H["吴部长
(销售部)
处理客诉"]:::approve + H --> J(["售后单封存
流程结束"]):::end classDef step fill:#409eff,stroke:#337ecc,color:#fff,stroke-width:2px classDef fork fill:#f0f5ff,stroke:#409eff,color:#303133,stroke-width:2px diff --git a/klp-ui/src/views/wms/post/objection/components/DeptOpinionForm.vue b/klp-ui/src/views/wms/post/objection/components/DeptOpinionForm.vue index 91e0675a1..8fd996976 100644 --- a/klp-ui/src/views/wms/post/objection/components/DeptOpinionForm.vue +++ b/klp-ui/src/views/wms/post/objection/components/DeptOpinionForm.vue @@ -68,7 +68,25 @@ - + + + +