/* * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: Chill 庄骞 (smallchill@163.com) */ package org.sxkj.gd.workorder.service.impl; import lombok.extern.slf4j.Slf4j; import org.sxkj.gd.workorder.entity.GdWorkOrderFlowEntity; import org.sxkj.gd.workorder.vo.GdWorkOrderFlowVO; import org.sxkj.gd.workorder.vo.WorkOrderStageVO; import org.sxkj.gd.workorder.vo.WorkOrderStatusDetailVO; import org.sxkj.gd.workorder.excel.GdWorkOrderFlowExcel; import org.sxkj.gd.workorder.mapper.GdWorkOrderFlowMapper; import org.sxkj.gd.workorder.service.IGdWorkOrderFlowService; import org.sxkj.gd.workorder.enums.WorkOrderStatusEnum; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import org.springblade.core.mp.base.BaseServiceImpl; import java.util.List; import java.util.ArrayList; import java.util.Arrays; /** * 流程记录表 服务实现类 * * @author lw * @since 2026-01-14 */ @Slf4j @Service public class GdWorkOrderFlowServiceImpl extends BaseServiceImpl implements IGdWorkOrderFlowService { @Override public IPage selectGdWorkOrderFlowPage(IPage page, GdWorkOrderFlowVO gdWorkOrderFlow) { return page.setRecords(baseMapper.selectGdWorkOrderFlowPage(page, gdWorkOrderFlow)); } @Override public List exportGdWorkOrderFlow(Wrapper queryWrapper) { List gdWorkOrderFlowList = baseMapper.exportGdWorkOrderFlow(queryWrapper); //gdWorkOrderFlowList.forEach(gdWorkOrderFlow -> { // gdWorkOrderFlow.setTypeName(DictCache.getValue(DictEnum.YES_NO, GdWorkOrderFlow.getType())); //}); return gdWorkOrderFlowList; } @Override public List getHierarchicalFlow(Wrapper queryWrapper) { // 1. 从数据库获取实际流程记录 List actualFlows = list(queryWrapper); // 2. 构建分层结构 return buildHierarchicalFlow(actualFlows); } /** * 构建分层结构的流程数据 * * @param actualFlows 实际流程记录 * @return 分层结构的流程数据 */ private List buildHierarchicalFlow(List actualFlows) { List stages = new ArrayList<>(); // 确定当前阶段代码 String currentStageCode = "0"; // 默认未开始 if (actualFlows != null && !actualFlows.isEmpty()) { // 获取最后一个流程的状态作为当前阶段 GdWorkOrderFlowEntity lastFlow = actualFlows.get(actualFlows.size() - 1); currentStageCode = lastFlow.getFlowStatus(); } // 3. 遍历所有工单阶段 // 工单发布阶段 stages.add(buildStage(WorkOrderStatusEnum.STAGE_WORK_ORDER_RELEASE.getStageDesc(), Arrays.asList( WorkOrderStatusEnum.PUBLISHING_ACCEPTING.getStageDesc(), WorkOrderStatusEnum.PUBLISHING_REJECTING.getStageDesc() ), actualFlows, WorkOrderStatusEnum.STAGE_WORK_ORDER_RELEASE.getMaxCode(), currentStageCode)); // 接单响应阶段 stages.add(buildStage(WorkOrderStatusEnum.STAGE_ORDER_RESPONSE.getStageDesc(), Arrays.asList( WorkOrderStatusEnum.RESPONDING_TO_BE_SPLIT.getStageDesc(), WorkOrderStatusEnum.RESPONDING_APPLY_CANCEL.getStageDesc(), WorkOrderStatusEnum.RESPONDING_APPLY_MODIFY.getStageDesc(), WorkOrderStatusEnum.RESPONDING_CANCELED.getStageDesc() ), actualFlows, WorkOrderStatusEnum.STAGE_ORDER_RESPONSE.getMaxCode(), currentStageCode)); // 执行中阶段 stages.add(buildStage(WorkOrderStatusEnum.STAGE_IN_EXECUTION.getStageDesc(), Arrays.asList( WorkOrderStatusEnum.EXECUTING_TO_BE_COMPLETED.getStageDesc(), WorkOrderStatusEnum.EXECUTING_NEGOTIATE_MODIFY.getStageDesc() ), actualFlows, WorkOrderStatusEnum.STAGE_IN_EXECUTION.getMaxCode(), currentStageCode)); // 完成待验阶段 stages.add(buildStage(WorkOrderStatusEnum.STAGE_COMPLETED_PENDING_INSPECTION.getStageDesc(), Arrays.asList( WorkOrderStatusEnum.COMPLETED_TO_BE_INSPECTED.getStageDesc() ), actualFlows, WorkOrderStatusEnum.STAGE_COMPLETED_PENDING_INSPECTION.getMaxCode(), currentStageCode)); // 验收通过阶段 stages.add(buildStage(WorkOrderStatusEnum.STAGE_ACCEPTED.getStageDesc(), Arrays.asList( WorkOrderStatusEnum.ACCEPTED_TO_BE_SETTLED.getStageDesc() ), actualFlows, WorkOrderStatusEnum.STAGE_ACCEPTED.getMaxCode(), currentStageCode)); // 结算完成阶段 stages.add(buildStage(WorkOrderStatusEnum.STAGE_SETTLEMENT_COMPLETED.getStageDesc(), Arrays.asList( WorkOrderStatusEnum.SETTLEMENT_COMPLETED.getStageDesc() ), actualFlows, WorkOrderStatusEnum.STAGE_SETTLEMENT_COMPLETED.getMaxCode(), currentStageCode)); return stages; } /** * 构建单个阶段的流程数据 * * @param stageName 阶段名称 * @param statusNames 状态名称列表 * @param actualFlows 实际流程记录 * @param flowStatus 流程状态码 * @param currentStageCode 当前阶段代码 * @return 阶段流程数据 */ private WorkOrderStageVO buildStage(String stageName, List statusNames, List actualFlows, String flowStatus, String currentStageCode) { List statuses = new ArrayList<>(); // 临时列表,用于收集所有状态详情 List tempStatuses = new ArrayList<>(); // 遍历该阶段的所有状态 for (String statusName : statusNames) { log.info("正在处理状态:{}", statusName); // 查找所有对应的实际流程记录 List matchingFlows = findMatchingFlows(actualFlows, statusName, flowStatus); if (!matchingFlows.isEmpty()) { // 对匹配的流程记录按创建时间排序 matchingFlows.sort((f1, f2) -> { if (f1.getCreateTime() != null && f2.getCreateTime() != null) { return f1.getCreateTime().compareTo(f2.getCreateTime()); } else if (f1.getCreateTime() != null) { return -1; } else { return 1; } }); // 无论阶段是否在当前阶段之后,只要有匹配的流程记录,就标记为已到达 for (GdWorkOrderFlowEntity matchingFlow : matchingFlows) { tempStatuses.add(new WorkOrderStatusDetailVO( statusName, true, matchingFlow.getOperator(), matchingFlow.getCreateTime() )); } } else { // 未到达的状态 // 如果阶段在当前阶段之后,则标记为未到达 // 如果阶段在当前阶段之前或等于,则也标记为未到达(因为没有匹配的流程记录) tempStatuses.add(new WorkOrderStatusDetailVO(statusName)); } } // 分离已到达和未到达的状态 List reachedStatuses = new ArrayList<>(); List unreachedStatuses = new ArrayList<>(); for (WorkOrderStatusDetailVO status : tempStatuses) { if (status.isReached()) { reachedStatuses.add(status); } else { unreachedStatuses.add(status); } } // 对已到达的状态按创建时间排序 reachedStatuses.sort((s1, s2) -> { if (s1.getCreateTime() != null && s2.getCreateTime() != null) { return s1.getCreateTime().compareTo(s2.getCreateTime()); } else if (s1.getCreateTime() != null) { return -1; } else { return 1; } }); // 合并已到达和未到达的状态(已到达的在前,未到达的在后) statuses.addAll(reachedStatuses); statuses.addAll(unreachedStatuses); return new WorkOrderStageVO(stageName, statuses); } /** * 查找所有匹配的流程记录 * * @param actualFlows 实际流程记录 * @param statusName 状态名称 * @param flowStatus 流程状态码 * @return 匹配的流程记录列表,没有则返回空列表 */ private List findMatchingFlows(List actualFlows, String statusName, String flowStatus) { List matchingFlows = new ArrayList<>(); if (actualFlows != null) { for (GdWorkOrderFlowEntity flow : actualFlows) { if (flow.getFlowStatus().equals(flowStatus) && flow.getFlowName().equals(statusName)) { matchingFlows.add(flow); } } } return matchingFlows; } }