Browse Source

Merge branch 'server-165' into fu-normal-push

fuyuchuan 2 weeks ago
parent
commit
a052bb650a
15 changed files with 321 additions and 205 deletions
  1. 21 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/web/VcDeviceController.java
  2. 5 0
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/VcDeviceService.java
  3. 0 1
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/BaseBuildServiceImpl.java
  4. 12 4
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/BaseGgpFacilityServiceImpl.java
  5. 18 20
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/DmpDeviceInfoServiceImpl.java
  6. 71 3
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/VcDeviceServiceImpl.java
  7. 17 17
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/vo/BaseGgpFacilityExportVo.java
  8. 34 9
      service-iot/service-iot-biz/src/main/java/com/usky/iot/service/vo/FacilityImportVo.java
  9. 5 11
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaFbdDocumentService.java
  10. 3 3
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaApprovalServiceImpl.java
  11. 6 2
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaDocumentServiceImpl.java
  12. 71 84
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFbdDocumentServiceImpl.java
  13. 3 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFormDefinitionServiceImpl.java
  14. 24 36
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaApprovalGeneration.java
  15. 31 15
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaSendMessageCenter.java

+ 21 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/controller/web/VcDeviceController.java

@@ -5,10 +5,13 @@ import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.bean.CommonPage;
 import com.usky.iot.domain.BaseGgpFacility;
 import com.usky.iot.domain.VcDevice;
+import com.usky.iot.domain.VcStream;
 import com.usky.iot.service.VcDeviceService;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.*;
 
