haogh 9 meses atrás
pai
commit
aa0d84175f

+ 3 - 1
sop-api/src/main/java/com/qmth/sop/server/api/ServiceUnitAnalyseController.java

@@ -69,10 +69,12 @@ public class ServiceUnitAnalyseController {
             @ApiParam(value = "客户所在省份", required = false) @RequestParam(required = false) String province,
             @ApiParam(value = "项目经理所在人力商", required = false) @RequestParam(required = false) Long supplierId,
             @ApiParam(value = "区域协调人ID", required = false) @RequestParam(required = false) Long coordinatorId,
+            @ApiParam(value = "类型", required = false) @RequestParam(required = false) String type,
+            @ApiParam(value = "预警字段", required = false) @RequestParam(required = false) String fieldObj,
             @ApiParam(value = "分页页码", required = true) @RequestParam @Min(SystemConstant.PAGE_NUMBER_MIN) Integer pageNumber,
             @ApiParam(value = "分页数", required = true) @RequestParam @Min(SystemConstant.PAGE_SIZE_MIN) @Max(SystemConstant.PAGE_SIZE_MAX) Integer pageSize) {
         return ResultUtil.ok(serviceUnitAnalyseService.pageSop(new Page<>(pageNumber, pageSize), serviceUnitId, crmUserId, customName, process,
-                leadId, province, supplierId, coordinatorId));
+                leadId, province, supplierId, coordinatorId, type, fieldObj));
     }
 
     @ApiOperation(value = "详情导出")

+ 29 - 0
sop-api/src/main/java/com/qmth/sop/server/api/SopWarnMonitorController.java

@@ -1,10 +1,39 @@
 package com.qmth.sop.server.api;
 
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.sop.business.bean.result.SopWarnMonitorResult;
+import com.qmth.sop.business.service.SopWarnMonitorService;
+import com.qmth.sop.common.contant.SystemConstant;
+import com.qmth.sop.common.util.Result;
+import com.qmth.sop.common.util.ResultUtil;
+import io.swagger.annotations.*;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
 /**
  * @Description sop预警监控
  * @Author haoguanghui
  * @date 2024/09/12
  */
+@Api(tags = "sop预警 Controller")
+@RestController
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_SOP_WARN_MONITOR)
 public class SopWarnMonitorController {
 
+    @Resource
+    SopWarnMonitorService sopWarnMonitorService;
+
+    @ApiOperation(value = "按大区预警统计")
+    @RequestMapping(value = "/region", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = SopWarnMonitorResult.class) })
+    public Result region(@ApiParam(value = "服务单元ID", required = true) @RequestParam(required = true) Long serviceUnitId) {
+        return ResultUtil.ok(sopWarnMonitorService.listWarnByRegion(serviceUnitId));
+    }
+
+
+
 }

+ 11 - 0
sop-business/src/main/java/com/qmth/sop/business/bean/result/ProjectMonitorResult.java

