ソースを参照

Merge remote-tracking branch 'origin/dev_1.1.1' into dev_1.1.1

wangliang 9 ヶ月 前
コミット
5f05eefb9e
24 ファイル変更907 行追加121 行削除
  1. 88 0
      sop-api/src/main/java/com/qmth/sop/server/api/SysCustomReceiverController.java
  2. 29 6
      sop-api/src/main/java/com/qmth/sop/server/api/TBDingController.java
  3. 36 0
      sop-business/src/main/java/com/qmth/sop/business/bean/dto/RegionCoordinatorDingTimeDto.java
  4. 96 0
      sop-business/src/main/java/com/qmth/sop/business/bean/params/CustomReceiverParam.java
  5. 17 2
      sop-business/src/main/java/com/qmth/sop/business/bean/params/DingSaveParam.java
  6. 123 0
      sop-business/src/main/java/com/qmth/sop/business/bean/result/SysCustomReceiverResult.java
  7. 0 1
      sop-business/src/main/java/com/qmth/sop/business/bean/result/SysDingGroupResult.java
  8. 91 0
      sop-business/src/main/java/com/qmth/sop/business/entity/SysCustomReceiver.java
  9. 25 0
      sop-business/src/main/java/com/qmth/sop/business/mapper/SysCustomReceiverMapper.java
  10. 23 0
      sop-business/src/main/java/com/qmth/sop/business/service/SysCustomReceiverService.java
  11. 24 4
      sop-business/src/main/java/com/qmth/sop/business/service/TBDingService.java
  12. 8 0
      sop-business/src/main/java/com/qmth/sop/business/service/TBUserArchivesService.java
  13. 111 0
      sop-business/src/main/java/com/qmth/sop/business/service/impl/SysCustomReceiverServiceImpl.java
  14. 16 2
      sop-business/src/main/java/com/qmth/sop/business/service/impl/SysDingObjServiceImpl.java
  15. 95 44
      sop-business/src/main/java/com/qmth/sop/business/service/impl/TBDingServiceImpl.java
  16. 8 26
      sop-business/src/main/java/com/qmth/sop/business/service/impl/TBUserArchivesAllocationServiceImpl.java
  17. 9 0
      sop-business/src/main/java/com/qmth/sop/business/service/impl/TBUserArchivesServiceImpl.java
  18. 7 0
      sop-business/src/main/resources/db/log/caozixuan_update_log.sql
  19. 28 31
      sop-business/src/main/resources/db/log/haoguanghui_update_log.sql
  20. 67 0
      sop-business/src/main/resources/mapper/SysCustomReceiverMapper.xml
  21. 1 1
      sop-business/src/main/resources/mapper/SysDingObjMapper.xml
  22. 2 2
      sop-business/src/main/resources/mapper/TBSopInfoMapper.xml
  23. 2 0
      sop-common/src/main/java/com/qmth/sop/common/contant/SystemConstant.java
  24. 1 2
      sop-common/src/main/java/com/qmth/sop/common/enums/SopRoleTypeEnum.java

+ 88 - 0
sop-api/src/main/java/com/qmth/sop/server/api/SysCustomReceiverController.java

@@ -0,0 +1,88 @@
+package com.qmth.sop.server.api;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.boot.api.constant.ApiConstant;
+import com.qmth.sop.business.bean.params.CustomReceiverParam;
+import com.qmth.sop.business.bean.result.SysCustomReceiverResult;
+import com.qmth.sop.business.entity.SysCustomReceiver;
+import com.qmth.sop.business.entity.SysUser;
+import com.qmth.sop.business.service.SysCustomReceiverService;
+import com.qmth.sop.common.annotation.OperationLog;
+import com.qmth.sop.common.contant.SystemConstant;
+import com.qmth.sop.common.enums.LogTypeEnum;
+import com.qmth.sop.common.enums.ProductTypeEnum;
+import com.qmth.sop.common.util.Result;
+import com.qmth.sop.common.util.ResultUtil;
+import com.qmth.sop.common.util.ServletUtil;
+import io.swagger.annotations.*;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+
+/**
+ * @Description 客户收件信息控制类
+ * @Author haoguanghui
+ * @date 2024/09/04
+ */
+@Api(tags = "客户收件信息表Controller")
+@RestController
+@RequestMapping(ApiConstant.DEFAULT_URI_PREFIX + SystemConstant.PREFIX_URL_CUSTOM_RECEIVER)
+public class SysCustomReceiverController {
+
+    @Resource
+    SysCustomReceiverService sysCustomReceiverService;
+
+
+    @ApiOperation(value = "客户列表")
+    @RequestMapping(value = "/list", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = SysCustomReceiver.class) })
+    public Result list(@ApiParam(value = "客户类型", required = false) @RequestParam(required = false) ProductTypeEnum type) {
+        return ResultUtil.ok(sysCustomReceiverService.listCustom(type));
+    }
+
+    @ApiOperation(value = "收件信息分页")
+    @RequestMapping(value = "/page", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "收件信息分页", response = SysCustomReceiverResult.class) })
+    public Result page(
+            @ApiParam(value = "客户类型", required = false) @RequestParam(required = false) ProductTypeEnum type,
+            @ApiParam(value = "客户名称", required = false) @RequestParam(required = false) String name,
+            @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(sysCustomReceiverService.pageReceiver(new Page<>(pageNumber, pageSize), type, name));
+    }
+
+    @ApiOperation(value = "收件信息保存/修改")
+    @RequestMapping(value = "/save", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "保存成功", response = Result.class) })
+    @OperationLog(logType = LogTypeEnum.EDIT)
+    public Result saveCustomReceiver(@Valid @RequestBody CustomReceiverParam param, BindingResult bindingResult) {
+        if (bindingResult.hasErrors()) {
+            return ResultUtil.error(bindingResult.getAllErrors().get(0).getDefaultMessage());
+        }
+        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+        return ResultUtil.ok(sysCustomReceiverService.saveCustomReceiver(param, requestUser));
+    }
+
+    @ApiOperation(value = "收件信息删除")
+    @RequestMapping(value = "/delete", method = RequestMethod.POST)
+    @ApiResponses({@ApiResponse(code = 200, message = "删除收件信息", response = Object.class)})
+    @OperationLog(logType = LogTypeEnum.DELETE)
+    public Result delete(@ApiParam(value = "id", required = true) @RequestParam(required = true) long id) {
+        sysCustomReceiverService.removeById(id);
+        return ResultUtil.ok();
+    }
+
+    @ApiOperation(value = "收件信息导出")
+    @RequestMapping(value = "/export", method = RequestMethod.POST)
+    @ApiResponses({ @ApiResponse(code = 200, message = "返回信息", response = Object.class) })
+    @OperationLog(logType = LogTypeEnum.EXPORT)
+    public void export(@ApiParam(value = "客户类型", required = false) @RequestParam(required = false) ProductTypeEnum type,
+            @ApiParam(value = "客户名称", required = false) @RequestParam(required = false) String name) throws Exception {
+        sysCustomReceiverService.export(type,name);
+    }
+
+}

+ 29 - 6
sop-api/src/main/java/com/qmth/sop/server/api/TBDingController.java

@@ -4,12 +4,12 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.qmth.boot.api.constant.ApiConstant;
-import com.qmth.sop.business.entity.*;
-import com.qmth.sop.common.annotation.OperationLog;
 import com.qmth.sop.business.bean.params.DingSaveParam;
 import com.qmth.sop.business.bean.result.*;
+import com.qmth.sop.business.entity.*;
 import com.qmth.sop.business.service.*;
 import com.qmth.sop.business.templete.execute.AsyncDingCountExportService;
+import com.qmth.sop.common.annotation.OperationLog;
 import com.qmth.sop.common.contant.SystemConstant;
 import com.qmth.sop.common.enums.*;
 import com.qmth.sop.common.util.Result;
@@ -66,6 +66,9 @@ public class TBDingController {
     @Resource
     TBCrmDetailService tbCrmDetailService;
 
+    @Resource
+    TBUserArchivesService tbUserArchivesService;
+
     @ApiOperation(value = "考勤明细")
     @RequestMapping(value = "/detail", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "查询成功", response = TBDing.class) })
@@ -194,17 +197,18 @@ public class TBDingController {
     @ApiOperation(value = "考勤打卡信息")
     @RequestMapping(value = "/ding_info", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "查询成功", response = DingElementResult.class) })