+import javax.annotation.Resource;
 import java.util.List;
 
 /**
@@ -56,6 +59,24 @@ public class VcDeviceController {
         return ApiResult.success(vcDeviceService.pageList(videoNumber, videoName, groupId, pageNum, pageSize));
     }
 
+    /**
+     * 实时拉取摄像头视频流
+     * @param deviceUuid
+     * @return
+     */
+    @GetMapping("getVcDeviceVideo")
+    public ApiResult<String> getVcDeviceVideo(@RequestParam(value = "deviceUuid") String deviceUuid) {
+        return ApiResult.success(vcDeviceService.getVcDeviceVideo(deviceUuid));
+    }
+
+    /**
+     * 停止拉取摄像头视频流
+     */
+    @GetMapping("stopDeviceVideo")
+    public void stopDeviceVideo(){
+        vcDeviceService.stopDeviceVideo();
+    }
+
     /**
      * 新增
      * @param vcDevice

+ 5 - 0
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/VcDeviceService.java

@@ -4,6 +4,7 @@ import com.usky.common.core.bean.CommonPage;
 import com.usky.iot.domain.BaseGgpFacility;
 import com.usky.iot.domain.VcDevice;
 import com.usky.common.mybatis.core.CrudService;
+import org.springframework.web.bind.annotation.RequestBody;
 
 import java.util.List;
 
@@ -20,6 +21,10 @@ public interface VcDeviceService extends CrudService<VcDevice> {
 
     CommonPage<VcDevice> pageList(String videoNumber, String videoName, Integer groupId ,Integer pageNum, Integer pageSize);
 
+    String getVcDeviceVideo(String deviceUuid);
+
+    void stopDeviceVideo();
+
     boolean add(VcDevice vcDevice);
 
     void update(VcDevice vcDevice);

+ 0 - 1
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/BaseBuildServiceImpl.java

@@ -22,7 +22,6 @@ import com.usky.iot.service.vo.BuildFacilityStatusVO;
 import org.apache.tomcat.jni.Local;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import sun.security.util.Length;
 
 import java.text.SimpleDateFormat;
 import java.time.LocalDateTime;

+ 12 - 4
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/BaseGgpFacilityServiceImpl.java

@@ -149,13 +149,11 @@ public class BaseGgpFacilityServiceImpl extends AbstractCrudService<BaseGgpFacil
         if (CollectionUtils.isNotEmpty(baseGgpFacilityList)) {
             for (int i = 0; i < baseGgpFacilityList.size(); i++) {
                 BaseGgpFacilityExportVo baseGgpFacilityExportVo = new BaseGgpFacilityExportVo();
-                baseGgpFacilityExportVo.setXh(i + 1);
-                baseGgpFacilityExportVo.setId(baseGgpFacilityList.get(i).getId());
                 baseGgpFacilityExportVo.setFacilityNum(baseGgpFacilityList.get(i).getFacilityNum());
                 baseGgpFacilityExportVo.setFacilityType("未知");
                 if (CollectionUtils.isNotEmpty(typeList)) {
                     for (int j = 0; j < typeList.size(); j++) {
-                        if (baseGgpFacilityList.get(i).getFacilityType().equals(typeList.get(j).getId())) {
+                        if (baseGgpFacilityList.get(i).getFacilityType().equals(typeList.get(j).getTypeCode())) {
                             baseGgpFacilityExportVo.setFacilityType(typeList.get(j).getTypeName());
                         }
                     }
@@ -166,7 +164,9 @@ public class BaseGgpFacilityServiceImpl extends AbstractCrudService<BaseGgpFacil
                 baseGgpFacilityExportVo.setImagesUrl(baseGgpFacilityList.get(i).getImagesUrl());
                 baseGgpFacilityExportVo.setContact(baseGgpFacilityList.get(i).getContact());
                 baseGgpFacilityExportVo.setContactPhone(baseGgpFacilityList.get(i).getContactPhone());
-                baseGgpFacilityExportVo.setStatus(baseGgpFacilityList.get(i).getFacilityStatus());
+                baseGgpFacilityExportVo.setFacilityStatus(baseGgpFacilityList.get(i).getFacilityStatus());
+                baseGgpFacilityExportVo.setLongitude(baseGgpFacilityList.get(i).getLongitude());
+                baseGgpFacilityExportVo.setLatitude(baseGgpFacilityList.get(i).getLatitude());
                 baseGgpFacilityExportVo.setCreateTime(baseGgpFacilityList.get(i).getCreateTime().format(df));
                 list.add(baseGgpFacilityExportVo);
             }
@@ -435,6 +435,14 @@ public class BaseGgpFacilityServiceImpl extends AbstractCrudService<BaseGgpFacil
                 int rot=3;
                 for (FacilityImportVo facilityImportVo:facilityImportVos) {
                     BaseGgpFacility baseGgpFacility = BeanMapperUtils.map(facilityImportVo, BaseGgpFacility.class);
+                    List<BaseGgpFacilityTypeNumVO> typeList = baseFacilityTypeMapper.typeNumList(SecurityUtils.getTenantId());
+                    if (CollectionUtils.isNotEmpty(typeList)) {
+                        for (int j = 0; j < typeList.size(); j++) {
+                            if (baseGgpFacility.getFacilityType().equals(typeList.get(j).getTypeName())) {
+                                baseGgpFacility.setFacilityType(typeList.get(j).getTypeCode());
+                            }
+                        }
+                    }
                     if (StringUtils.isBlank(baseGgpFacility.getFacilityType())||StringUtils.isBlank(baseGgpFacility.getFacilityName())||StringUtils.isBlank(baseGgpFacility.getAddress())||StringUtils.isBlank(baseGgpFacility.getLatitude())||StringUtils.isBlank(baseGgpFacility.getLongitude())){
 
                         String tmp = ",第"+rot+"行数据导入失败,必填字段不能为空";

+ 18 - 20
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/DmpDeviceInfoServiceImpl.java

@@ -46,10 +46,10 @@ import com.usky.transfer.RemoteTransferService;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.interceptor.TransactionAspectSupport;
 import org.springframework.web.multipart.MultipartFile;
-import sun.net.dns.ResolverConfiguration;
 
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletResponse;
@@ -423,7 +423,7 @@ public class DmpDeviceInfoServiceImpl extends AbstractCrudService<DmpDeviceInfoM
         return null != one && !Objects.equals(one.getId(), id);
     }
 
-    @Override
+    @Async
     public void deviceStatus(){
         log.info("定时同步设备状态数据 start");
         LastInnerQueryVO queryVO = new LastInnerQueryVO();
@@ -442,28 +442,26 @@ public class DmpDeviceInfoServiceImpl extends AbstractCrudService<DmpDeviceInfoM
         }
         queryVO.setDeviceuuid(deviceuuidList);
 
-        List<LastInnerResultVO> list = remoteTsdbProxyService.last(queryVO);
+        List<Map<String,Object>> list = remoteTsdbProxyService.getAllDeviceRealTime();
         if(CollectionUtils.isNotEmpty(list)){
             for(int i=0;i<list.size();i++){
-                if(Objects.nonNull(list.get(i).getMetrics())){
-                    String deviceuuid = list.get(i).getDeviceuuid();
-                    LocalDateTime lTime = Instant.ofEpochMilli(Long.valueOf(list.get(i).getMetrics().get("time").toString())).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
-                    String date =  lTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
-                    String currentDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
-                    LambdaUpdateWrapper<DmpDeviceStatus> updateWrapper = Wrappers.lambdaUpdate();
-                    if(date.equals(currentDate)){
-                        updateWrapper.set(DmpDeviceStatus::getDeviceStatus,1)  //设备在线
-                                .set(DmpDeviceStatus::getLastOnlineTime,lTime)
-                                .eq(DmpDeviceStatus::getDeviceUuid,deviceuuid);
+                String deviceuuid = list.get(i).get("deviceuuid").toString();
+                LocalDateTime lTime = Instant.ofEpochMilli(Long.valueOf(list.get(i).get("time").toString())).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
+                String date =  lTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+                String currentDate = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+                LambdaUpdateWrapper<DmpDeviceStatus> updateWrapper = Wrappers.lambdaUpdate();
+                if(date.equals(currentDate)){
+                    updateWrapper.set(DmpDeviceStatus::getDeviceStatus,1)  //设备在线
+                            .set(DmpDeviceStatus::getLastOnlineTime,lTime)
+                            .eq(DmpDeviceStatus::getDeviceUuid,deviceuuid);
+
+                }else{
+                    updateWrapper.set(DmpDeviceStatus::getDeviceStatus,2)  //设备离线
+                            .set(DmpDeviceStatus::getLastOnlineTime,lTime)
+                            .eq(DmpDeviceStatus::getDeviceUuid,deviceuuid);
 
-                    }else{
-                        updateWrapper.set(DmpDeviceStatus::getDeviceStatus,2)  //设备离线
-                                .set(DmpDeviceStatus::getLastOnlineTime,lTime)
-                                .eq(DmpDeviceStatus::getDeviceUuid,deviceuuid);
-
-                    }
-                    dmpDeviceStatusService.update(updateWrapper);
                 }
+                dmpDeviceStatusService.update(updateWrapper);
 
             }
 

+ 71 - 3
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/impl/VcDeviceServiceImpl.java

@@ -6,16 +6,20 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.usky.common.core.bean.CommonPage;
+import com.usky.common.core.exception.BusinessException;
 import com.usky.common.security.utils.SecurityUtils;
-import com.usky.iot.domain.BaseFacilityDevice;
-import com.usky.iot.domain.BaseGgpFacility;
 import com.usky.iot.domain.VcDevice;
 import com.usky.iot.mapper.VcDeviceMapper;
 import com.usky.iot.service.VcDeviceService;
 import com.usky.common.mybatis.core.AbstractCrudService;
-import com.usky.iot.service.vo.BaseFacilityDeviceVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.time.LocalDateTime;
 import java.util.List;
 
@@ -27,8 +31,15 @@ import java.util.List;
  * @author han
  * @since 2024-10-22
  */
