Commit 39b27610dd2989bd07208d1f927992d294c629ec

Authored by 陈强
1 parent f6e4d9cc

CPS体系驾驶舱-过程确认、PJO计划相关接口添加

Showing 26 changed files with 3498 additions and 226 deletions
1 1 package com.qgutech.qgyun.apaas.sync.cps.controller;
2 2
  3 +import com.qgutech.qgyun.apaas.sync.cps.dto.PjoExecDetailDTO;
  4 +import com.qgutech.qgyun.apaas.sync.cps.dto.PjoExecSummaryDTO;
3 5 import com.qgutech.qgyun.apaas.sync.cps.model.PjoExec;
4 6 import com.qgutech.qgyun.apaas.sync.cps.service.PjoExecService;
5 7 import com.qgutech.qgyun.framework.common.result.JsonResult;
6 8 import lombok.extern.slf4j.Slf4j;
7 9 import org.springframework.web.bind.annotation.GetMapping;
8 10 import org.springframework.web.bind.annotation.RequestMapping;
  11 +import org.springframework.web.bind.annotation.RequestParam;
9 12 import org.springframework.web.bind.annotation.RestController;
10 13
11 14 import javax.annotation.Resource;
... ... @@ -32,4 +35,48 @@ public class PjoExecController {
32 35 List<PjoExec> pjoExecList = pjoExecService.listAll();
33 36 return new JsonResult<>(true, "成功", pjoExecList);
34 37 }
  38 +
  39 + /**
  40 + * 根据 PJO 开展日期范围汇总 PJO 计划执行统计信息
  41 + * <p>
  42 + * 统计维度包括:
  43 + * <ul>
  44 + * <li>整体:PJO计划数、已执行数、执行率,第一/二/三阶段问题数与发现率,整体问题数与发现率</li>
  45 + * <li>各车间:同上统计信息</li>
  46 + * <li>各车间下各 PJO 执行人:同上统计信息</li>
  47 + * </ul>
  48 + * 开始时间为空时默认使用当前月 1 号,结束时间为空时默认使用当前日期前一天
  49 + *
  50 + * @param startTime 开始时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前月 1 号 00:00:00)
  51 + * @param endTime 结束时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前日期前一天 23:59:59)
  52 + * @return PJO 计划执行汇总结果
  53 + */
  54 + @GetMapping("/summary/exec")
  55 + public JsonResult summaryByPjoDate(@RequestParam(required = false) String startTime,
  56 + @RequestParam(required = false) String endTime) {
  57 + PjoExecSummaryDTO summary = pjoExecService.summaryByPjoDate(startTime, endTime);
  58 + return new JsonResult<>(true, "成功", summary);
  59 + }
  60 +
  61 + /**
  62 + * 根据条件查询人员 PJO 计划明细列表
  63 + * <p>
  64 + * 按 PJO 开展日期范围筛选,可再按车间单位id、人员id(PJO执行人)过滤,
  65 + * 返回含关联实体名称、枚举中文描述及各阶段问题标记的明细记录。
  66 + * 开始时间为空时默认使用当前月 1 号,结束时间为空时默认使用当前日期前一天。
  67 + *
  68 + * @param startTime 开始时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前月 1 号 00:00:00)
  69 + * @param endTime 结束时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前日期前一天 23:59:59)
  70 + * @param cj 车间单位id,可为空
  71 + * @param pjozxr 人员id(PJO执行人),可为空
  72 + * @return PJO 计划执行记录明细列表
  73 + */
  74 + @GetMapping("/list/detail")
  75 + public JsonResult listDetailByCondition(@RequestParam(required = false) String startTime,
  76 + @RequestParam(required = false) String endTime,
  77 + @RequestParam(required = false) String cj,
  78 + @RequestParam(required = false) String pjozxr) {
  79 + List<PjoExecDetailDTO> detailList = pjoExecService.listDetailByCondition(startTime, endTime, cj, pjozxr);
  80 + return new JsonResult<>(true, "成功", detailList);
  81 + }
35 82 }
... ...
1 1 package com.qgutech.qgyun.apaas.sync.cps.controller;
2 2
  3 +import com.qgutech.qgyun.apaas.sync.cps.dto.ProcessConfirmExecDetailDTO;
  4 +import com.qgutech.qgyun.apaas.sync.cps.dto.ProcessConfirmExecSummaryDTO;
3 5 import com.qgutech.qgyun.apaas.sync.cps.model.ProcessConfirmExec;
4 6 import com.qgutech.qgyun.apaas.sync.cps.service.ProcessConfirmExecService;
5 7 import com.qgutech.qgyun.framework.common.result.JsonResult;
6 8 import lombok.extern.slf4j.Slf4j;
7 9 import org.springframework.web.bind.annotation.GetMapping;
8 10 import org.springframework.web.bind.annotation.RequestMapping;
  11 +import org.springframework.web.bind.annotation.RequestParam;
9 12 import org.springframework.web.bind.annotation.RestController;
10 13
11 14 import javax.annotation.Resource;
... ... @@ -32,4 +35,49 @@ public class ProcessConfirmExecController {
32 35 List<ProcessConfirmExec> processConfirmExecList = processConfirmExecService.listAll();
33 36 return new JsonResult<>(true, "成功", processConfirmExecList);
34 37 }
  38 +
  39 + /**
  40 + * 根据活动执行日期范围汇总过程确认执行记录统计信息
  41 + * <p>
  42 + * 统计维度包括:
  43 + * <ul>
  44 + * <li>各单位:记录总数、已执行数量、执行率、问题发现数、问题发现率</li>
  45 + * <li>各单位下各人员类别:记录总数、已执行数量、执行率、问题发现数、问题发现率</li>
  46 + * <li>整体:记录总数、已执行总数、总执行率、问题发现总数、总问题发现率</li>
  47 + * </ul>
  48 + * 开始时间为空时默认使用当前月1号,结束时间为空时默认使用当前日期前一天
  49 + *
  50 + * @param startTime 开始时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前月 1 号 00:00:00)
  51 + * @param endTime 结束时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前日期前一天 23:59:59)
  52 + * @return 过程确认执行记录汇总结果
  53 + */
  54 + @GetMapping("/summary/exec")
  55 + public JsonResult summaryByExecDate(@RequestParam(required = false) String startTime,
  56 + @RequestParam(required = false) String endTime) {
  57 + ProcessConfirmExecSummaryDTO summary = processConfirmExecService.summaryByExecDate(startTime, endTime);
  58 + return new JsonResult<>(true, "成功", summary);
  59 + }
  60 +
  61 + /**
  62 + * 根据条件查询过程确认执行记录明细列表(不含问题记录信息)
  63 + * <p>
  64 + * 所有参数均非必填;开始时间为空时默认使用当前月 1 号,结束时间为空时默认使用当前日期前一天
  65 + *
  66 + * @param startTime 开始时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前月 1 号 00:00:00)
  67 + * @param endTime 结束时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前日期前一天 23:59:59)
  68 + * @param dw 单位id,可为空
  69 + * @param rylb 人员类别编号(#1#-#7#,兼容 1 ~ 7),可为空
  70 + * @param zt 过程确认状态编号(#1#-#4#,兼容 1 ~ 4),可为空
  71 + * @return 过程确认执行记录明细列表
  72 + */
  73 + @GetMapping("/list/detail")
  74 + public JsonResult listDetailByCondition(@RequestParam(required = false) String startTime,
  75 + @RequestParam(required = false) String endTime,
  76 + @RequestParam(required = false) String dw,
  77 + @RequestParam(required = false) String rylb,
  78 + @RequestParam(required = false) String zt) {
  79 + List<ProcessConfirmExecDetailDTO> detailList =
  80 + processConfirmExecService.listDetailByCondition(startTime, endTime, dw, rylb, zt);
  81 + return new JsonResult<>(true, "成功", detailList);
  82 + }