-    public Result findDingInfo(@ApiParam(value = "sop单号", required = true) @RequestParam String sopNo) {
+    public Result findDingInfo(@ApiParam(value = "服务单元id", required = true) @RequestParam Long serviceId,
+            @ApiParam(value = "sop单号") @RequestParam(required = false) String sopNo) {
         SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
-        return ResultUtil.ok(tBDingService.findDingElements(sopNo, requestUser.getId()));
+        return ResultUtil.ok(tBDingService.findDingElements(serviceId, sopNo, requestUser.getId()));
     }
 
     @ApiOperation(value = "考勤结果统计")
     @RequestMapping(value = "/ding_statistic", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "查询成功", response = DingStatisticResult.class) })
-    public Result findDingStatistic(@ApiParam(value = "sop单号", required = true) @RequestParam String sopNo,
+    public Result findDingStatistic(@ApiParam(value = "服务单元id", required = true) @RequestParam Long serviceId, @ApiParam(value = "sop单号") @RequestParam(required = false) String sopNo,
             @ApiParam(value = "打卡人id", required = true) @RequestParam String userId) {
-        return ResultUtil.ok(tBDingService.findDingStatistic(sopNo, SystemConstant.convertIdToLong(userId)));
+        return ResultUtil.ok(tBDingService.findDingStatistic(serviceId, sopNo, SystemConstant.convertIdToLong(userId)));
     }
 
     @ApiOperation(value = "考勤打卡保存")
@@ -227,6 +231,8 @@ public class TBDingController {
         List<DingSopInfo> resultList = new ArrayList<>();
         SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
         Long requestUserId = requestUser.getId();
+        // 判断是否包含区域协调人身份
+        boolean isCoordinator = tbUserArchivesService.containsRegionCoordinator(requestUserId);
 
         List<TBCrm> tbCrmList = tbCrmService.findAllCrm(requestUserId, null);
         if (CollectionUtils.isNotEmpty(tbCrmList)) {
@@ -241,6 +247,12 @@ public class TBDingController {
                 }
                 cell.setServiceUnitId(serviceUnitId);
                 cell.setServiceUnitName(service.getName());
+
+                if (isCoordinator) {
+                    // 包含区域协调人角色 - 打卡不选择sop
+                    resultList.add(cell);
+                    continue;
+                }
                 List<TBCrm> crmInServiceList = tbCrmList.stream().filter(e -> serviceUnitId.equals(e.getServiceId()))
                         .distinct().collect(Collectors.toList());
                 List<SopInfoResult> sopInfo = new ArrayList<>();
@@ -280,9 +292,14 @@ public class TBDingController {
     @RequestMapping(value = "/ding_find_all_sop", method = RequestMethod.POST)
     @ApiResponses({ @ApiResponse(code = 200, message = "查询成功", response = DingElementResult.class) })
     public Result findDingAllSop() {
+        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+        Long requestUserId = requestUser.getId();
+        boolean isCoordinator = tbUserArchivesService.containsRegionCoordinator(requestUserId);
+
         List<DingSopInfo> resultList = new ArrayList<>();
         List<SopInfoResult> list = tbSopInfoService.findFlowByServiceId(null);
         List<Long> serviceUnitIdList = list.stream().map(SopInfoResult::getServiceId).distinct().collect(Collectors.toList());
+
         for (Long serviceUnitId : serviceUnitIdList) {
             DingSopInfo cell = new DingSopInfo();
             TBService service = tbServiceService.getById(serviceUnitId);
@@ -292,6 +309,12 @@ public class TBDingController {
 
             cell.setServiceUnitId(serviceUnitId);
             cell.setServiceUnitName(service.getName());
+            if (isCoordinator) {
+                // 区协打卡不选择sop
+                resultList.add(cell);
+                continue;
+            }
+
             List<SopInfoResult> sopInServiceList = list.stream().filter(e -> serviceUnitId.equals(e.getServiceId()))
                     .distinct().collect(Collectors.toList());
             cell.setSopInfo(sopInServiceList);

+ 36 - 0
sop-business/src/main/java/com/qmth/sop/business/bean/dto/RegionCoordinatorDingTimeDto.java

@@ -0,0 +1,36 @@
+package com.qmth.sop.business.bean.dto;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Description: 区协打卡时间段
+ * @Author: CaoZixuan
+ * @Date: 2024-09-04
+ */
+public class RegionCoordinatorDingTimeDto {
+    @ApiModelProperty("开始时间")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long startTime;
+
+    @ApiModelProperty("结束时间")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long endTime;
+
+    public Long getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Long startTime) {
+        this.startTime = startTime;
+    }
+
+    public Long getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Long endTime) {
+        this.endTime = endTime;
+    }
+}

+ 96 - 0
sop-business/src/main/java/com/qmth/sop/business/bean/params/CustomReceiverParam.java

@@ -0,0 +1,96 @@
+package com.qmth.sop.business.bean.params;
+
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.sop.common.annotation.EditKey;
+import com.qmth.sop.common.enums.ProductTypeEnum;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotNull;
+
+public class CustomReceiverParam {
+
+    @ApiModelProperty(value = "ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @EditKey
+    private Long id;
+
+    @ApiModelProperty(value = "业务类型")
+    @NotNull(message = "请选择业务类型")
+    private ProductTypeEnum type;
+
+    @ApiModelProperty(value = "客户名称")
+    @NotNull(message = "请输入客户名称")
+    private String name;
+
+    @ApiModelProperty(value = "具体单位")
+    private String unit;
+
+    @ApiModelProperty(value = "收件人")
+    @NotNull(message = "请输入收件人")
+    private String consignee;
+
+    @ApiModelProperty(value = "收件人电话")
+    @NotNull(message = "请输入收件人电话")
+    private String consigneePhone;
+
+    @ApiModelProperty(value = "收件人地址")
+    @NotNull(message = "请输入收件人地址")
+    private String consigneeAddress;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public ProductTypeEnum getType() {
+        return type;
+    }
+
+    public void setType(ProductTypeEnum type) {
+        this.type = type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+
+    public String getConsignee() {
+        return consignee;
+    }
+
+    public void setConsignee(String consignee) {
+        this.consignee = consignee;
+    }
+
+    public String getConsigneePhone() {
+        return consigneePhone;
+    }
+
+    public void setConsigneePhone(String consigneePhone) {
+        this.consigneePhone = consigneePhone;
+    }
+
+    public String getConsigneeAddress() {
+        return consigneeAddress;
+    }
+
+    public void setConsigneeAddress(String consigneeAddress) {
+        this.consigneeAddress = consigneeAddress;
+    }
+}

+ 17 - 2
sop-business/src/main/java/com/qmth/sop/business/bean/params/DingSaveParam.java

@@ -1,5 +1,7 @@
 package com.qmth.sop.business.bean.params;
 
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
 import com.qmth.sop.common.enums.InOutTypeEnum;
 import io.swagger.annotations.ApiModelProperty;
 import org.hibernate.validator.constraints.Range;
@@ -13,9 +15,14 @@ import javax.validation.constraints.NotNull;
  * @Date: 2023-09-05
  */
 public class DingSaveParam {
+
+    @ApiModelProperty("服务单元id")
+    @NotNull(message = "缺少服务单元")
+    @Range(min = 1L, message = "缺少服务单元")
+    @JsonSerialize(using = ToStringSerializer.class)
+    private Long serviceId;
+
     @ApiModelProperty("sop号")
-    @NotNull(message = "缺少sop号")
-    @NotBlank(message = "缺少sop号")
     private String sopNo;
 
     @ApiModelProperty("签到时间")
@@ -45,6 +52,14 @@ public class DingSaveParam {
     @NotBlank(message = "缺少y坐标")
     private String axisY;
 
+    public Long getServiceId() {
+        return serviceId;
+    }
+
+    public void setServiceId(Long serviceId) {
+        this.serviceId = serviceId;
+    }
+
     public String getSopNo() {
         return sopNo;
     }

+ 123 - 0
sop-business/src/main/java/com/qmth/sop/business/bean/result/SysCustomReceiverResult.java

@@ -0,0 +1,123 @@
+package com.qmth.sop.business.bean.result;
+
+import com.alibaba.excel.annotation.ExcelIgnore;
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.alibaba.excel.annotation.write.style.ColumnWidth;
+import com.alibaba.excel.annotation.write.style.HeadFontStyle;
+import com.alibaba.excel.annotation.write.style.HeadStyle;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.qmth.sop.common.enums.ProductTypeEnum;
+import io.swagger.annotations.ApiModelProperty;
+
+import java.io.Serializable;
+
+/**
+ * @Description 客户收件信息
+ * @Author haoguanghui
+ * @date 2024/09/04
+ */
+@ColumnWidth(value = 30)
+@HeadStyle(fillForegroundColor = 12)
+@HeadFontStyle(color = 1)
+public class SysCustomReceiverResult implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "ID")
+    @JsonSerialize(using = ToStringSerializer.class)
+    @ExcelIgnore
+    private Long id;
+
+    @ApiModelProperty(value = "业务类型")
+    @ExcelIgnore
+    private ProductTypeEnum type;
+
+    @ApiModelProperty(value = "业务类型")
+    @ExcelProperty(value = "业务类型")
+    private String typeName;
+
+    @ApiModelProperty(value = "客户名称")
+    @ExcelProperty(value = "客户名称")
+    private String name;
+
+    @ApiModelProperty(value = "具体单位")
+    @ExcelProperty(value = "具体单位")
+    private String unit;
+
+    @ApiModelProperty(value = "收件人")
+    @ExcelProperty(value = "收件人")
+    private String consignee;
+
+    @ApiModelProperty(value = "收件人电话")
+    @ExcelProperty(value = "收件人电话")
+    private String consigneePhone;
+
+    @ApiModelProperty(value = "收件人地址")
+    @ExcelProperty(value = "收件人地址")
+    private String consigneeAddress;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public ProductTypeEnum getType() {
+        return type;
+    }
+
+    public void setType(ProductTypeEnum type) {
+        this.type = type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+
+    public String getConsignee() {
+        return consignee;
+    }
+
+    public void setConsignee(String consignee) {
+        this.consignee = consignee;
+    }
+
+    public String getConsigneePhone() {
+        return consigneePhone;
+    }
+
+    public void setConsigneePhone(String consigneePhone) {
+        this.consigneePhone = consigneePhone;
+    }
+
+    public String getConsigneeAddress() {
+        return consigneeAddress;
+    }
+
+    public void setConsigneeAddress(String consigneeAddress) {
+        this.consigneeAddress = consigneeAddress;
+    }
+
+    public String getTypeName() {
+        return typeName;
+    }
+
+    public void setTypeName(String typeName) {
+        this.typeName = typeName;
+    }
+}

+ 0 - 1
sop-business/src/main/java/com/qmth/sop/business/bean/result/SysDingGroupResult.java

@@ -6,7 +6,6 @@ import com.qmth.sop.business.entity.SysDingGroup;
 import com.qmth.sop.common.enums.ServiceStatusEnum;
 import io.swagger.annotations.ApiModelProperty;
 
-import javax.validation.constraints.NotEmpty;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;

+ 91 - 0
sop-business/src/main/java/com/qmth/sop/business/entity/SysCustomReceiver.java

@@ -0,0 +1,91 @@
+package com.qmth.sop.business.entity;
+
+import com.qmth.sop.common.base.BaseEntity;
+import com.qmth.sop.common.enums.ProductTypeEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotBlank;
+import java.io.Serializable;
+
+/**
+ * @Description 客户收件信息表
+ * @Author haoguanghui
+ * @date 2024/09/04
+ */
+@ApiModel(value = "SysCustomReceiver对象", description = "客户收件信息表")
+public class SysCustomReceiver extends BaseEntity implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "类型,OFFICE:教务处,CLOUD_MARK:研究生")
+    @NotBlank(message = "客户类型不能为空")
+    private ProductTypeEnum type;
+
+    @ApiModelProperty(value = "客户名称")
+    @NotBlank(message = "客户名称不能为空")
+    private String name;
+
+    @ApiModelProperty(value = "具体单位")
+    private String unit;
+
+    @ApiModelProperty(value = "收件人")
+    @NotBlank(message = "收件人不能为空")
+    private String consignee;
+
+    @ApiModelProperty(value = "收件人电话")
+    @NotBlank(message = "收件人电话不能为空")
+    private String consigneePhone;
+
+    @ApiModelProperty(value = "收件人地址")
+    @NotBlank(message = "收件人地址不能为空")
+    private String consigneeAddress;
+
+    public ProductTypeEnum getType() {
+        return type;
+    }
+
+    public void setType(ProductTypeEnum type) {
+        this.type = type;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getUnit() {
+        return unit;
+    }
+
+    public void setUnit(String unit) {
+        this.unit = unit;
+    }
+
+    public String getConsignee() {
+        return consignee;
+    }
+
+    public void setConsignee(String consignee) {
+        this.consignee = consignee;
+    }
+
+    public String getConsigneePhone() {
+        return consigneePhone;
+    }
+
+    public void setConsigneePhone(String consigneePhone) {
+        this.consigneePhone = consigneePhone;
+    }
+
+    public String getConsigneeAddress() {
+        return consigneeAddress;
+    }
+
+    public void setConsigneeAddress(String consigneeAddress) {
+        this.consigneeAddress = consigneeAddress;
+    }
+}

+ 25 - 0
sop-business/src/main/java/com/qmth/sop/business/mapper/SysCustomReceiverMapper.java

@@ -0,0 +1,25 @@
+package com.qmth.sop.business.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.qmth.sop.business.bean.dto.DataPermissionDto;
+import com.qmth.sop.business.bean.result.SysCustomReceiverResult;
+import com.qmth.sop.business.entity.SysCustomReceiver;
+import com.qmth.sop.common.enums.ProductTypeEnum;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface SysCustomReceiverMapper extends BaseMapper<SysCustomReceiver> {
+
+    List<SysCustomReceiver> listCustom(@Param(value = "type") ProductTypeEnum type);
+
+    IPage<SysCustomReceiverResult> page(Page<SysCustomReceiverResult> page, @Param(value = "type") ProductTypeEnum type, @Param(value = "name") String name,
+            @Param(value = "dpr") DataPermissionDto dpr);
+
+    List<SysCustomReceiverResult> listCustomReceiver(@Param(value = "type") ProductTypeEnum type, @Param(value = "name") String name,
+            @Param(value = "dpr") DataPermissionDto dpr);
+
+
+}

+ 23 - 0
sop-business/src/main/java/com/qmth/sop/business/service/SysCustomReceiverService.java

@@ -0,0 +1,23 @@
+package com.qmth.sop.business.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.qmth.sop.business.bean.params.CustomReceiverParam;
+import com.qmth.sop.business.bean.result.SysCustomReceiverResult;
+import com.qmth.sop.business.entity.SysCustomReceiver;
+import com.qmth.sop.business.entity.SysUser;
+import com.qmth.sop.common.enums.ProductTypeEnum;
+
+import java.util.List;
+
+public interface SysCustomReceiverService extends IService<SysCustomReceiver> {
+
+    List<SysCustomReceiver> listCustom(ProductTypeEnum type);
+
+    IPage<SysCustomReceiverResult> pageReceiver(Page<SysCustomReceiverResult> page, ProductTypeEnum type, String name);
+
+    Long saveCustomReceiver(CustomReceiverParam param, SysUser requestUser);
+
+    void export(ProductTypeEnum type, String name);
+}

+ 24 - 4
sop-business/src/main/java/com/qmth/sop/business/service/TBDingService.java

@@ -3,6 +3,7 @@ package com.qmth.sop.business.service;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.qmth.sop.business.bean.dto.DateFormDto;
+import com.qmth.sop.business.bean.dto.RegionCoordinatorDingTimeDto;
 import com.qmth.sop.business.bean.params.DingSaveParam;
 import com.qmth.sop.business.bean.result.*;
 import com.qmth.sop.business.entity.SysUser;
@@ -30,20 +31,22 @@ public interface TBDingService extends IService<TBDing> {
     /**
      * 根据sop查询打卡界面元素
      *
-     * @param sopNo  sop编号
-     * @param userId 用户id
+     * @param serviceId 服务单元id
+     * @param sopNo     sop编号
+     * @param userId    用户id
      * @return 打卡元素
      */
-    DingElementResult findDingElements(String sopNo, Long userId);
+    DingElementResult findDingElements(Long serviceId, String sopNo, Long userId);
 
     /**
      * 考勤结果统计
      *
+     * @param serviceId 服务单元id
      * @param sopNo  sop单号
      * @param userId 用户id
      * @return 考勤结果统计
      */
-    DingStatisticResult findDingStatistic(String sopNo, Long userId);
+    DingStatisticResult findDingStatistic(Long serviceId, String sopNo, Long userId);
 
     /**
      * 保存打卡记录
@@ -89,6 +92,15 @@ public interface TBDingService extends IService<TBDing> {
      */
     DingElementResult findDingRule(Long userId, String sopNo);
 
+    /**
+     * 查询考勤组规则(只查询工程师的考勤规则)
+     *
+     * @param userId        用户id
+     * @param serviceUnitId 服务单元id
+     * @return 规则
+     */
+    DingElementResult findDingRule(Long userId, Long serviceUnitId);
+
     /**
      * 查询剩余补卡天数
      *
@@ -123,8 +135,16 @@ public interface TBDingService extends IService<TBDing> {
 
     /**
      * 根据sopNo查询状态
+     *
      * @param sopNo sopNo
      * @return 审批
      */
     TFFlowApprove findFlowApproveBySopNo(String sopNo);
+
+    /**
+     * 获取区协打卡时间段
+     *
+     * @return 区协打卡时间段
+     */
+    RegionCoordinatorDingTimeDto findRegionCoordinatorDingTime();
 }

+ 8 - 0
sop-business/src/main/java/com/qmth/sop/business/service/TBUserArchivesService.java

@@ -135,4 +135,12 @@ public interface TBUserArchivesService extends IService<TBUserArchives> {
     List<ArchivesSourceResult> findArchivesSourceByType(Set<RoleTypeEnum> roleTypes);
 
     List<Map<String, Object>> findTempEmp();
+
+    /**
+     * 查询是否包含区域协调人
+     *
+     * @param userId 用户id
+     * @return true是,false否
+     */
+    boolean containsRegionCoordinator(Long userId);
 }

+ 111 - 0
sop-business/src/main/java/com/qmth/sop/business/service/impl/SysCustomReceiverServiceImpl.java

@@ -0,0 +1,111 @@
+package com.qmth.sop.business.service.impl;
+
+import com.alibaba.excel.EasyExcel;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.boot.core.exception.StatusException;
+import com.qmth.sop.business.bean.dto.DataPermissionDto;
+import com.qmth.sop.business.bean.params.CustomReceiverParam;
+import com.qmth.sop.business.bean.result.SysCustomReceiverResult;
+import com.qmth.sop.business.bean.result.TBDeviceDeliveryResult;
+import com.qmth.sop.business.entity.SysCustomReceiver;
+import com.qmth.sop.business.entity.SysUser;
+import com.qmth.sop.business.mapper.SysCustomReceiverMapper;
+import com.qmth.sop.business.service.SysCustomReceiverService;
+import com.qmth.sop.business.service.SysUserService;
+import com.qmth.sop.common.contant.SystemConstant;
+import com.qmth.sop.common.enums.ExceptionResultEnum;
+import com.qmth.sop.common.enums.ProductTypeEnum;
+import com.qmth.sop.common.util.FileUtil;
+import com.qmth.sop.common.util.ServletUtil;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @Description
+ * @Author haoguanghui
+ * @date 2024/09/04
+ */
+@Service
+public class SysCustomReceiverServiceImpl extends ServiceImpl<SysCustomReceiverMapper, SysCustomReceiver> implements SysCustomReceiverService {
+
+    @Resource
+    private SysUserService sysUserService;
+
+    @Override
+    public List<SysCustomReceiver> listCustom(ProductTypeEnum type) {
+        return baseMapper.listCustom(type);
+    }
+
+    @Override
+    public IPage<SysCustomReceiverResult> pageReceiver(Page<SysCustomReceiverResult> page, ProductTypeEnum type, String name) {
+        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+        DataPermissionDto dpr = sysUserService.buildUserDataPermission(requestUser.getId());
+        return baseMapper.page(new Page<>(page.getCurrent(), page.getSize()), type, name, dpr);
+    }
+
+    @Override
+    public Long saveCustomReceiver(CustomReceiverParam param, SysUser requestUser) {
+        Long id = param.getId();
+        SysCustomReceiver sysCustomReceiver = new SysCustomReceiver();
+        BeanUtils.copyProperties(param, sysCustomReceiver);
+
+        //新增
+        if (id == null) {
+            LambdaQueryWrapper<SysCustomReceiver> queryWrapper = new LambdaQueryWrapper<>();
+            queryWrapper.eq(SysCustomReceiver::getType, param.getType());
+            queryWrapper.eq(SysCustomReceiver::getName, param.getName());
+            queryWrapper.eq(SysCustomReceiver::getUnit, param.getUnit());
+            queryWrapper.eq(SysCustomReceiver::getConsignee, param.getConsignee());
+            List<SysCustomReceiver> customReceiverList = this.list(queryWrapper);
+            if (!customReceiverList.isEmpty()) {
+                throw ExceptionResultEnum.ERROR.exception(String.format("该客户下已经存在收件人:%s,请不要重复新增", param.getConsignee()));
+            }
+
+            sysCustomReceiver.insertInfo(requestUser.getId());
+            this.save(sysCustomReceiver);
+            id = sysCustomReceiver.getId();
+        } else { //编辑
+            SysCustomReceiver existCustomReceiver = this.getById(id);
+            if (Objects.isNull(existCustomReceiver)) {
+                throw ExceptionResultEnum.ERROR.exception("操作的数据记录不存在");
+            }
+
+            sysCustomReceiver.updateInfo(requestUser.getId());
+            this.updateById(sysCustomReceiver);
+        }
+        return id;
+    }
+
+    @Override
+    public void export(ProductTypeEnum type, String name) {
+        SysUser requestUser = (SysUser) ServletUtil.getRequestUser();
+        DataPermissionDto dpr = sysUserService.buildUserDataPermission(requestUser.getId());
+        List<SysCustomReceiverResult> receiverResultList = baseMapper.listCustomReceiver(type, name, dpr);
+        receiverResultList.forEach(item -> {
+            item.setTypeName(item.getType().getTitle());
+        });
+        File fileTemp = null;
+        try {
+            fileTemp = SystemConstant.getFileTempVar(SystemConstant.XLSX_PREFIX);
+            EasyExcel.write(fileTemp, SysCustomReceiverResult.class).sheet("客户收件信息").doWrite(receiverResultList);
+            HttpServletResponse response = ServletUtil.getResponse();
+            FileUtil.outputFile(response, fileTemp, "客户收件信息.xlsx");
+        } catch (IOException e) {
+            throw ExceptionResultEnum.ERROR.exception(e.getMessage());
+        } finally {
+            if (Objects.nonNull(fileTemp)) {
+                fileTemp.delete();
+            }
+        }
+    }
+}

+ 16 - 2
sop-business/src/main/java/com/qmth/sop/business/service/impl/SysDingObjServiceImpl.java

@@ -1,13 +1,16 @@
 package com.qmth.sop.business.service.impl;
 
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.sop.business.bean.result.SysDingGroupRoleResult;
 import com.qmth.sop.business.entity.SysDingObj;
 import com.qmth.sop.business.mapper.SysDingObjMapper;
 import com.qmth.sop.business.service.SysDingObjService;
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.qmth.sop.common.contant.SystemConstant;
+import com.qmth.sop.common.enums.SopRoleTypeEnum;
 import org.springframework.stereotype.Service;
 
 import java.util.List;
+import java.util.Objects;
 
 /**
  * <p>
@@ -22,6 +25,17 @@ public class SysDingObjServiceImpl extends ServiceImpl<SysDingObjMapper, SysDing
 
     @Override
     public List<SysDingGroupRoleResult> getList(long id) {
-        return this.baseMapper.getList(id);
+        List<SysDingGroupRoleResult> result = this.baseMapper.getList(id);
+        for (SysDingGroupRoleResult sysDingGroupRoleResult : result) {
+            Long roleId = sysDingGroupRoleResult.getRoleId();
+            if (!SystemConstant.longNotNull(roleId)) {
+                // 打卡类型 名称根据sop_role_type来
+                SopRoleTypeEnum sopRoleType = sysDingGroupRoleResult.getSopRoleType();
+                if (Objects.nonNull(sopRoleType)) {
+                    sysDingGroupRoleResult.setRoleName(sopRoleType.getTitle());
+                }
+            }
+        }
+        return result;
     }
 }

+ 95 - 44
sop-business/src/main/java/com/qmth/sop/business/service/impl/TBDingServiceImpl.java

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.sop.business.bean.dto.DataPermissionDto;
 import com.qmth.sop.business.bean.dto.DateFormDto;
+import com.qmth.sop.business.bean.dto.RegionCoordinatorDingTimeDto;
 import com.qmth.sop.business.bean.dto.SopCrmInfo;
 import com.qmth.sop.business.bean.params.DingSaveParam;
 import com.qmth.sop.business.bean.result.*;
@@ -90,18 +91,25 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
     private TBCrmDetailService tbCrmDetailService;
 
     @Override
-    public DingElementResult findDingElements(String sopNo, Long userId) {
-
-        SopCrmInfo sopCrmInfo = tbCrmService.findSopCrmInfoBySop(sopNo);
-        if (Objects.isNull(sopCrmInfo)) {
-            throw ExceptionResultEnum.ERROR.exception(String.format("未找到sop单号为[%s]的派单信息", sopNo));
+    public DingElementResult findDingElements(Long serviceId, String sopNo, Long userId) {
+        if (SystemConstant.strNotNull(sopNo)) {
+            SopCrmInfo sopCrmInfo = tbCrmService.findSopCrmInfoBySop(sopNo);
+            if (Objects.isNull(sopCrmInfo)) {
+                throw ExceptionResultEnum.ERROR.exception(String.format("未找到sop单号为[%s]的派单信息", sopNo));
+            }
         }
-        DingElementResult dingElementResult = this.findDingRule(userId, sopNo);
+
+        DingElementResult dingElementResult = this.findDingRule(userId, serviceId);
         if (Objects.nonNull(dingElementResult)) {
             Long userArchivesId = dingElementResult.getUserArchivesId();
             String currentDayStr = DateFormatUtils.format(System.currentTimeMillis(), SystemConstant.DEFAULT_DATE_DAY_PATTERN);
-            List<TBDing> tbDingList = this.list(new QueryWrapper<TBDing>().lambda().eq(TBDing::getSopNo, sopNo)
-                    .eq(TBDing::getUserArchivesId, userArchivesId).eq(TBDing::getSignDate, currentDayStr));
+            QueryWrapper<TBDing> queryWrapper = new QueryWrapper<>();
+            queryWrapper.lambda().eq(TBDing::getServiceId, serviceId).eq(TBDing::getUserArchivesId, userArchivesId).eq(TBDing::getSignDate, currentDayStr);
+            if (SystemConstant.strNotNull(sopNo)) {
+                queryWrapper.lambda().eq(TBDing::getSopNo, sopNo);
+            }
+
+            List<TBDing> tbDingList = this.list(queryWrapper);
             if (CollectionUtils.isNotEmpty(tbDingList)) {
                 // 有考勤记录
                 if (tbDingList.size() > 1) {
@@ -124,7 +132,7 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
     }
 
     @Override
-    public DingStatisticResult findDingStatistic(String sopNo, Long userId) {
+    public DingStatisticResult findDingStatistic(Long serviceId, String sopNo, Long userId) {
         // 截取年分割截止
         final int yearEnd = 4;
         // 截取日分割开始
@@ -138,9 +146,13 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
         int exceptionCount = 0;
         List<DingFormResult> formList = new ArrayList<>();
         if (CollectionUtils.isNotEmpty(dateFormList)) {
+            QueryWrapper<TBDing> dingQueryWrapper = new QueryWrapper<>();
+            dingQueryWrapper.lambda().eq(TBDing::getServiceId, serviceId).eq(TBDing::getUserId, userId).orderByAsc(TBDing::getId);
+            if (SystemConstant.strNotNull(sopNo)) {
+                dingQueryWrapper.lambda().eq(TBDing::getSopNo, sopNo);
+            }
 
-            List<TBDing> tbDingList = this.list(
-                    new QueryWrapper<TBDing>().lambda().eq(TBDing::getSopNo, sopNo).eq(TBDing::getUserId, userId).orderByAsc(TBDing::getId));
+            List<TBDing> tbDingList = this.list(dingQueryWrapper);
 
             // 签到表
             List<DingFormResult> formDingList = new ArrayList<>();
@@ -158,7 +170,7 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
                 if (signInTime == null || signInTime == 0) {
                     signInInfo.setStatus(DingStatusEnum.NO_SIGN);
                 } else {
-                    if (sopNo.equals(dingSopNo)) {
+                    if (Objects.equals(sopNo, dingSopNo)) {
                         signInInfo.setStatus(DingStatusEnum.SIGN);
                     } else {
                         signInInfo.setStatus(DingStatusEnum.OTHER);
@@ -179,7 +191,7 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
                 if (signOutTime == null || signOutTime == 0) {
                     signOutInfo.setStatus(DingStatusEnum.NO_SIGN);
                 } else {
-                    if (sopNo.equals(dingSopNo)) {
+                    if (Objects.equals(sopNo, dingSopNo)) {
                         signOutInfo.setStatus(DingStatusEnum.SIGN);
                     } else {
                         signOutInfo.setStatus(DingStatusEnum.OTHER);
@@ -202,6 +214,7 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
             String endDate = dateFormDto.getEndDate();
             endDate = endDate.substring(dayStart);
 
+            // TODO: 2024/9/4 更改补卡记录
             // 查询正在补卡中的记录
             List<TBDingApply> resigningList = tbDingApplyService.list(
                     new QueryWrapper<TBDingApply>().lambda().select(TBDingApply::getType, TBDingApply::getApplyTime).eq(TBDingApply::getSopNo, sopNo).eq(TBDingApply::getCreateId, userId)
@@ -288,23 +301,46 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
 
     @Override
     public void dingSave(DingSaveParam dingSaveParam, Long userId) throws IOException {
+        boolean isCoordinator = tbUserArchivesService.containsRegionCoordinator(userId);
+        Long serviceId = dingSaveParam.getServiceId();
         String sopNo = dingSaveParam.getSopNo();
-        SopCrmInfo sopCrmInfo = tbCrmService.findSopCrmInfoBySop(sopNo);
-        if (Objects.isNull(sopCrmInfo)) {
-            throw ExceptionResultEnum.ERROR.exception(String.format("未找到sop单号为[%s]的派单信息", sopNo));
+        String crmNo = null;
+        Long flowId = null;
+        List<SopRoleTypeEnum> roleType = new ArrayList<>();
+        if (SystemConstant.strNotNull(sopNo)) {
+            SopCrmInfo sopCrmInfo = tbCrmService.findSopCrmInfoBySop(sopNo);
+            if (Objects.isNull(sopCrmInfo)) {
+                throw ExceptionResultEnum.ERROR.exception(String.format("未找到sop单号为[%s]的派单信息", sopNo));
+            }
+            crmNo = sopCrmInfo.getCrmNo();
+            flowId = sopCrmInfo.getFlowId();
+            roleType = tbUserArchivesAllocationService.findSopRoleTypeByUserSopNo(userId, sopNo);
+            if (CollectionUtils.isEmpty(roleType)) {
+                throw ExceptionResultEnum.ERROR.exception("未找到用户在当前sop的身份信息");
+            }
+        } else {
+            if (!isCoordinator) {
+                throw ExceptionResultEnum.ERROR.exception("非区域协调人,必须选择sop");
+            }
+            roleType.add(SopRoleTypeEnum.REGION_COORDINATOR);
         }
 
-        DingElementResult dingElementResult = this.findDingRule(userId, sopNo);
+        DingElementResult dingElementResult = this.findDingRule(userId, serviceId);
         if (Objects.isNull(dingElementResult)) {
             throw ExceptionResultEnum.ERROR.exception("未能获取考勤相关规则");
         }
 
         Long signTime = dingSaveParam.getSignTime();
-        TBCrmDetail tbCrmDetail = tbCrmDetailService.findBySopNo(sopNo);
-        Long scanStartTime = tbCrmDetail.getScanStartTime();
-        Long scanEndTime = tbCrmDetail.getScanEndTime();
-        Long markPaperStartTime = tbCrmDetail.getMarkPaperStartTime();
-        Long markPaperEndTime = tbCrmDetail.getMarkPaperEndTime();
+        if (isCoordinator) {
+            RegionCoordinatorDingTimeDto dingTimeDto = this.findRegionCoordinatorDingTime();
+            Long startTime = dingTimeDto.getStartTime();
+            Long endTime = dingTimeDto.getEndTime();
+            if (signTime < startTime || signTime > endTime) {
+                throw ExceptionResultEnum.ERROR.exception(
+                        String.format("区域协调人请在%s - %s打卡", DateFormatUtils.format(startTime, "yyyy/MM/dd"),
+                                DateFormatUtils.format(endTime, "yyyy/MM/dd")));
+            }
+        }
 
         DingDateTypeEnum dateType = sysDingDateService.getDingDateType(DateDisposeUtils.timestampToLocalDate(signTime));
 
@@ -345,13 +381,6 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
             facePass = score.compareTo(limit) > -1;
         }
 
-        String crmNo = sopCrmInfo.getCrmNo();
-        Long serviceId = sopCrmInfo.getServiceUnitId();
-        Long flowId = sopCrmInfo.getFlowId();
-        List<SopRoleTypeEnum> roleType = tbUserArchivesAllocationService.findSopRoleTypeByUserSopNo(userId, sopNo);
-        if (CollectionUtils.isEmpty(roleType)) {
-            throw ExceptionResultEnum.ERROR.exception("未找到用户在当前sop的身份信息");
-        }
         String signDate = DateFormatUtils.format(signTime, SystemConstant.DEFAULT_DATE_DAY_PATTERN);
         String signYear = DateFormatUtils.format(signTime, SystemConstant.DEFAULT_DATE_YEAR_PATTERN);
         String currentDayStr = DateFormatUtils.format(System.currentTimeMillis(), SystemConstant.DEFAULT_DATE_DAY_PATTERN);
@@ -362,7 +391,13 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
         List<TBDing> todayDingList = this.list(
                 new QueryWrapper<TBDing>().lambda().eq(TBDing::getUserId, userId).eq(TBDing::getSignYear, signYear).eq(TBDing::getSignDate, signDate));
         // 该用户在其他sop的当天打卡记录
-        List<TBDing> otherSopDingList = todayDingList.stream().filter(e -> !e.getSopNo().equals(sopNo)).collect(Collectors.toList());
+        List<TBDing> otherSopDingList;
+        if (isCoordinator) {
+            otherSopDingList = todayDingList.stream().filter(e -> !e.getServiceId().equals(serviceId)).collect(Collectors.toList());
+        } else {
+            otherSopDingList = todayDingList.stream().filter(e -> !e.getSopNo().equals(sopNo)).collect(Collectors.toList());
+        }
+
         if (CollectionUtils.isNotEmpty(otherSopDingList)) {
             List<TBDing> unFinishDingList = otherSopDingList.stream()
                     .filter(e -> !SystemConstant.longNotNull(e.getSignInTime()) || !SystemConstant.longNotNull(e.getSignOutTime())).collect(Collectors.toList());
@@ -392,8 +427,12 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
             log.error("人脸识别不通过,score :" + score);
             throw ExceptionResultEnum.ERROR.exception("人脸识别不通过!");
         }
-
-        List<TBDing> tbDingList = todayDingList.stream().filter(e -> e.getSopNo().equals(sopNo)).collect(Collectors.toList());
+        List<TBDing> tbDingList;
+        if (isCoordinator) {
+            tbDingList = todayDingList.stream().filter(e -> e.getServiceId().equals(serviceId)).collect(Collectors.toList());
+        } else {
+            tbDingList = todayDingList.stream().filter(e -> e.getSopNo().equals(sopNo)).collect(Collectors.toList());
+        }
         if (CollectionUtils.isEmpty(tbDingList)) {
             // 没有这天的打卡记录 - 新增打卡记录
             TBDing tbDing = new TBDing();
@@ -447,16 +486,6 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
                 tbDing.setFaceOutPass(facePass);
                 break;
             }
-            Long signInTime = tbDing.getSignInTime();
-            Long signOutTime = tbDing.getSignOutTime();
-            if (signInTime != null && signInTime > 0 && signOutTime != null && signOutTime > 0) {
-                // 打卡异常 (两个打卡时间均不在时间点 -> 异常)
-                boolean signInException = !((scanStartTime <= signInTime && signInTime <= scanEndTime) || (
-                        markPaperStartTime <= signInTime && signInTime <= markPaperEndTime));
-                boolean signOutException = !((scanStartTime <= signOutTime && signOutTime <= scanEndTime) || (
-                        markPaperStartTime <= signOutTime && signOutTime <= markPaperEndTime));
-                tbDing.setDingException(signInException && signOutException);
-            }
             this.updateById(tbDing);
         }
     }
@@ -566,11 +595,11 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
     public DateFormDto buildSignDateFormBySop(String sopNo) {
         DateFormDto result = new DateFormDto();
         List<String> dateList = new ArrayList<>();
+        long currentTime = System.currentTimeMillis();
         if (sopNo != null && sopNo.length() > 0) {
             TFFlowApprove tfFlowApprove = this.findFlowApproveBySopNo(sopNo);
             FlowStatusEnum flowStatusEnum = tfFlowApprove.getStatus();
             Long updateTime = tfFlowApprove.getUpdateTime();
-            Long currentTime = System.currentTimeMillis();
 
             TBCrmDetail tbCrmDetail = tbCrmDetailService.findBySopNo(sopNo);
             if (Objects.isNull(tbCrmDetail)) {
@@ -587,7 +616,16 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
             }
             dateList.sort(Collections.reverseOrder());
             result.setDateFormList(dateList);
-
+        } else {
+            // 区协固定打卡时间
+            RegionCoordinatorDingTimeDto dingTimeDto = this.findRegionCoordinatorDingTime();
+            Long startTime = dingTimeDto.getStartTime();
+            if (currentTime < startTime) {
+                return result;
+            }
+            Long endTime = dingTimeDto.getEndTime();
+            result.setDateFormList(DateDisposeUtils.getDaysBetween(startTime, Math.min(currentTime, endTime),
+                    SystemConstant.DEFAULT_DATE_YMD_S_PATTERN));
         }
         if (CollectionUtils.isNotEmpty(dateList)) {
             result.setEndDate(dateList.get(0));
@@ -599,7 +637,11 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
     public DingElementResult findDingRule(Long userId, String sopNo) {
         SopCrmInfo sopCrmInfo = tbCrmService.findSopCrmInfoBySop(sopNo);
         Long serviceUnitId = sopCrmInfo.getServiceUnitId();
+        return this.findDingRule(userId, serviceUnitId);
+    }
 
+    @Override
+    public DingElementResult findDingRule(Long userId, Long serviceUnitId) {
         List<DingElementResult> dingElementResultList = this.baseMapper.findDingResultByUserId(userId, serviceUnitId);
         List<Long> dingGroupIds = dingElementResultList.stream().map(DingElementResult::getDingGroupId).distinct().collect(Collectors.toList());
 
@@ -756,4 +798,13 @@ public class TBDingServiceImpl extends ServiceImpl<TBDingMapper, TBDing> impleme
         }
         return tfFlowApproves.get(0);
     }
+
+    @Override
+    public RegionCoordinatorDingTimeDto findRegionCoordinatorDingTime() {
+        SysConfig sysConfig = sysConfigService.findByConfigKey(SystemConstant.REGION_COORDINATOR_DING_TIME);
+        if (Objects.isNull(sysConfig)) {
+            throw ExceptionResultEnum.ERROR.exception("缺少区域协调人打卡时间段");
+        }
+        return JSON.parseObject(sysConfig.getConfigValue(), RegionCoordinatorDingTimeDto.class);
+    }
 }

+ 8 - 26
sop-business/src/main/java/com/qmth/sop/business/service/impl/TBUserArchivesAllocationServiceImpl.java

@@ -533,23 +533,13 @@ public class TBUserArchivesAllocationServiceImpl
         switch (sopRoleTypeEnum) {
         case ENGINEER:
         case PROJECT_MANAGER:
-            switch (productTypeEnum) {
-            case OFFICE:
-                datasource = tbUserArchivesService.list().stream().map(TBUserArchives::getId).distinct()
-                        .collect(Collectors.toList());
-                break;
-            case CLOUD_MARK:
-                datasource = tbUserArchivesService.findArchivesSourceByType(
-                                new HashSet<>(Arrays.asList(RoleTypeEnum.EFFECT_ENGINEER, RoleTypeEnum.ASSISTANT_ENGINEER)))
-                        .stream().map(ArchivesSourceResult::getArchivesId).distinct().collect(Collectors.toList());
-                break;
-            default:
-                break;
-            }
+            datasource = tbUserArchivesService.findArchivesSourceByType(
+                            new HashSet<>(Arrays.asList(RoleTypeEnum.EFFECT_ENGINEER, RoleTypeEnum.ASSISTANT_ENGINEER)))
+                    .stream().map(ArchivesSourceResult::getArchivesId).distinct().collect(Collectors.toList());
             break;
         case REGION_COORDINATOR:
             datasource = tbUserArchivesService.findArchivesSourceByType(
-                            new HashSet<>(Arrays.asList(RoleTypeEnum.REGION_COORDINATOR))).stream()
+                            new HashSet<>(Collections.singletonList(RoleTypeEnum.REGION_COORDINATOR))).stream()
                     .map(ArchivesSourceResult::getArchivesId).distinct().collect(Collectors.toList());
             break;
         }
@@ -597,21 +587,13 @@ public class TBUserArchivesAllocationServiceImpl
             switch (sopRoleTypeCompositeEnum) {
             case ENGINEER:
             case PROJECT_MANAGER:
-                switch (productTypeEnum) {
-                case OFFICE:
-                    datasource = tbUserArchivesService.list().stream().map(TBUserArchives::getId).distinct()
-                            .collect(Collectors.toList());
-                    break;
-                case CLOUD_MARK:
-                    datasource = tbUserArchivesService.findArchivesSourceByType(
-                                    new HashSet<>(Arrays.asList(RoleTypeEnum.EFFECT_ENGINEER, RoleTypeEnum.ASSISTANT_ENGINEER)))
-                            .stream().map(ArchivesSourceResult::getArchivesId).distinct().collect(Collectors.toList());
-                    break;
-                }
+                datasource = tbUserArchivesService.findArchivesSourceByType(
+                                new HashSet<>(Arrays.asList(RoleTypeEnum.EFFECT_ENGINEER, RoleTypeEnum.ASSISTANT_ENGINEER)))
+                        .stream().map(ArchivesSourceResult::getArchivesId).distinct().collect(Collectors.toList());
                 break;
             case REGION_COORDINATOR:
                 datasource = tbUserArchivesService.findArchivesSourceByType(
-                                new HashSet<>(Arrays.asList(RoleTypeEnum.REGION_COORDINATOR))).stream()
+                                new HashSet<>(Collections.singletonList(RoleTypeEnum.REGION_COORDINATOR))).stream()
                         .map(ArchivesSourceResult::getArchivesId).distinct().collect(Collectors.toList());
                 break;
             }

+ 9 - 0
sop-business/src/main/java/com/qmth/sop/business/service/impl/TBUserArchivesServiceImpl.java

@@ -615,4 +615,13 @@ public class TBUserArchivesServiceImpl extends ServiceImpl<TBUserArchivesMapper,
     public List<Map<String, Object>> findTempEmp() {
         return this.baseMapper.findTempEmp();
     }
+
+    @Override
+    public boolean containsRegionCoordinator(Long userId) {
+        UserArchivesResult userArchivesResult = tbUserArchivesService.findUserArchivesByArchivesIdORUserId(null,
+                userId);
+        List<RoleResult> roleInfoList = userArchivesResult.getRoleInfoList();
+        // 判断是否包含区域协调人身份
+        return roleInfoList.stream().anyMatch(e -> RoleTypeEnum.REGION_COORDINATOR.name().equals(e.getRoleType()));
+    }
 }

+ 7 - 0
sop-business/src/main/resources/db/log/caozixuan_update_log.sql

@@ -175,3 +175,10 @@ ALTER TABLE t_b_ding_submit
     ADD COLUMN user_id BIGINT NOT NULL COMMENT '人员id' AFTER crm_no,
     DROP INDEX t_b_ding_submit_un ,
     ADD UNIQUE INDEX t_b_ding_submit_un USING BTREE (sop_no, user_id);
+
+-- 2024-09-04
+ALTER TABLE t_b_ding
+    CHANGE COLUMN sop_no sop_no VARCHAR(100) CHARACTER SET 'utf8mb4' NULL COMMENT 'sop单号' ,
+    CHANGE COLUMN ding_sop_no ding_sop_no VARCHAR(100) CHARACTER SET 'utf8mb4' NULL COMMENT '实际打卡对应的sop单号' ;
+
+INSERT INTO sys_config (id, config_key, config_name, config_value, enable, sort, create_id) VALUES ('41', 'region.coordinator.ding.time', '区域协调人打卡时间段', '{\"startTime\": 1725292800000,\"endTime\": 1725897600000}', '1', '1', '1');

+ 28 - 31
sop-business/src/main/resources/db/log/haoguanghui_update_log.sql

@@ -1,32 +1,29 @@
--- 2024-05-15
-ALTER TABLE t_b_device_delivery
-    ADD COLUMN `device_status` varchar(30) NULL COMMENT '设备状态,正常:NORMAL; 故障:FAULT' AFTER `effect`;
-ALTER TABLE t_b_device_delivery
-    ADD COLUMN `source_id` bigint NULL COMMENT '设备来源ID,不为空,说明该设备由其他单号中转过来' AFTER `device_status`;
+-- 2024-09-04
+CREATE TABLE sys_custom_receiver  (
+    `id` bigint(0) NOT NULL COMMENT '主键',
+    `type` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '类型,OFFICE:教务处,CLOUD_MARK:研究生',
+    `name` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '客户名称',
+    `unit` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '具体单位',
+    `consignee` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '收件人',
+    `consignee_phone` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '收件人电话',
+    `consignee_address` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '收件人地址',
+    `create_id` bigint(0) NULL DEFAULT NULL COMMENT '创建人id',
+    `create_time` bigint(0) NULL DEFAULT NULL COMMENT '创建时间',
+    `update_id` bigint(0) NULL DEFAULT NULL COMMENT '更新人id',
+    `update_time` bigint(0) NULL DEFAULT NULL COMMENT '更新时间',
+    PRIMARY KEY (`id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '客户收件人信息表' ROW_FORMAT = Dynamic;
 
--- 2024-05-16
-ALTER TABLE t_b_device_delivery
-    ADD COLUMN `remark` varchar(200) NULL COMMENT '其他的运输方式说明' AFTER `source_id`;
-
--- 2024-05-17
-ALTER TABLE t_b_device_delivery
-    ADD COLUMN `mail_type` varchar(20) NULL COMMENT '邮寄方式:邮寄、其他' AFTER `remark`;
-
--- 2024-05-21
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4000, '设备管理', 'deviceDeliveryManage', 'MENU', 36, 1, NULL, NULL, 1, 0, 1);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4010, '设备签收列表', 'List', 'LIST', 4000, 1, 'AUTH', '4018', 1, 0, 1);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4011, '签收', 'Sign', 'LINK', 4000, 2, 'AUTH', '4019', 1, 0, 1);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4012, '未签收', 'UnSigned', 'LINK', 4000, 3, 'AUTH', '4020', 1, 0, 1);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4013, '编辑', 'Update', 'LINK', 4000, 4, 'AUTH', '4021', 1, 0, 1);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4014, '设备去处列表', 'List', 'LIST', 4000, 1, 'AUTH', '4022', 1, 0, 1);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4015, '入库', 'In', 'LINK', 4000, 2, 'AUTH', '4023', 1, 0, 1);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4016, '中转', 'Transfer', 'LINK', 4000, 3, 'AUTH', '4024', 1, 0, 1);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4017, '编辑', 'Update', 'LINK', 4000, 4, 'AUTH', '4025', 1, 0, 1);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4018, '设备签收列表', '/api/admin/device/manage/sign/list', 'URL', 4000, 1, 'AUTH', NULL, 1, 1, 0);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4019, '设备签收', '/api/admin/device/manage/sign', 'URL', 4000, 2, 'AUTH', NULL, 1, 1, 0);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4020, '设备未签收', '/api/admin/device/manage/unsigned', 'URL', 4000, 3, 'AUTH', NULL, 1, 1, 0);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4021, '设备签收编辑', '/api/admin/device/manage/sign/edit', 'URL', 4000, 4, 'AUTH', NULL, 1, 1, 0);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4022, '设备去处列表', '/api/admin/device/manage/place/list', 'URL', 4000, 1, 'AUTH', NULL, 1, 1, 0);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4023, '设备去处入库', '/api/admin/device/manage/in', 'URL', 4000, 2, 'AUTH', NULL, 1, 1, 0);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4024, '设备去处中转', '/api/admin/device/manage/transfer', 'URL', 4000, 3, 'AUTH', NULL, 1, 1, 0);
-INSERT INTO sys_privilege(id, name, url, type, parent_id, sequence, property, related, enable, default_auth, front_display) VALUES (4025, '设备去处编辑', '/api/admin/device/manage/place/edit', 'URL', 4000, 4, 'AUTH', NULL, 1, 1, 0);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (400, '收件信息', 'receiver', 'MENU', 2, 6, NULL, NULL, 1, 0, 1);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (401, '新增', 'Add', 'BUTTON', 400, 1, 'AUTH', '407', 1, 0, 1);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (402, '查询', 'Select', 'BUTTON', 400, 2, 'AUTH', '411,412', 1, 0, 1);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (403, '导出', 'Export', 'BUTTON', 400, 3, 'AUTH', '410', 1, 0, 1);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (404, '列表', 'List', 'LIST', 400, 4, 'AUTH', '411,412', 1, 0, 1);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (405, '修改', 'Update', 'LINK', 400, 1, 'AUTH', '408', 1, 0, 1);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (406, '删除', 'Delete', 'LINK', 400, 2, 'AUTH', '409', 1, 0, 1);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (407, '收件信息新增', '/api/sys/custom/receiver/save', 'URL', 400, 1, 'AUTH', NULL, 1, 1, 0);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (408, '收件信息修改', '/api/sys/custom/receiver/save', 'URL', 400, 2, 'AUTH', NULL, 1, 1, 0);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (409, '收件信息删除', '/api/sys/custom/receiver/delete', 'URL', 400, 3, 'AUTH', NULL, 1, 1, 0);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (410, '收件信息导出', '/api/sys/custom/receiver/export', 'URL', 400, 4, 'AUTH', NULL, 1, 1, 0);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (411, '收件信息列表', '/api/sys/custom/receiver/page', 'URL', 400, 5, 'AUTH', NULL, 1, 1, 0);
+INSERT INTO sys_privilege(`id`, `name`, `url`, `type`, `parent_id`, `sequence`, `property`, `related`, `enable`, `default_auth`, `front_display`) VALUES (412, '客户列表', '/api/sys/custom/receiver/list', 'URL', 400, 6, 'AUTH', NULL, 1, 1, 0);

+ 67 - 0
sop-business/src/main/resources/mapper/SysCustomReceiverMapper.xml

@@ -0,0 +1,67 @@
+<?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.SysCustomReceiverMapper">
+
+    <select id="listCustom" resultType="com.qmth.sop.business.entity.SysCustomReceiver" parameterType="com.qmth.sop.common.enums.ProductTypeEnum">
+        select distinct name from sys_custom_receiver
+        <where>
+            <if test="type !=null">
+                AND type=#{type}
+            </if>
+        </where>
+    </select>
+
+    <select id="page" resultType="com.qmth.sop.business.bean.result.SysCustomReceiverResult">
+        SELECT
+        r.id,
+        r.type,
+        r.NAME,
+        r.unit,
+        r.consignee,
+        r.consignee_phone consigneePhone,
+        r.consignee_address consigneeAddress
+        FROM
+        sys_custom_receiver r
+        <where>
+            <if test="type != null">
+                AND r.type=#{type}
+            </if>
+            <if test="name != null and name != ''">
+                AND r.name=#{name}
+            </if>
+            <if test="dpr != null and !dpr.hasAdmin and !dpr.hasPmo and !dpr.hasBusiness">
+                <if test="dpr.hasAccountManager">
+                    AND r.create_id = #{dpr.requestUserId}
+                </if>
+            </if>
+        </where>
+        order by r.update_time desc
+    </select>
+
+    <select id="listCustomReceiver" resultType="com.qmth.sop.business.bean.result.SysCustomReceiverResult">
+        SELECT
+        r.type,
+        r.NAME,
+        r.unit,
+        r.consignee,
+        r.consignee_phone consigneePhone,
+        r.consignee_address consigneeAddress
+        FROM
+        sys_custom_receiver r
+        <where>
+            <if test="type != null">
+                AND r.type=#{type}
+            </if>
+            <if test="name != null and name != ''">
+                AND r.name=#{name}
+            </if>
+            <if test="dpr != null and !dpr.hasAdmin and !dpr.hasPmo and !dpr.hasBusiness">
+                <if test="dpr.hasAccountManager">
+                    AND r.create_id = #{dpr.requestUserId}
+                </if>
+            </if>
+        </where>
+        order by r.update_time desc
+    </select>
+
+</mapper>

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

@@ -2,7 +2,7 @@
 <!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.SysDingObjMapper">
     <select id="getList" resultType="com.qmth.sop.business.bean.result.SysDingGroupRoleResult">
-        select a.*,ifnull(r.name,'工程师') role_name from sys_ding_obj a
+        select a.*,r.name AS role_name from sys_ding_obj a
         left join sys_role r on r.id=a.role_id
         <where>
             <if test="id != null and id != ''">

+ 2 - 2
sop-business/src/main/resources/mapper/TBSopInfoMapper.xml

@@ -252,7 +252,7 @@
             <if test="userId != null and userId != ''">
                 and tbuaa.user_id = #{userId}
             </if>
-            and tbuaa.sop_role_type in ('ENGINEER','PROJECT_MANAGER')
+            and tbuaa.sop_role_type in ('ENGINEER','PROJECT_MANAGER','REGION_COORDINATOR')
             and tffa.status not in('END')
         </where>
         union
@@ -286,7 +286,7 @@
             <if test="userId != null and userId != ''">
                 and tbuaa.user_id = #{userId}
             </if>
-            and tbuaa.sop_role_type in ('ENGINEER','PROJECT_MANAGER')
+            and tbuaa.sop_role_type in ('ENGINEER','PROJECT_MANAGER','REGION_COORDINATOR')
             and tffa.status not in('END')
             and tbuaal.crm_detail_id = tbuaa.crm_detail_id
         </where>

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

@@ -224,6 +224,7 @@ public class SystemConstant {
     public static final String FXXK_CUSTOM_QUERY_URL = "fxxk.custom.query.url";
     public static final String FXXK_USER_QUERY_URL = "fxxk.user.query.url";
     public static final String RTZF_OSS_LOGIN_URL = "rtzf.oss.login.url";
+    public static final String REGION_COORDINATOR_DING_TIME = "region.coordinator.ding.time";
 
     /**
      * api前缀
@@ -240,6 +241,7 @@ public class SystemConstant {
     public static final String PREFIX_URL_SYS = "/admin/sys";
     public static final String PREFIX_URL_ORG = "/admin/org";
     public static final String PREFIX_URL_CUSTOM = "/sys/custom";
+    public static final String PREFIX_URL_CUSTOM_RECEIVER = "/sys/custom/receiver";
     public static final String PREFIX_URL_LEVEL = "/sys/level";
     public static final String PREFIX_URL_DEVICE = "/sys/device";
     public static final String PREFIX_URL_DING_GROUP = "/sys/ding/group";

+ 1 - 2
sop-common/src/main/java/com/qmth/sop/common/enums/SopRoleTypeEnum.java

@@ -6,8 +6,7 @@ package com.qmth.sop.common.enums;
  * @Date: 2024-05-14
  */
 public enum SopRoleTypeEnum {
-    REGION_COORDINATOR("区域协调人", new RoleTypeEnum[] { RoleTypeEnum.REGION_MANAGER, RoleTypeEnum.REGION_COORDINATOR,
-            RoleTypeEnum.EFFECT_ENGINEER, RoleTypeEnum.ASSISTANT_ENGINEER }),
+    REGION_COORDINATOR("区域协调人", new RoleTypeEnum[] {RoleTypeEnum.REGION_COORDINATOR}),
     PROJECT_MANAGER("项目经理", new RoleTypeEnum[] { RoleTypeEnum.REGION_MANAGER, RoleTypeEnum.REGION_COORDINATOR,
             RoleTypeEnum.EFFECT_ENGINEER, RoleTypeEnum.ASSISTANT_ENGINEER }),
     ENGINEER("工程师", new RoleTypeEnum[] { RoleTypeEnum.REGION_MANAGER, RoleTypeEnum.REGION_COORDINATOR,