+@Slf4j
 @Service
 public class VcDeviceServiceImpl extends AbstractCrudService<VcDeviceMapper, VcDevice> implements VcDeviceService {
+
+    @Value("${vc.rtmp-ip}")
+    private String rtmpIp;
+
+    Process process = null;
+
     @Override
     public List<VcDevice> VcDeviceList(Integer groupId){
         LambdaQueryWrapper<VcDevice> queryWrapper = Wrappers.lambdaQuery();
@@ -51,6 +62,63 @@ public class VcDeviceServiceImpl extends AbstractCrudService<VcDeviceMapper, VcD
         return new CommonPage<>(page.getRecords(),page.getTotal(),page.getCurrent(),page.getSize());
     }
 
+    @Override
+    public String getVcDeviceVideo(String deviceUuid){
+        LambdaQueryWrapper<VcDevice> lambdaQuery = Wrappers.lambdaQuery();
+        lambdaQuery.like(StringUtils.isNotBlank(deviceUuid),VcDevice::getVideoNumber,deviceUuid)
+                .eq(VcDevice::getDelFlag,0);
+        VcDevice one = this.getOne(lambdaQuery);
+        if(one==null){
+            throw new BusinessException("未查询到设备信息");
+        }
+        String accountNumber = one.getAccountNumber();
+        String videoPassword = one.getVideoPassword();
+        String videoIp = one.getVideoIp();
+        String videoPort = one.getVideoPort().toString();
+        String command = "ffmpeg -i rtsp://"+accountNumber+":"+videoPassword+"@"+videoIp+":"+videoPort+" -vcodec copy -acodec aac -ar 44100 -c:v libx264 -preset ultrafast -tune zerolatency -strict -2 -ac 1 -r 30 -s 1280x720 -q 10 -f flv -hls_time 1 -hls_list_size 3 -hls_flags delete_segments rtmp://"+rtmpIp+":1935/hls/"+deviceUuid;
+        System.out.println(command);
+
+        try {
+            log.info("【begin】实时拉取摄像头数据流 "+command);
+            // 创建 ProcessBuilder 实例
+            ProcessBuilder processBuilder = new ProcessBuilder(command.split(" "));
+            // 启动进程
+            process = processBuilder.start();
+
+            new Thread(() -> {
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
+                    String line;
+                    while ((line = reader.readLine()) != null) {
+                        System.out.println(line);
+                    }
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }).start();
+
+            String repDeviceVideo = rtmpIp+":80/hls/"+deviceUuid+".m3u8";
+            return repDeviceVideo;
+
+
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+
+    }
+
+    @Override
+    public void stopDeviceVideo() {
+        if (process != null && process.isAlive()) {
+            process.destroy();
+            try {
+                process.waitFor();
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
     @Override
     public boolean add(VcDevice vcDevice){
         vcDevice.setCreateBy(SecurityUtils.getUsername());

+ 17 - 17
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/vo/BaseGgpFacilityExportVo.java

@@ -24,18 +24,6 @@ public class BaseGgpFacilityExportVo implements Serializable {
 
     private static final long serialVersionUID = 1L;
 
-    /**
-     * 主键ID
-     */
-    @TableId(value = "id", type = IdType.AUTO)
-    private Integer id;
-
-    /**
-     * 序号
-     */
-    @Excel(name = "序号")
-    private Integer xh;
-
     /**
      * 设施编号
      */
@@ -61,7 +49,7 @@ public class BaseGgpFacilityExportVo implements Serializable {
     private String address;
 
     /**
-     * 图片地址URL
+     * 设施图片
      */
     @Excel(name = "设施图片")
     private String imagesUrl;
@@ -73,19 +61,31 @@ public class BaseGgpFacilityExportVo implements Serializable {
     private String contact;
 
     /**
-     * 联系方式
+     * 联系电话
      */
-    @Excel(name = "联系方式")
+    @Excel(name = "联系电话")
     private String contactPhone;
 
     /**
      * 设施状态
      */
     @Excel(name = "设施状态", readConverterExp = "0=正常,1=维修,2=关闭")
-    private Integer status;
+    private Integer facilityStatus;
+
+    /**
+     * 经度
+     */
+    @Excel(name = "经度")
+    private String longitude;
+
+    /**
+     * 维度
+     */
+    @Excel(name = "维度")
+    private String latitude;
 
     /**
-     * 开始时间
+     * 创建时间
      */
     @Excel(name = "创建时间")
     private String createTime;

+ 34 - 9
service-iot/service-iot-biz/src/main/java/com/usky/iot/service/vo/FacilityImportVo.java

@@ -1,8 +1,12 @@
 package com.usky.iot.service.vo;
 
-import cn.afterturn.easypoi.excel.annotation.Excel;
 
+import cn.afterturn.easypoi.excel.annotation.Excel;
+import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
 
 /**
  * <p>
@@ -13,24 +17,38 @@ import lombok.Data;
  * @since 2023-07-27
  */
 @Data
+@EqualsAndHashCode(callSuper = false)
 public class FacilityImportVo{
+    /**
+     * 设施编号
+     */
+    @Excel(name = "设施编号")
+    private String facilityNum;
+
     /**
      * 设施类型(必填)
      */
-    @Excel(name = "设施类型(必填)")
+    @Excel(name = "设施类型")
     private String facilityType;
 
     /**
      * 设施名称(必填)
      */
-    @Excel(name = "设施名称(必填)")
+    @Excel(name = "设施名称")
     private String facilityName;
 
     /**
      * 设施地址(必填)
      */
-    @Excel(name = "设施地址(必填)")
+    @Excel(name = "设施地址")
     private String address;
+
+    /**
+     * 设施图片
+     */
+    @Excel(name = "设施图片")
+    private String imagesUrl;
+
     /**
      * 联系人
      */
@@ -44,21 +62,28 @@ public class FacilityImportVo{
     private String contactPhone;
 
     /**
-     * 备注
+     * 设施状态
      */
-    @Excel(name = "备注")
-    private String facilityDesc;
+    @Excel(name = "设施状态",replace = {"正常_0", "维修_1", "关闭_2"})
+    private Integer facilityStatus;
 
     /**
      * 经度(必填)
      */
-    @Excel(name = "经度(必填)")
+    @Excel(name = "经度")
     private String longitude;
 
     /**
      * 维度(必填)
      */
-    @Excel(name = "维度(必填)")
+    @Excel(name = "维度")
     private String latitude;
 
+    /**
+     * 创建时间
+     */
+    @Excel(name = "创建时间")
+    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
 }

+ 5 - 11
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaFbdDocumentService.java

@@ -1,8 +1,8 @@
 package com.usky.oa.service;
 
+import com.alibaba.fastjson.JSONObject;
 import com.usky.oa.domain.OaFbdDocument;
 import com.usky.common.mybatis.core.CrudService;
-import org.springframework.stereotype.Component;
 
 /**
  * <p>
@@ -12,19 +12,13 @@ import org.springframework.stereotype.Component;
  * @author fu
  * @since 2025-02-20
  */
-public interface OaFbdDocumentService extends CrudService<OaFbdDocument>{
+public interface OaFbdDocumentService extends CrudService<OaFbdDocument> {
 
     /**
-     * 新增发布申请
-     * @param oaFbdDocument
-     */
-    void add(OaFbdDocument oaFbdDocument);
+     * 新增发布申请 或 更新发布申请
+     **/
+    void addOrUpDate(OaFbdDocument oaFbdDocument, JSONObject node);
 
-    /**
-     * 更新发布申请
-     * @param oaFbdDocument
-     */
-    void update(OaFbdDocument oaFbdDocument);
 
     // 获取审批表数据
     void getOaApproval(OaFbdDocument oaFbdDocument);

+ 3 - 3
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaApprovalServiceImpl.java

@@ -239,7 +239,7 @@ public class OaApprovalServiceImpl extends AbstractCrudService<OaApprovalMapper,
                             // 发送消息通知下一步审批人
                             oaSendMessageCenter.sendAsyncMessage(
                                     oaApproval.getCreateBy(),
-                                    Long.valueOf(oaApproval.getProposer()),
+                                    oaApproval.getApprovalUid(),
                                     approval.getId(),
                                     userIds,
                                     3,
@@ -254,7 +254,7 @@ public class OaApprovalServiceImpl extends AbstractCrudService<OaApprovalMapper,
                 Long proposerId = Long.valueOf(oaApproval.getProposer());
                 oaSendMessageCenter.sendAsyncMessage(
                         oaApproval.getCreateBy(),
-                        proposerId,
+                        oaApproval.getApprovalUid(),
                         oaApproval.getId(),
                         Collections.singletonList(proposerId),
                         1,
@@ -266,7 +266,7 @@ public class OaApprovalServiceImpl extends AbstractCrudService<OaApprovalMapper,
             // 发送消息通知申请人审核不通过
             oaSendMessageCenter.sendAsyncMessage(
                     oaApproval.getCreateBy(),
-                    proposerId,
+                    oaApproval.getApprovalUid(),
                     oaApproval.getId(),
                     Collections.singletonList(proposerId),
                     0,

+ 6 - 2
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaDocumentServiceImpl.java

@@ -204,6 +204,8 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
         queryWrapper.select(OaFormDefinition::getFieldInfo).eq(OaFormDefinition::getId, oaDocument.get("formId"));
         OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectOne(queryWrapper);
 
+        JSONObject node = oaDocument.getJSONObject("node");
+
         if (oaFormDefinition == null) {
             throw new BusinessException("新增表单模板不存在!请联系管理员");
         }
@@ -220,7 +222,7 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
                 oaCgdDocumentService.add(JSON.parseObject(oaDocument.toJSONString(), OaCgdDocument.class));
                 break;
             case "FBD":
-                oaFbdDocumentService.add(JSON.parseObject(oaDocument.toJSONString(), OaFbdDocument.class));
+                oaFbdDocumentService.addOrUpDate(JSON.parseObject(oaDocument.toJSONString(), OaFbdDocument.class), node);
                 break;
             default:
                 throw new BusinessException("新增表单模板不存在!请联系管理员");
@@ -236,6 +238,8 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
         OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectOne(queryWrapper);
         String sign = oaFormDefinition.getFieldInfo();
 
+        JSONObject node = jsonDocument.getJSONObject("node");
+
         switch (sign) {
             case "QJD":
                 oaQjdDocumentService.updateQjDocument(JSON.parseObject(jsonDocument.toJSONString(), OaQjdDocument.class));
@@ -247,7 +251,7 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
                 oaCgdDocumentService.update(JSON.parseObject(jsonDocument.toJSONString(), OaCgdDocument.class));
                 break;
             case "FBD":
-                oaFbdDocumentService.update(JSON.parseObject(jsonDocument.toJSONString(), OaFbdDocument.class));
+                oaFbdDocumentService.addOrUpDate(JSON.parseObject(jsonDocument.toJSONString(), OaFbdDocument.class), node);
                 break;
             default:
                 throw new BusinessException("单据模板不存在!请联系管理员");

+ 71 - 84
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFbdDocumentServiceImpl.java

@@ -1,5 +1,6 @@
 package com.usky.oa.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.usky.common.core.exception.BusinessException;
@@ -15,7 +16,6 @@ import com.usky.system.domain.SysUser;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
@@ -63,86 +63,74 @@ public class OaFbdDocumentServiceImpl extends AbstractCrudService<OaFbdDocumentM
     private OaApprovalService oaApprovalService;
 
     @Override
-    public void add(OaFbdDocument oaFbdDocument) {
+    public void addOrUpDate(OaFbdDocument oaFbdDocument, JSONObject node) {
         // 校验表单数据
         validateDocument(oaFbdDocument);
 
-        Long userId = SecurityUtils.getUserId();
-        String username = SecurityUtils.getUsername();
-        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
-        Integer tenantId = SecurityUtils.getTenantId();
-
-        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmmss");
-        LocalDateTime now = LocalDateTime.now();
-        String formattedDate = now.format(formatter);
-
-        LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
-        queryWrapper.select(OaFormDefinition::getFormSign).eq(OaFormDefinition::getId, oaFbdDocument.getFormId());
-        OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectOne(queryWrapper);
-        String sign = oaFormDefinition.getFormSign();
-        String docNo = sign + "-" + formattedDate;
-
-        // 插入发布表数据
-        oaFbdDocument.setDocNo(docNo);
-        oaFbdDocument.setProposer(userId);
-        oaFbdDocument.setCreateBy(username);
-        oaFbdDocument.setCreateTime(now);
-        oaFbdDocument.setDeptId(deptId);
-        oaFbdDocument.setTenantId(tenantId);
-        oaFbdDocumentMapper.insert(oaFbdDocument);
-
-        // 插入单据表数据
-        OaDocument oaDocument = new OaDocument();
-        oaDocument.setFormId(oaFbdDocument.getFormId());
-        oaDocument.setType(sign);
-        oaDocument.setDocNo(docNo);
-        oaDocument.setProposer(userId);
-        oaDocument.setDocStatus(oaFbdDocument.getDocStatus());
-        oaDocument.setCreateBy(username);
-        oaDocument.setCreateTime(oaFbdDocument.getCreateTime());
-        oaDocument.setDeptId(deptId);
-        oaDocument.setTenantId(tenantId);
-        oaDocumentMapper.insert(oaDocument);
-
-        // 插入审批表数据,第一条审批记录
-        if (oaFbdDocument.getDocStatus().equals(1)) {
-            getOaApproval(oaFbdDocument);
-        }
-    }
-
-    // 更新发布表数据
-    //@Transactional(rollbackFor = Exception.class)
-    @Transactional
-    @Override
-    public void update(OaFbdDocument oaFbdDocument) {
-        // 验证文档
-        validateDocument(oaFbdDocument);
-
-        // 获取当前用户和时间
         String username = SecurityUtils.getUsername();
         LocalDateTime now = LocalDateTime.now();
         Integer tenantId = SecurityUtils.getTenantId();
-
-        // 设置更新信息
-        oaFbdDocument.setUpdateBy(username);
-        oaFbdDocument.setUpdateTime(now);
-
-        // 更新发布表数据
-        oaFbdDocumentMapper.updateById(oaFbdDocument);
-
-        // 更新总单据状态
-        oaDocumentMapper.update(null, Wrappers.lambdaUpdate(OaDocument.class)
-                .eq(OaDocument::getDocNo, oaFbdDocument.getDocNo())
-                .set(OaDocument::getDocStatus, oaFbdDocument.getDocStatus())
-                .set(OaDocument::getUpdateBy, username)
-                .set(OaDocument::getUpdateTime, now)
-        );
-
-        // 如果文档状态为1,创建并插入审批记录
-        if (oaFbdDocument.getDocStatus() == 1) {
-            OaFbdDocument updatedDocument = oaFbdDocumentMapper.selectById(oaFbdDocument.getId());
-            getOaApproval(updatedDocument);
+        String sign = null;
+
+        if (oaFbdDocument.getId() == null) {
+            // 插入操作
+            Long userId = SecurityUtils.getUserId();
+            Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
+
+            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmmss");
+            String formattedDate = now.format(formatter);
+
+            LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
+            queryWrapper.select(OaFormDefinition::getFormSign).eq(OaFormDefinition::getId, oaFbdDocument.getFormId());
+            OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectOne(queryWrapper);
+            sign = oaFormDefinition.getFormSign();
+            String docNo = sign + "-" + formattedDate;
+
+            oaFbdDocument.setDocNo(docNo);
+            oaFbdDocument.setProposer(userId);
+            oaFbdDocument.setCreateBy(username);
+            oaFbdDocument.setCreateTime(now);
+            oaFbdDocument.setDeptId(deptId);
+            oaFbdDocument.setTenantId(tenantId);
+            oaFbdDocumentMapper.insert(oaFbdDocument);
+
+            // 插入单据表数据
+            OaDocument oaDocument = new OaDocument();
+            oaDocument.setFormId(oaFbdDocument.getFormId());
+            oaDocument.setType(sign);
+            oaDocument.setDocNo(docNo);
+            oaDocument.setProposer(userId);
+            oaDocument.setDocStatus(oaFbdDocument.getDocStatus());
+            oaDocument.setCreateBy(username);
+            oaDocument.setCreateTime(now);
+            oaDocument.setDeptId(deptId);
+            oaDocument.setTenantId(tenantId);
+            oaDocumentMapper.insert(oaDocument);
+
+            if (oaFbdDocument.getDocStatus().equals(1)) {
+                getOaApproval(oaFbdDocument);
+            }
+        } else {
+            // 更新操作
+            oaFbdDocument.setUpdateBy(username);
+            oaFbdDocument.setUpdateTime(now);
+            oaFbdDocumentMapper.updateById(oaFbdDocument);
+
+            oaDocumentMapper.update(null, Wrappers.lambdaUpdate(OaDocument.class)
+                    .eq(OaDocument::getDocNo, oaFbdDocument.getDocNo())
+                    .set(OaDocument::getDocStatus, oaFbdDocument.getDocStatus())
+                    .set(OaDocument::getUpdateBy, username)
+                    .set(OaDocument::getUpdateTime, now)
+            );
+
+            if (oaFbdDocument.getDocStatus() == 1) {
+                OaFbdDocument updatedDocument = oaFbdDocumentMapper.selectById(oaFbdDocument.getId());
+                getOaApproval(updatedDocument);
+            }
+
+            sign = oaFbdDocumentMapper.selectById(oaFbdDocument.getId()).getDocNo().split("-")[0];
         }
+        oaApprovalGeneration.nodeSave(node, sign);
     }
 
     // 获取审批表数据
@@ -157,8 +145,6 @@ public class OaFbdDocumentServiceImpl extends AbstractCrudService<OaFbdDocumentM
 
         switch (oaNode.getNodeScope()) {
             case 0:
-            case 1:
-            case 2:
                 userIds = Arrays.stream(oaNode.getProposer().split(",")).map(Long::parseLong).collect(Collectors.toList());
                 break;
             case 3:
@@ -191,16 +177,17 @@ public class OaFbdDocumentServiceImpl extends AbstractCrudService<OaFbdDocumentM
             approval.setTenantId(oaFbdDocument.getTenantId());
             approval.setNodeId(oaNode.getId());
             oaApprovalMapper.insert(approval);
+
+            oaSendMessageCenter.sendAsyncMessage(
+                    oaFbdDocument.getCreateBy(),
+                    approval.getApprovalUid(),
+                    oaFbdDocument.getId(),
+                    userIds,
+                    3,
+                    oaApprovalService.getFieldInfo(oaFbdDocument.getDocNo())
+            );
         }
 
-        oaSendMessageCenter.sendAsyncMessage(
-                oaFbdDocument.getCreateBy(),
-                oaFbdDocument.getProposer(),
-                oaFbdDocument.getId(),
-                userIds,
-                3,
-                oaApprovalService.getFieldInfo(oaFbdDocument.getDocNo())
-        );
     }
 
     /**

+ 3 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFormDefinitionServiceImpl.java

@@ -18,7 +18,9 @@ import com.usky.oa.service.vo.OaFormNameResponseVO;
 import com.usky.system.domain.SysUser;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDateTime;
 import java.util.*;
@@ -58,6 +60,7 @@ public class OaFormDefinitionServiceImpl extends AbstractCrudService<OaFormDefin
      * @param oaFormDefinition 表单定义对象,包含表单的详细信息
      * @throws BusinessException 当表单名称或标识不符合规范或已存在时抛出
      */
+    @Transactional
     @Override
     public void addForm(OaFormDefinition oaFormDefinition) {
 

+ 24 - 36
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaApprovalGeneration.java

@@ -14,16 +14,11 @@ import com.usky.system.domain.SysUser;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Configuration;
 import org.springframework.scheduling.annotation.Async;
-import org.springframework.stereotype.Component;
 import org.springframework.stereotype.Service;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
+import java.time.LocalDateTime;
 import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  *
@@ -47,9 +42,6 @@ public class OaApprovalGeneration {
     @Autowired
     private SysUserMapper sysUserMapper;
 
-    @Autowired
-    private OaSendMessageCenter oaSendMessageCenter;
-
     /**
      * @description: 新增流程与节点信息
      * @author: fyc
@@ -58,7 +50,6 @@ public class OaApprovalGeneration {
      * @param: [oaFormDefinition]
      * @return: void
      **/
-    @Async
     public void addGenerate(OaFormDefinition oaFormDefinition) {
         // 新增流程数据
         OaFlow oaFlow = new OaFlow();
@@ -96,14 +87,10 @@ public class OaApprovalGeneration {
 
                 switch (nodeScope) {
                     case 0:
-                    case 2:
                         proposer = node.getString("appointApprover");
                         break;
                     case 1:
-                        Long deptLeader = getDeptLeader();
-                        if (deptLeader != null) {
-                            proposer = deptLeader.toString();
-                        }
+                    case 2:
                         break;
                     case 3:
                         deptId2 = node.getInteger("deptId");
@@ -134,7 +121,6 @@ public class OaApprovalGeneration {
         }
     }
 
-    @Async
     public void updateGenerate(OaFormDefinition oaFormDefinition) {
         Integer formId = oaFormDefinition.getId();
         OaFlow flow = oaFlowMapper.selectOne(Wrappers.lambdaQuery(OaFlow.class).eq(OaFlow::getFormId, formId));
@@ -164,14 +150,10 @@ public class OaApprovalGeneration {
 
                 switch (nodeScope) {
                     case 0:
-                    case 2:
                         proposer = node.getString("appointApprover");
                         break;
                     case 1:
-                        Long deptLeader = getDeptLeader();
-                        if (deptLeader != null) {
-                            proposer = deptLeader.toString();
-                        }
+                    case 2:
                         break;
                     case 3:
                         deptId2 = node.getInteger("deptId");
@@ -197,7 +179,26 @@ public class OaApprovalGeneration {
         }
     }
 
-    private Long getDeptLeader() {
+    public void nodeSave(JSONObject jsonObject, String sign) {
+        Integer flowId = selectBySign(sign).getId();
+        List<JSONObject> nodeList = jsonObject.getJSONArray("node").toJavaList(JSONObject.class);
+        String proposer = null;
+        for (JSONObject node : nodeList) {
+            String nodeNo = node.getString("nodebh");
+            Integer nodeScope = node.getInteger("nodeScope");
+            proposer = node.getString("appointApprover");
+
+            OaNode oaNode = new OaNode();
+            if (nodeScope == 1) {
+                oaNode.setProposer(getDeptLeader().toString());
+            } else if (nodeScope == 2) {
+                oaNode.setProposer(proposer);
+            }
+            oaNodeMapper.update(oaNode, new LambdaQueryWrapper<OaNode>().eq(OaNode::getFlowId, flowId).eq(OaNode::getNodeNo, nodeNo));
+        }
+    }
+
+    public Long getDeptLeader() {
         Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
         Integer tenantId = SecurityUtils.getTenantId();
 
@@ -206,20 +207,7 @@ public class OaApprovalGeneration {
                 .eq(SysDept::getDeptId, deptId)
                 .select(SysDept::getLeader);
         SysDept deptLeader = sysDeptMapper.selectOne(deptLeaderQuery);
-        String leader = deptLeader.getLeader();
-
-        LambdaQueryWrapper<SysUser> userQuery = new LambdaQueryWrapper<>();
-        userQuery.select(SysUser::getUserId)
-                .eq(SysUser::getTenantId, tenantId)
-                .eq(SysUser::getUserName, leader);
-        SysUser sysUser = sysUserMapper.selectOne(userQuery);
-        return sysUser.getUserId();
-    }
-
-    @Async
-    public void generateApproval(OaApproval approval) {
-        LambdaQueryWrapper<OaApproval> approvalQuery = new LambdaQueryWrapper<>();
-
+        return Long.valueOf(deptLeader.getLeader());
     }
 
     // 根据单据类型获取流程信息

+ 31 - 15
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaSendMessageCenter.java

@@ -10,6 +10,7 @@ import com.usky.oa.mapper.OaFormDefinitionMapper;
 import com.usky.oa.mapper.SysUserMapper;
 import com.usky.oa.service.enums.OaBuiltInDocument;
 import com.usky.system.RemoteMceService;
+import com.usky.system.domain.MceRequestVO;
 import com.usky.system.domain.SysUser;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -49,44 +50,59 @@ public class OaSendMessageCenter {
      * 异步发送消息
      *
      * @param username 提交人账号名
-     * @param submitterId 提交人id
+     * @param approvalUid 审批人userId
      * @param id 数据id
      * @param receivers 接收人userId集合
      * @param isPass 是否通过(0:不通过,1:通过)
+     * @param sign 申请单类型
      */
     @Async
-    public void sendAsyncMessage(String username, Long submitterId, Integer id, List<Long> receivers, Integer isPass, String sign) {
+    public void sendAsyncMessage(String username, Long approvalUid, Integer id, List<Long> receivers, Integer isPass, String sign) {
 
         log.info(username + "的申请开始发送消息中心-----------------------------------");
 
         LambdaQueryWrapper<SysUser> nickNameQuery = Wrappers.lambdaQuery();
         nickNameQuery.select(SysUser::getNickName)
-                .eq(SysUser::getUserId, submitterId);
-        SysUser nickName = sysUserMapper.selectOne(nickNameQuery);
-        JSONObject jsonObject = new JSONObject();
-        jsonObject.put("infoTitle", INFO_TITLE);
+                .eq(SysUser::getUserId, approvalUid);
+        SysUser user = sysUserMapper.selectOne(nickNameQuery);
+
+        // JSONObject jsonObject = new JSONObject();
+        // jsonObject.put("infoTitle", INFO_TITLE);
+
+        MceRequestVO mceRequestVO = new MceRequestVO();
+        mceRequestVO.setInfoTitle(INFO_TITLE);
 
         switch (isPass) {
             case 0:
-                jsonObject.put("infoContent", nickName.getNickName() + INFO_APPROVE_FAIL);
+                // jsonObject.put("infoContent", nickName.getNickName() + INFO_APPROVE_FAIL);
+                mceRequestVO.setInfoContent(user.getNickName() + INFO_APPROVE_FAIL);
                 break;
             case 1:
-                jsonObject.put("infoContent", nickName.getNickName() + INFO_APPROVE_SUCCESS);
+                // jsonObject.put("infoContent", nickName.getNickName() + INFO_APPROVE_SUCCESS);
+                mceRequestVO.setInfoContent(user.getNickName() + INFO_APPROVE_SUCCESS);
                 break;
             default:
                 OaBuiltInDocument oaBuiltInDocument = OaBuiltInDocument.valueOf(sign);
                 String name = oaBuiltInDocument.getName();
-                jsonObject.put("infoContent", nickName.getNickName() + "的" + name + INFO_CONTENT);
+                // jsonObject.put("infoContent", username + "的" + name + INFO_CONTENT);
+                mceRequestVO.setInfoContent(username + "的" + name + INFO_CONTENT);
         }
 
-        jsonObject.put("infoType", INFO_TYPE);
-        jsonObject.put("id", id);
-        jsonObject.put("infoTypeName", INFO_TITLE);
-        jsonObject.put("userName", username);
-        jsonObject.put("userIds", receivers);
+        // jsonObject.put("infoType", INFO_TYPE);
+        // jsonObject.put("id", id);
+        // jsonObject.put("infoTypeName", INFO_TITLE);
+        // jsonObject.put("userName", username);
+        // jsonObject.put("userIds", receivers);
+
+        mceRequestVO.setInfoType(String.valueOf(INFO_TYPE));
+        mceRequestVO.setId(id);
+        mceRequestVO.setInfoTypeName(INFO_TITLE);
+        mceRequestVO.setUserName(username);
+        mceRequestVO.setUserIds(receivers);
         try {
             // 推送消息中心
-            ApiResult<Void> voidApiResult = remoteMceService.addMce(jsonObject.toString());
+            //ApiResult<Void> voidApiResult = remoteMceService.addMce(jsonObject.toString());
+            ApiResult<Void> voidApiResult = remoteMceService.addMceReceive(mceRequestVO);
 
             if (voidApiResult.isSuccess()) {
                 log.info("申请消息发送成功!");