@@ -49,6 +49,9 @@ public class ProjectMonitorResult implements Serializable {
     @ApiModelProperty(value = "流程id")
     private String flowId;
 
+    @ApiModelProperty(value = "预警字段")
+    private String fieldObj;
+
     @ApiModelProperty(value = "区域协调人")
     private ProjectMonitorUserResult regionCoordinator;
 
@@ -161,4 +164,12 @@ public class ProjectMonitorResult implements Serializable {
     public void setLeadId(Long leadId) {
         this.leadId = leadId;
     }
+
+    public String getFieldObj() {
+        return fieldObj;
+    }
+
+    public void setFieldObj(String fieldObj) {
+        this.fieldObj = fieldObj;
+    }
 }

+ 66 - 0
sop-business/src/main/java/com/qmth/sop/business/bean/result/SopWarnMonitorDetailResult.java

@@ -0,0 +1,66 @@
+package com.qmth.sop.business.bean.result;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Description sop预警监控-数据查询结果
+ * @Author haoguanghui
+ * @date 2024/09/14
+ */
+public class SopWarnMonitorDetailResult {
+
+    @ApiModelProperty(value = "派单号")
+    private String crmNo;
+
+    @ApiModelProperty(value = "sop编号")
+    private String sopNo;
+
+    @ApiModelProperty(value = "预警字段")
+    private String fieldObj;
+
+    @ApiModelProperty(value = "大区经理ID")
+    private Long leadId;
+
+    @ApiModelProperty(value = "大区经理名称")
+    private String leadName;
+
+    public String getCrmNo() {
+        return crmNo;
+    }
+
+    public void setCrmNo(String crmNo) {
+        this.crmNo = crmNo;
+    }
+
+    public String getSopNo() {
+        return sopNo;
+    }
+
+    public void setSopNo(String sopNo) {
+        this.sopNo = sopNo;
+    }
+
+    public String getFieldObj() {
+        return fieldObj;
+    }
+
+    public void setFieldObj(String fieldObj) {
+        this.fieldObj = fieldObj;
+    }
+
+    public Long getLeadId() {
+        return leadId;
+    }
+
+    public void setLeadId(Long leadId) {
+        this.leadId = leadId;
+    }
+
+    public String getLeadName() {
+        return leadName;
+    }
+
+    public void setLeadName(String leadName) {
+        this.leadName = leadName;
+    }
+}

+ 183 - 0
sop-business/src/main/java/com/qmth/sop/business/bean/result/SopWarnMonitorResult.java

@@ -0,0 +1,183 @@
+package com.qmth.sop.business.bean.result;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Description sop预警返回结果
+ * @Author haoguanghui
+ * @date 2024/09/14
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class SopWarnMonitorResult {
+
+    @ApiModelProperty(value = "大区经理ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long leadId;
+
+    @ApiModelProperty(value = "大区经理名称")
+    private String leadName;
+
+    @ApiModelProperty(value = "人力供应商ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long supplierId;
+
+    @ApiModelProperty(value = "人力供应商名字")
+    private String supplierName;
+
+    @ApiModelProperty(value = "区域协调人ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long coordinatorId;
+
+    @ApiModelProperty(value = "区域协调人名称")
+    private String coordinatorName;
+
+    @ApiModelProperty(value = "预警总数")
+    private Integer total;
+
+    @ApiModelProperty(value = "扫描开始时间预警数")
+    private Integer scanStartTimeNum;
+
+    @ApiModelProperty(value = "扫描开始时间预警占比")
+    private String scanStarTimeRatio;
+
+    @ApiModelProperty(value = "扫描结束时间预警")
+    private Integer scanEndTimeNum;
+
+    @ApiModelProperty(value = "扫描结束时间预警占比")
+    private String scanEndTimeRatio;
+
+    @ApiModelProperty(value = "评卷开始时间预警")
+    private Integer markStartTimeNum;
+
+    @ApiModelProperty(value = "评卷开始时间预警占比")
+    private String markStartTimeRatio;
+
+    @ApiModelProperty(value = "评卷结束时间预警")
+    private Integer markEndTimeNum;
+
+    @ApiModelProperty(value = "评卷结束时间预警占比")
+    private String markEndTimeRatio;
+
+    public String getLeadName() {
+        return leadName;
+    }
+
+    public void setLeadName(String leadName) {
+        this.leadName = leadName;
+    }
+
+    public Long getLeadId() {
+        return leadId;
+    }
+
+    public void setLeadId(Long leadId) {
+        this.leadId = leadId;
+    }
+
+    public Long getSupplierId() {
+        return supplierId;
+    }
+
+    public void setSupplierId(Long supplierId) {
+        this.supplierId = supplierId;
+    }
+
+    public String getSupplierName() {
+        return supplierName;
+    }
+
+    public void setSupplierName(String supplierName) {
+        this.supplierName = supplierName;
+    }
+
+    public Long getCoordinatorId() {
+        return coordinatorId;
+    }
+
+    public void setCoordinatorId(Long coordinatorId) {
+        this.coordinatorId = coordinatorId;
+    }
+
+    public String getCoordinatorName() {
+        return coordinatorName;
+    }
+
+    public void setCoordinatorName(String coordinatorName) {
+        this.coordinatorName = coordinatorName;
+    }
+
+    public Integer getTotal() {
+        return total;
+    }
+
+    public void setTotal(Integer total) {
+        this.total = total;
+    }
+
+    public Integer getScanStartTimeNum() {
+        return scanStartTimeNum;
+    }
+
+    public void setScanStartTimeNum(Integer scanStartTimeNum) {
+        this.scanStartTimeNum = scanStartTimeNum;
+    }
+
+    public String getScanStarTimeRatio() {
+        return scanStarTimeRatio;
+    }
+
+    public void setScanStarTimeRatio(String scanStarTimeRatio) {
+        this.scanStarTimeRatio = scanStarTimeRatio;
+    }
+
+    public Integer getScanEndTimeNum() {
+        return scanEndTimeNum;
+    }
+
+    public void setScanEndTimeNum(Integer scanEndTimeNum) {
+        this.scanEndTimeNum = scanEndTimeNum;
+    }
+
+    public String getScanEndTimeRatio() {
+        return scanEndTimeRatio;
+    }
+
+    public void setScanEndTimeRatio(String scanEndTimeRatio) {
+        this.scanEndTimeRatio = scanEndTimeRatio;
+    }
+
+    public Integer getMarkStartTimeNum() {
+        return markStartTimeNum;
+    }
+
+    public void setMarkStartTimeNum(Integer markStartTimeNum) {
+        this.markStartTimeNum = markStartTimeNum;
+    }
+
+    public String getMarkStartTimeRatio() {
+        return markStartTimeRatio;
+    }
+
+    public void setMarkStartTimeRatio(String markStartTimeRatio) {
+        this.markStartTimeRatio = markStartTimeRatio;
+    }
+
+    public Integer getMarkEndTimeNum() {
+        return markEndTimeNum;
+    }
+
+    public void setMarkEndTimeNum(Integer markEndTimeNum) {
+        this.markEndTimeNum = markEndTimeNum;
+    }
+
+    public String getMarkEndTimeRatio() {
+        return markEndTimeRatio;
+    }
+
+    public void setMarkEndTimeRatio(String markEndTimeRatio) {
+        this.markEndTimeRatio = markEndTimeRatio;
+    }
+}

+ 2 - 1
sop-business/src/main/java/com/qmth/sop/business/mapper/ServiceUnitAnalyseMapper.java

@@ -75,7 +75,8 @@ public interface ServiceUnitAnalyseMapper extends BaseMapper<TBService> {
      */
     IPage<ProjectMonitorResult> pageSop(Page<ProjectMonitorResult> page, @Param(value = "serviceUnitId") Long serviceUnitId,
             @Param(value = "crmUserId") Long crmUserId, @Param(value = "customName") String customName, @Param(value = "process") CrmProcessEnum process,
-            @Param(value = "leadId") Long leadId, @Param(value = "province") String province, @Param(value = "prList") List<String> processList);
+            @Param(value = "leadId") Long leadId, @Param(value = "province") String province, @Param(value = "prList") List<String> processList,
+            @Param(value = "type") String type, @Param(value = "fieldObj") String fieldObj);
 
     /**
      * 过服务单元等条件查询sop列表

+ 14 - 0
sop-business/src/main/java/com/qmth/sop/business/mapper/SopWarnMonitorMapper.java

@@ -0,0 +1,14 @@
+package com.qmth.sop.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.qmth.sop.business.bean.result.SopWarnMonitorDetailResult;
+import com.qmth.sop.business.entity.TBDelayWarn;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface SopWarnMonitorMapper extends BaseMapper<TBDelayWarn> {
+
+    List<SopWarnMonitorDetailResult> listDelayWarn(@Param(value = "serviceUnitId") Long serviceUnitId,
+            @Param(value = "warnFieldList") List<String> warnFieldList);
+}

+ 1 - 1
sop-business/src/main/java/com/qmth/sop/business/service/ServiceUnitAnalyseService.java

@@ -26,7 +26,7 @@ public interface ServiceUnitAnalyseService extends IService<TBService> {
     List<ServiceUnitProvinceResult> province(Long serviceUnitId);
 
     IPage<ProjectMonitorResult> pageSop(Page<ProjectMonitorResult> page, Long serviceUnitId, Long crmUserId, String customName, CrmProcessEnum process,
-            Long leadId, String province, Long supplierId, Long coordinatorId);
+            Long leadId, String province, Long supplierId, Long coordinatorId, String type, String fieldObj);
 
     void export(Long serviceUnitId, Long crmUserId, String customName, CrmProcessEnum process, Long leadId, String province, Long supplierId,
             Long coordinatorId);

+ 12 - 0
sop-business/src/main/java/com/qmth/sop/business/service/SopWarnMonitorService.java

@@ -0,0 +1,12 @@
+package com.qmth.sop.business.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.sop.business.bean.result.SopWarnMonitorResult;
+import com.qmth.sop.business.entity.TBDelayWarn;
+
+import java.util.List;
+
+public interface SopWarnMonitorService extends IService<TBDelayWarn> {
+
+    List<SopWarnMonitorResult> listWarnByRegion(Long serviceUnitId);
+}

+ 4 - 4
sop-business/src/main/java/com/qmth/sop/business/service/impl/ServiceUnitAnalyseServiceImpl.java

@@ -159,7 +159,7 @@ public class ServiceUnitAnalyseServiceImpl extends ServiceImpl<ServiceUnitAnalys
 
     @Override
     public IPage<ProjectMonitorResult> pageSop(Page<ProjectMonitorResult> page, Long serviceUnitId, Long crmUserId, String customName, CrmProcessEnum process,
-            Long leadId, String province, Long supplierId, Long coordinatorId) {
+            Long leadId, String province, Long supplierId, Long coordinatorId, String type, String fieldObj) {
         List<String> processList = new ArrayList<>();
         if (process != null) {
             processList = getProcessList(process);
@@ -173,11 +173,11 @@ public class ServiceUnitAnalyseServiceImpl extends ServiceImpl<ServiceUnitAnalys
         }
 
         IPage<ProjectMonitorResult> pageSop;
-        // 人力供应商、区域协调人
+        // 其他
         if (supplierId == null && coordinatorId == null) {
             pageSop = baseMapper.pageSop(new Page<>(page.getCurrent(), page.getSize()), serviceUnitId, crmUserId,
-                    customName, process, leadId, province, processList);
-        } else { // 其他
+                    customName, process, leadId, province, processList, type, fieldObj);
+        } else { // 人力供应商、区域协调人
             pageSop = baseMapper.pageSopByUserAllocation(new Page<>(page.getCurrent(), page.getSize()), serviceUnitId, crmUserId,
                     customName, process, leadId, province, processList, supplierId, coordinatorId, roleType);
         }

+ 147 - 0
sop-business/src/main/java/com/qmth/sop/business/service/impl/SopWarnMonitorServiceImpl.java

@@ -0,0 +1,147 @@
+package com.qmth.sop.business.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.sop.business.bean.result.SopWarnMonitorDetailResult;
+import com.qmth.sop.business.bean.result.SopWarnMonitorResult;
+import com.qmth.sop.business.entity.TBDelayWarn;
+import com.qmth.sop.business.mapper.SopWarnMonitorMapper;
+import com.qmth.sop.business.service.SopWarnMonitorService;
+import com.qmth.sop.common.enums.WarnFieldEnum;
+import org.apache.commons.collections4.CollectionUtils;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.NumberFormat;
+import java.util.*;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Service
+public class SopWarnMonitorServiceImpl extends ServiceImpl<SopWarnMonitorMapper, TBDelayWarn> implements SopWarnMonitorService {
+
+    @Override
+    public List<SopWarnMonitorResult> listWarnByRegion(Long serviceUnitId) {
+        List<SopWarnMonitorResult> resultList = new ArrayList<>();
+        List<String> warnFieldList = getWarnField();
+
+        List<SopWarnMonitorDetailResult> warnDetailList = baseMapper.listDelayWarn(serviceUnitId, warnFieldList);
+        //按照大区经理分组
+        Function<SopWarnMonitorDetailResult, List<Object>> compositeKey = warn -> Arrays.asList(warn.getLeadId(), warn.getLeadName());
+        Map<List<Object>, List<SopWarnMonitorDetailResult>> warnMap = warnDetailList.stream().collect(Collectors.groupingBy(compositeKey, Collectors.toList()));
+
+        Set<Map.Entry<List<Object>, List<SopWarnMonitorDetailResult>>> entries = warnMap.entrySet();
+        for (Map.Entry<List<Object>, List<SopWarnMonitorDetailResult>> entry : entries) {
+            SopWarnMonitorResult result = new SopWarnMonitorResult();
+            List<Object> leadList = entry.getKey();
+            List<SopWarnMonitorDetailResult> detailList = entry.getValue();
+
+            result.setLeadId(Long.parseLong(leadList.get(0).toString()));
+            result.setLeadName(leadList.get(1).toString());
+            result.setTotal(detailList.size());
+            resultList.add(result);
+        }
+
+        //排序
+        List<SopWarnMonitorResult> warnOrderList = resultList.stream()
+                .sorted(Comparator.comparing(SopWarnMonitorResult::getTotal).reversed())
+                .collect(Collectors.toList());
+        //设置预警数量和占比
+        for (SopWarnMonitorResult result : warnOrderList) {
+            List<SopWarnMonitorDetailResult> filterWarnList = warnDetailList.stream()
+                    .filter(item -> item.getLeadId().equals(result.getLeadId()))
+                    .collect(Collectors.toList());
+            getWarnFieldNum(result, filterWarnList);
+        }
+
+        //合计
+        getSum(resultList);
+
+        return resultList;
+    }
+
+    private void getSum(List<SopWarnMonitorResult> resultList) {
+        if(CollectionUtils.isNotEmpty(resultList)) {
+            SopWarnMonitorResult result = new SopWarnMonitorResult();
+            //总量
+            int sum = resultList.stream().mapToInt(SopWarnMonitorResult::getTotal).sum();
+            //扫描起始时间的预警总量
+            int scanStartTimeSum = resultList.stream().mapToInt(SopWarnMonitorResult::getScanStartTimeNum).sum();
+            //扫描结束时间的预警总量
+            int scanEndTimeSum = resultList.stream().mapToInt(SopWarnMonitorResult::getScanEndTimeNum).sum();
+            //评卷起始时间的预警总量
+            int markStartTimeSum = resultList.stream().mapToInt(SopWarnMonitorResult::getMarkStartTimeNum).sum();
+            //评卷结束时间的预警总量
+            int markEndTimeSum = resultList.stream().mapToInt(SopWarnMonitorResult::getMarkEndTimeNum).sum();
+
+            result.setTotal(sum);
+            result.setScanStartTimeNum(scanStartTimeSum);
+            result.setScanStarTimeRatio(getRatio(BigDecimal.valueOf(sum), BigDecimal.valueOf(scanStartTimeSum)));
+            result.setScanEndTimeNum(scanEndTimeSum);
+            result.setScanEndTimeRatio(getRatio(BigDecimal.valueOf(sum), BigDecimal.valueOf(scanEndTimeSum)));
+            result.setMarkStartTimeNum(markStartTimeSum);
+            result.setMarkStartTimeRatio(getRatio(BigDecimal.valueOf(sum), BigDecimal.valueOf(markStartTimeSum)));
+            result.setMarkEndTimeNum(markEndTimeSum);
+            result.setMarkEndTimeRatio(getRatio(BigDecimal.valueOf(sum), BigDecimal.valueOf(markEndTimeSum)));
+
+            resultList.add(result);
+        }
+    }
+
+    private void getWarnFieldNum(SopWarnMonitorResult result, List<SopWarnMonitorDetailResult> filterWarnList) {
+        //按照预警字段分组,统计数量
+        Map<String, List<SopWarnMonitorDetailResult>> map = filterWarnList.stream().collect(Collectors.groupingBy(SopWarnMonitorDetailResult::getFieldObj));
+        for (WarnFieldEnum field : WarnFieldEnum.values()) {
+            int warnNum = 0;
+            String ratio = "";
+            //设置预警数量和占比
+            if (map.containsKey(field.getTitle())) {
+                warnNum = map.get(field.getTitle()).size();
+                //计算占比
+                BigDecimal num = BigDecimal.valueOf(warnNum);
+                BigDecimal totalNum = BigDecimal.valueOf(result.getTotal());
+                ratio = getRatio(totalNum, num);
+            }
+            switch (field) {
+            case SCAN_START_TIME:
+                result.setScanStartTimeNum(warnNum);
+                result.setScanStarTimeRatio(ratio);
+                break;
+            case SCAN_END_TIME:
+                result.setScanEndTimeNum(warnNum);
+                result.setScanEndTimeRatio(ratio);
+                break;
+            case MARK_START_TIME:
+                result.setMarkStartTimeNum(warnNum);
+                result.setMarkStartTimeRatio(ratio);
+                break;
+            case MARK_END_TIME:
+                result.setMarkEndTimeNum(warnNum);
+                result.setMarkEndTimeRatio(ratio);
+                break;
+            }
+        }
+
+    }
+
+    private String getRatio(BigDecimal total, BigDecimal num) {
+        String ratio = "";
+        //计算占比
+        if (total.intValue() != 0) {
+            num = num.divide(total, 4, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
+            NumberFormat formatter = NumberFormat.getPercentInstance();
+            formatter.setMinimumFractionDigits(2);
+            ratio = formatter.format(num.doubleValue() / 100);
+        }
+        return ratio;
+    }
+
+    private List<String> getWarnField() {
+        List<String> fieldList = new ArrayList<>();
+        WarnFieldEnum[] fieldEnums = WarnFieldEnum.values();
+        for (WarnFieldEnum fieldEnum : fieldEnums) {
+            fieldList.add(fieldEnum.getTitle());
+        }
+        return fieldList;
+    }
+}

+ 10 - 1
sop-business/src/main/resources/mapper/ServiceUnitAnalyseMapper.xml

@@ -70,7 +70,8 @@
         tbcd.id AS crmDetailId,
         IF ( sc.type = 'OFFICE', '教务处', '研究生' ) AS customManagerTypeStr,
         cast( tfcfe.flow_id AS CHAR ) AS flowId,
-        tbsi.update_time AS updateTime
+        tbsi.update_time AS updateTime,
+        tbdw.field_obj AS fieldObj
         FROM
         t_b_sop_info tbsi
         LEFT JOIN t_b_crm tbc ON tbc.crm_no = tbsi.crm_no
@@ -83,6 +84,7 @@
         LEFT JOIN t_f_custom_flow tfcf ON tfcf.id = tfcfe.t_f_custom_flow_id
         LEFT JOIN t_b_crm_detail tbcd ON tbcd.sop_no = tbsi.sop_no
         LEFT JOIN sys_user su3 ON su3.id = tbc.lead_id
+        LEFT JOIN t_b_delay_warn tbdw on tbdw.crm_no=tbc.crm_no and tbdw.sop_no=tbcd.sop_no
         <where>
             <if test="serviceUnitId != null">
                 AND tbsi.service_id=#{serviceUnitId}
@@ -99,6 +101,13 @@
             <if test="province != null and province != '' ">
                 AND sc.province=#{province}
             </if>
+             <!-- 预警字段 -->
+            <if test="type != null and type != '' ">
+                AND tbdw.field_obj is not null
+            </if>
+            <if test="fieldObj != null and fieldObj != '' ">
+                AND tbdw.field_obj = #{fieldObj}
+            </if>
 
             <if test="process != null">
                 <choose>

+ 25 - 0
sop-business/src/main/resources/mapper/SopWarnMonitorMapper.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.qmth.sop.business.mapper.SopWarnMonitorMapper">
+
+    <select id="listDelayWarn" resultType="com.qmth.sop.business.bean.result.SopWarnMonitorDetailResult">
+        SELECT
+        tbdw.crm_no AS crmNo,
+        tbdw.sop_no AS sopNo,
+        tbdw.field_obj AS fieldObj,
+        tbc.lead_id AS leadId,
+        su.real_name AS leadName
+        FROM
+        t_b_delay_warn tbdw
+        LEFT JOIN t_b_crm tbc ON tbdw.crm_no = tbc.crm_no
+        LEFT JOIN sys_user su ON su.id = tbc.lead_id
+        WHERE
+        tbdw.service_id = #{serviceUnitId}
+        <if test="warnFieldList != null and warnFieldList.size() > 0">
+            AND tbdw.field_obj IN
+            <foreach collection="warnFieldList" item="item" index="index" separator="," open="(" close=")">
+                #{item}
+            </foreach>
+        </if>
+    </select>
+</mapper>

+ 2 - 0
sop-common/src/main/java/com/qmth/sop/common/contant/SystemConstant.java

@@ -447,6 +447,8 @@ public class SystemConstant {
 
     public static final String PREFIX_URL_RESOURCE_SECURITY = "/admin/resource/security";
 
+    public static final String PREFIX_URL_SOP_WARN_MONITOR = "/admin/sop/warn/monitor";
+
     /**
      * 缓存配置
      */

+ 33 - 0
sop-common/src/main/java/com/qmth/sop/common/enums/WarnFieldEnum.java

@@ -0,0 +1,33 @@
+package com.qmth.sop.common.enums;
+
+/**
+ * @Description 预警字段
+ * @Author haoguanghui
+ * @date 2024/09/14
+ */
+public enum WarnFieldEnum {
+    SCAN_START_TIME("scan_start_time", "扫描开始时间"),
+
+    SCAN_END_TIME("scan_end_time", "扫描结束时间"),
+
+    MARK_START_TIME("mark_start_time", "评卷开始时间"),
+
+    MARK_END_TIME("mark_end_time", "评卷结束时间");
+
+    private String title;
+
+    private String desc;
+
+    WarnFieldEnum(String title, String desc) {
+        this.title = title;
+        this.desc = desc;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+}