feat(crm,wms): 重构客诉流程,优化节点与展示逻辑

1.  重构客诉受理流程:改为质量部+生产部并行处理,后续流转至陈总审批、吴部长处理
2.  移除原有的下发、驳回相关接口与逻辑
3.  更新全流程状态文案、标签与步骤展示
4.  调整页面筛选条件与操作按钮
5.  新增陈总审批表单与对应逻辑
This commit is contained in:
王文昊
2026-07-11 10:11:02 +08:00
parent 2a611bad19
commit 3c506e8ca6
13 changed files with 213 additions and 293 deletions

View File

@@ -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<Void> 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<Void> feedbackDispatch(@RequestParam Long acceptId,
@RequestParam String deptIds) {
List<Long> 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<Void> 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<Void> feedbackReject(@NotNull(message = "主键不能为空")
@PathVariable Long relId,
@RequestParam String reason) {
return toAjax(iTsComplaintAcceptService.feedbackReject(relId, reason));
}
}

View File

@@ -48,22 +48,7 @@ public interface ITsComplaintAcceptService {
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
* 意见下发:修改flow_status=2按字典flow_coil_objection部门创建代办任务
* 发起流程:创建质量部+生产部并行任务,更新flowStatus=1
*/
Boolean opinionDispatch(Long acceptId);
/**
* 反馈下发修改flow_status=4按传入部门创建执行反馈记录
*/
Boolean feedbackDispatch(Long acceptId, List<Long> 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);
}

View File

@@ -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<SysDictData> 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<TsComplaintAccept> 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<Long> deptIds) {
if (acceptId == null || deptIds == null || deptIds.isEmpty()) {
return false;
}
// 更新受理单流程状态为4方案下发执行反馈中
LambdaUpdateWrapper<TsComplaintAccept> 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;
}
/**
* 意见驳回
* 当前tasktaskStatus→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. 更新当前tasktaskStatus=1, rejectMark=1
LambdaUpdateWrapper<TsComplaintTask> 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<TsComplaintAccept> acceptUw = Wrappers.lambdaUpdate();
acceptUw.eq(TsComplaintAccept::getAcceptId, acceptId)
.set(TsComplaintAccept::getFlowStatus, 1L);
baseMapper.update(null, acceptUw);
// 3. 同acceptId下其他task若rejectMark!=1则→2
LambdaUpdateWrapper<TsComplaintTask> 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;
}
/**
* 反馈驳回
* 当前relexecuteStatus→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. 更新当前relexecuteStatus=1, rejectMark=1
LambdaUpdateWrapper<TsPlanExecuteRel> 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<TsComplaintAccept> acceptUw = Wrappers.lambdaUpdate();
acceptUw.eq(TsComplaintAccept::getAcceptId, acceptId)
.set(TsComplaintAccept::getFlowStatus, 3L);
baseMapper.update(null, acceptUw);
// 3. 同acceptId下其他rel若rejectMark!=1则→2
LambdaUpdateWrapper<TsPlanExecuteRel> 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;
}

View File

@@ -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<TsComplaintTask> taskList = baseMapper.selectList(
Wrappers.<TsComplaintTask>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<TsComplaintAccept> uw = Wrappers.lambdaUpdate();
uw.eq(TsComplaintAccept::getAcceptId, acceptId)
.set(TsComplaintAccept::getFlowStatus, 3L);
tsComplaintAcceptMapper.update(null, uw);
if (taskList.isEmpty()) {
return;
}
// 按 deptId 分组查询各节点状态
Map<Long, List<TsComplaintTask>> 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<TsComplaintAccept> uw = Wrappers.lambdaUpdate();
uw.eq(TsComplaintAccept::getAcceptId, acceptId)
.set(TsComplaintAccept::getFlowStatus, status);
tsComplaintAcceptMapper.update(null, uw);
}
/**