35 83 }
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.dto;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
  4 +import lombok.Getter;
  5 +import lombok.Setter;
  6 +import lombok.ToString;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import java.io.Serializable;
  10 +import java.util.Date;
  11 +
  12 +/**
  13 + * PJO计划执行记录明细(含关联实体名称、枚举中文描述、各阶段问题标记)
  14 + */
  15 +@Getter
  16 +@Setter
  17 +@ToString
  18 +public class PjoExecDetailDTO implements Serializable {
  19 +
  20 + private static final long serialVersionUID = 1L;
  21 +
  22 + /*
  23 + * 记录ID
  24 + */
  25 + private String id;
  26 +
  27 + /*
  28 + * 创建时间
  29 + */
  30 + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  31 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  32 + private Date createdAt;
  33 +
  34 + /*
  35 + * PJO开展日期
  36 + */
  37 + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  38 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  39 + private Date qkxdwk;
  40 +
  41 + /*
  42 + * 当日生产班次
  43 + */
  44 + private String drscbc;
  45 +
  46 + /*
  47 + * PJO执行人id(组织用户)
  48 + */
  49 + private String pjozxr;
  50 +
  51 + /*
  52 + * PJO执行人姓名
  53 + */
  54 + private String pjozxrName;
  55 +
  56 + /*
  57 + * PJO观察人姓名
  58 + */
  59 + private String pjogcrxm;
  60 +
  61 + /*
  62 + * PJO批次id
  63 + */
  64 + private String pjopc;
  65 +
  66 + /*
  67 + * PJO批次名称
  68 + */
  69 + private String pjopcName;
  70 +
  71 + /*
  72 + * PJO批次编号
  73 + */
  74 + private String pjopcCode;
  75 +
  76 + /*
  77 + * 岗位性质编号(#1#-A类;#2#-B类;#3#-C类)
  78 + */
  79 + private String gwxz;
  80 +
  81 + /*
  82 + * 岗位性质名称(枚举 GwxzEnum)
  83 + */
  84 + private String gwxzDesc;
  85 +
  86 + /*
  87 + * 工位1-PJO工位执行情况记录id
  88 + */
  89 + private String gwzx1;
  90 +
  91 + /*
  92 + * 工位1名称
  93 + */
  94 + private String gwzx1Name;
  95 +
  96 + /*
  97 + * 工位1编号
  98 + */
  99 + private String gwzx1Code;
  100 +
  101 + /*
  102 + * 工位2-PJO工位执行情况记录id
  103 + */
  104 + private String gwzx2;
  105 +
  106 + /*
  107 + * 工位2名称
  108 + */
  109 + private String gwzx2Name;
  110 +
  111 + /*
  112 + * 工位2编号
  113 + */
  114 + private String gwzx2Code;
  115 +
  116 + /*
  117 + * PJO是否正常开展
  118 + */
  119 + private Boolean pjosfzckz;
  120 +
  121 + /*
  122 + * 观察和填写主要异常
  123 + */
  124 + private String gchtxzyyc;
  125 +
  126 + /*
  127 + * 观察和填写次要异常
  128 + */
  129 + private String gchtxcyyc;
  130 +
  131 + /*
  132 + * 观察的问题(第一阶段问题来源)
  133 + */
  134 + private String gcdwt;
  135 +
  136 + /*
  137 + * 观测改进机会
  138 + */
  139 + private String gcgjjh;
  140 +
  141 + /*
  142 + * 观察的改善点描述(第二阶段问题来源)
  143 + */
  144 + private String lfwkuc;
  145 +
  146 + /*
  147 + * 组员存在的问题编号(第三阶段问题来源,#1#-无)
  148 + */
  149 + private String zyczdwt;
  150 +
  151 + /*
  152 + * 组员存在的问题名称(枚举 ZyczdwtEnum)
  153 + */
  154 + private String zyczdwtDesc;
  155 +
  156 + /*
  157 + * 针对本工位的改善建议
  158 + */
  159 + private String zdbgwdgsjy;
  160 +
  161 + /*
  162 + * 三个动作
  163 + */
  164 + private String lvqwyc;
  165 +
  166 + /*
  167 + * 组员是否有建议
  168 + */
  169 + private Boolean zysfyjy;
  170 +
  171 + /*
  172 + * 成员建议&意见处理人员id(组织用户)
  173 + */
  174 + private String cyjy;
  175 +
  176 + /*
  177 + * 成员建议&意见处理人员姓名
  178 + */
  179 + private String cyjyName;
  180 +
  181 + /*
  182 + * 组员建议&意见处理方案
  183 + */
  184 + private String zyjy;
  185 +
  186 + /*
  187 + * 状态编号(#1#-待执行;#2#-执行中;#3#-已执行;#4#-已关闭)
  188 + */
  189 + private String zt;
  190 +
  191 + /*
  192 + * 状态名称(枚举 PjoExecZtEnum)
  193 + */
  194 + private String ztDesc;
  195 +
  196 + /*
  197 + * 第一阶段是否发现问题(观察的问题 gcdwt 有值)
  198 + */
  199 + private Boolean stage1Problem;
  200 +
  201 + /*
  202 + * 第二阶段是否发现问题(观察的改善点描述 lfwkuc 有值)
  203 + */
  204 + private Boolean stage2Problem;
  205 +
  206 + /*
  207 + * 第三阶段是否发现问题(组员存在的问题 zyczdwt 有值且不是 #1#-无)
  208 + */
  209 + private Boolean stage3Problem;
  210 +
  211 + /*
  212 + * 该记录发现问题总数(三阶段合计,0~3)
  213 + */
  214 + private Integer problemCount;
  215 +
  216 + // ========== 关联实体ID及名称 ==========
  217 +
  218 + /*
  219 + * 车间id
  220 + */
  221 + private String cj;
  222 +
  223 + /*
  224 + * 车间名称
  225 + */
  226 + private String cjName;
  227 +
  228 + /*
  229 + * 车间编号
  230 + */
  231 + private String cjCode;
  232 +
  233 + /*
  234 + * 区域id
  235 + */
  236 + private String qy;
  237 +
  238 + /*
  239 + * 区域名称
  240 + */
  241 + private String qyName;
  242 +
  243 + /*
  244 + * 区域编号
  245 + */
  246 + private String qyCode;
  247 +
  248 + /*
  249 + * 班组id
  250 + */
  251 + private String bz;
  252 +
  253 + /*
  254 + * 班组名称
  255 + */
  256 + private String bzName;
  257 +
  258 + /*
  259 + * 班组编号
  260 + */
  261 + private String bzCode;
  262 +
  263 + /*
  264 + * 线体id
  265 + */
  266 + private String xt;
  267 +
  268 + /*
  269 + * 线体名称
  270 + */
  271 + private String xtName;
  272 +
  273 + /*
  274 + * 线体编号
  275 + */
  276 + private String xtCode;
  277 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.dto;
  2 +
  3 +import lombok.Getter;
  4 +import lombok.Setter;
  5 +import lombok.ToString;
  6 +
  7 +import java.util.ArrayList;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * PJO计划执行汇总结果(整体 + 各车间 + 各PJO执行人 三级维度)
  12 + * <p>
  13 + * 三级维度共用 {@link PjoStatBase} 的统计指标:PJO计划数、已执行数、执行率,
  14 + * 第一/二/三阶段问题数与发现率,以及整体问题数与发现率。
  15 + */
  16 +@Getter
  17 +@Setter
  18 +@ToString(callSuper = true)
  19 +public class PjoExecSummaryDTO extends PjoStatBase {
  20 +
  21 + private static final long serialVersionUID = 1L;
  22 +
  23 + /*
  24 + * 各车间统计信息列表
  25 + */
  26 + private List<CjStat> cjStats = new ArrayList<>();
  27 +
  28 + /**
  29 + * 车间维度统计明细
  30 + */
  31 + @Getter
  32 + @Setter
  33 + @ToString(callSuper = true)
  34 + public static class CjStat extends PjoStatBase {
  35 +
  36 + private static final long serialVersionUID = 1L;
  37 +
  38 + /*
  39 + * 车间id
  40 + */
  41 + private String cj;
  42 +
  43 + /*
  44 + * 车间名称
  45 + */
  46 + private String cjName;
  47 +
  48 + /*
  49 + * 车间编号
  50 + */
  51 + private String cjCode;
  52 +
  53 + /*
  54 + * 该车间下各PJO执行人统计信息列表
  55 + */
  56 + private List<ZxrStat> zxrStats = new ArrayList<>();
  57 + }
  58 +
  59 + /**
  60 + * PJO执行人维度统计明细
  61 + */
  62 + @Getter
  63 + @Setter
  64 + @ToString(callSuper = true)
  65 + public static class ZxrStat extends PjoStatBase {
  66 +
  67 + private static final long serialVersionUID = 1L;
  68 +
  69 + /*
  70 + * PJO执行人id(组织用户)
  71 + */
  72 + private String pjozxr;
  73 +
  74 + /*
  75 + * PJO执行人姓名
  76 + */
  77 + private String pjozxrName;
  78 + }
  79 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.dto;
  2 +
  3 +import lombok.Getter;
  4 +import lombok.Setter;
  5 +import lombok.ToString;
  6 +
  7 +import java.io.Serializable;
  8 +
  9 +/**
  10 + * PJO 统计指标基类
  11 + * <p>
  12 + * 整体、各车间、各 PJO 执行人三级维度共用同一套统计指标:
  13 + * PJO计划数、已执行数、执行率,以及第一/二/三阶段问题数与发现率、整体问题数与发现率。
  14 + */
  15 +@Getter
  16 +@Setter
  17 +@ToString
  18 +public abstract class PjoStatBase implements Serializable {
  19 +
  20 + private static final long serialVersionUID = 1L;
  21 +
  22 + /*
  23 + * PJO计划数(记录总数)
  24 + */
  25 + private Integer totalCount;
  26 +
  27 + /*
  28 + * 已执行状态的数量(状态为 #3#-已执行)
  29 + */
  30 + private Integer executedCount;
  31 +
  32 + /*
  33 + * 执行率(%)= 已执行数量 / PJO计划数 × 100
  34 + */
  35 + private Double execRate;
  36 +
  37 + /*
  38 + * 第一阶段问题数(观察的问题 gcdwt 有值)
  39 + */
  40 + private Integer stage1ProblemCount;
  41 +
  42 + /*
  43 + * 第一阶段问题发现率(%)= 第一阶段问题数 / PJO计划数 × 100
  44 + */
  45 + private Double stage1ProblemRate;
  46 +
  47 + /*
  48 + * 第二阶段问题数(观察的改善点描述 lfwkuc 有值)
  49 + */
  50 + private Integer stage2ProblemCount;
  51 +
  52 + /*
  53 + * 第二阶段问题发现率(%)= 第二阶段问题数 / PJO计划数 × 100
  54 + */
  55 + private Double stage2ProblemRate;
  56 +
  57 + /*
  58 + * 第三阶段问题数(组员存在的问题 zyczdwt 有值且不是 #1#-无)
  59 + */
  60 + private Integer stage3ProblemCount;
  61 +
  62 + /*
  63 + * 第三阶段问题发现率(%)= 第三阶段问题数 / PJO计划数 × 100
  64 + */
  65 + private Double stage3ProblemRate;
  66 +
  67 + /*
  68 + * 整体问题数(第一、二、三阶段问题数合计)
  69 + */
  70 + private Integer problemCount;
  71 +
  72 + /*
  73 + * 整体问题发现率(%)= 整体问题数 / PJO计划数 × 100
  74 + */
  75 + private Double problemRate;
  76 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.dto;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonFormat;
  4 +import lombok.Getter;
  5 +import lombok.Setter;
  6 +import lombok.ToString;
  7 +import org.springframework.format.annotation.DateTimeFormat;
  8 +
  9 +import java.io.Serializable;
  10 +import java.util.Date;
  11 +
  12 +/**
  13 + * 过程确认执行记录明细(含关联实体名称、枚举中文描述)
  14 + */
  15 +@Getter
  16 +@Setter
  17 +@ToString
  18 +public class ProcessConfirmExecDetailDTO implements Serializable {
  19 +
  20 + private static final long serialVersionUID = 1L;
  21 +
  22 + /*
  23 + * 记录ID
  24 + */
  25 + private String id;
  26 +
  27 + /*
  28 + * 创建时间
  29 + */
  30 + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  31 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  32 + private Date createdAt;
  33 +
  34 + /*
  35 + * 活动执行日期
  36 + */
  37 + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  38 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  39 + private Date hdzxrq;
  40 +
  41 + /*
  42 + * 过期时间
  43 + */
  44 + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  45 + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
  46 + private Date gqsj;
  47 +
  48 + /*
  49 + * 过程确认计划人员id
  50 + */
  51 + private String gcqrjhry;
  52 +
  53 + /*
  54 + * 过程确认计划人员姓名
  55 + */
  56 + private String gcqrjhryName;
  57 +
  58 + /*
  59 + * 执行人员
  60 + */
  61 + private String zxry;
  62 +
  63 + /*
  64 + * 工号
  65 + */
  66 + private String gh;
  67 +
  68 + /*
  69 + * 人员类别:#1#-区长;#2#-班长;#3#-高级经理;#4#-经理;#5#-主管;#6#-专家;#7#-一般员工
  70 + */
  71 + private String rylb;
  72 +
  73 + /*
  74 + * 人员类别名称(枚举 RylbEnum)
  75 + */
  76 + private String rylbDesc;
  77 +
  78 + /*
  79 + * 状态:#1#-待确认;#2#-未执行;#3#-已执行;#4#-已逾期
  80 + */
  81 + private String zt;
  82 +
  83 + /*
  84 + * 状态名称(枚举 GcqrZtEnum)
  85 + */
  86 + private String ztDesc;
  87 +
  88 + /*
  89 + * 是否已执行
  90 + */
  91 + private Boolean sfyzx;
  92 +
  93 + /*
  94 + * 是否发现问题
  95 + */
  96 + private Boolean sffxwt;
  97 +
  98 + /*
  99 + * 未执行原因:#1#-车间停产;#99#-其他
  100 + */
  101 + private String wzxyys;
  102 +
  103 + /*
  104 + * 未执行原因名称(枚举 WzxyysEnum)
  105 + */
  106 + private String wzxyysDesc;
  107 +
  108 + /*
  109 + * 未执行原因说明
  110 + */
  111 + private String wzxyysm;
  112 +
  113 + // ========== 关联实体ID及名称 ==========
  114 +
  115 + /*
  116 + * 单位id
  117 + */
  118 + private String dw;
  119 +
  120 + /*
  121 + * 单位名称
  122 + */
  123 + private String dwName;
  124 +
  125 + /*
  126 + * 单位编号
  127 + */
  128 + private String dwCode;
  129 +
  130 + /*
  131 + * 室组id
  132 + */
  133 + private String sz;
  134 +
  135 + /*
  136 + * 室组名称
  137 + */
  138 + private String szName;
  139 +
  140 + /*
  141 + * 室组编号
  142 + */
  143 + private String szCode;
  144 +
  145 + /*
  146 + * 区域id
  147 + */
  148 + private String qy;
  149 +
  150 + /*
  151 + * 区域名称
  152 + */
  153 + private String qyName;
  154 +
  155 + /*
  156 + * 区域编号
  157 + */
  158 + private String qyCode;
  159 +
  160 + /*
  161 + * 班组id
  162 + */
  163 + private String bz;
  164 +
  165 + /*
  166 + * 班组名称
  167 + */
  168 + private String bzName;
  169 +
  170 + /*
  171 + * 班组编号
  172 + */
  173 + private String bzCode;
  174 +
  175 + /*
  176 + * 线体id
  177 + */
  178 + private String xt;
  179 +
  180 + /*
  181 + * 线体名称
  182 + */
  183 + private String xtName;
  184 +
  185 + /*
  186 + * 线体编号
  187 + */
  188 + private String xtCode;
  189 +
  190 + /*
  191 + * 班次id
  192 + */
  193 + private String bc;
  194 +
  195 + /*
  196 + * 班次名称
  197 + */
  198 + private String bcName;
  199 +
  200 + /*
  201 + * 班次编号
  202 + */
  203 + private String bcCode;
  204 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.dto;
  2 +
  3 +import lombok.Getter;
  4 +import lombok.Setter;
  5 +import lombok.ToString;
  6 +
  7 +import java.io.Serializable;
  8 +import java.util.ArrayList;
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * 过程确认执行记录汇总结果(按单位 + 人员类别维度)
  13 + */
  14 +@Getter
  15 +@Setter
  16 +@ToString
  17 +public class ProcessConfirmExecSummaryDTO implements Serializable {
  18 +
  19 + private static final long serialVersionUID = 1L;
  20 +
  21 + /*
  22 + * 单位id
  23 + */
  24 + private String dw;
  25 +
  26 + /*
  27 + * 单位名称
  28 + */
  29 + private String dwName;
  30 +
  31 + /*
  32 + * 单位编号
  33 + */
  34 + private String dwCode;
  35 +
  36 + /*
  37 + * 该单位下过程确认记录总数
  38 + */
  39 + private Integer totalCount;
  40 +
  41 + /*
  42 + * 该单位下已执行数量
  43 + */
  44 + private Integer executedCount;
  45 +
  46 + /*
  47 + * 执行率(%)= 已执行数量 / 记录总数 × 100
  48 + */
  49 + private Double execRate;
  50 +
  51 + /*
  52 + * 该单位下过程确认发现的问题数
  53 + */
  54 + private Integer problemCount;
  55 +
  56 + /*
  57 + * 问题发现率(%)= 问题数 / 记录总数 × 100
  58 + */
  59 + private Double problemRate;
  60 +
  61 + /*
  62 + * 各人员类别下的统计明细
  63 + */
  64 + private List<RylbStat> rylbStats = new ArrayList<>();
  65 +
  66 + /*
  67 + * 各单位统计信息列表(仅整体汇总时返回)
  68 + */
  69 + private List<ProcessConfirmExecSummaryDTO> dwStats = new ArrayList<>();
  70 +
  71 + /**
  72 + * 人员类别统计明细
  73 + */
  74 + @Getter
  75 + @Setter
  76 + @ToString
  77 + public static class RylbStat implements Serializable {
  78 +
  79 + private static final long serialVersionUID = 1L;
  80 +
  81 + /*
  82 + * 人员类别编号(#1#-区长;#2#-班长;#3#-高级经理;#4#-经理;#5#-主管;#6#-专家;#7#-一般员工)
  83 + */
  84 + private String rylb;
  85 +
  86 + /*
  87 + * 人员类别中文描述
  88 + */
  89 + private String rylbDesc;
  90 +
  91 + /*
  92 + * 该人员类别下记录总数
  93 + */
  94 + private Integer totalCount;
  95 +
  96 + /*
  97 + * 该人员类别下已执行数量
  98 + */
  99 + private Integer executedCount;
  100 +
  101 + /*
  102 + * 执行率(%)= 已执行数量 / 记录总数 × 100
  103 + */
  104 + private Double execRate;
  105 +
  106 + /*
  107 + * 该人员类别下问题发现数
  108 + */
  109 + private Integer problemCount;
  110 +
  111 + /*
  112 + * 问题发现率(%)= 问题数 / 记录总数 × 100
  113 + */
  114 + private Double problemRate;
  115 +
  116 + public RylbStat() {
  117 + }
  118 +
  119 + public RylbStat(String rylb, String rylbDesc, Integer totalCount, Integer executedCount,
  120 + Double execRate, Integer problemCount, Double problemRate) {
  121 + this.rylb = rylb;
  122 + this.rylbDesc = rylbDesc;
  123 + this.totalCount = totalCount;
  124 + this.executedCount = executedCount;
  125 + this.execRate = execRate;
  126 + this.problemCount = problemCount;
  127 + this.problemRate = problemRate;
  128 + }
  129 + }
  130 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.enums;
  2 +
  3 +import lombok.Getter;
  4 +
  5 +/**
  6 + * 数据状态枚举
  7 + * <p>
  8 + * 数据库字段 zt 存储编号:
  9 + * #1#-草稿,#2#-启用,#3#-停用
  10 + */
  11 +@Getter
  12 +public enum DataStatusEnum {
  13 +
  14 + CAOGAO("#1#", "草稿"),
  15 + QIYONG("#2#", "启用"),
  16 + TINGYONG("#3#", "停用");
  17 +
  18 + private final String code;
  19 + private final String desc;
  20 +
  21 + DataStatusEnum(String code, String desc) {
  22 + this.code = code;
  23 + this.desc = desc;
  24 + }
  25 +
  26 + public static DataStatusEnum fromCode(String code) {
  27 + if (code == null) {
  28 + return null;
  29 + }
  30 + for (DataStatusEnum item : values()) {
  31 + if (item.code.equals(code)) {
  32 + return item;
  33 + }
  34 + }
  35 + if (!code.startsWith("#")) {
  36 + String wrapped = "#" + code + "#";
  37 + for (DataStatusEnum item : values()) {
  38 + if (item.code.equals(wrapped)) {
  39 + return item;
  40 + }
  41 + }
  42 + }
  43 + return null;
  44 + }
  45 +
  46 + public static String getDescByCode(String code) {
  47 + DataStatusEnum item = fromCode(code);
  48 + return item != null ? item.getDesc() : code;
  49 + }
  50 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.enums;
  2 +
  3 +import lombok.Getter;
  4 +
  5 +/**
  6 + * 过程确认状态枚举
  7 + * <p>
  8 + * 数据库字段 zt 存储编号:
  9 + * #1#-待确认,#2#-未执行,#3#-已执行,#4#-已逾期
  10 + */
  11 +@Getter
  12 +public enum GcqrZtEnum {
  13 +
  14 + DAIQUEREN("#1#", "待确认"),
  15 + WEIZHIXING("#2#", "未执行"),
  16 + YIZHIXING("#3#", "已执行"),
  17 + YIYUQI("#4#", "已逾期");
  18 +
  19 + private final String code;
  20 + private final String desc;
  21 +
  22 + GcqrZtEnum(String code, String desc) {
  23 + this.code = code;
  24 + this.desc = desc;
  25 + }
  26 +
  27 + public static GcqrZtEnum fromCode(String code) {
  28 + if (code == null) {
  29 + return null;
  30 + }
  31 + for (GcqrZtEnum item : values()) {
  32 + if (item.code.equals(code)) {
  33 + return item;
  34 + }
  35 + }
  36 + if (!code.startsWith("#")) {
  37 + String wrapped = "#" + code + "#";
  38 + for (GcqrZtEnum item : values()) {
  39 + if (item.code.equals(wrapped)) {
  40 + return item;
  41 + }
  42 + }
  43 + }
  44 + return null;
  45 + }
  46 +
  47 + public static String getDescByCode(String code) {
  48 + GcqrZtEnum item = fromCode(code);
  49 + return item != null ? item.getDesc() : code;
  50 + }
  51 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.enums;
  2 +
  3 +import lombok.Getter;
  4 +
  5 +/**
  6 + * 岗位性质枚举
  7 + * <p>
  8 + * 数据库字段 gwxz 存储编号:
  9 + * #1#-A类,#2#-B类,#3#-C类
  10 + */
  11 +@Getter
  12 +public enum GwxzEnum {
  13 +
  14 + A_LEI("#1#", "A类"),
  15 + B_LEI("#2#", "B类"),
  16 + C_LEI("#3#", "C类");
  17 +
  18 + private final String code;
  19 + private final String desc;
  20 +
  21 + GwxzEnum(String code, String desc) {
  22 + this.code = code;
  23 + this.desc = desc;
  24 + }
  25 +
  26 + public static GwxzEnum fromCode(String code) {
  27 + if (code == null) {
  28 + return null;
  29 + }
  30 + for (GwxzEnum item : values()) {
  31 + if (item.code.equals(code)) {
  32 + return item;
  33 + }
  34 + }
  35 + if (!code.startsWith("#")) {
  36 + String wrapped = "#" + code + "#";
  37 + for (GwxzEnum item : values()) {
  38 + if (item.code.equals(wrapped)) {
  39 + return item;
  40 + }
  41 + }
  42 + }
  43 + return null;
  44 + }
  45 +
  46 + public static String getDescByCode(String code) {
  47 + GwxzEnum item = fromCode(code);
  48 + return item != null ? item.getDesc() : code;
  49 + }
  50 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.enums;
  2 +
  3 +import lombok.Getter;
  4 +
  5 +/**
  6 + * PJO工位状态枚举
  7 + * <p>
  8 + * 数据库字段 gwzt 存储编号:
  9 + * #1#-未选中,#2#-已选中,#3#-已释放
  10 + */
  11 +@Getter
  12 +public enum GwztEnum {
  13 +
  14 + WEIXUANZHONG("#1#", "未选中"),
  15 + YIXUANZHONG("#2#", "已选中"),
  16 + YISHIFANG("#3#", "已释放");
  17 +
  18 + private final String code;
  19 + private final String desc;
  20 +
  21 + GwztEnum(String code, String desc) {
  22 + this.code = code;
  23 + this.desc = desc;
  24 + }
  25 +
  26 + public static GwztEnum fromCode(String code) {
  27 + if (code == null) {
  28 + return null;
  29 + }
  30 + for (GwztEnum item : values()) {
  31 + if (item.code.equals(code)) {
  32 + return item;
  33 + }
  34 + }
  35 + if (!code.startsWith("#")) {
  36 + String wrapped = "#" + code + "#";
  37 + for (GwztEnum item : values()) {
  38 + if (item.code.equals(wrapped)) {
  39 + return item;
  40 + }
  41 + }
  42 + }
  43 + return null;
  44 + }
  45 +
  46 + public static String getDescByCode(String code) {
  47 + GwztEnum item = fromCode(code);
  48 + return item != null ? item.getDesc() : code;
  49 + }
  50 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.enums;
  2 +
  3 +import lombok.Getter;
  4 +
  5 +/**
  6 + * PJO计划执行状态枚举
  7 + * <p>
  8 + * 数据库字段 zt 存储编号:
  9 + * #1#-待执行,#2#-执行中,#3#-已执行,#4#-已关闭
  10 + */
  11 +@Getter
  12 +public enum PjoExecZtEnum {
  13 +
  14 + DAIZHIXING("#1#", "待执行"),
  15 + ZHIXINGZHONG("#2#", "执行中"),
  16 + YIZHIXING("#3#", "已执行"),
  17 + YIGUANBI("#4#", "已关闭");
  18 +
  19 + private final String code;
  20 + private final String desc;
  21 +
  22 + PjoExecZtEnum(String code, String desc) {
  23 + this.code = code;
  24 + this.desc = desc;
  25 + }
  26 +
  27 + public static PjoExecZtEnum fromCode(String code) {
  28 + if (code == null) {
  29 + return null;
  30 + }
  31 + for (PjoExecZtEnum item : values()) {
  32 + if (item.code.equals(code)) {
  33 + return item;
  34 + }
  35 + }
  36 + if (!code.startsWith("#")) {
  37 + String wrapped = "#" + code + "#";
  38 + for (PjoExecZtEnum item : values()) {
  39 + if (item.code.equals(wrapped)) {
  40 + return item;
  41 + }
  42 + }
  43 + }
  44 + return null;
  45 + }
  46 +
  47 + public static String getDescByCode(String code) {
  48 + PjoExecZtEnum item = fromCode(code);
  49 + return item != null ? item.getDesc() : code;
  50 + }
  51 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.enums;
  2 +
  3 +import lombok.Getter;
  4 +
  5 +/**
  6 + * 未执行原因枚举
  7 + * <p>
  8 + * 数据库字段 wzxyys 存储编号:
  9 + * #1#-车间停产,#99#-其他
  10 + */
  11 +@Getter
  12 +public enum WzxyysEnum {
  13 +
  14 + CHEJIANTINGCHAN("#1#", "车间停产"),
  15 + QITA("#99#", "其他");
  16 +
  17 + private final String code;
  18 + private final String desc;
  19 +
  20 + WzxyysEnum(String code, String desc) {
  21 + this.code = code;
  22 + this.desc = desc;
  23 + }
  24 +
  25 + public static WzxyysEnum fromCode(String code) {
  26 + if (code == null) {
  27 + return null;
  28 + }
  29 + for (WzxyysEnum item : values()) {
  30 + if (item.code.equals(code)) {
  31 + return item;
  32 + }
  33 + }
  34 + if (!code.startsWith("#")) {
  35 + String wrapped = "#" + code + "#";
  36 + for (WzxyysEnum item : values()) {
  37 + if (item.code.equals(wrapped)) {
  38 + return item;
  39 + }
  40 + }
  41 + }
  42 + return null;
  43 + }
  44 +
  45 + public static String getDescByCode(String code) {
  46 + WzxyysEnum item = fromCode(code);
  47 + return item != null ? item.getDesc() : code;
  48 + }
  49 +}
... ...
  1 +package com.qgutech.qgyun.apaas.sync.cps.enums;
  2 +
  3 +import lombok.Getter;
  4 +
  5 +/**
  6 + * 组员存在的问题枚举
  7 + * <p>
  8 + * 数据库字段 zyczdwt 存储编号:
  9 + * #1#-无(值为 #1# 表示第三阶段未发现问题,其余值表示发现了一个问题)
  10 + */
  11 +@Getter
  12 +public enum ZyczdwtEnum {
  13 +
  14 + WU("#1#", "无");
  15 +
  16 + private final String code;
  17 + private final String desc;
  18 +
  19 + ZyczdwtEnum(String code, String desc) {
  20 + this.code = code;
  21 + this.desc = desc;
  22 + }
  23 +
  24 + public static ZyczdwtEnum fromCode(String code) {
  25 + if (code == null) {
  26 + return null;
  27 + }
  28 + for (ZyczdwtEnum item : values()) {
  29 + if (item.code.equals(code)) {
  30 + return item;
  31 + }
  32 + }
  33 + if (!code.startsWith("#")) {
  34 + String wrapped = "#" + code + "#";
  35 + for (ZyczdwtEnum item : values()) {
  36 + if (item.code.equals(wrapped)) {
  37 + return item;
  38 + }
  39 + }
  40 + }
  41 + return null;
  42 + }
  43 +
  44 + public static String getDescByCode(String code) {
  45 + ZyczdwtEnum item = fromCode(code);
  46 + return item != null ? item.getDesc() : code;
  47 + }
  48 +}
... ...
... ... @@ -22,6 +22,7 @@ public class CpsProblem extends BaseCorpModel {
22 22 public static final String WTZRDW = "wtzrdw";
23 23 public static final String WTCLZT = "wtclzt";
24 24 public static final String WTLY = "wtly";
  25 + public static final String LYGCQRZX = "lygcqrzx";
25 26
26 27 /*
27 28 * 问题编号
... ... @@ -94,6 +95,11 @@ public class CpsProblem extends BaseCorpModel {
94 95 private String sz;
95 96
96 97 /*
  98 + * 来源过程确认执行记录
  99 + */
  100 + private String lygcqrzx;
  101 +
  102 + /*
97 103 * 问题层级-#1#-1;#2#-2;#3#-3;#4#-4;#5#-5;#0#-0;
98 104 */
99 105 private String mbghlk;
... ...
... ... @@ -43,7 +43,7 @@ public class PjoBatch extends BaseCorpModel {
43 43 private String zxqy;
44 44
45 45 /*
46   - * 状态
  46 + * 状态:数据状态枚举 DataStatusEnum:#1#-草稿;#2#-启用;#3#-停用;
47 47 */
48 48 private String zt;
49 49
... ...
... ... @@ -17,18 +17,24 @@ import java.util.Date;
17 17 @Table(name = "t_auto_hfca_ixzvok_wmkgsv")
18 18 public class PjoExec extends BaseCorpModel {
19 19
  20 + public static final String QKXDWK = "qkxdwk";
  21 + public static final String PJOZXR = "pjozxr";
  22 + public static final String CJ = "cj";
  23 + public static final String GWXZ = "gwxz";
  24 + public static final String ZT = "zt";
  25 +
20 26 /*
21 27 * 当日生产班次
22 28 */
23 29 private String drscbc;
24 30
25 31 /*
26   - * qkxdwk
  32 + * PJO开展日期
27 33 */
28 34 private Date qkxdwk;
29 35
30 36 /*
31   - * PJO执行人
  37 + * PJO执行人-组织用户
32 38 */
33 39 private String pjozxr;
34 40
... ... @@ -38,142 +44,88 @@ public class PjoExec extends BaseCorpModel {
38 44 private String pjopc;
39 45
40 46 /*
41   - * 车间
  47 + * 岗位性质-枚举 GwxzEnum:#1#-A类;#2#-B类;#3#-C类;
42 48 */
43   - private String cj;
44   -
  49 + private String gwxz;
45 50 /*
46   - * 产线
  51 + * 工位-PJO工位执行情况记录id
47 52 */
48   - private String cx;
49   -
  53 + private String gwzx1;
50 54 /*
51   - * CPS区域
  55 + * PJO观察人姓名
52 56 */
53   - private String cpsqy;
54   -
  57 + private String pjogcrxm;
55 58 /*
56   - * 班组
  59 + * 工位2-PJO工位执行情况记录id
57 60 */
58   - private String bz;
59   -
  61 + private String gwzx2;
60 62 /*
61   - * PJO观察人姓名
  63 + * 线体
62 64 */
63   - private String pjogcrxm;
64   -
  65 + private String xt;
65 66 /*
66   - * 工位信息
  67 + * 车间
67 68 */
68   - private String gwxx;
69   -
  69 + private String cj;
70 70 /*
71   - * 所属批次
  71 + * 区域
72 72 */
73   - private String sspc;
74   -
  73 + private String qy;
75 74 /*
76   - * 工位性质
  75 + * 班组
77 76 */
78   - private String gwxz;
79   -
  77 + private String bz;
80 78 /*
81 79 * PJO是否正常开展
82 80 */
83 81 private Boolean pjosfzckz;
84   -
85 82 /*
86   - * gchtxzyyc
  83 + * 观察和填写主要异常-枚举:
87 84 */
88 85 private String gchtxzyyc;
89   -
90 86 /*
91   - * gchtxcyyc
  87 + * 观察和填写次要异常-枚举:
92 88 */
93 89 private String gchtxcyyc;
94   -
95 90 /*
96   - * gcdwt
  91 + * 观察的问题-若记录该项有值,则表明第一阶段发现了一个问题;
97 92 */
98 93 private String gcdwt;
99   -
100 94 /*
101   - * gcgjjh
  95 + * 观测改进机会-枚举:
102 96 */
103 97 private String gcgjjh;
104   -
105 98 /*
106   - * lfwkuc
  99 + * 观察的改善点描述-若记录该项有值,则表明第二阶段发现了一个问题;
107 100 */
108 101 private String lfwkuc;
109   -
110 102 /*
111   - * zyczdwt
  103 + * 组员存在的问题-枚举 ZyczdwtEnum:#1#-无;
  104 + * -若记录该项有值,且值不是#1#,则表明第三阶段发现了一个问题;
112 105 */
113 106 private String zyczdwt;
114   -
115 107 /*
116   - * zdbgwdgsjy
  108 + * 针对本工位的改善建议
117 109 */
118 110 private String zdbgwdgsjy;
119   -
120 111 /*
121   - * lvqwyc
  112 + * 三个动作-枚举
122 113 */
123 114 private String lvqwyc;
124   -
125 115 /*
126   - * zyqm
127   - */
128   - private String zyqm;
129   -
130   - /*
131   - * zysfyjy
  116 + * 组员是否有建议
132 117 */
133 118 private Boolean zysfyjy;
134   -
135 119 /*
136   - * cyjy
  120 + * 成员建议&意见处理人员-组织用户
137 121 */
138 122 private String cyjy;
139   -
140 123 /*
141   - * zyjy
  124 + * 组员建议&意见处理方案
142 125 */
143 126 private String zyjy;
144   -
145 127 /*
146   - * 状态
  128 + * 状态-枚举 PjoExecZtEnum:#1#-待执行;#2#-执行中;#3#-已执行;#4#-已关闭;
147 129 */
148 130 private String zt;
149   -
150   - /*
151   - * 区域
152   - */
153   - private String qy;
154   -
155   - /*
156   - * gwxx2
157   - */
158   - private String gwxx2;
159   -
160   - /*
161   - * zyqmb
162   - */
163   - private String zyqmb;
164   -
165   - /*
166   - * gwzx1
167   - */
168   - private String gwzx1;
169   -
170   - /*
171   - * gwzx2
172   - */
173   - private String gwzx2;
174   -
175   - /*
176   - * 线体
177   - */
178   - private String xt;
179 131 }
... ...
... ... @@ -17,7 +17,7 @@ import javax.persistence.Table;
17 17 public class PjoWorkstationExec extends BaseCorpModel {
18 18
19 19 /*
20   - * 工位状态
  20 + * 工位状态:枚举 GwztEnum:#1#-未选中;#2#-已选中;#3#-已释放;
21 21 */
22 22 private String gwzt;
23 23
... ... @@ -32,7 +32,7 @@ public class PjoWorkstationExec extends BaseCorpModel {
32 32 private String gw;
33 33
34 34 /*
35   - * clbcfl
  35 + * 工位批次内执行次数
36 36 */
37 37 private Double clbcfl;
38 38
... ...
... ... @@ -19,6 +19,12 @@ import java.util.Date;
19 19 @Table(name = "t_auto_hfca_ixzvok_gcqrjhzx")
20 20 public class ProcessConfirmExec extends BaseCorpModel {
21 21
  22 + public static final String HDZXRQ = "hdzxrq";
  23 + public static final String DW = "dw";
  24 + public static final String RYLB = "rylb";
  25 + public static final String SFYZX = "sfyzx";
  26 + public static final String ZT = "zt";
  27 +
22 28 /*
23 29 * 活动执行日期
24 30 */
... ... @@ -42,7 +48,7 @@ public class ProcessConfirmExec extends BaseCorpModel {
42 48 private String gh;
43 49
44 50 /*
45   - * 人员类别
  51 + * 人员类别 -对应人员类别RylbEnum枚举:#1#-区长,#2#-班长,#3#-高级经理,#4#-经理,#5#-主管,#6#-专家,#7#-一般员工
46 52 */
47 53 private String rylb;
48 54
... ... @@ -84,7 +90,7 @@ public class ProcessConfirmExec extends BaseCorpModel {
84 90 private Date gqsj;
85 91
86 92 /*
87   - * 状态
  93 + * 状态-过程确认状态枚举:#1#-待确认;#2#-未执行;#3#-已执行;#4#-已逾期;
88 94 */
89 95 private String zt;
90 96
... ... @@ -104,7 +110,7 @@ public class ProcessConfirmExec extends BaseCorpModel {
104 110 private Boolean sffxwt;
105 111
106 112 /*
107   - * 未执行原因
  113 + * 未执行原因-枚举:#1#-车间停产;#99#-其他;
108 114 */
109 115 private String wzxyys;
110 116 }
... ...
... ... @@ -18,162 +18,43 @@ import java.util.Date;
18 18 public class ProcessConfirmPersonnel extends BaseCorpModel {
19 19
20 20 /*
21   - * 活动执行日期
22   - */
23   - private Date hdzxrq;
24   -
25   - /*
26   - * 执行人员
  21 + * 人员
27 22 */
28   - private String zxry;
29   -
  23 + private String ry;
30 24 /*
31   - * 活动执行人姓名
  25 + * 人员姓名
32 26 */
33   - private String hdzxrxm;
34   -
  27 + private String ryxm;
35 28 /*
36 29 * 工号
37 30 */
38   - private String gh;
39   -
40   - /*
41   - * 工作单位
42   - */
43   - private String gzdw;
44   -
  31 + private String eaohkg;
45 32 /*
46   - * 人员类别
  33 + * 人员类别-对应人员类别RylbEnum枚举:#1#-区长,#2#-班长,#3#-高级经理,#4#-经理,#5#-主管,#6#-专家,#7#-一般员工
47 34 */
48 35 private String rylb;
49   -
50   - /*
51   - * 所在区域名称
52   - */
53   - private String szqymc;
54   -
55   - /*
56   - * 班组
57   - */
58   - private String bz;
59   -
60   - /*
61   - * 线体
62   - */
63   - private String xt;
64   -
65   - /*
66   - * 班次
67   - */
68   - private String bc;
69   -
70 36 /*
71   - * 过期时间
72   - */
73   - private Date gqsj;
74   -
75   - /*
76   - * 状态
77   - */
78   - private String zt;
79   -
80   - /*
81   - * 过程执行
82   - */
83   - private String gczx;
84   -
85   - /*
86   - * 未执行原因
87   - */
88   - private String wzxyy;
89   -
90   - /*
91   - * 是否发现问题
92   - */
93   - private Boolean sffxwt;
94   -
95   - /*
96   - * 单位名称
97   - */
98   - private String dwmc;
99   -
100   - /*
101   - * 单位编号
102   - */
103   - private String dwbh;
104   -
105   - /*
106   - * 单位负责人
107   - */
108   - private String dwfzr;
109   -
110   - /*
111   - * 人员
  37 + * 所属线体
112 38 */
113   - private String ry;
114   -
  39 + private String ssxt;
115 40 /*
116   - * 人员所属单位
  41 + * 所属单位
117 42 */
118   - private String ryssdw;
119   -
  43 + private String ssdw;
120 44 /*
121 45 * 所属室组
122 46 */
123 47 private String sssz;
124   -
125   - /*
126   - * 所属班组
127   - */
128   - private String ssbz;
129   -
130   - /*
131   - * 室组
132   - */
133   - private String sz;
134   -
135   - /*
136   - * 区域
137   - */
138   - private String qy;
139   -
140 48 /*
141 49 * 所属区域
142 50 */
143 51 private String ssqy;
144   -
145 52 /*
146   - * eaohkg
147   - */
148   - private String eaohkg;
149   -
150   - /*
151   - * 过程确认计划人员
152   - */
153   - private String gcqrjhry;
154   -
155   - /*
156   - * 单位
157   - */
158   - private String dw;
159   -
160   - /*
161   - * 所属单位
162   - */
163   - private String ssdw;
164   -
165   - /*
166   - * 所属线体
167   - */
168   - private String ssxt;
169   -
170   - /*
171   - * 人员姓名
  53 + * 所属班组
172 54 */
173   - private String ryxm;
174   -
  55 + private String ssbz;
175 56 /*
176   - * 是否已执行
  57 + * 状态-数据状态枚举:#1#-草稿;#2#-启用;#3#-停用;
177 58 */
178   - private Boolean sfyzx;
  59 + private String zt;
179 60 }
... ...
... ... @@ -104,6 +104,25 @@ public class CpsProblemService extends BaseServiceImpl<CpsProblem> {
104 104 }
105 105
106 106 /**
  107 + * 根据来源过程确认执行记录id集合查询问题记录
  108 + *
  109 + * @param lygcqrzxIds 来源过程确认执行记录id集合
  110 + * @return 问题记录列表
  111 + */
  112 + @Transactional(readOnly = true)
  113 + public List<CpsProblem> listByLygcqrzxIds(Collection<String> lygcqrzxIds) {
  114 + Assert.notEmpty(lygcqrzxIds, "lygcqrzxIds is empty!");
  115 +
  116 + Example example = new Example(entityClass);
  117 + example.createCriteria().andIn(CpsProblem.LYGCQRZX, lygcqrzxIds);
  118 + List<CpsProblem> cpsProblemList = cpsProblemMapper.selectByExample(example);
  119 + if (CollectionUtils.isEmpty(cpsProblemList)) {
  120 + return new ArrayList<>(0);
  121 + }
  122 + return cpsProblemList;
  123 + }
  124 +
  125 + /**
107 126 * 根据计划解决时间范围查询问题记录,并按责任单位 + 问题处理状态维度汇总问题数
108 127 * <p>
109 128 * 开始、结束时间为空时默认使用当前月的开始、结束时间
... ...
... ... @@ -3,15 +3,34 @@ package com.qgutech.qgyun.apaas.sync.cps.service;
3 3 import com.qgutech.qgyun.framework.database.mybatis.service.BaseServiceImpl;
4 4 import com.qgutech.qgyun.apaas.sync.base.BoErrorCode;
5 5 import com.qgutech.qgyun.apaas.sync.base.BoException;
  6 +import com.qgutech.qgyun.apaas.sync.cps.dto.PjoExecDetailDTO;
  7 +import com.qgutech.qgyun.apaas.sync.cps.dto.PjoExecSummaryDTO;
  8 +import com.qgutech.qgyun.apaas.sync.cps.dto.PjoStatBase;
  9 +import com.qgutech.qgyun.apaas.sync.cps.enums.GwxzEnum;
  10 +import com.qgutech.qgyun.apaas.sync.cps.enums.PjoExecZtEnum;
  11 +import com.qgutech.qgyun.apaas.sync.cps.enums.ZyczdwtEnum;
6 12 import com.qgutech.qgyun.apaas.sync.cps.mapper.PjoExecMapper;
  13 +import com.qgutech.qgyun.apaas.sync.cps.model.Area;
  14 +import com.qgutech.qgyun.apaas.sync.cps.model.PjoBatch;
7 15 import com.qgutech.qgyun.apaas.sync.cps.model.PjoExec;
  16 +import com.qgutech.qgyun.apaas.sync.cps.model.PjoWorkstationExec;
  17 +import com.qgutech.qgyun.apaas.sync.cps.model.Team;
  18 +import com.qgutech.qgyun.apaas.sync.cps.model.Workshop;
  19 +import com.qgutech.qgyun.apaas.sync.cps.model.XtLine;
  20 +import com.qgutech.qgyun.apaas.sync.org.model.UcUser;
  21 +import com.qgutech.qgyun.apaas.sync.org.service.UcUserService;
  22 +import com.qgutech.qgyun.apaas.sync.utils.DateDealUtils;
8 23 import org.apache.commons.collections4.CollectionUtils;
  24 +import org.apache.commons.lang3.StringUtils;
  25 +import org.springframework.beans.BeanUtils;
9 26 import org.springframework.stereotype.Service;
10 27 import org.springframework.transaction.annotation.Transactional;
11 28 import org.springframework.util.Assert;
12 29 import tk.mybatis.mapper.entity.Example;
13 30
14 31 import javax.annotation.Resource;
  32 +import java.math.BigDecimal;
  33 +import java.math.RoundingMode;
15 34 import java.util.*;
16 35 import java.util.stream.Collectors;
17 36
... ... @@ -24,6 +43,27 @@ public class PjoExecService extends BaseServiceImpl<PjoExec> {
24 43 @Resource
25 44 private PjoExecMapper pjoExecMapper;
26 45
  46 + @Resource
  47 + private WorkshopService workshopService;
  48 +
  49 + @Resource
  50 + private UcUserService ucUserService;
  51 +
  52 + @Resource
  53 + private AreaService areaService;
  54 +
  55 + @Resource
  56 + private TeamService teamService;
  57 +
  58 + @Resource
  59 + private XtLineService xtLineService;
  60 +
  61 + @Resource
  62 + private PjoBatchService pjoBatchService;
  63 +
  64 + @Resource
  65 + private PjoWorkstationExecService pjoWorkstationExecService;
  66 +
27 67 @Transactional(readOnly = true)
28 68 public PjoExec getById(String id) {
29 69 Assert.hasLength(id, "id is empty!");
... ... @@ -67,4 +107,383 @@ public class PjoExecService extends BaseServiceImpl<PjoExec> {
67 107
68 108 return pjoExecMapper.selectAll();
69 109 }
  110 +
  111 + /**
  112 + * 根据 PJO 开展日期范围查询 PJO 计划执行记录,并按 车间 + PJO执行人 维度汇总统计
  113 + * <p>
  114 + * 统计指标包括:PJO计划数、已执行数(状态 #3#-已执行)、执行率、发现问题数、问题发现率。
  115 + * 问题发现按第一、二、三阶段判断逻辑累加:
  116 + * <ul>
  117 + * <li>第一阶段:观察的问题(gcdwt)有值 → 发现一个问题</li>
  118 + * <li>第二阶段:观察的改善点描述(lfwkuc)有值 → 发现一个问题</li>
  119 + * <li>第三阶段:组员存在的问题(zyczdwt)有值且不是 #1#-无 → 发现一个问题</li>
  120 + * </ul>
  121 + * 层级结构:整体汇总 → 各车间(cjStats) → 各 PJO 执行人(zxrStats)。
  122 + * 开始时间为空时默认使用当前月 1 号,结束时间为空时默认使用当前日期前一天。
  123 + *
  124 + * @param startTime 开始时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前月 1 号 00:00:00)
  125 + * @param endTime 结束时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前日期前一天 23:59:59)
  126 + * @return PJO 计划执行汇总结果(车间按编号升序)
  127 + */
  128 + @Transactional(readOnly = true)
  129 + public PjoExecSummaryDTO summaryByPjoDate(String startTime, String endTime) {
  130 + // 1. 解析时间参数,开始时间为空默认当前月1号,结束时间为空默认当前日期前一天
  131 + Date start = DateDealUtils.parseStartTimeOrCurrentMonthStart(startTime);
  132 + Date end = DateDealUtils.parseEndTimeOrYesterdayEnd(endTime);
  133 + Assert.notNull(start, "startTime is invalid!");
  134 + Assert.notNull(end, "endTime is invalid!");
  135 + Assert.isTrue(!start.after(end), "startTime must be earlier than endTime!");
  136 +
  137 + // 2. 查询 PJO 开展日期在范围内的记录
  138 + Example example = new Example(PjoExec.class);
  139 + example.createCriteria().andBetween(PjoExec.QKXDWK, start, end);
  140 + List<PjoExec> execList = pjoExecMapper.selectByExample(example);
  141 +
  142 + // 3. 计算整体汇总
  143 + PjoExecSummaryDTO result = new PjoExecSummaryDTO();
  144 + fillStat(result, execList);
  145 + if (CollectionUtils.isEmpty(execList)) {
  146 + result.setCjStats(new ArrayList<>(0));
  147 + return result;
  148 + }
  149 +
  150 + // 4. 批量查询车间信息
  151 + Set<String> cjIds = execList.stream()
  152 + .map(PjoExec::getCj)
  153 + .filter(StringUtils::isNotBlank)
  154 + .collect(Collectors.toSet());
  155 + Map<String, Workshop> workshopMap = CollectionUtils.isEmpty(cjIds)
  156 + ? new HashMap<>(0) : workshopService.mapByIds(cjIds);
  157 +
  158 + // 5. 批量查询 PJO 执行人(组织用户)信息
  159 + Set<String> zxrIds = execList.stream()
  160 + .map(PjoExec::getPjozxr)
  161 + .filter(StringUtils::isNotBlank)
  162 + .collect(Collectors.toSet());
  163 + Map<String, UcUser> userMap = CollectionUtils.isEmpty(zxrIds)
  164 + ? new HashMap<>(0) : ucUserService.mapByIds(zxrIds);
  165 +
  166 + // 6. 按车间分组(车间为空的记录用空串作分组键,避免维度丢失)
  167 + Map<String, List<PjoExec>> cjExecMap = execList.stream()
  168 + .collect(Collectors.groupingBy(
  169 + item -> StringUtils.isBlank(item.getCj()) ? "" : item.getCj(),
  170 + Collectors.toList()));
  171 +
  172 + List<PjoExecSummaryDTO.CjStat> cjStats = new ArrayList<>();
  173 + for (Map.Entry<String, List<PjoExec>> cjEntry : cjExecMap.entrySet()) {
  174 + String cj = cjEntry.getKey();
  175 + List<PjoExec> cjExecList = cjEntry.getValue();
  176 +
  177 + PjoExecSummaryDTO.CjStat cjStat = new PjoExecSummaryDTO.CjStat();
  178 + cjStat.setCj(StringUtils.isBlank(cj) ? null : cj);
  179 + Workshop workshop = workshopMap.get(cj);
  180 + if (workshop != null) {
  181 + cjStat.setCjName(workshop.getDwmc());
  182 + cjStat.setCjCode(workshop.getDwbh());
  183 + }
  184 + fillStat(cjStat, cjExecList);
  185 +
  186 + // 6.1 车间内按 PJO 执行人分组
  187 + Map<String, List<PjoExec>> zxrExecMap = cjExecList.stream()
  188 + .collect(Collectors.groupingBy(
  189 + item -> StringUtils.isBlank(item.getPjozxr()) ? "" : item.getPjozxr(),
  190 + Collectors.toList()));
  191 + List<PjoExecSummaryDTO.ZxrStat> zxrStats = new ArrayList<>();
  192 + for (Map.Entry<String, List<PjoExec>> zxrEntry : zxrExecMap.entrySet()) {
  193 + String zxr = zxrEntry.getKey();
  194 + List<PjoExec> zxrExecList = zxrEntry.getValue();
  195 +
  196 + PjoExecSummaryDTO.ZxrStat zxrStat = new PjoExecSummaryDTO.ZxrStat();
  197 + zxrStat.setPjozxr(StringUtils.isBlank(zxr) ? null : zxr);
  198 + UcUser user = userMap.get(zxr);
  199 + if (user != null) {
  200 + zxrStat.setPjozxrName(user.getName());
  201 + }
  202 + fillStat(zxrStat, zxrExecList);
  203 + zxrStats.add(zxrStat);
  204 + }
  205 + // 执行人按姓名升序,姓名为空的排在最后
  206 + zxrStats.sort(Comparator.comparing(PjoExecSummaryDTO.ZxrStat::getPjozxrName,
  207 + Comparator.nullsLast(Comparator.naturalOrder())));
  208 + cjStat.setZxrStats(zxrStats);
  209 + cjStats.add(cjStat);
  210 + }
  211 +
  212 + // 7. 车间按编号升序排序,编号为空的排在最后
  213 + cjStats.sort(Comparator.comparing(PjoExecSummaryDTO.CjStat::getCjCode,
  214 + Comparator.nullsLast(Comparator.naturalOrder())));
  215 + result.setCjStats(cjStats);
  216 +
  217 + return result;
  218 + }
  219 +
  220 + /**
  221 + * 计算一组 PJO 记录的统计指标并填充到目标对象(整体/车间/执行人三级共用)
  222 + * <p>
  223 + * 指标包括:计划数、已执行数、执行率,第一/二/三阶段问题数与发现率,整体问题数与发现率。
  224 + */
  225 + private void fillStat(PjoStatBase target, List<PjoExec> list) {
  226 + int totalCount = CollectionUtils.isEmpty(list) ? 0 : list.size();
  227 + target.setTotalCount(totalCount);
  228 + if (totalCount == 0) {
  229 + target.setExecutedCount(0);
  230 + target.setExecRate(0.0);
  231 + target.setStage1ProblemCount(0);
  232 + target.setStage1ProblemRate(0.0);
  233 + target.setStage2ProblemCount(0);
  234 + target.setStage2ProblemRate(0.0);
  235 + target.setStage3ProblemCount(0);
  236 + target.setStage3ProblemRate(0.0);
  237 + target.setProblemCount(0);
  238 + target.setProblemRate(0.0);
  239 + return;
  240 + }
  241 + int executedCount = (int) list.stream().filter(this::isExecuted).count();
  242 + int stage1 = (int) list.stream().filter(this::hasStage1Problem).count();
  243 + int stage2 = (int) list.stream().filter(this::hasStage2Problem).count();
  244 + int stage3 = (int) list.stream().filter(this::hasStage3Problem).count();
  245 + int problemCount = stage1 + stage2 + stage3;
  246 +
  247 + target.setExecutedCount(executedCount);
  248 + target.setExecRate(round2((double) executedCount / totalCount * 100));
  249 + target.setStage1ProblemCount(stage1);
  250 + target.setStage1ProblemRate(round2((double) stage1 / totalCount * 100));
  251 + target.setStage2ProblemCount(stage2);
  252 + target.setStage2ProblemRate(round2((double) stage2 / totalCount * 100));
  253 + target.setStage3ProblemCount(stage3);
  254 + target.setStage3ProblemRate(round2((double) stage3 / totalCount * 100));
  255 + target.setProblemCount(problemCount);
  256 + target.setProblemRate(round2((double) problemCount / totalCount * 100));
  257 + }
  258 +
  259 + /**
  260 + * 是否为已执行状态(#3#-已执行)
  261 + */
  262 + private boolean isExecuted(PjoExec item) {
  263 + return PjoExecZtEnum.fromCode(item.getZt()) == PjoExecZtEnum.YIZHIXING;
  264 + }
  265 +
  266 + /**
  267 + * 第一阶段是否发现问题:观察的问题(gcdwt)有值
  268 + */
  269 + private boolean hasStage1Problem(PjoExec item) {
  270 + return StringUtils.isNotBlank(item.getGcdwt());
  271 + }
  272 +
  273 + /**
  274 + * 第二阶段是否发现问题:观察的改善点描述(lfwkuc)有值
  275 + */
  276 + private boolean hasStage2Problem(PjoExec item) {
  277 + return StringUtils.isNotBlank(item.getLfwkuc());
  278 + }
  279 +
  280 + /**
  281 + * 第三阶段是否发现问题:组员存在的问题(zyczdwt)有值且不是 #1#-无
  282 + */
  283 + private boolean hasStage3Problem(PjoExec item) {
  284 + return StringUtils.isNotBlank(item.getZyczdwt())
  285 + && ZyczdwtEnum.fromCode(item.getZyczdwt()) != ZyczdwtEnum.WU;
  286 + }
  287 +
  288 + /**
  289 + * 根据条件查询 PJO 计划执行记录明细列表
  290 + * <p>
  291 + * 所有参数均非必填:
  292 + * <ul>
  293 + * <li>startTime/endTime:PJO 开展日期范围,开始时间为空默认当前月 1 号 00:00:00,结束时间为空默认当前日期前一天 23:59:59</li>
  294 + * <li>cj:车间单位id</li>
  295 + * <li>pjozxr:PJO 执行人id(组织用户)</li>
  296 + * </ul>
  297 + * 结果中包含车间、区域、班组、线体、批次、工位、执行人等关联实体名称及枚举中文描述、各阶段问题标记
  298 + *
  299 + * @param startTime 开始时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前月 1 号 00:00:00)
  300 + * @param endTime 结束时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前日期前一天 23:59:59)
  301 + * @param cj 车间单位id,可为空
  302 + * @param pjozxr PJO 执行人id,可为空
  303 + * @return PJO 计划执行记录明细列表(按 PJO 开展日期降序)
  304 + */
  305 + @Transactional(readOnly = true)
  306 + public List<PjoExecDetailDTO> listDetailByCondition(String startTime, String endTime,
  307 + String cj, String pjozxr) {
  308 + // 1. 解析时间参数,开始时间为空默认当前月1号,结束时间为空默认当前日期前一天
  309 + Date start = DateDealUtils.parseStartTimeOrCurrentMonthStart(startTime);
  310 + Date end = DateDealUtils.parseEndTimeOrYesterdayEnd(endTime);
  311 + Assert.notNull(start, "startTime is invalid!");
  312 + Assert.notNull(end, "endTime is invalid!");
  313 + Assert.isTrue(!start.after(end), "startTime must be earlier than endTime!");
  314 +
  315 + // 2. 构建查询条件(PJO 开展日期范围必带,其余条件非空才追加)
  316 + Example example = new Example(PjoExec.class);
  317 + Example.Criteria criteria = example.createCriteria()
  318 + .andBetween(PjoExec.QKXDWK, start, end);
  319 + if (StringUtils.isNotBlank(cj)) {
  320 + criteria.andEqualTo(PjoExec.CJ, cj);
  321 + }
  322 + if (StringUtils.isNotBlank(pjozxr)) {
  323 + criteria.andEqualTo(PjoExec.PJOZXR, pjozxr);
  324 + }
  325 + List<PjoExec> execList = pjoExecMapper.selectByExample(example);
  326 + if (CollectionUtils.isEmpty(execList)) {
  327 + return new ArrayList<>(0);
  328 + }
  329 +
  330 + // 3. 收集所有关联实体ID
  331 + Set<String> workshopIds = new HashSet<>();
  332 + Set<String> areaIds = new HashSet<>();
  333 + Set<String> teamIds = new HashSet<>();
  334 + Set<String> xtLineIds = new HashSet<>();
  335 + Set<String> batchIds = new HashSet<>();
  336 + Set<String> workstationIds = new HashSet<>();
  337 + Set<String> userIds = new HashSet<>();
  338 + for (PjoExec item : execList) {
  339 + if (StringUtils.isNotBlank(item.getCj())) workshopIds.add(item.getCj());
  340 + if (StringUtils.isNotBlank(item.getQy())) areaIds.add(item.getQy());
  341 + if (StringUtils.isNotBlank(item.getBz())) teamIds.add(item.getBz());
  342 + if (StringUtils.isNotBlank(item.getXt())) xtLineIds.add(item.getXt());
  343 + if (StringUtils.isNotBlank(item.getPjopc())) batchIds.add(item.getPjopc());
  344 + if (StringUtils.isNotBlank(item.getGwzx1())) workstationIds.add(item.getGwzx1());
  345 + if (StringUtils.isNotBlank(item.getGwzx2())) workstationIds.add(item.getGwzx2());
  346 + if (StringUtils.isNotBlank(item.getPjozxr())) userIds.add(item.getPjozxr());
  347 + if (StringUtils.isNotBlank(item.getCyjy())) userIds.add(item.getCyjy());
  348 + }
  349 +
  350 + // 4. 批量查询关联实体
  351 + Map<String, Workshop> workshopMap = CollectionUtils.isEmpty(workshopIds)
  352 + ? new HashMap<>(0) : workshopService.mapByIds(workshopIds);
  353 + Map<String, Area> areaMap = CollectionUtils.isEmpty(areaIds)
  354 + ? new HashMap<>(0) : areaService.mapByIds(areaIds);
  355 + Map<String, Team> teamMap = CollectionUtils.isEmpty(teamIds)
  356 + ? new HashMap<>(0) : teamService.mapByIds(teamIds);
  357 + Map<String, XtLine> xtLineMap = CollectionUtils.isEmpty(xtLineIds)
  358 + ? new HashMap<>(0) : xtLineService.mapByIds(xtLineIds);
  359 + Map<String, PjoBatch> batchMap = CollectionUtils.isEmpty(batchIds)
  360 + ? new HashMap<>(0) : pjoBatchService.mapByIds(batchIds);
  361 + Map<String, PjoWorkstationExec> workstationMap = CollectionUtils.isEmpty(workstationIds)
  362 + ? new HashMap<>(0) : pjoWorkstationExecService.mapByIds(workstationIds);
  363 + Map<String, UcUser> userMap = CollectionUtils.isEmpty(userIds)
  364 + ? new HashMap<>(0) : ucUserService.mapByIds(userIds);
  365 +
  366 + // 5. 组装明细结果
  367 + List<PjoExecDetailDTO> resultList = buildDetailList(execList, workshopMap, areaMap,
  368 + teamMap, xtLineMap, batchMap, workstationMap, userMap);
  369 +
  370 + // 6. 按 PJO 开展日期降序排序,为空的排在最后
  371 + resultList.sort(Comparator.comparing(PjoExecDetailDTO::getQkxdwk,
  372 + Comparator.nullsLast(Comparator.reverseOrder())));
  373 + return resultList;
  374 + }
  375 +
  376 + /**
  377 + * 组装 PJO 计划执行记录明细 DTO 列表(含枚举名称、关联实体名称、各阶段问题标记)
  378 + */
  379 + private List<PjoExecDetailDTO> buildDetailList(List<PjoExec> execList,
  380 + Map<String, Workshop> workshopMap,
  381 + Map<String, Area> areaMap,
  382 + Map<String, Team> teamMap,
  383 + Map<String, XtLine> xtLineMap,
  384 + Map<String, PjoBatch> batchMap,
  385 + Map<String, PjoWorkstationExec> workstationMap,
  386 + Map<String, UcUser> userMap) {
  387 + return execList.stream()
  388 + .map(item -> {
  389 + PjoExecDetailDTO dto = new PjoExecDetailDTO();
  390 + // 复制原始字段(同名属性)
  391 + BeanUtils.copyProperties(item, dto);
  392 +
  393 + // 枚举字段中文名称
  394 + dto.setGwxzDesc(GwxzEnum.getDescByCode(item.getGwxz()));
  395 + dto.setZtDesc(PjoExecZtEnum.getDescByCode(item.getZt()));
  396 + dto.setZyczdwtDesc(ZyczdwtEnum.getDescByCode(item.getZyczdwt()));
  397 +
  398 + // 各阶段问题标记及问题总数
  399 + boolean stage1 = hasStage1Problem(item);
  400 + boolean stage2 = hasStage2Problem(item);
  401 + boolean stage3 = hasStage3Problem(item);
  402 + dto.setStage1Problem(stage1);
  403 + dto.setStage2Problem(stage2);
  404 + dto.setStage3Problem(stage3);
  405 + dto.setProblemCount((stage1 ? 1 : 0) + (stage2 ? 1 : 0) + (stage3 ? 1 : 0));
  406 +
  407 + // PJO 执行人
  408 + if (item.getPjozxr() != null) {
  409 + UcUser user = userMap.get(item.getPjozxr());
  410 + if (user != null) {
  411 + dto.setPjozxrName(user.getName());
  412 + }
  413 + }
  414 + // 成员建议&意见处理人员
  415 + if (item.getCyjy() != null) {
  416 + UcUser user = userMap.get(item.getCyjy());
  417 + if (user != null) {
  418 + dto.setCyjyName(user.getName());
  419 + }
  420 + }
  421 + // PJO 批次
  422 + if (item.getPjopc() != null) {
  423 + PjoBatch batch = batchMap.get(item.getPjopc());
  424 + if (batch != null) {
  425 + dto.setPjopcName(batch.getPcmc());
  426 + dto.setPjopcCode(batch.getPcbh());
  427 + }
  428 + }
  429 + // 工位1
  430 + if (item.getGwzx1() != null) {
  431 + PjoWorkstationExec ws = workstationMap.get(item.getGwzx1());
  432 + if (ws != null) {
  433 + dto.setGwzx1Name(ws.getGwmc());
  434 + dto.setGwzx1Code(ws.getGwbh());
  435 + }
  436 + }
  437 + // 工位2
  438 + if (item.getGwzx2() != null) {
  439 + PjoWorkstationExec ws = workstationMap.get(item.getGwzx2());
  440 + if (ws != null) {
  441 + dto.setGwzx2Name(ws.getGwmc());
  442 + dto.setGwzx2Code(ws.getGwbh());
  443 + }
  444 + }
  445 + // 车间
  446 + if (item.getCj() != null) {
  447 + Workshop workshop = workshopMap.get(item.getCj());
  448 + if (workshop != null) {
  449 + dto.setCjName(workshop.getDwmc());
  450 + dto.setCjCode(workshop.getDwbh());
  451 + }
  452 + }
  453 + // 区域
  454 + if (item.getQy() != null) {
  455 + Area area = areaMap.get(item.getQy());
  456 + if (area != null) {
  457 + dto.setQyName(area.getQymc());
  458 + dto.setQyCode(area.getQybh());
  459 + }
  460 + }
  461 + // 班组
  462 + if (item.getBz() != null) {
  463 + Team team = teamMap.get(item.getBz());
  464 + if (team != null) {
  465 + dto.setBzName(team.getBzmc());
  466 + dto.setBzCode(team.getBzbh());
  467 + }
  468 + }
  469 + // 线体
  470 + if (item.getXt() != null) {
  471 + XtLine xtLine = xtLineMap.get(item.getXt());
  472 + if (xtLine != null) {
  473 + dto.setXtName(xtLine.getXtmc());
  474 + dto.setXtCode(xtLine.getXtbh());
  475 + }
  476 + }
  477 +
  478 + return dto;
  479 + })
  480 + .collect(Collectors.toList());
  481 + }
  482 +
  483 + /**
  484 + * 保留两位小数,四舍五入
  485 + */
  486 + private double round2(double value) {
  487 + return BigDecimal.valueOf(value).setScale(2, RoundingMode.HALF_UP).doubleValue();
  488 + }
70 489 }
... ...
1 1 package com.qgutech.qgyun.apaas.sync.cps.service;
2 2
3   -import com.qgutech.qgyun.framework.database.mybatis.service.BaseServiceImpl;
4 3 import com.qgutech.qgyun.apaas.sync.base.BoErrorCode;
5 4 import com.qgutech.qgyun.apaas.sync.base.BoException;
  5 +import com.qgutech.qgyun.apaas.sync.cps.dto.ProcessConfirmExecDetailDTO;
  6 +import com.qgutech.qgyun.apaas.sync.cps.dto.ProcessConfirmExecSummaryDTO;
  7 +import com.qgutech.qgyun.apaas.sync.cps.enums.GcqrZtEnum;
  8 +import com.qgutech.qgyun.apaas.sync.cps.enums.RylbEnum;
  9 +import com.qgutech.qgyun.apaas.sync.cps.enums.WzxyysEnum;
6 10 import com.qgutech.qgyun.apaas.sync.cps.mapper.ProcessConfirmExecMapper;
  11 +import com.qgutech.qgyun.apaas.sync.cps.model.Area;
  12 +import com.qgutech.qgyun.apaas.sync.cps.model.CpsProblem;
7 13 import com.qgutech.qgyun.apaas.sync.cps.model.ProcessConfirmExec;
  14 +import com.qgutech.qgyun.apaas.sync.cps.model.ProcessConfirmPersonnel;
  15 +import com.qgutech.qgyun.apaas.sync.cps.model.RoomGroup;
  16 +import com.qgutech.qgyun.apaas.sync.cps.model.Shift;
  17 +import com.qgutech.qgyun.apaas.sync.cps.model.Team;
  18 +import com.qgutech.qgyun.apaas.sync.cps.model.Workshop;
  19 +import com.qgutech.qgyun.apaas.sync.cps.model.XtLine;
  20 +import com.qgutech.qgyun.apaas.sync.utils.DateDealUtils;
  21 +import com.qgutech.qgyun.framework.database.mybatis.service.BaseServiceImpl;
8 22 import org.apache.commons.collections4.CollectionUtils;
  23 +import org.apache.commons.lang3.StringUtils;
  24 +import org.springframework.beans.BeanUtils;
9 25 import org.springframework.stereotype.Service;
10 26 import org.springframework.transaction.annotation.Transactional;
11 27 import org.springframework.util.Assert;
12 28 import tk.mybatis.mapper.entity.Example;
13 29
14 30 import javax.annotation.Resource;
  31 +import java.math.BigDecimal;
  32 +import java.math.RoundingMode;
15 33 import java.util.*;
16 34 import java.util.stream.Collectors;
17 35
... ... @@ -24,6 +42,30 @@ public class ProcessConfirmExecService extends BaseServiceImpl<ProcessConfirmExe
24 42 @Resource
25 43 private ProcessConfirmExecMapper processConfirmExecMapper;
26 44
  45 + @Resource
  46 + private WorkshopService workshopService;
  47 +
  48 + @Resource
  49 + private CpsProblemService cpsProblemService;
  50 +
  51 + @Resource
  52 + private RoomGroupService roomGroupService;
  53 +
  54 + @Resource
  55 + private AreaService areaService;
  56 +
  57 + @Resource
  58 + private TeamService teamService;
  59 +
  60 + @Resource
  61 + private XtLineService xtLineService;
  62 +
  63 + @Resource
  64 + private ShiftService shiftService;
  65 +
  66 + @Resource
  67 + private ProcessConfirmPersonnelService processConfirmPersonnelService;
  68 +
27 69 @Transactional(readOnly = true)
28 70 public ProcessConfirmExec getById(String id) {
29 71 Assert.hasLength(id, "id is empty!");
... ... @@ -67,4 +109,362 @@ public class ProcessConfirmExecService extends BaseServiceImpl<ProcessConfirmExe
67 109
68 110 return processConfirmExecMapper.selectAll();
69 111 }
  112 +
  113 + /**
  114 + * 根据活动执行日期范围查询过程确认执行记录,并按单位 + 人员类别维度汇总统计
  115 + * <p>
  116 + * 统计维度包括:
  117 + * <ul>
  118 + * <li>各单位:记录总数、已执行数量、执行率、问题发现数、问题发现率</li>
  119 + * <li>各单位下各人员类别:记录总数、已执行数量、执行率、问题发现数、问题发现率</li>
  120 + * <li>整体:记录总数、已执行总数、总执行率、问题发现总数、总问题发现率</li>
  121 + * </ul>
  122 + * 开始、结束时间为空时默认使用当前月的开始、结束时间
  123 + *
  124 + * @param startTime 开始时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前月 1 号 00:00:00)
  125 + * @param endTime 结束时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前日期前一天 23:59:59)
  126 + * @return 过程确认执行记录汇总结果(按单位编号升序)
  127 + */
  128 + @Transactional(readOnly = true)
  129 + public ProcessConfirmExecSummaryDTO summaryByExecDate(String startTime, String endTime) {
  130 + // 1. 解析时间参数,开始时间为空默认当前月1号,结束时间为空默认当前日期前一天
  131 + Date start = DateDealUtils.parseStartTimeOrCurrentMonthStart(startTime);
  132 + Date end = DateDealUtils.parseEndTimeOrYesterdayEnd(endTime);
  133 + Assert.notNull(start, "startTime is invalid!");
  134 + Assert.notNull(end, "endTime is invalid!");
  135 + Assert.isTrue(!start.after(end), "startTime must be earlier than endTime!");
  136 +
  137 + // 2. 查询活动执行日期在范围内的过程确认执行记录
  138 + Example example = new Example(ProcessConfirmExec.class);
  139 + example.createCriteria()
  140 + .andBetween(ProcessConfirmExec.HDZXRQ, start, end);
  141 + List<ProcessConfirmExec> execList = processConfirmExecMapper.selectByExample(example);
  142 +
  143 + // 3. 查询关联的问题记录(来源过程确认执行记录id在execList中的问题)
  144 + List<String> execIds = execList.stream()
  145 + .map(ProcessConfirmExec::getId)
  146 + .collect(Collectors.toList());
  147 + List<CpsProblem> problemList = CollectionUtils.isEmpty(execIds)
  148 + ? new ArrayList<>(0)
  149 + : cpsProblemService.listByLygcqrzxIds(execIds);
  150 +
  151 + // 4. 构建 execId -> problemList 映射(一个exec可能对应多个问题)
  152 + Map<String, List<CpsProblem>> execProblemMap = problemList.stream()
  153 + .filter(item -> item.getLygcqrzx() != null)
  154 + .collect(Collectors.groupingBy(CpsProblem::getLygcqrzx));
  155 +
  156 + // 5. 按单位分组统计
  157 + Map<String, List<ProcessConfirmExec>> dwExecMap = execList.stream()
  158 + .filter(item -> item.getDw() != null)
  159 + .collect(Collectors.groupingBy(ProcessConfirmExec::getDw));
  160 +
  161 + // 6. 批量查询单位信息
  162 + Set<String> workshopIds = dwExecMap.keySet();
  163 + Map<String, Workshop> workshopMap = CollectionUtils.isEmpty(workshopIds)
  164 + ? new HashMap<>(0) : workshopService.mapByIds(workshopIds);
  165 +
  166 + // 7. 组装各单位汇总结果
  167 + List<ProcessConfirmExecSummaryDTO> dwSummaryList = dwExecMap.entrySet().stream()
  168 + .map(entry -> {
  169 + String dw = entry.getKey();
  170 + List<ProcessConfirmExec> dwExecList = entry.getValue();
  171 +
  172 + ProcessConfirmExecSummaryDTO dto = new ProcessConfirmExecSummaryDTO();
  173 + dto.setDw(dw);
  174 +
  175 + // 设置单位名称、编号
  176 + Workshop workshop = workshopMap.get(dw);
  177 + if (workshop != null) {
  178 + dto.setDwName(workshop.getDwmc());
  179 + dto.setDwCode(workshop.getDwbh());
  180 + }
  181 +
  182 + // 计算该单位总数、已执行数、执行率
  183 + int totalCount = dwExecList.size();
  184 + int executedCount = (int) dwExecList.stream()
  185 + .filter(item -> Boolean.TRUE.equals(item.getSfyzx()))
  186 + .count();
  187 + double execRate = totalCount > 0 ? round2((double) executedCount / totalCount * 100) : 0.0;
  188 + dto.setTotalCount(totalCount);
  189 + dto.setExecutedCount(executedCount);
  190 + dto.setExecRate(execRate);
  191 +
  192 + // 计算该单位问题发现数、问题发现率
  193 + int problemCount = dwExecList.stream()
  194 + .mapToInt(item -> {
  195 + List<CpsProblem> problems = execProblemMap.get(item.getId());
  196 + return problems == null ? 0 : problems.size();
  197 + })
  198 + .sum();
  199 + double problemRate = totalCount > 0 ? round2((double) problemCount / totalCount * 100) : 0.0;
  200 + dto.setProblemCount(problemCount);
  201 + dto.setProblemRate(problemRate);
  202 +
  203 + // 按人员类别分组统计
  204 + Map<String, List<ProcessConfirmExec>> rylbExecMap = dwExecList.stream()
  205 + .filter(item -> item.getRylb() != null)
  206 + .collect(Collectors.groupingBy(ProcessConfirmExec::getRylb));
  207 + List<ProcessConfirmExecSummaryDTO.RylbStat> rylbStats = new ArrayList<>();
  208 + for (RylbEnum rylbEnum : RylbEnum.values()) {
  209 + List<ProcessConfirmExec> rylbExecList = rylbExecMap.get(rylbEnum.getCode());
  210 + int rylbTotal = rylbExecList == null ? 0 : rylbExecList.size();
  211 + int rylbExecuted = rylbExecList == null ? 0 : (int) rylbExecList.stream()
  212 + .filter(item -> Boolean.TRUE.equals(item.getSfyzx()))
  213 + .count();
  214 + double rylbExecRate = rylbTotal > 0 ? round2((double) rylbExecuted / rylbTotal * 100) : 0.0;
  215 + int rylbProblemCount = rylbExecList == null ? 0 : rylbExecList.stream()
  216 + .mapToInt(item -> {
  217 + List<CpsProblem> problems = execProblemMap.get(item.getId());
  218 + return problems == null ? 0 : problems.size();
  219 + })
  220 + .sum();
  221 + double rylbProblemRate = rylbTotal > 0 ? round2((double) rylbProblemCount / rylbTotal * 100) : 0.0;
  222 + rylbStats.add(new ProcessConfirmExecSummaryDTO.RylbStat(
  223 + rylbEnum.getCode(), rylbEnum.getDesc(),
  224 + rylbTotal, rylbExecuted, rylbExecRate,
  225 + rylbProblemCount, rylbProblemRate));
  226 + }
  227 + // 处理非预定义人员类别(如空值或异常编号)
  228 + for (Map.Entry<String, List<ProcessConfirmExec>> rylbEntry : rylbExecMap.entrySet()) {
  229 + String code = rylbEntry.getKey();
  230 + if (StringUtils.isBlank(code) || RylbEnum.fromCode(code) == null) {
  231 + List<ProcessConfirmExec> rylbExecList = rylbEntry.getValue();
  232 + int rylbTotal = rylbExecList.size();
  233 + int rylbExecuted = (int) rylbExecList.stream()
  234 + .filter(item -> Boolean.TRUE.equals(item.getSfyzx()))
  235 + .count();
  236 + double rylbExecRate = rylbTotal > 0 ? round2((double) rylbExecuted / rylbTotal * 100) : 0.0;
  237 + int rylbProblemCount = rylbExecList.stream()
  238 + .mapToInt(item -> {
  239 + List<CpsProblem> problems = execProblemMap.get(item.getId());
  240 + return problems == null ? 0 : problems.size();
  241 + })
  242 + .sum();
  243 + double rylbProblemRate = rylbTotal > 0 ? round2((double) rylbProblemCount / rylbTotal * 100) : 0.0;
  244 + String desc = StringUtils.isBlank(code) ? "未设置" : code;
  245 + rylbStats.add(new ProcessConfirmExecSummaryDTO.RylbStat(
  246 + code, desc, rylbTotal, rylbExecuted, rylbExecRate,
  247 + rylbProblemCount, rylbProblemRate));
  248 + }
  249 + }
  250 + dto.setRylbStats(rylbStats);
  251 +
  252 + return dto;
  253 + })
  254 + .collect(Collectors.toList());
  255 +
  256 + // 8. 按单位编号升序排序,编号为空的排在最后
  257 + dwSummaryList.sort(Comparator.comparing(ProcessConfirmExecSummaryDTO::getDwCode,
  258 + Comparator.nullsLast(Comparator.naturalOrder())));
  259 +
  260 + // 9. 计算整体汇总
  261 + ProcessConfirmExecSummaryDTO result = new ProcessConfirmExecSummaryDTO();
  262 + int totalCount = execList.size();
  263 + int executedCount = (int) execList.stream()
  264 + .filter(item -> Boolean.TRUE.equals(item.getSfyzx()))
  265 + .count();
  266 + double execRate = totalCount > 0 ? round2((double) executedCount / totalCount * 100) : 0.0;
  267 + int problemCount = problemList.size();
  268 + double problemRate = totalCount > 0 ? round2((double) problemCount / totalCount * 100) : 0.0;
  269 + result.setTotalCount(totalCount);
  270 + result.setExecutedCount(executedCount);
  271 + result.setExecRate(execRate);
  272 + result.setProblemCount(problemCount);
  273 + result.setProblemRate(problemRate);
  274 + result.setRylbStats(new ArrayList<>(0));
  275 + result.setDwStats(dwSummaryList);
  276 +
  277 + return result;
  278 + }
  279 +
  280 + /**
  281 + * 根据条件查询过程确认执行记录明细列表(不含问题记录信息)
  282 + * <p>
  283 + * 所有参数均非必填:
  284 + * <ul>
  285 + * <li>startTime/endTime:活动执行日期范围,开始时间为空默认当前月 1 号 00:00:00,结束时间为空默认当前日期前一天 23:59:59</li>
  286 + * <li>dw:单位id</li>
  287 + * <li>rylb:人员类别编号(兼容 #1# 与 1 两种形式)</li>
  288 + * <li>zt:过程确认状态编号(兼容 #1# 与 1 两种形式)</li>
  289 + * </ul>
  290 + * 结果中包含单位、室组、区域、班组、线体、班次、计划人员等关联实体名称及枚举中文描述
  291 + *
  292 + * @param startTime 开始时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前月 1 号 00:00:00)
  293 + * @param endTime 结束时间,格式:yyyy-MM-dd [HH:mm:ss],可为空(默认当前日期前一天 23:59:59)
  294 + * @param dw 单位id,可为空
  295 + * @param rylb 人员类别编号,可为空
  296 + * @param zt 过程确认状态编号,可为空
  297 + * @return 过程确认执行记录明细列表(按活动执行日期降序)
  298 + */
  299 + @Transactional(readOnly = true)
  300 + public List<ProcessConfirmExecDetailDTO> listDetailByCondition(String startTime, String endTime,
  301 + String dw, String rylb, String zt) {
  302 + // 1. 解析时间参数,开始时间为空默认当前月1号,结束时间为空默认当前日期前一天
  303 + Date start = DateDealUtils.parseStartTimeOrCurrentMonthStart(startTime);
  304 + Date end = DateDealUtils.parseEndTimeOrYesterdayEnd(endTime);
  305 + Assert.notNull(start, "startTime is invalid!");
  306 + Assert.notNull(end, "endTime is invalid!");
  307 + Assert.isTrue(!start.after(end), "startTime must be earlier than endTime!");
  308 +
  309 + // 2. 构建查询条件(活动执行日期范围必带,其余条件非空才追加)
  310 + Example example = new Example(ProcessConfirmExec.class);
  311 + Example.Criteria criteria = example.createCriteria()
  312 + .andBetween(ProcessConfirmExec.HDZXRQ, start, end);
  313 + if (StringUtils.isNotBlank(dw)) {
  314 + criteria.andEqualTo(ProcessConfirmExec.DW, dw);
  315 + }
  316 + if (StringUtils.isNotBlank(rylb)) {
  317 + RylbEnum rylbEnum = RylbEnum.fromCode(rylb);
  318 + Assert.notNull(rylbEnum, "rylb format is invalid!");
  319 + criteria.andEqualTo(ProcessConfirmExec.RYLB, rylbEnum.getCode());
  320 + }
  321 + if (StringUtils.isNotBlank(zt)) {
  322 + GcqrZtEnum ztEnum = GcqrZtEnum.fromCode(zt);
  323 + Assert.notNull(ztEnum, "zt format is invalid!");
  324 + criteria.andEqualTo(ProcessConfirmExec.ZT, ztEnum.getCode());
  325 + }
  326 + List<ProcessConfirmExec> execList = processConfirmExecMapper.selectByExample(example);
  327 + if (CollectionUtils.isEmpty(execList)) {
  328 + return new ArrayList<>(0);
  329 + }
  330 +
  331 + // 3. 收集所有关联实体ID
  332 + Set<String> workshopIds = new HashSet<>();
  333 + Set<String> roomGroupIds = new HashSet<>();
  334 + Set<String> areaIds = new HashSet<>();
  335 + Set<String> teamIds = new HashSet<>();
  336 + Set<String> xtLineIds = new HashSet<>();
  337 + Set<String> shiftIds = new HashSet<>();
  338 + Set<String> personnelIds = new HashSet<>();
  339 + for (ProcessConfirmExec item : execList) {
  340 + if (item.getDw() != null) workshopIds.add(item.getDw());
  341 + if (item.getSz() != null) roomGroupIds.add(item.getSz());
  342 + if (item.getQy() != null) areaIds.add(item.getQy());
  343 + if (item.getBz() != null) teamIds.add(item.getBz());
  344 + if (item.getXt() != null) xtLineIds.add(item.getXt());
  345 + if (item.getBc() != null) shiftIds.add(item.getBc());
  346 + if (item.getGcqrjhry() != null) personnelIds.add(item.getGcqrjhry());
  347 + }
  348 +
  349 + // 4. 批量查询关联实体
  350 + Map<String, Workshop> workshopMap = CollectionUtils.isEmpty(workshopIds)
  351 + ? new HashMap<>(0) : workshopService.mapByIds(workshopIds);
  352 + Map<String, RoomGroup> roomGroupMap = CollectionUtils.isEmpty(roomGroupIds)
  353 + ? new HashMap<>(0) : roomGroupService.mapByIds(roomGroupIds);
  354 + Map<String, Area> areaMap = CollectionUtils.isEmpty(areaIds)
  355 + ? new HashMap<>(0) : areaService.mapByIds(areaIds);
  356 + Map<String, Team> teamMap = CollectionUtils.isEmpty(teamIds)
  357 + ? new HashMap<>(0) : teamService.mapByIds(teamIds);
  358 + Map<String, XtLine> xtLineMap = CollectionUtils.isEmpty(xtLineIds)
  359 + ? new HashMap<>(0) : xtLineService.mapByIds(xtLineIds);
  360 + Map<String, Shift> shiftMap = CollectionUtils.isEmpty(shiftIds)
  361 + ? new HashMap<>(0) : shiftService.mapByIds(shiftIds);
  362 + Map<String, ProcessConfirmPersonnel> personnelMap = CollectionUtils.isEmpty(personnelIds)
  363 + ? new HashMap<>(0) : processConfirmPersonnelService.mapByIds(personnelIds);
  364 +
  365 + // 5. 组装明细结果
  366 + List<ProcessConfirmExecDetailDTO> resultList = buildDetailList(execList, workshopMap, roomGroupMap,
  367 + areaMap, teamMap, xtLineMap, shiftMap, personnelMap);
  368 +
  369 + // 6. 按活动执行日期降序排序,为空的排在最后
  370 + resultList.sort(Comparator.comparing(ProcessConfirmExecDetailDTO::getHdzxrq,
  371 + Comparator.nullsLast(Comparator.reverseOrder())));
  372 + return resultList;
  373 + }
  374 +
  375 + /**
  376 + * 组装过程确认执行记录明细 DTO 列表(含枚举名称、关联实体名称)
  377 + */
  378 + private List<ProcessConfirmExecDetailDTO> buildDetailList(List<ProcessConfirmExec> execList,
  379 + Map<String, Workshop> workshopMap,
  380 + Map<String, RoomGroup> roomGroupMap,
  381 + Map<String, Area> areaMap,
  382 + Map<String, Team> teamMap,
  383 + Map<String, XtLine> xtLineMap,
  384 + Map<String, Shift> shiftMap,
  385 + Map<String, ProcessConfirmPersonnel> personnelMap) {
  386 + return execList.stream()
  387 + .map(item -> {
  388 + ProcessConfirmExecDetailDTO dto = new ProcessConfirmExecDetailDTO();
  389 + // 复制原始字段(同名属性)
  390 + BeanUtils.copyProperties(item, dto);
  391 +
  392 + // 枚举字段中文名称
  393 + dto.setRylbDesc(RylbEnum.getDescByCode(item.getRylb()));
  394 + dto.setZtDesc(GcqrZtEnum.getDescByCode(item.getZt()));
  395 + dto.setWzxyysDesc(WzxyysEnum.getDescByCode(item.getWzxyys()));
  396 +
  397 + // 计划人员姓名
  398 + if (item.getGcqrjhry() != null) {
  399 + ProcessConfirmPersonnel personnel = personnelMap.get(item.getGcqrjhry());
  400 + if (personnel != null) {
  401 + dto.setGcqrjhryName(personnel.getRyxm());
  402 + }
  403 + }
  404 +
  405 + // 单位
  406 + if (item.getDw() != null) {
  407 + Workshop ws = workshopMap.get(item.getDw());
  408 + if (ws != null) {
  409 + dto.setDwName(ws.getDwmc());
  410 + dto.setDwCode(ws.getDwbh());
  411 + }
  412 + }
  413 +
  414 + // 室组
  415 + if (item.getSz() != null) {
  416 + RoomGroup rg = roomGroupMap.get(item.getSz());
  417 + if (rg != null) {
  418 + dto.setSzName(rg.getSzmc());
  419 + dto.setSzCode(rg.getSzbh());
  420 + }
  421 + }
  422 +
  423 + // 区域
  424 + if (item.getQy() != null) {
  425 + Area area = areaMap.get(item.getQy());
  426 + if (area != null) {
  427 + dto.setQyName(area.getQymc());
  428 + dto.setQyCode(area.getQybh());
  429 + }
  430 + }
  431 +
  432 + // 班组
  433 + if (item.getBz() != null) {
  434 + Team team = teamMap.get(item.getBz());
  435 + if (team != null) {
  436 + dto.setBzName(team.getBzmc());
  437 + dto.setBzCode(team.getBzbh());
  438 + }
  439 + }
  440 +
  441 + // 线体
  442 + if (item.getXt() != null) {
  443 + XtLine xtLine = xtLineMap.get(item.getXt());
  444 + if (xtLine != null) {
  445 + dto.setXtName(xtLine.getXtmc());
  446 + dto.setXtCode(xtLine.getXtbh());
  447 + }
  448 + }
  449 +
  450 + // 班次
  451 + if (item.getBc() != null) {
  452 + Shift shift = shiftMap.get(item.getBc());
  453 + if (shift != null) {
  454 + dto.setBcName(shift.getBcmc());
  455 + dto.setBcCode(shift.getBcbh());
  456 + }
  457 + }
  458 +
  459 + return dto;
  460 + })
  461 + .collect(Collectors.toList());
  462 + }
  463 +
  464 + /**
  465 + * 保留两位小数,四舍五入
  466 + */
  467 + private double round2(double value) {
  468 + return BigDecimal.valueOf(value).setScale(2, RoundingMode.HALF_UP).doubleValue();
  469 + }
70 470 }
... ...
... ... @@ -177,4 +177,27 @@ public class DateDealUtils {
177 177 }
178 178 return parseEndTime(dateStr);
179 179 }
  180 +
  181 + /**
  182 + * 获取当前日期前一天的结束时间(昨天 23:59:59.999)
  183 + */
  184 + public static Date getYesterdayEndTime() {
  185 + Calendar cal = Calendar.getInstance();
  186 + cal.add(Calendar.DAY_OF_MONTH, -1);
  187 + cal.set(Calendar.HOUR_OF_DAY, 23);
  188 + cal.set(Calendar.MINUTE, 59);
  189 + cal.set(Calendar.SECOND, 59);
  190 + cal.set(Calendar.MILLISECOND, 999);
  191 + return cal.getTime();
  192 + }
  193 +
  194 + /**
  195 + * 解析结束时间字符串,为空时默认返回当前日期前一天的结束时间
  196 + */
  197 + public static Date parseEndTimeOrYesterdayEnd(String dateStr) {
  198 + if (dateStr == null || dateStr.trim().isEmpty()) {
  199 + return getYesterdayEndTime();
  200 + }
  201 + return parseEndTime(dateStr);
  202 + }
180 203 }
... ...
... ... @@ -15,6 +15,13 @@
15 15 - [3.3 根据计划解决时间范围、责任单位id、问题处理状态查询问题记录明细](#33-根据计划解决时间范围责任单位id问题处理状态查询问题记录明细)
16 16 - [3.4 根据创建时间范围汇总各问题来源对应的问题数](#34-根据创建时间范围汇总各问题来源对应的问题数)
17 17 - [3.5 根据创建时间范围、问题来源查询问题记录明细](#35-根据创建时间范围问题来源查询问题记录明细)
  18 +- [4. 过程确认执行接口](#4-过程确认执行接口)
  19 + - [4.1 获取所有过程确认执行记录列表](#41-获取所有过程确认执行记录列表)
  20 + - [4.2 根据活动执行日期范围汇总过程确认执行记录统计信息](#42-根据活动执行日期范围汇总过程确认执行记录统计信息)
  21 + - [4.3 根据条件查询过程确认执行记录明细列表](#43-根据条件查询过程确认执行记录明细列表)
  22 +- [5. PJO计划执行接口](#5-pjo计划执行接口)
  23 + - [5.1 根据PJO开展日期范围汇总PJO计划执行统计信息](#51-根据pjo开展日期范围汇总pjo计划执行统计信息)
  24 + - [5.2 根据条件查询人员PJO计划明细列表](#52-根据条件查询人员pjo计划明细列表)
18 25
19 26 ---
20 27
... ... @@ -138,6 +145,47 @@
138 145 | #3# | 已否决 |
139 146 | #4# | 已确认 |
140 147
  148 +#### 过程确认状态枚举(GcqrZtEnum)
  149 +
  150 +| 编号 | 描述 |
  151 +|------|------|
  152 +| #1# | 待确认 |
  153 +| #2# | 未执行 |
  154 +| #3# | 已执行 |
  155 +| #4# | 已逾期 |
  156 +
  157 +#### 未执行原因枚举(WzxyysEnum)
  158 +
  159 +| 编号 | 描述 |
  160 +|------|------|
  161 +| #1# | 车间停产 |
  162 +| #99# | 其他 |
  163 +
  164 +#### PJO执行状态枚举(PjoExecZtEnum)
  165 +
  166 +| 编号 | 描述 |
  167 +|------|------|
  168 +| #1# | 待执行 |
  169 +| #2# | 执行中 |
  170 +| #3# | 已执行 |
  171 +| #4# | 已关闭 |
  172 +
  173 +#### 岗位性质枚举(GwxzEnum)
  174 +
  175 +| 编号 | 描述 |
  176 +|------|------|
  177 +| #1# | A类 |
  178 +| #2# | B类 |
  179 +| #3# | C类 |
  180 +
  181 +#### 组员存在的问题枚举(ZyczdwtEnum)
  182 +
  183 +| 编号 | 描述 |
  184 +|------|------|
  185 +| #1# | 无 |
  186 +
  187 +> 说明:`zyczdwt` 字段值为 `#1#-无` 表示第三阶段未发现问题;其余任意非空值均表示第三阶段发现了一个问题。
  188 +
141 189 ---
142 190
143 191 ## 1. AB类改善接口
... ... @@ -962,3 +1010,693 @@
962 1010 ]
963 1011 }
964 1012 ```
  1013 +
  1014 +---
  1015 +
  1016 +## 4. 过程确认执行接口
  1017 +
  1018 +### 4.1 获取所有过程确认执行记录列表
  1019 +
  1020 +**接口路径:** `GET /processConfirmExec/list/all`
  1021 +
  1022 +**接口说明:** 获取系统中所有过程确认计划执行记录列表。
  1023 +
  1024 +**请求参数:** 无
  1025 +
  1026 +**响应数据:** `List<ProcessConfirmExec>`
  1027 +
  1028 +**响应字段说明:**
  1029 +
  1030 +| 字段 | 类型 | 说明 |
  1031 +|------|------|------|
  1032 +| id | String | 记录ID |
  1033 +| createdAt | Date | 创建时间(yyyy-MM-dd HH:mm:ss) |
  1034 +| hdzxrq | Date | 活动执行日期 |
  1035 +| gcqrjhry | String | 过程确认计划人员id |
  1036 +| zxry | String | 执行人员id |
  1037 +| gh | String | 工号 |
  1038 +| rylb | String | 人员类别(#1#-区长;#2#-班长;#3#-高级经理;#4#-经理;#5#-主管;#6#-专家;#7#-一般员工) |
  1039 +| dw | String | 单位id |
  1040 +| sz | String | 室组id |
  1041 +| qy | String | 区域id |
  1042 +| bz | String | 班组id |
  1043 +| xt | String | 线体id |
  1044 +| bc | String | 班次id |
  1045 +| gqsj | Date | 过期时间 |
  1046 +| zt | String | 状态(#1#-待确认;#2#-未执行;#3#-已执行;#4#-已逾期) |
  1047 +| sfyzx | Boolean | 是否已执行 |
  1048 +| wzxyysm | String | 未执行原因说明 |
  1049 +| sffxwt | Boolean | 是否发现问题 |
  1050 +| wzxyys | String | 未执行原因(#1#-车间停产;#99#-其他) |
  1051 +
  1052 +**响应示例:**
  1053 +
  1054 +```json
  1055 +{
  1056 + "success": true,
  1057 + "message": "成功",
  1058 + "data": [
  1059 + {
  1060 + "id": "a8IaDbP2C79yQsAY6Vv",
  1061 + "createdAt": "2026-09-11 01:47:47",
  1062 + "hdzxrq": "2026-09-11 01:47:47",
  1063 + "gcqrjhry": "XMOHi7joEhYbGCQ3JZ4",
  1064 + "zxry": "jU1pkX6iMiZjUPP19MP",
  1065 + "gh": "18326083100",
  1066 + "rylb": "#2#",
  1067 + "dw": "ahImSLxXBuQkFtU8Ace",
  1068 + "sz": "gjCsFTBShT36aQhnACN",
  1069 + "qy": "NpZtfnU8FcGXCXPUhEr",
  1070 + "bz": "6Lj0fH9rB5bXm19thta",
  1071 + "xt": "Uh0niQWd9MPKym55RvN",
  1072 + "bc": "rdFZ59DMjk5EzDV4uFo",
  1073 + "gqsj": "2026-09-11 15:59:59",
  1074 + "zt": "#3#",
  1075 + "sfyzx": true,
  1076 + "wzxyysm": null,
  1077 + "sffxwt": true,
  1078 + "wzxyys": null
  1079 + }
  1080 + ]
  1081 +}
  1082 +```
  1083 +
  1084 +---
  1085 +
  1086 +### 4.2 根据活动执行日期范围汇总过程确认执行记录统计信息
  1087 +
  1088 +**接口路径:** `GET /processConfirmExec/summary/exec`
  1089 +
  1090 +**接口说明:** 按活动执行日期范围查询过程确认执行记录,返回整体、各单位、各单位下各人员类别三个维度的统计信息。统计指标包括记录总数、已执行数量、执行率、问题发现数、问题发现率。开始时间为空时默认使用当前月 1 号,结束时间为空时默认使用当前日期前一天。
  1091 +
  1092 +**请求参数:**
  1093 +
  1094 +| 参数名 | 类型 | 必传 | 说明 |
  1095 +|--------|------|------|------|
  1096 +| startTime | String | 否 | 开始时间,格式:yyyy-MM-dd [HH:mm:ss],为空默认当前月 1 号 00:00:00 |
  1097 +| endTime | String | 否 | 结束时间,格式:yyyy-MM-dd [HH:mm:ss],为空默认当前日期前一天 23:59:59 |
  1098 +
  1099 +**响应数据:** `ProcessConfirmExecSummaryDTO`
  1100 +
  1101 +**响应字段说明:**
  1102 +
  1103 +| 字段 | 类型 | 说明 |
  1104 +|------|------|------|
  1105 +| dw | String | 单位id(整体汇总时为 null) |
  1106 +| dwName | String | 单位名称(整体汇总时为 null) |
  1107 +| dwCode | String | 单位编号(整体汇总时为 null) |
  1108 +| totalCount | Integer | 记录总数 |
  1109 +| executedCount | Integer | 已执行数量 |
  1110 +| execRate | Double | 执行率(%)= 已执行数量 / 记录总数 × 100 |
  1111 +| problemCount | Integer | 问题发现数 |
  1112 +| problemRate | Double | 问题发现率(%)= 问题数 / 记录总数 × 100 |
  1113 +| rylbStats | Array | 各人员类别下的统计明细 |
  1114 +| rylbStats[].rylb | String | 人员类别编号 |
  1115 +| rylbStats[].rylbDesc | String | 人员类别中文描述 |
  1116 +| rylbStats[].totalCount | Integer | 该人员类别下记录总数 |
  1117 +| rylbStats[].executedCount | Integer | 该人员类别下已执行数量 |
  1118 +| rylbStats[].execRate | Double | 该人员类别下执行率(%) |
  1119 +| rylbStats[].problemCount | Integer | 该人员类别下问题发现数 |
  1120 +| rylbStats[].problemRate | Double | 该人员类别下问题发现率(%) |
  1121 +| dwStats | Array | 各单位统计信息列表(结构同本 DTO,仅整体汇总时返回) |
  1122 +
  1123 +**响应示例:**
  1124 +
  1125 +```json
  1126 +{
  1127 + "success": true,
  1128 + "message": "成功",
  1129 + "data": {
  1130 + "dw": null,
  1131 + "dwName": null,
  1132 + "dwCode": null,
  1133 + "totalCount": 8,
  1134 + "executedCount": 6,
  1135 + "execRate": 75,
  1136 + "problemCount": 4,
  1137 + "problemRate": 50,
  1138 + "rylbStats": [],
  1139 + "dwStats": [
  1140 + {
  1141 + "dw": "ahImSLxXBuQkFtU8Ace",
  1142 + "dwName": "总装车间",
  1143 + "dwCode": "104",
  1144 + "totalCount": 5,
  1145 + "executedCount": 4,
  1146 + "execRate": 80,
  1147 + "problemCount": 3,
  1148 + "problemRate": 60,
  1149 + "rylbStats": [
  1150 + {
  1151 + "rylb": "#1#",
  1152 + "rylbDesc": "区长",
  1153 + "totalCount": 0,
  1154 + "executedCount": 0,
  1155 + "execRate": 0,
  1156 + "problemCount": 0,
  1157 + "problemRate": 0
  1158 + },
  1159 + {
  1160 + "rylb": "#2#",
  1161 + "rylbDesc": "班长",
  1162 + "totalCount": 5,
  1163 + "executedCount": 4,
  1164 + "execRate": 80,
  1165 + "problemCount": 3,
  1166 + "problemRate": 60
  1167 + },
  1168 + {
  1169 + "rylb": "#3#",
  1170 + "rylbDesc": "高级经理",
  1171 + "totalCount": 0,
  1172 + "executedCount": 0,
  1173 + "execRate": 0,
  1174 + "problemCount": 0,
  1175 + "problemRate": 0
  1176 + },
  1177 + {
  1178 + "rylb": "#4#",
  1179 + "rylbDesc": "经理",
  1180 + "totalCount": 0,
  1181 + "executedCount": 0,
  1182 + "execRate": 0,
  1183 + "problemCount": 0,
  1184 + "problemRate": 0
  1185 + },
  1186 + {
  1187 + "rylb": "#5#",
  1188 + "rylbDesc": "主管",
  1189 + "totalCount": 0,
  1190 + "executedCount": 0,
  1191 + "execRate": 0,
  1192 + "problemCount": 0,
  1193 + "problemRate": 0
  1194 + },
  1195 + {
  1196 + "rylb": "#6#",
  1197 + "rylbDesc": "专家",
  1198 + "totalCount": 0,
  1199 + "executedCount": 0,
  1200 + "execRate": 0,
  1201 + "problemCount": 0,
  1202 + "problemRate": 0
  1203 + },
  1204 + {
  1205 + "rylb": "#7#",
  1206 + "rylbDesc": "一般员工",
  1207 + "totalCount": 0,
  1208 + "executedCount": 0,
  1209 + "execRate": 0,
  1210 + "problemCount": 0,
  1211 + "problemRate": 0
  1212 + }
  1213 + ],
  1214 + "dwStats": []
  1215 + },
  1216 + {
  1217 + "dw": "Iv9y56sXFNZyuPFPQ85",
  1218 + "dwName": "人力资源处",
  1219 + "dwCode": "108",
  1220 + "totalCount": 3,
  1221 + "executedCount": 2,
  1222 + "execRate": 66.67,
  1223 + "problemCount": 1,
  1224 + "problemRate": 33.33,
  1225 + "rylbStats": [
  1226 + {
  1227 + "rylb": "#1#",
  1228 + "rylbDesc": "区长",
  1229 + "totalCount": 3,
  1230 + "executedCount": 2,
  1231 + "execRate": 66.67,
  1232 + "problemCount": 1,
  1233 + "problemRate": 33.33
  1234 + }
  1235 + ],
  1236 + "dwStats": []
  1237 + }
  1238 + ]
  1239 + }
  1240 +}
  1241 +```
  1242 +
  1243 +---
  1244 +
  1245 +### 4.3 根据条件查询过程确认执行记录明细列表
  1246 +
  1247 +**接口路径:** `GET /processConfirmExec/list/detail`
  1248 +
  1249 +**接口说明:** 按条件查询过程确认执行记录明细(不含问题记录信息),并补充关联实体名称与枚举中文描述。所有参数均非必填;开始时间为空时默认使用当前月 1 号,结束时间为空时默认使用当前日期前一天。
  1250 +
  1251 +**请求参数:**
  1252 +
  1253 +| 参数名 | 类型 | 必传 | 说明 |
  1254 +|--------|------|------|------|
  1255 +| startTime | String | 否 | 开始时间,格式:yyyy-MM-dd [HH:mm:ss],为空默认当前月 1 号 00:00:00 |
  1256 +| endTime | String | 否 | 结束时间,格式:yyyy-MM-dd [HH:mm:ss],为空默认当前日期前一天 23:59:59 |
  1257 +| dw | String | 否 | 单位id |
  1258 +| rylb | String | 否 | 人员类别编号(#1#-#7#,兼容 1 ~ 7) |
  1259 +| zt | String | 否 | 过程确认状态编号(#1#-#4#,兼容 1 ~ 4) |
  1260 +
  1261 +**响应数据:** `List<ProcessConfirmExecDetailDTO>`
  1262 +
  1263 +**响应字段说明:**
  1264 +
  1265 +| 字段 | 类型 | 说明 |
  1266 +|------|------|------|
  1267 +| id | String | 记录ID |
  1268 +| createdAt | Date | 创建时间(yyyy-MM-dd HH:mm:ss) |
  1269 +| hdzxrq | Date | 活动执行日期(yyyy-MM-dd HH:mm:ss) |
  1270 +| gqsj | Date | 过期时间(yyyy-MM-dd HH:mm:ss) |
  1271 +| gcqrjhry | String | 过程确认计划人员id |
  1272 +| gcqrjhryName | String | 过程确认计划人员姓名 |
  1273 +| zxry | String | 执行人员id |
  1274 +| gh | String | 工号 |
  1275 +| rylb | String | 人员类别编号 |
  1276 +| rylbDesc | String | 人员类别名称 |
  1277 +| zt | String | 状态编号 |
  1278 +| ztDesc | String | 状态名称 |
  1279 +| sfyzx | Boolean | 是否已执行 |
  1280 +| sffxwt | Boolean | 是否发现问题 |
  1281 +| wzxyys | String | 未执行原因编号 |
  1282 +| wzxyysDesc | String | 未执行原因名称 |
  1283 +| wzxyysm | String | 未执行原因说明 |
  1284 +| dw | String | 单位id |
  1285 +| dwName | String | 单位名称 |
  1286 +| dwCode | String | 单位编号 |
  1287 +| sz | String | 室组id |
  1288 +| szName | String | 室组名称 |
  1289 +| szCode | String | 室组编号 |
  1290 +| qy | String | 区域id |
  1291 +| qyName | String | 区域名称 |
  1292 +| qyCode | String | 区域编号 |
  1293 +| bz | String | 班组id |
  1294 +| bzName | String | 班组名称 |
  1295 +| bzCode | String | 班组编号 |
  1296 +| xt | String | 线体id |
  1297 +| xtName | String | 线体名称 |
  1298 +| xtCode | String | 线体编号 |
  1299 +| bc | String | 班次id |
  1300 +| bcName | String | 班次名称 |
  1301 +| bcCode | String | 班次编号 |
  1302 +
  1303 +**响应示例:**
  1304 +
  1305 +```json
  1306 +{
  1307 + "success": true,
  1308 + "message": "成功",
  1309 + "data": [
  1310 + {
  1311 + "id": "a8IaDbP2C79yQsAY6Vv",
  1312 + "createdAt": null,
  1313 + "hdzxrq": "2026-09-11 01:47:47",
  1314 + "gqsj": "2026-09-11 15:59:59",
  1315 + "gcqrjhry": "XMOHi7joEhYbGCQ3JZ4",
  1316 + "gcqrjhryName": "陈工",
  1317 + "zxry": "jU1pkX6iMiZjUPP19MP",
  1318 + "gh": "18326083100",
  1319 + "rylb": "#2#",
  1320 + "rylbDesc": "班长",
  1321 + "zt": "#3#",
  1322 + "ztDesc": "已执行",
  1323 + "sfyzx": true,
  1324 + "sffxwt": true,
  1325 + "wzxyys": null,
  1326 + "wzxyysDesc": null,
  1327 + "wzxyysm": null,
  1328 + "dw": "ahImSLxXBuQkFtU8Ace",
  1329 + "dwName": "总装车间",
  1330 + "dwCode": "104",
  1331 + "sz": "gjCsFTBShT36aQhnACN",
  1332 + "szName": "制造室",
  1333 + "szCode": "76",
  1334 + "qy": "NpZtfnU8FcGXCXPUhEr",
  1335 + "qyName": "制造室",
  1336 + "qyCode": "76",
  1337 + "bz": "6Lj0fH9rB5bXm19thta",
  1338 + "bzName": "班组1",
  1339 + "bzCode": "999",
  1340 + "xt": "Uh0niQWd9MPKym55RvN",
  1341 + "xtName": "A线",
  1342 + "xtCode": "A",
  1343 + "bc": "rdFZ59DMjk5EzDV4uFo",
  1344 + "bcName": "一班",
  1345 + "bcCode": "1"
  1346 + }
  1347 + ]
  1348 +}
  1349 +```
  1350 +
  1351 +---
  1352 +
  1353 +## 5. PJO计划执行接口
  1354 +
  1355 +### 5.1 根据PJO开展日期范围汇总PJO计划执行统计信息
  1356 +
  1357 +**接口路径:** `GET /pjoExec/summary/exec`
  1358 +
  1359 +**接口说明:** 按 PJO 开展日期(qkxdwk)范围查询 PJO 计划执行记录,返回 **整体 → 各车间 → 各 PJO 执行人** 三级维度的统计信息。统计指标包括 PJO 计划数、已执行数(状态 `#3#-已执行`)、执行率,以及第一/二/三阶段问题数与发现率、整体问题数与发现率。
  1360 +
  1361 +问题按三个阶段分别判定:
  1362 +
  1363 +- **第一阶段**:观察的问题(`gcdwt`)有值 → 发现一个问题;
  1364 +- **第二阶段**:观察的改善点描述(`lfwkuc`)有值 → 发现一个问题;
  1365 +- **第三阶段**:组员存在的问题(`zyczdwt`)有值且不是 `#1#-无` → 发现一个问题。
  1366 +
  1367 +开始时间为空时默认使用当前月 1 号,结束时间为空时默认使用当前日期前一天。车间按编号升序、执行人按姓名升序排列。
  1368 +
  1369 +**请求参数:**
  1370 +
  1371 +| 参数名 | 类型 | 必传 | 说明 |
  1372 +|--------|------|------|------|
  1373 +| startTime | String | 否 | 开始时间,格式:yyyy-MM-dd [HH:mm:ss],为空默认当前月 1 号 00:00:00 |
  1374 +| endTime | String | 否 | 结束时间,格式:yyyy-MM-dd [HH:mm:ss],为空默认当前日期前一天 23:59:59 |
  1375 +
  1376 +**响应数据:** `PjoExecSummaryDTO`
  1377 +
  1378 +**响应字段说明:**
  1379 +
  1380 +整体、`cjStats[]`、`zxrStats[]` 三级均包含下表相同的统计字段(公共统计指标):
  1381 +
  1382 +| 字段 | 类型 | 说明 |
  1383 +|------|------|------|
  1384 +| totalCount | Integer | PJO计划数(记录总数) |
  1385 +| executedCount | Integer | 已执行数量(状态 #3#-已执行) |
  1386 +| execRate | Double | 执行率(%)= 已执行数量 / PJO计划数 × 100 |
  1387 +| stage1ProblemCount | Integer | 第一阶段问题数(gcdwt 有值) |
  1388 +| stage1ProblemRate | Double | 第一阶段问题发现率(%)= 第一阶段问题数 / PJO计划数 × 100 |
  1389 +| stage2ProblemCount | Integer | 第二阶段问题数(lfwkuc 有值) |
  1390 +| stage2ProblemRate | Double | 第二阶段问题发现率(%)= 第二阶段问题数 / PJO计划数 × 100 |
  1391 +| stage3ProblemCount | Integer | 第三阶段问题数(zyczdwt 有值且非 #1#-无) |
  1392 +| stage3ProblemRate | Double | 第三阶段问题发现率(%)= 第三阶段问题数 / PJO计划数 × 100 |
  1393 +| problemCount | Integer | 整体问题数(第一、二、三阶段合计) |
  1394 +| problemRate | Double | 整体问题发现率(%)= 整体问题数 / PJO计划数 × 100 |
  1395 +
  1396 +> 注:单条记录最多可同时命中三个阶段(贡献 3 个问题),因此 `problemRate` 及各阶段发现率之和可能大于 100%。
  1397 +
  1398 +各级额外字段:
  1399 +
  1400 +| 字段 | 类型 | 说明 |
  1401 +|------|------|------|
  1402 +| cjStats | Array | 各车间统计信息列表(仅整体层返回) |
  1403 +| cjStats[].cj | String | 车间id |
  1404 +| cjStats[].cjName | String | 车间名称 |
  1405 +| cjStats[].cjCode | String | 车间编号 |
  1406 +| cjStats[].zxrStats | Array | 该车间下各 PJO 执行人统计信息列表 |
  1407 +| zxrStats[].pjozxr | String | PJO执行人id(组织用户) |
  1408 +| zxrStats[].pjozxrName | String | PJO执行人姓名 |
  1409 +
  1410 +**响应示例:**
  1411 +
  1412 +```json
  1413 +{
  1414 + "success": true,
  1415 + "message": "成功",
  1416 + "data": {
  1417 + "totalCount": 6,
  1418 + "executedCount": 5,
  1419 + "execRate": 83.33,
  1420 + "stage1ProblemCount": 3,
  1421 + "stage1ProblemRate": 50,
  1422 + "stage2ProblemCount": 3,
  1423 + "stage2ProblemRate": 50,
  1424 + "stage3ProblemCount": 2,
  1425 + "stage3ProblemRate": 33.33,
  1426 + "problemCount": 8,
  1427 + "problemRate": 133.33,
  1428 + "cjStats": [
  1429 + {
  1430 + "cj": "ahImSLxXBuQkFtU8Ace",
  1431 + "cjName": "总装车间",
  1432 + "cjCode": "104",
  1433 + "totalCount": 5,
  1434 + "executedCount": 4,
  1435 + "execRate": 80,
  1436 + "stage1ProblemCount": 2,
  1437 + "stage1ProblemRate": 40,
  1438 + "stage2ProblemCount": 2,
  1439 + "stage2ProblemRate": 40,
  1440 + "stage3ProblemCount": 2,
  1441 + "stage3ProblemRate": 40,
  1442 + "problemCount": 6,
  1443 + "problemRate": 120,
  1444 + "zxrStats": [
  1445 + {
  1446 + "pjozxr": "cyTZZMgy3WliwVfM3LT",
  1447 + "pjozxrName": "周雪",
  1448 + "totalCount": 2,
  1449 + "executedCount": 2,
  1450 + "execRate": 100,
  1451 + "stage1ProblemCount": 2,
  1452 + "stage1ProblemRate": 100,
  1453 + "stage2ProblemCount": 2,
  1454 + "stage2ProblemRate": 100,
  1455 + "stage3ProblemCount": 2,
  1456 + "stage3ProblemRate": 100,
  1457 + "problemCount": 6,
  1458 + "problemRate": 300
  1459 + },
  1460 + {
  1461 + "pjozxr": "jU1pkX6iMiZjUPP19MP",
  1462 + "pjozxrName": "陈工",
  1463 + "totalCount": 3,
  1464 + "executedCount": 2,
  1465 + "execRate": 66.67,
  1466 + "stage1ProblemCount": 0,
  1467 + "stage1ProblemRate": 0,
  1468 + "stage2ProblemCount": 0,
  1469 + "stage2ProblemRate": 0,
  1470 + "stage3ProblemCount": 0,
  1471 + "stage3ProblemRate": 0,
  1472 + "problemCount": 0,
  1473 + "problemRate": 0
  1474 + }
  1475 + ]
  1476 + },
  1477 + {
  1478 + "cj": "Iv9y56sXFNZyuPFPQ85",
  1479 + "cjName": "人力资源处",
  1480 + "cjCode": "108",
  1481 + "totalCount": 1,
  1482 + "executedCount": 1,
  1483 + "execRate": 100,
  1484 + "stage1ProblemCount": 1,
  1485 + "stage1ProblemRate": 100,
  1486 + "stage2ProblemCount": 1,
  1487 + "stage2ProblemRate": 100,
  1488 + "stage3ProblemCount": 0,
  1489 + "stage3ProblemRate": 0,
  1490 + "problemCount": 2,
  1491 + "problemRate": 200,
  1492 + "zxrStats": [
  1493 + {
  1494 + "pjozxr": "cyTZZMgy3WliwVfM3LT",
  1495 + "pjozxrName": "周雪",
  1496 + "totalCount": 1,
  1497 + "executedCount": 1,
  1498 + "execRate": 100,
  1499 + "stage1ProblemCount": 1,
  1500 + "stage1ProblemRate": 100,
  1501 + "stage2ProblemCount": 1,
  1502 + "stage2ProblemRate": 100,
  1503 + "stage3ProblemCount": 0,
  1504 + "stage3ProblemRate": 0,
  1505 + "problemCount": 2,
  1506 + "problemRate": 200
  1507 + }
  1508 + ]
  1509 + }
  1510 + ]
  1511 + }
  1512 +}
  1513 +```
  1514 +
  1515 +---
  1516 +
  1517 +### 5.2 根据条件查询人员PJO计划明细列表
  1518 +
  1519 +**接口路径:** `GET /pjoExec/list/detail`
  1520 +
  1521 +**接口说明:** 按 PJO 开展日期(qkxdwk)范围查询人员 PJO 计划执行明细记录,可再按车间单位id、人员id(PJO 执行人)过滤,并补充关联实体名称/编号、枚举中文描述及各阶段问题标记。所有参数均非必填;开始时间为空时默认使用当前月 1 号,结束时间为空时默认使用当前日期前一天。结果按 PJO 开展日期降序排列。
  1522 +
  1523 +**请求参数:**
  1524 +
  1525 +| 参数名 | 类型 | 必传 | 说明 |
  1526 +|--------|------|------|------|
  1527 +| startTime | String | 否 | 开始时间,格式:yyyy-MM-dd [HH:mm:ss],为空默认当前月 1 号 00:00:00 |
  1528 +| endTime | String | 否 | 结束时间,格式:yyyy-MM-dd [HH:mm:ss],为空默认当前日期前一天 23:59:59 |
  1529 +| cj | String | 否 | 车间单位id |
  1530 +| pjozxr | String | 否 | 人员id(PJO 执行人-组织用户) |
  1531 +
  1532 +**响应数据:** `List<PjoExecDetailDTO>`
  1533 +
  1534 +**响应字段说明:**
  1535 +
  1536 +| 字段 | 类型 | 说明 |
  1537 +|------|------|------|
  1538 +| id | String | 记录ID |
  1539 +| createdAt | Date | 创建时间(yyyy-MM-dd HH:mm:ss) |
  1540 +| qkxdwk | Date | PJO开展日期(yyyy-MM-dd HH:mm:ss) |
  1541 +| drscbc | String | 当日生产班次id |
  1542 +| pjozxr | String | PJO执行人id(组织用户) |
  1543 +| pjozxrName | String | PJO执行人姓名 |
  1544 +| pjogcrxm | String | PJO观察人姓名 |
  1545 +| pjopc | String | PJO批次id |
  1546 +| pjopcName | String | PJO批次名称 |
  1547 +| pjopcCode | String | PJO批次编号 |
  1548 +| gwxz | String | 岗位性质编号(#1#-A类;#2#-B类;#3#-C类) |
  1549 +| gwxzDesc | String | 岗位性质名称 |
  1550 +| gwzx1 | String | 工位1-PJO工位执行情况记录id |
  1551 +| gwzx1Name | String | 工位1名称 |
  1552 +| gwzx1Code | String | 工位1编号 |
  1553 +| gwzx2 | String | 工位2-PJO工位执行情况记录id |
  1554 +| gwzx2Name | String | 工位2名称 |
  1555 +| gwzx2Code | String | 工位2编号 |
  1556 +| pjosfzckz | Boolean | PJO是否正常开展 |
  1557 +| gchtxzyyc | String | 观察和填写主要异常 |
  1558 +| gchtxcyyc | String | 观察和填写次要异常 |
  1559 +| gcdwt | String | 观察的问题(第一阶段问题来源) |
  1560 +| gcgjjh | String | 观测改进机会 |
  1561 +| lfwkuc | String | 观察的改善点描述(第二阶段问题来源) |
  1562 +| zyczdwt | String | 组员存在的问题编号(第三阶段问题来源,#1#-无) |
  1563 +| zyczdwtDesc | String | 组员存在的问题名称 |
  1564 +| zdbgwdgsjy | String | 针对本工位的改善建议 |
  1565 +| lvqwyc | String | 三个动作 |
  1566 +| zysfyjy | Boolean | 组员是否有建议 |
  1567 +| cyjy | String | 成员建议&意见处理人员id(组织用户) |
  1568 +| cyjyName | String | 成员建议&意见处理人员姓名 |
  1569 +| zyjy | String | 组员建议&意见处理方案 |
  1570 +| zt | String | 状态编号(#1#-待执行;#2#-执行中;#3#-已执行;#4#-已关闭) |
  1571 +| ztDesc | String | 状态名称 |
  1572 +| stage1Problem | Boolean | 第一阶段是否发现问题(gcdwt 有值) |
  1573 +| stage2Problem | Boolean | 第二阶段是否发现问题(lfwkuc 有值) |
  1574 +| stage3Problem | Boolean | 第三阶段是否发现问题(zyczdwt 有值且非 #1#-无) |
  1575 +| problemCount | Integer | 该记录发现问题总数(三阶段合计,0~3) |
  1576 +| cj | String | 车间id |
  1577 +| cjName | String | 车间名称 |
  1578 +| cjCode | String | 车间编号 |
  1579 +| qy | String | 区域id |
  1580 +| qyName | String | 区域名称 |
  1581 +| qyCode | String | 区域编号 |
  1582 +| bz | String | 班组id |
  1583 +| bzName | String | 班组名称 |
  1584 +| bzCode | String | 班组编号 |
  1585 +| xt | String | 线体id |
  1586 +| xtName | String | 线体名称 |
  1587 +| xtCode | String | 线体编号 |
  1588 +
  1589 +**响应示例:**
  1590 +
  1591 +```json
  1592 +{
  1593 + "success": true,
  1594 + "message": "成功",
  1595 + "data": [
  1596 + {
  1597 + "id": "53DfARB8Lllis48Qc5S",
  1598 + "createdAt": null,
  1599 + "qkxdwk": "2026-09-14 16:00:00",
  1600 + "drscbc": "04XZ79FFFNlMQvVRbNC",
  1601 + "pjozxr": "jU1pkX6iMiZjUPP19MP",
  1602 + "pjozxrName": "陈工",
  1603 + "pjogcrxm": "17",
  1604 + "pjopc": "Rx9pcihofirkRXKwp7U",
  1605 + "pjopcName": "1111",
  1606 + "pjopcCode": "103",
  1607 + "gwxz": "#1#",
  1608 + "gwxzDesc": "A类",
  1609 + "gwzx1": "sWIvFIxMCEIBPQe1vnp",
  1610 + "gwzx1Name": "PT-17",
  1611 + "gwzx1Code": "PT-17",
  1612 + "gwzx2": null,
  1613 + "gwzx2Name": null,
  1614 + "gwzx2Code": null,
  1615 + "pjosfzckz": true,
  1616 + "gchtxzyyc": "#5#",
  1617 + "gchtxcyyc": "#6#",
  1618 + "gcdwt": null,
  1619 + "gcgjjh": null,
  1620 + "lfwkuc": null,
  1621 + "zyczdwt": null,
  1622 + "zyczdwtDesc": null,
  1623 + "zdbgwdgsjy": null,
  1624 + "lvqwyc": "#3#",
  1625 + "zysfyjy": true,
  1626 + "cyjy": "jU1pkX6iMiZjUPP19MP",
  1627 + "cyjyName": "陈工",
  1628 + "zyjy": "12345788342",
  1629 + "zt": "#3#",
  1630 + "ztDesc": "已执行",
  1631 + "stage1Problem": false,
  1632 + "stage2Problem": false,
  1633 + "stage3Problem": false,
  1634 + "problemCount": 0,
  1635 + "cj": "ahImSLxXBuQkFtU8Ace",
  1636 + "cjName": "总装车间",
  1637 + "cjCode": "104",
  1638 + "qy": "fmGDmYdCswHy1AfNO7R",
  1639 + "qyName": "底盘分装",
  1640 + "qyCode": "51",
  1641 + "bz": "GQ8wL2PXGUutYA7HKks",
  1642 + "bzName": "发动机分装班",
  1643 + "bzCode": "142",
  1644 + "xt": "6J4vk1uvwmoj6e3AL2G",
  1645 + "xtName": "B线",
  1646 + "xtCode": "B"
  1647 + },
  1648 + {
  1649 + "id": "GqsLUmb6KPFbksGLCMy",
  1650 + "createdAt": null,
  1651 + "qkxdwk": "2026-09-10 16:00:00",
  1652 + "drscbc": "2wuZLNVlL697coAgZd9",
  1653 + "pjozxr": "jU1pkX6iMiZjUPP19MP",
  1654 + "pjozxrName": "陈工",
  1655 + "pjogcrxm": null,
  1656 + "pjopc": "Rx9pcihofirkRXKwp7U",
  1657 + "pjopcName": "1111",
  1658 + "pjopcCode": "103",
  1659 + "gwxz": "#1#",
  1660 + "gwxzDesc": "A类",
  1661 + "gwzx1": "qvyrMf6zeRTtOk20Oug",
  1662 + "gwzx1Name": "PT-18-FZ-02",
  1663 + "gwzx1Code": "PT-18-FZ-02",
  1664 + "gwzx2": null,
  1665 + "gwzx2Name": null,
  1666 + "gwzx2Code": null,
  1667 + "pjosfzckz": true,
  1668 + "gchtxzyyc": "#2#",
  1669 + "gchtxcyyc": "#2#",
  1670 + "gcdwt": null,
  1671 + "gcgjjh": null,
  1672 + "lfwkuc": null,
  1673 + "zyczdwt": null,
  1674 + "zyczdwtDesc": null,
  1675 + "zdbgwdgsjy": null,
  1676 + "lvqwyc": null,
  1677 + "zysfyjy": true,
  1678 + "cyjy": "cyTZZMgy3WliwVfM3LT",
  1679 + "cyjyName": "周雪",
  1680 + "zyjy": null,
  1681 + "zt": "#2#",
  1682 + "ztDesc": "执行中",
  1683 + "stage1Problem": false,
  1684 + "stage2Problem": false,
  1685 + "stage3Problem": false,
  1686 + "problemCount": 0,
  1687 + "cj": "ahImSLxXBuQkFtU8Ace",
  1688 + "cjName": "总装车间",
  1689 + "cjCode": "104",
  1690 + "qy": "fmGDmYdCswHy1AfNO7R",
  1691 + "qyName": "底盘分装",
  1692 + "qyCode": "51",
  1693 + "bz": "GQ8wL2PXGUutYA7HKks",
  1694 + "bzName": "发动机分装班",
  1695 + "bzCode": "142",
  1696 + "xt": null,
  1697 + "xtName": null,
  1698 + "xtCode": null
  1699 + }
  1700 + ]
  1701 +}
  1702 +```
... ...
... ... @@ -654,4 +654,622 @@ http://localhost:8090/cpsProblem/list/detail/source?startTime=2026-08-01&endTime
654 654 ],
655 655 "msg": "成功",
656 656 "errCode": null
657   -}
\ No newline at end of file
  657 +}
  658 +
  659 +
  660 +过程确认执行模块
  661 +1、过程确认指标整体数据、各单位执行率、各单位问题发现率,及各单位下探的各人员类别柱状图-数据来源:
  662 +
  663 +请求url:http://localhost:8090/processConfirmExec/summary/exec?startTime=2026-09-01&endTime=2026-09-21
  664 +
  665 +出参示例:
  666 +{
  667 + "success": true,
  668 + "data": {
  669 + "dw": null,
  670 + "dwName": null,
  671 + "dwCode": null,
  672 + "totalCount": 8,
  673 + "executedCount": 6,
  674 + "execRate": 75,
  675 + "problemCount": 4,
  676 + "problemRate": 50,
  677 + "rylbStats": [],
  678 + "dwStats": [
  679 + {
  680 + "dw": "ahImSLxXBuQkFtU8Ace",
  681 + "dwName": "总装车间",
  682 + "dwCode": "104",
  683 + "totalCount": 5,
  684 + "executedCount": 4,
  685 + "execRate": 80,
  686 + "problemCount": 3,
  687 + "problemRate": 60,
  688 + "rylbStats": [
  689 + {
  690 + "rylb": "#1#",
  691 + "rylbDesc": "区长",
  692 + "totalCount": 0,
  693 + "executedCount": 0,
  694 + "execRate": 0,
  695 + "problemCount": 0,
  696 + "problemRate": 0
  697 + },
  698 + {
  699 + "rylb": "#2#",
  700 + "rylbDesc": "班长",
  701 + "totalCount": 5,
  702 + "executedCount": 4,
  703 + "execRate": 80,
  704 + "problemCount": 3,
  705 + "problemRate": 60
  706 + },
  707 + {
  708 + "rylb": "#3#",
  709 + "rylbDesc": "高级经理",
  710 + "totalCount": 0,
  711 + "executedCount": 0,
  712 + "execRate": 0,
  713 + "problemCount": 0,
  714 + "problemRate": 0
  715 + },
  716 + {
  717 + "rylb": "#4#",
  718 + "rylbDesc": "经理",
  719 + "totalCount": 0,
  720 + "executedCount": 0,
  721 + "execRate": 0,
  722 + "problemCount": 0,
  723 + "problemRate": 0
  724 + },
  725 + {
  726 + "rylb": "#5#",
  727 + "rylbDesc": "主管",
  728 + "totalCount": 0,
  729 + "executedCount": 0,
  730 + "execRate": 0,
  731 + "problemCount": 0,
  732 + "problemRate": 0
  733 + },
  734 + {
  735 + "rylb": "#6#",
  736 + "rylbDesc": "专家",
  737 + "totalCount": 0,
  738 + "executedCount": 0,
  739 + "execRate": 0,
  740 + "problemCount": 0,
  741 + "problemRate": 0
  742 + },
  743 + {
  744 + "rylb": "#7#",
  745 + "rylbDesc": "一般员工",
  746 + "totalCount": 0,
  747 + "executedCount": 0,
  748 + "execRate": 0,
  749 + "problemCount": 0,
  750 + "problemRate": 0
  751 + }
  752 + ],
  753 + "dwStats": []
  754 + },
  755 + {
  756 + "dw": "Iv9y56sXFNZyuPFPQ85",
  757 + "dwName": "人力资源处",
  758 + "dwCode": "108",
  759 + "totalCount": 3,
  760 + "executedCount": 2,
  761 + "execRate": 66.67,
  762 + "problemCount": 1,
  763 + "problemRate": 33.33,
  764 + "rylbStats": [
  765 + {
  766 + "rylb": "#1#",
  767 + "rylbDesc": "区长",
  768 + "totalCount": 3,
  769 + "executedCount": 2,
  770 + "execRate": 66.67,
  771 + "problemCount": 1,
  772 + "problemRate": 33.33
  773 + },
  774 + {
  775 + "rylb": "#2#",
  776 + "rylbDesc": "班长",
  777 + "totalCount": 0,
  778 + "executedCount": 0,
  779 + "execRate": 0,
  780 + "problemCount": 0,
  781 + "problemRate": 0
  782 + },
  783 + {
  784 + "rylb": "#3#",
  785 + "rylbDesc": "高级经理",
  786 + "totalCount": 0,
  787 + "executedCount": 0,
  788 + "execRate": 0,
  789 + "problemCount": 0,
  790 + "problemRate": 0
  791 + },
  792 + {
  793 + "rylb": "#4#",
  794 + "rylbDesc": "经理",
  795 + "totalCount": 0,
  796 + "executedCount": 0,
  797 + "execRate": 0,
  798 + "problemCount": 0,
  799 + "problemRate": 0
  800 + },
  801 + {
  802 + "rylb": "#5#",
  803 + "rylbDesc": "主管",
  804 + "totalCount": 0,
  805 + "executedCount": 0,
  806 + "execRate": 0,
  807 + "problemCount": 0,
  808 + "problemRate": 0
  809 + },
  810 + {
  811 + "rylb": "#6#",
  812 + "rylbDesc": "专家",
  813 + "totalCount": 0,
  814 + "executedCount": 0,
  815 + "execRate": 0,
  816 + "problemCount": 0,
  817 + "problemRate": 0
  818 + },
  819 + {
  820 + "rylb": "#7#",
  821 + "rylbDesc": "一般员工",
  822 + "totalCount": 0,
  823 + "executedCount": 0,
  824 + "execRate": 0,
  825 + "problemCount": 0,
  826 + "problemRate": 0
  827 + }
  828 + ],
  829 + "dwStats": []
  830 + }
  831 + ]
  832 + },
  833 + "msg": "成功",
  834 + "errCode": null
  835 +}
  836 +
  837 +
  838 +2、人员类别柱状图下探明细列表、未执行过程确认明细列表-数据来源
  839 +
  840 +请求url:
  841 +http://localhost:8090/processConfirmExec/list/detail?startTime=2026-09-01&endTime=2026-09-21&dw=ahImSLxXBuQkFtU8Ace&zt=3
  842 +
  843 +出参示例:
  844 +{
  845 + "success": true,
  846 + "data": [
  847 + {
  848 + "id": "a8IaDbP2C79yQsAY6Vv",
  849 + "createdAt": null,
  850 + "hdzxrq": "2026-09-11 01:47:47",
  851 + "gqsj": "2026-09-11 15:59:59",
  852 + "gcqrjhry": "XMOHi7joEhYbGCQ3JZ4",
  853 + "gcqrjhryName": "陈工",
  854 + "zxry": "jU1pkX6iMiZjUPP19MP",
  855 + "gh": "18326083100",
  856 + "rylb": "#2#",
  857 + "rylbDesc": "班长",
  858 + "zt": "#3#",
  859 + "ztDesc": "已执行",
  860 + "sfyzx": true,
  861 + "sffxwt": true,
  862 + "wzxyys": null,
  863 + "wzxyysDesc": null,
  864 + "wzxyysm": null,
  865 + "dw": "ahImSLxXBuQkFtU8Ace",
  866 + "dwName": "总装车间",
  867 + "dwCode": "104",
  868 + "sz": "gjCsFTBShT36aQhnACN",
  869 + "szName": "制造室",
  870 + "szCode": "76",
  871 + "qy": "NpZtfnU8FcGXCXPUhEr",
  872 + "qyName": "制造室",
  873 + "qyCode": "76",
  874 + "bz": "6Lj0fH9rB5bXm19thta",
  875 + "bzName": "班组1",
  876 + "bzCode": "999",
  877 + "xt": "Uh0niQWd9MPKym55RvN",
  878 + "xtName": "A线",
  879 + "xtCode": "A",
  880 + "bc": null,
  881 + "bcName": null,
  882 + "bcCode": null
  883 + },
  884 + {
  885 + "id": "vxLYbjFRshVnN3YuCGG",
  886 + "createdAt": null,
  887 + "hdzxrq": "2026-09-09 12:47:38",
  888 + "gqsj": "2026-09-09 16:00:00",
  889 + "gcqrjhry": "XMOHi7joEhYbGCQ3JZ4",
  890 + "gcqrjhryName": "陈工",
  891 + "zxry": "jU1pkX6iMiZjUPP19MP",
  892 + "gh": "18326083100",
  893 + "rylb": "#2#",
  894 + "rylbDesc": "班长",
  895 + "zt": "#3#",
  896 + "ztDesc": "已执行",
  897 + "sfyzx": true,
  898 + "sffxwt": true,
  899 + "wzxyys": null,
  900 + "wzxyysDesc": null,
  901 + "wzxyysm": null,
  902 + "dw": "ahImSLxXBuQkFtU8Ace",
  903 + "dwName": "总装车间",
  904 + "dwCode": "104",
  905 + "sz": "gjCsFTBShT36aQhnACN",
  906 + "szName": "制造室",
  907 + "szCode": "76",
  908 + "qy": "NpZtfnU8FcGXCXPUhEr",
  909 + "qyName": "制造室",
  910 + "qyCode": "76",
  911 + "bz": "6Lj0fH9rB5bXm19thta",
  912 + "bzName": "班组1",
  913 + "bzCode": "999",
  914 + "xt": "Uh0niQWd9MPKym55RvN",
  915 + "xtName": "A线",
  916 + "xtCode": "A",
  917 + "bc": "rdFZ59DMjk5EzDV4uFo",
  918 + "bcName": "一班",
  919 + "bcCode": "1"
  920 + },
  921 + {
  922 + "id": "4YQszAaNdJ3jClo3hKA",
  923 + "createdAt": null,
  924 + "hdzxrq": "2026-09-07 16:00:00",
  925 + "gqsj": "2026-09-08 16:00:00",
  926 + "gcqrjhry": "XMOHi7joEhYbGCQ3JZ4",
  927 + "gcqrjhryName": "陈工",
  928 + "zxry": "jU1pkX6iMiZjUPP19MP",
  929 + "gh": "18326083100",
  930 + "rylb": "#2#",
  931 + "rylbDesc": "班长",
  932 + "zt": "#3#",
  933 + "ztDesc": "已执行",
  934 + "sfyzx": true,
  935 + "sffxwt": true,
  936 + "wzxyys": null,
  937 + "wzxyysDesc": null,
  938 + "wzxyysm": null,
  939 + "dw": "ahImSLxXBuQkFtU8Ace",
  940 + "dwName": "总装车间",
  941 + "dwCode": "104",
  942 + "sz": "gjCsFTBShT36aQhnACN",
  943 + "szName": "制造室",
  944 + "szCode": "76",
  945 + "qy": "NpZtfnU8FcGXCXPUhEr",
  946 + "qyName": "制造室",
  947 + "qyCode": "76",
  948 + "bz": "6Lj0fH9rB5bXm19thta",
  949 + "bzName": "班组1",
  950 + "bzCode": "999",
  951 + "xt": "Uh0niQWd9MPKym55RvN",
  952 + "xtName": "A线",
  953 + "xtCode": "A",
  954 + "bc": null,
  955 + "bcName": null,
  956 + "bcCode": null
  957 + },
  958 + {
  959 + "id": "elE6d8NiH8Bot6Sxq07",
  960 + "createdAt": null,
  961 + "hdzxrq": "2026-09-06 16:00:00",
  962 + "gqsj": "2026-09-07 16:00:00",
  963 + "gcqrjhry": "XMOHi7joEhYbGCQ3JZ4",
  964 + "gcqrjhryName": "陈工",
  965 + "zxry": "jU1pkX6iMiZjUPP19MP",
  966 + "gh": "18326083100",
  967 + "rylb": "#2#",
  968 + "rylbDesc": "班长",
  969 + "zt": "#3#",
  970 + "ztDesc": "已执行",
  971 + "sfyzx": true,
  972 + "sffxwt": true,
  973 + "wzxyys": null,
  974 + "wzxyysDesc": null,
  975 + "wzxyysm": null,
  976 + "dw": "ahImSLxXBuQkFtU8Ace",
  977 + "dwName": "总装车间",
  978 + "dwCode": "104",
  979 + "sz": "gjCsFTBShT36aQhnACN",
  980 + "szName": "制造室",
  981 + "szCode": "76",
  982 + "qy": "NpZtfnU8FcGXCXPUhEr",
  983 + "qyName": "制造室",
  984 + "qyCode": "76",
  985 + "bz": "6Lj0fH9rB5bXm19thta",
  986 + "bzName": "班组1",
  987 + "bzCode": "999",
  988 + "xt": "Uh0niQWd9MPKym55RvN",
  989 + "xtName": "A线",
  990 + "xtCode": "A",
  991 + "bc": null,
  992 + "bcName": null,
  993 + "bcCode": null
  994 + }
  995 + ],
  996 + "msg": "成功",
  997 + "errCode": null
  998 +}
  999 +
  1000 +
  1001 +PJO计划模块
  1002 +1、PJO计划指标整体数据、各单位执行率、各单位问题发现率,及各单位下探的各人员柱状图-数据来源:
  1003 +
  1004 +请求url:http://localhost:8090/pjoExec/summary/exec?startTime=2026-09-01&endTime=2026-09-21
  1005 +出参示例:
  1006 +{
  1007 + "success": true,
  1008 + "data": {
  1009 + "totalCount": 6,
  1010 + "executedCount": 5,
  1011 + "execRate": 83.33,
  1012 + "stage1ProblemCount": 3,
  1013 + "stage1ProblemRate": 50,
  1014 + "stage2ProblemCount": 3,
  1015 + "stage2ProblemRate": 50,
  1016 + "stage3ProblemCount": 2,
  1017 + "stage3ProblemRate": 33.33,
  1018 + "problemCount": 8,
  1019 + "problemRate": 133.33,
  1020 + "cjStats": [
  1021 + {
  1022 + "totalCount": 5,
  1023 + "executedCount": 4,
  1024 + "execRate": 80,
  1025 + "stage1ProblemCount": 2,
  1026 + "stage1ProblemRate": 40,
  1027 + "stage2ProblemCount": 2,
  1028 + "stage2ProblemRate": 40,
  1029 + "stage3ProblemCount": 2,
  1030 + "stage3ProblemRate": 40,
  1031 + "problemCount": 6,
  1032 + "problemRate": 120,
  1033 + "cj": "ahImSLxXBuQkFtU8Ace",
  1034 + "cjName": "总装车间",
  1035 + "cjCode": "104",
  1036 + "zxrStats": [
  1037 + {
  1038 + "totalCount": 2,
  1039 + "executedCount": 2,
  1040 + "execRate": 100,
  1041 + "stage1ProblemCount": 2,
  1042 + "stage1ProblemRate": 100,
  1043 + "stage2ProblemCount": 2,
  1044 + "stage2ProblemRate": 100,
  1045 + "stage3ProblemCount": 2,
  1046 + "stage3ProblemRate": 100,
  1047 + "problemCount": 6,
  1048 + "problemRate": 300,
  1049 + "pjozxr": "cyTZZMgy3WliwVfM3LT",
  1050 + "pjozxrName": "周雪"
  1051 + },
  1052 + {
  1053 + "totalCount": 3,
  1054 + "executedCount": 2,
  1055 + "execRate": 66.67,
  1056 + "stage1ProblemCount": 0,
  1057 + "stage1ProblemRate": 0,
  1058 + "stage2ProblemCount": 0,
  1059 + "stage2ProblemRate": 0,
  1060 + "stage3ProblemCount": 0,
  1061 + "stage3ProblemRate": 0,
  1062 + "problemCount": 0,
  1063 + "problemRate": 0,
  1064 + "pjozxr": "jU1pkX6iMiZjUPP19MP",
  1065 + "pjozxrName": "陈工"
  1066 + }
  1067 + ]
  1068 + },
  1069 + {
  1070 + "totalCount": 1,
  1071 + "executedCount": 1,
  1072 + "execRate": 100,
  1073 + "stage1ProblemCount": 1,
  1074 + "stage1ProblemRate": 100,
  1075 + "stage2ProblemCount": 1,
  1076 + "stage2ProblemRate": 100,
  1077 + "stage3ProblemCount": 0,
  1078 + "stage3ProblemRate": 0,
  1079 + "problemCount": 2,
  1080 + "problemRate": 200,
  1081 + "cj": "Iv9y56sXFNZyuPFPQ85",
  1082 + "cjName": "人力资源处",
  1083 + "cjCode": "108",
  1084 + "zxrStats": [
  1085 + {
  1086 + "totalCount": 1,
  1087 + "executedCount": 1,
  1088 + "execRate": 100,
  1089 + "stage1ProblemCount": 1,
  1090 + "stage1ProblemRate": 100,
  1091 + "stage2ProblemCount": 1,
  1092 + "stage2ProblemRate": 100,
  1093 + "stage3ProblemCount": 0,
  1094 + "stage3ProblemRate": 0,
  1095 + "problemCount": 2,
  1096 + "problemRate": 200,
  1097 + "pjozxr": "cyTZZMgy3WliwVfM3LT",
  1098 + "pjozxrName": "周雪"
  1099 + }
  1100 + ]
  1101 + }
  1102 + ]
  1103 + },
  1104 + "msg": "成功",
  1105 + "errCode": null
  1106 +}
  1107 +
  1108 +2、人员柱状图下探明细列表-数据来源
  1109 +请求url:
  1110 +http://localhost:8090/pjoExec/list/detail?startTime=2026-09-01&endTime=2026-09-21&cj=ahImSLxXBuQkFtU8Ace&pjozxr=jU1pkX6iMiZjUPP19MP
  1111 +
  1112 +出参示例:
  1113 +{
  1114 + "success": true,
  1115 + "data": [
  1116 + {
  1117 + "id": "53DfARB8Lllis48Qc5S",
  1118 + "createdAt": null,
  1119 + "qkxdwk": "2026-09-14 16:00:00",
  1120 + "drscbc": "04XZ79FFFNlMQvVRbNC",
  1121 + "pjozxr": "jU1pkX6iMiZjUPP19MP",
  1122 + "pjozxrName": "陈工",
  1123 + "pjogcrxm": "17",
  1124 + "pjopc": "Rx9pcihofirkRXKwp7U",
  1125 + "pjopcName": "1111",
  1126 + "pjopcCode": "103",
  1127 + "gwxz": "#1#",
  1128 + "gwxzDesc": "A类",
  1129 + "gwzx1": "sWIvFIxMCEIBPQe1vnp",
  1130 + "gwzx1Name": "PT-17",
  1131 + "gwzx1Code": "PT-17",
  1132 + "gwzx2": null,
  1133 + "gwzx2Name": null,
  1134 + "gwzx2Code": null,
  1135 + "pjosfzckz": true,
  1136 + "gchtxzyyc": "#5#",
  1137 + "gchtxcyyc": "#6#",
  1138 + "gcdwt": null,
  1139 + "gcgjjh": null,
  1140 + "lfwkuc": null,
  1141 + "zyczdwt": null,
  1142 + "zyczdwtDesc": null,
  1143 + "zdbgwdgsjy": null,
  1144 + "lvqwyc": "#3#",
  1145 + "zysfyjy": true,
  1146 + "cyjy": "jU1pkX6iMiZjUPP19MP",
  1147 + "cyjyName": "陈工",
  1148 + "zyjy": "12345788342",
  1149 + "zt": "#3#",
  1150 + "ztDesc": "已执行",
  1151 + "stage1Problem": false,
  1152 + "stage2Problem": false,
  1153 + "stage3Problem": false,
  1154 + "problemCount": 0,
  1155 + "cj": "ahImSLxXBuQkFtU8Ace",
  1156 + "cjName": "总装车间",
  1157 + "cjCode": "104",
  1158 + "qy": "fmGDmYdCswHy1AfNO7R",
  1159 + "qyName": "底盘分装",
  1160 + "qyCode": "51",
  1161 + "bz": "GQ8wL2PXGUutYA7HKks",
  1162 + "bzName": "发动机分装班",
  1163 + "bzCode": "142",
  1164 + "xt": "6J4vk1uvwmoj6e3AL2G",
  1165 + "xtName": "B线",
  1166 + "xtCode": "B"
  1167 + },
  1168 + {
  1169 + "id": "8hfehNIqjGmtso6DJoE",
  1170 + "createdAt": null,
  1171 + "qkxdwk": "2026-09-14 16:00:00",
  1172 + "drscbc": "2wuZLNVlL697coAgZd9",
  1173 + "pjozxr": "jU1pkX6iMiZjUPP19MP",
  1174 + "pjozxrName": "陈工",
  1175 + "pjogcrxm": "56",
  1176 + "pjopc": "Rx9pcihofirkRXKwp7U",
  1177 + "pjopcName": "1111",
  1178 + "pjopcCode": "103",
  1179 + "gwxz": "#1#",
  1180 + "gwxzDesc": "A类",
  1181 + "gwzx1": "sWIvFIxMCEIBPQe1vnp",
  1182 + "gwzx1Name": "PT-17",
  1183 + "gwzx1Code": "PT-17",
  1184 + "gwzx2": null,
  1185 + "gwzx2Name": null,
  1186 + "gwzx2Code": null,
  1187 + "pjosfzckz": true,
  1188 + "gchtxzyyc": "#3#",
  1189 + "gchtxcyyc": "#2#",
  1190 + "gcdwt": null,
  1191 + "gcgjjh": null,
  1192 + "lfwkuc": null,
  1193 + "zyczdwt": null,
  1194 + "zyczdwtDesc": null,
  1195 + "zdbgwdgsjy": null,
  1196 + "lvqwyc": "#1#",
  1197 + "zysfyjy": null,
  1198 + "cyjy": null,
  1199 + "cyjyName": null,
  1200 + "zyjy": null,
  1201 + "zt": "#3#",
  1202 + "ztDesc": "已执行",
  1203 + "stage1Problem": false,
  1204 + "stage2Problem": false,
  1205 + "stage3Problem": false,
  1206 + "problemCount": 0,
  1207 + "cj": "ahImSLxXBuQkFtU8Ace",
  1208 + "cjName": "总装车间",
  1209 + "cjCode": "104",
  1210 + "qy": "fmGDmYdCswHy1AfNO7R",
  1211 + "qyName": "底盘分装",
  1212 + "qyCode": "51",
  1213 + "bz": "GQ8wL2PXGUutYA7HKks",
  1214 + "bzName": "发动机分装班",
  1215 + "bzCode": "142",
  1216 + "xt": null,
  1217 + "xtName": null,
  1218 + "xtCode": null
  1219 + },
  1220 + {
  1221 + "id": "GqsLUmb6KPFbksGLCMy",
  1222 + "createdAt": null,
  1223 + "qkxdwk": "2026-09-10 16:00:00",
  1224 + "drscbc": "2wuZLNVlL697coAgZd9",
  1225 + "pjozxr": "jU1pkX6iMiZjUPP19MP",
  1226 + "pjozxrName": "陈工",
  1227 + "pjogcrxm": null,
  1228 + "pjopc": "Rx9pcihofirkRXKwp7U",
  1229 + "pjopcName": "1111",
  1230 + "pjopcCode": "103",
  1231 + "gwxz": "#1#",
  1232 + "gwxzDesc": "A类",
  1233 + "gwzx1": "qvyrMf6zeRTtOk20Oug",
  1234 + "gwzx1Name": "PT-18-FZ-02",
  1235 + "gwzx1Code": "PT-18-FZ-02",
  1236 + "gwzx2": null,
  1237 + "gwzx2Name": null,
  1238 + "gwzx2Code": null,
  1239 + "pjosfzckz": true,
  1240 + "gchtxzyyc": "#2#",
  1241 + "gchtxcyyc": "#2#",
  1242 + "gcdwt": null,
  1243 + "gcgjjh": null,
  1244 + "lfwkuc": null,
  1245 + "zyczdwt": null,
  1246 + "zyczdwtDesc": null,
  1247 + "zdbgwdgsjy": null,
  1248 + "lvqwyc": null,
  1249 + "zysfyjy": true,
  1250 + "cyjy": "cyTZZMgy3WliwVfM3LT",
  1251 + "cyjyName": "周雪",
  1252 + "zyjy": null,
  1253 + "zt": "#2#",
  1254 + "ztDesc": "执行中",
  1255 + "stage1Problem": false,
  1256 + "stage2Problem": false,
  1257 + "stage3Problem": false,
  1258 + "problemCount": 0,
  1259 + "cj": "ahImSLxXBuQkFtU8Ace",
  1260 + "cjName": "总装车间",
  1261 + "cjCode": "104",
  1262 + "qy": "fmGDmYdCswHy1AfNO7R",
  1263 + "qyName": "底盘分装",
  1264 + "qyCode": "51",
  1265 + "bz": "GQ8wL2PXGUutYA7HKks",
  1266 + "bzName": "发动机分装班",
  1267 + "bzCode": "142",
  1268 + "xt": null,
  1269 + "xtName": null,
  1270 + "xtCode": null
  1271 + }
  1272 + ],
  1273 + "msg": "成功",
  1274 + "errCode": null
  1275 +}
... ...