|
@@ -3,6 +3,7 @@ package com.qunzhixinxi.hnqz.admin.manager;
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.bean.copier.CopyOptions;
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.date.DatePattern;
|
|
|
import cn.hutool.core.lang.tree.Tree;
|
|
|
import cn.hutool.core.lang.tree.TreeNode;
|
|
|
import cn.hutool.core.lang.tree.TreeUtil;
|
|
@@ -27,6 +28,7 @@ import com.qunzhixinxi.hnqz.admin.api.entity.SysImplementPlan;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.SysPlanPkg;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.WmScorePackage;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.WmTaskType;
|
|
|
+import com.qunzhixinxi.hnqz.admin.api.model.excel.PlanDetailsExportModel;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.model.excel.PlanInfoExportModel;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.vo.SysImplementPlanVO;
|
|
|
import com.qunzhixinxi.hnqz.admin.service.SysDeptService;
|
|
@@ -43,6 +45,7 @@ import com.qunzhixinxi.hnqz.admin.service.WmTaskTypeService;
|
|
|
import com.qunzhixinxi.hnqz.common.core.constant.CommonConstants;
|
|
|
import com.qunzhixinxi.hnqz.common.core.exception.BizException;
|
|
|
import com.qunzhixinxi.hnqz.common.security.service.HnqzUser;
|
|
|
+import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
@@ -51,6 +54,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Collections;
|
|
|
import java.util.Comparator;
|
|
@@ -347,7 +351,8 @@ public class SysImplementPlanManager {
|
|
|
wrapper.eq(SysImplementPlan::getPlanState, UpmsState.ImplementPlanState.PASSED).apply("plan_score != avail_score");
|
|
|
break;
|
|
|
case PASSED_TO_GO:
|
|
|
- wrapper.eq(SysImplementPlan::getPlanState, UpmsState.ImplementPlanState.PASSED).apply("plan_score = avail_score");;
|
|
|
+ wrapper.eq(SysImplementPlan::getPlanState, UpmsState.ImplementPlanState.PASSED).apply("plan_score = avail_score");
|
|
|
+ ;
|
|
|
break;
|
|
|
case REJECTED:
|
|
|
wrapper.eq(SysImplementPlan::getPlanState, UpmsState.ImplementPlanState.REJECTED);
|
|
@@ -985,4 +990,280 @@ public class SysImplementPlanManager {
|
|
|
|
|
|
return collect;
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导出计划详情
|
|
|
+ *
|
|
|
+ * @param query 查询条件
|
|
|
+ * @param user 操作人
|
|
|
+ * @return 详情信息
|
|
|
+ */
|
|
|
+ public List<PlanDetailsExportModel> exportPlanDetails(SysImplementPlanDetailsDTO.OnExport query, HnqzUser user) {
|
|
|
+
|
|
|
+
|
|
|
+ List<Integer> roles = SecurityUtils.getRoles();
|
|
|
+
|
|
|
+
|
|
|
+ UpmsState.ImplPlanDetailsState detailsState;
|
|
|
+ // 区域管理员
|
|
|
+ if (roles.contains(4)) {
|
|
|
+ detailsState = UpmsState.ImplPlanDetailsState.INIT;
|
|
|
+ }
|
|
|
+ // 商务管理员
|
|
|
+ else if (roles.contains(40)){
|
|
|
+ detailsState = UpmsState.ImplPlanDetailsState.CKT1;
|
|
|
+ }
|
|
|
+ // 事业部分管领导
|
|
|
+ else if(roles.contains(41)) {
|
|
|
+ detailsState = UpmsState.ImplPlanDetailsState.CKT2;
|
|
|
+ } else {
|
|
|
+ throw new BizException("当前角色没有导出权限");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取当前人操作的所有可见企业
|
|
|
+ List<Long> entIds = listVisibleEntIds(user);
|
|
|
+
|
|
|
+ if (CollUtil.isEmpty(entIds)) {
|
|
|
+ throw new BizException("操作人未分配管理区域");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取所见区域下的所有服务上
|
|
|
+ List<SysDept> depts = deptService.listByIds(entIds);
|
|
|
+ // 过滤出服务
|
|
|
+ Set<Integer> serviceIds = depts.stream().filter(d -> d.getLevel() == 4).mapToInt(SysDept::getDeptId).boxed().collect(Collectors.toSet());
|
|
|
+ if (CollUtil.isEmpty(serviceIds)) {
|
|
|
+ throw new BizException("操作人所在区域不存在服务商");
|
|
|
+ }
|
|
|
+
|
|
|
+ List<SysImplementPlan> plans = implementPlanService.list(Wrappers.<SysImplementPlan>lambdaQuery()
|
|
|
+ .eq(SysImplementPlan::getPlanState, UpmsState.ImplementPlanState.PASSED)
|
|
|
+ .in(SysImplementPlan::getConsigneeId, serviceIds));
|
|
|
+
|
|
|
+ if (CollUtil.isEmpty(plans)) {
|
|
|
+ throw new BizException("没有查询到服务计划");
|
|
|
+ }
|
|
|
+
|
|
|
+ Set<Integer> planIds = plans.stream().mapToInt(SysImplementPlan::getPlanId).boxed().collect(Collectors.toSet());
|
|
|
+
|
|
|
+
|
|
|
+ List<SysImplPlanDetails> details = implPlanDetailsService.list(Wrappers.<SysImplPlanDetails>lambdaQuery()
|
|
|
+ .eq(SysImplPlanDetails::getDetailsState, detailsState)
|
|
|
+ .in(SysImplPlanDetails::getPlanId, planIds));
|
|
|
+
|
|
|
+ if (CollUtil.isEmpty(details)) {
|
|
|
+ throw new BizException("计划尚未拆解");
|
|
|
+ }
|
|
|
+
|
|
|
+ Set<Integer> detailsIds = details.stream().mapToInt(SysImplPlanDetails::getDetailsId).boxed().collect(Collectors.toSet());
|
|
|
+
|
|
|
+ List<SysImplPlanDetailsItem> detailsItems = implPlanDetailsItemService.list(Wrappers.<SysImplPlanDetailsItem>lambdaQuery().in(SysImplPlanDetailsItem::getDetailsId, detailsIds));
|
|
|
+
|
|
|
+ if (CollUtil.isEmpty(detailsItems)) {
|
|
|
+ throw new BizException("计划详情拆解信息不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Map<Integer, SysImplementPlan> planId2PlanMap = plans.stream().collect(Collectors.toMap(SysImplementPlan::getPlanId, Function.identity()));
|
|
|
+
|
|
|
+ List<PlanDetailsExportModel> collect = details.stream().map(d -> {
|
|
|
+ PlanDetailsExportModel model = new PlanDetailsExportModel();
|
|
|
+ model.setDetailsId(d.getDetailsId().toString());
|
|
|
+ // model.setConsignee();
|
|
|
+ SysImplementPlan plan = planId2PlanMap.get(d.getPlanId());
|
|
|
+
|
|
|
+ SysDept dept = deptService.getById(plan.getConsignorId());
|
|
|
+ model.setConsignor(dept == null ? "" : dept.getName());
|
|
|
+ model.setPlanName(plan.getPlanName());
|
|
|
+
|
|
|
+ SysDept dept1 = deptService.getById(plan.getConsigneeId());
|
|
|
+ model.setConsignee(dept1 == null ? "" : dept1.getName());
|
|
|
+
|
|
|
+ String issue = DateTimeFormatter.ofPattern(DatePattern.CHINESE_DATE_PATTERN).format(plan.getPlanIssue());
|
|
|
+ String expiry = DateTimeFormatter.ofPattern(DatePattern.CHINESE_DATE_PATTERN).format(plan.getPlanExpiry());
|
|
|
+ model.setPeriod(issue + "~" + expiry);
|
|
|
+
|
|
|
+
|
|
|
+ List<SysImplPlanDetailsItem> items = implPlanDetailsItemService.list(Wrappers.<SysImplPlanDetailsItem>lambdaQuery().eq(SysImplPlanDetailsItem::getDetailsId, d.getDetailsId()));
|
|
|
+
|
|
|
+ StringBuilder summary = new StringBuilder();
|
|
|
+
|
|
|
+ items.forEach(i -> {
|
|
|
+ summary.append("[");
|
|
|
+ summary.append("服务名称:【").append(i.getTaskTypeName()).append("】");
|
|
|
+ summary.append("服务次数:【").append(i.getQty()).append("】");
|
|
|
+ summary.append("单项积分:【").append(i.getScore()).append("】");
|
|
|
+ summary.append("服务小记:【").append(i.getSubtotal()).append("】");
|
|
|
+ summary.append("]\n");
|
|
|
+ });
|
|
|
+
|
|
|
+ model.setSummary(summary.toString());
|
|
|
+ model.setCurrentState(d.getDetailsState().getState());
|
|
|
+ model.setTotal(plan.getPlanScore().toString());
|
|
|
+
|
|
|
+ return model;
|
|
|
+
|
|
|
+
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+
|
|
|
+
|
|
|
+ return collect;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public List<Map<String, String>> batchCheckPlanDetails(List<SysImplementPlanDetailsDTO.OnBatchCheck> resource, HnqzUser user) {
|
|
|
+
|
|
|
+
|
|
|
+ // 上锁
|
|
|
+ Set<String> cacheKeySet = resource.stream().map(res -> "lock:plan:details:check:batch:" + res.getDetailsId()).collect(Collectors.toSet());
|
|
|
+
|
|
|
+ List<String> lockKey = new ArrayList<>(resource.size());
|
|
|
+
|
|
|
+ try {
|
|
|
+
|
|
|
+ cacheKeySet.forEach(key -> {
|
|
|
+ boolean locked = Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key, IdUtil.fastUUID(), 10, TimeUnit.MINUTES));
|
|
|
+
|
|
|
+ if (!locked) {
|
|
|
+ throw new BizException("有在途的操作,请稍后");
|
|
|
+ }
|
|
|
+ log.info("批量操作加锁:{} =====================================", key);
|
|
|
+ lockKey.add(key);
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ // 校验
|
|
|
+ List<Map<String, String>> errorList = this.checkDataOnBatchCheckDetails(resource);
|
|
|
+
|
|
|
+ if (CollUtil.isNotEmpty(errorList)) {
|
|
|
+ return errorList;
|
|
|
+ }
|
|
|
+
|
|
|
+ LocalDateTime now = LocalDateTime.now();
|
|
|
+ String username = user.getUsername();
|
|
|
+ List<SysImplPlanDetails> det = resource.stream().map(res -> {
|
|
|
+
|
|
|
+
|
|
|
+ boolean result = "通过".equals(res.getResult());
|
|
|
+ String msg = res.getMsg();
|
|
|
+ Integer detailsId = res.getDetailsId();
|
|
|
+
|
|
|
+ SysImplPlanDetails details = new SysImplPlanDetails();
|
|
|
+ details.setDetailsId(detailsId);
|
|
|
+
|
|
|
+ UpmsState.ImplPlanDetailsState implPlanDetailsState = Enum.valueOf(UpmsState.ImplPlanDetailsState.class, res.getCurrentState());
|
|
|
+ switch (implPlanDetailsState) {
|
|
|
+ case INIT:
|
|
|
+ details.setDetailsState(result ? UpmsState.ImplPlanDetailsState.CKT1 : UpmsState.ImplPlanDetailsState.REJECTED);
|
|
|
+ details.setCktRes1(result);
|
|
|
+ details.setCktMsg1(msg);
|
|
|
+ details.setCktTime1(now);
|
|
|
+ details.setCktName1(username);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case CKT1:
|
|
|
+ details.setDetailsState(result ? UpmsState.ImplPlanDetailsState.CKT2 : UpmsState.ImplPlanDetailsState.REJECTED);
|
|
|
+ details.setCktRes2(result);
|
|
|
+ details.setCktMsg2(msg);
|
|
|
+ details.setCktTime2(now);
|
|
|
+ details.setCktName2(username);
|
|
|
+ break;
|
|
|
+ case CKT2:
|
|
|
+ details.setDetailsState(result ? UpmsState.ImplPlanDetailsState.PASSED : UpmsState.ImplPlanDetailsState.REJECTED);
|
|
|
+ details.setCktRes3(result);
|
|
|
+ details.setCktMsg3(msg);
|
|
|
+ details.setCktTime3(now);
|
|
|
+ details.setCktName3(username);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new BizException("当前状态不支持审核");
|
|
|
+
|
|
|
+ }
|
|
|
+ details.setUpdateBy(username);
|
|
|
+ details.setUpdateTime(now);
|
|
|
+
|
|
|
+ return details;
|
|
|
+
|
|
|
+
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+
|
|
|
+ implPlanDetailsService.updateBatchById(det);
|
|
|
+
|
|
|
+
|
|
|
+ return Collections.emptyList();
|
|
|
+
|
|
|
+
|
|
|
+ } finally {
|
|
|
+ if (CollUtil.isNotEmpty(lockKey)) {
|
|
|
+ redisTemplate.delete(lockKey);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Map<String, String>> checkDataOnBatchCheckDetails(List<SysImplementPlanDetailsDTO.OnBatchCheck> resource) {
|
|
|
+
|
|
|
+ List<Map<String, String>> errorList = new LinkedList<>();
|
|
|
+
|
|
|
+ int size = resource.size();
|
|
|
+
|
|
|
+ if (size == 0) {
|
|
|
+ Map<String, String> errorMap = new HashMap<>(2);
|
|
|
+ errorMap.put("idx", "1");
|
|
|
+ errorMap.put("errorMsg", "空表单不支持审核");
|
|
|
+ errorList.add(errorMap);
|
|
|
+ return errorList;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Map<Integer, List<SysImplementPlanDetailsDTO.OnBatchCheck>> detailsId2batchCheck = resource.stream().collect(Collectors.groupingBy(SysImplementPlanDetailsDTO.OnBatchCheck::getDetailsId));
|
|
|
+
|
|
|
+
|
|
|
+ for (int i = 0; i < size; i++) {
|
|
|
+
|
|
|
+
|
|
|
+ StringBuilder errorMsg = new StringBuilder();
|
|
|
+
|
|
|
+ SysImplementPlanDetailsDTO.OnBatchCheck onBatchCheck = resource.get(i);
|
|
|
+
|
|
|
+ String result = onBatchCheck.getResult();
|
|
|
+ String msg = onBatchCheck.getMsg();
|
|
|
+ String currentState = onBatchCheck.getCurrentState();
|
|
|
+ Integer detailsId = onBatchCheck.getDetailsId();
|
|
|
+
|
|
|
+ // 校验空值
|
|
|
+ if (StrUtil.hasBlank(result, currentState) || detailsId == null) {
|
|
|
+ errorMsg.append("存在未填写的内容;");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!StrUtil.equalsAny(currentState, "CKT2", "CKT1", "INIT")) {
|
|
|
+ errorMsg.append("当前审核节点(系统用)值错误,只能是INIT/CKT1/CKT2;");
|
|
|
+ }
|
|
|
+
|
|
|
+ List<SysImplementPlanDetailsDTO.OnBatchCheck> onBatchChecks = detailsId2batchCheck.get(onBatchCheck.getDetailsId());
|
|
|
+ if (CollUtil.isNotEmpty(onBatchChecks) && onBatchChecks.size() > 1) {
|
|
|
+ errorMsg.append("表单中存在重复的详情ID;");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!StrUtil.equalsAny(result, "通过", "驳回")) {
|
|
|
+ errorMsg.append("审核结果只能是通过/驳回;");
|
|
|
+ }
|
|
|
+
|
|
|
+ if ("驳回".equals(result) && StrUtil.isBlank(msg)) {
|
|
|
+ errorMsg.append("驳回信息必填;");
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (StrUtil.isNotBlank(errorMsg)) {
|
|
|
+ Map<String, String> errorMap = new HashMap<>(2);
|
|
|
+ String idx = String.valueOf(i + 1);
|
|
|
+ errorMap.put("idx", idx);
|
|
|
+ errorMap.put("errorMsg", errorMsg.toString());
|
|
|
+ errorList.add(errorMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ return errorList;
|
|
|
+ }
|
|
|
}
|