Browse Source

Merge branch 'fu-dev' of uskycloud/usky-modules into master

gez 3 weeks ago
parent
commit
0f49e8f7ec
56 changed files with 2139 additions and 218 deletions
  1. 3 3
      service-oa/service-oa-biz/pom.xml
  2. 4 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/ServiceOaApplication.java
  3. 1 1
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/MybatisGeneratorUtils.java
  4. 11 3
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaApprovalController.java
  5. 27 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaCgdDocumentController.java
  6. 22 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaFbdDocumentController.java
  7. 22 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaFlowController.java
  8. 22 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaNodeController.java
  9. 0 24
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaQjdDocumentController.java
  10. 21 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/SysDeptController.java
  11. 21 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/SysUserPostController.java
  12. 6 1
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaApproval.java
  13. 117 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaCgdDocument.java
  14. 116 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaFbdDocument.java
  15. 81 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaFlow.java
  16. 0 5
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaFormDefinition.java
  17. 75 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaNode.java
  18. 101 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/SysDept.java
  19. 32 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/SysUserPost.java
  20. 18 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaCgdDocumentMapper.java
  21. 16 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaFbdDocumentMapper.java
  22. 19 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaFlowMapper.java
  23. 18 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaNodeMapper.java
  24. 16 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/SysDeptMapper.java
  25. 16 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/SysUserPostMapper.java
  26. 11 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/DocumentDetailsService.java
  27. 5 2
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaApprovalService.java
  28. 27 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaCgdDocumentService.java
  29. 31 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaFbdDocumentService.java
  30. 16 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaFlowService.java
  31. 16 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaNodeService.java
  32. 16 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/SysDeptService.java
  33. 16 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/SysUserPostService.java
  34. 5 4
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/enums/OaBuiltInDocument.java
  35. 160 37
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaApprovalServiceImpl.java
  36. 99 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaCgdDocumentServiceImpl.java
  37. 126 30
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaDocumentServiceImpl.java
  38. 241 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFbdDocumentServiceImpl.java
  39. 20 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFlowServiceImpl.java
  40. 68 9
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFormDefinitionServiceImpl.java
  41. 1 49
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaJbdDocumentServiceImpl.java
  42. 20 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaNodeServiceImpl.java
  43. 1 41
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaQjdDocumentServiceImpl.java
  44. 20 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/SysDeptServiceImpl.java
  45. 20 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/SysUserPostServiceImpl.java
  46. 238 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaApprovalGeneration.java
  47. 11 5
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaProcessAnalysis.java
  48. 13 4
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaSendMessageCenter.java
  49. 44 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/vo/OaApprovalGenerationRequestVO.java
  50. 1 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/OaApprovalMapper.xml
  51. 27 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/OaCgdDocumentMapper.xml
  52. 27 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/OaFbdDocumentMapper.xml
  53. 20 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/OaFlowMapper.xml
  54. 19 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/OaNodeMapper.xml
  55. 24 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/SysDeptMapper.xml
  56. 11 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/SysUserPostMapper.xml

+ 3 - 3
service-oa/service-oa-biz/pom.xml

@@ -51,11 +51,11 @@
 
         <!-- 流程XML解析 -->
         <!-- https://mvnrepository.com/artifact/org.dom4j/dom4j -->
-        <dependency>
+<!--        <dependency>
             <groupId>org.dom4j</groupId>
             <artifactId>dom4j</artifactId>
-            <version>2.1.1</version>
-        </dependency>
+            <version>2.1.4</version>
+        </dependency>-->
 
     </dependencies>
 

+ 4 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/ServiceOaApplication.java

@@ -9,6 +9,8 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
 import org.springframework.context.ConfigurableApplicationContext;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.core.env.Environment;
+import org.springframework.scheduling.annotation.EnableAsync;
+
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 
@@ -23,6 +25,8 @@ import java.net.UnknownHostException;
 @MapperScan(value = "com.usky.oa.mapper")
 @ComponentScan("com.usky")
 @SpringBootApplication
+//开启异步
+@EnableAsync
 public class ServiceOaApplication
 {
     private static final Logger LOGGER = LoggerFactory.getLogger(ServiceOaApplication.class);

+ 1 - 1
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/MybatisGeneratorUtils.java

@@ -71,7 +71,7 @@ public class MybatisGeneratorUtils {
         // strategy.setTablePrefix("t_"); // 表名前缀
         strategy.setEntityLombokModel(true); // 使用lombok
         // 修改自己想要生成的表
-        strategy.setInclude("oa_jb_document");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
+        strategy.setInclude("sys_dept");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
         mpg.setStrategy(strategy);
 
         // 关闭默认 xml 生成,调整生成 至 根目录

+ 11 - 3
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaApprovalController.java

@@ -46,7 +46,14 @@ public class OaApprovalController {
      * @author: fyc
      * @email yuchuan.fu@chinausky.com
      * @date: 2024/12/30 16:19
-     * @param: [queryType, docNo, type, approvalStatus, startTime, endTime, pageNum, pageSize]
+     * @param: queryType 查询类型(1:待处理,2:已处理,3:我收到,4:我发出)
+     * @param: docNo 单据号
+     * @param: formSign 表单标识
+     * @param: approvalStatus 审批状态 1:审批中 2:审批通过 3:不通过
+     * @param: startTime 开始时间
+     * @param: endTime 结束时间
+     * @param: pageNum 页码
+     * @param: pageSize 每页条数
      * @return: com.usky.common.core.bean.CommonPage<com.usky.oa.domain.OaApproval>
      **/
     @GetMapping("/pageList")
@@ -76,10 +83,11 @@ public class OaApprovalController {
         oaApprovalService.approve(id, approvalStatus, opinion);
     }
 
-    @GetMapping("/analysisTest")
+    // xml 流程解析测试
+/*    @GetMapping("/analysisTest")
     public void analysisTest(@RequestParam(value = "id") Integer id) {
         oaApprovalService.analysisTest(id);
-    }
+    }*/
 
 }
 

+ 27 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaCgdDocumentController.java

@@ -0,0 +1,27 @@
+package com.usky.oa.controller.web;
+
+
+import com.usky.oa.domain.OaCgdDocument;
+import com.usky.oa.service.OaCgdDocumentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 特殊用品采购单表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-14
+ */
+@RestController
+@RequestMapping("/oaCgdDocument")
+public class OaCgdDocumentController {
+
+}
+

+ 22 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaFbdDocumentController.java

@@ -0,0 +1,22 @@
+package com.usky.oa.controller.web;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 发布申请表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-20
+ */
+@RestController
+@RequestMapping("/oaFbdDocument")
+public class OaFbdDocumentController {
+
+}
+

+ 22 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaFlowController.java

@@ -0,0 +1,22 @@
+package com.usky.oa.controller.web;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * oa_审批流程表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-06
+ */
+@RestController
+@RequestMapping("/oaFlow")
+public class OaFlowController {
+
+}
+

+ 22 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaNodeController.java

@@ -0,0 +1,22 @@
+package com.usky.oa.controller.web;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * oa_流程节点表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-06
+ */
+@RestController
+@RequestMapping("/oaNode")
+public class OaNodeController {
+
+}
+

+ 0 - 24
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaQjdDocumentController.java

@@ -22,28 +22,4 @@ import org.springframework.web.bind.annotation.*;
 @RequestMapping("/oaQjDocument")
 public class OaQjdDocumentController {
 
-    @Autowired
-    private OaQjdDocumentService oaQjdDocumentService;
-
-    // 新增请假单
-    @Log(title = "新增请假单", businessType = BusinessType.INSERT)
-    @PostMapping("/addQjDocument")
-    public void addQjDocument(@RequestBody OaQjdDocument oaQjdDocument) {
-        oaQjdDocumentService.addQjDocument(oaQjdDocument);
-    }
-
-    // 更新请假单
-    @Log(title = "更新请假单", businessType = BusinessType.UPDATE)
-    @PostMapping("/updateQjDocument")
-    public void updateQjDocument(@RequestBody OaQjdDocument oaQjdDocument) {
-        oaQjdDocumentService.updateQjDocument(oaQjdDocument);
-    }
-
-    // 删除请假单
-    @Log(title = "删除请假单", businessType = BusinessType.DELETE)
-    @DeleteMapping("/delQjDocument/{docNo}")
-    public void delQjDocument(String docNo) {
-        oaQjdDocumentService.delQjDocument(docNo);
-    }
-
 }

+ 21 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/SysDeptController.java

@@ -0,0 +1,21 @@
+package com.usky.oa.controller.web;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.stereotype.Controller;
+
+/**
+ * <p>
+ * 部门表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-25
+ */
+@Controller
+@RequestMapping("/sysDept")
+public class SysDeptController {
+
+}
+

+ 21 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/SysUserPostController.java

@@ -0,0 +1,21 @@
+package com.usky.oa.controller.web;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.stereotype.Controller;
+
+/**
+ * <p>
+ * 用户与岗位关联表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-24
+ */
+@Controller
+@RequestMapping("/sysUserPost")
+public class SysUserPostController {
+
+}
+

+ 6 - 1
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaApproval.java

@@ -45,7 +45,7 @@ public class OaApproval implements Serializable {
     private Integer proposer;
 
     /**
-     * 审批类型(0:审批,1:知会)
+     * 审批类型(1:审批,2:知会)
      */
     private Integer type;
 
@@ -101,5 +101,10 @@ public class OaApproval implements Serializable {
      */
     private Integer tenantId;
 
+    /**
+     * 节点id
+     */
+    private Integer nodeId;
+
 
 }

+ 117 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaCgdDocument.java

@@ -0,0 +1,117 @@
+package com.usky.oa.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import java.time.LocalDate;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 特殊用品采购单表
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-14
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OaCgdDocument implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 特殊用品采购单表主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 表单定义表主键
+     */
+    private Integer formId;
+
+    /**
+     * 单据编号
+     */
+    private String docNo;
+
+    /**
+     * 申请人id
+     */
+    private Long proposer;
+
+    /**
+     * 单据状态 (0:未提交,1:审批中,2:审批通过,3:审批不通过)
+     */
+    private Integer docStatus;
+
+    /**
+     * 采购明细
+     */
+    private String purchaseDetails;
+
+    /**
+     * 采购原因
+     */
+    private String reason;
+
+    /**
+     * 供应商
+     */
+    private String supplier;
+
+    /**
+     * 期望到货日期
+     */
+    private LocalDate arrivalTime;
+
+    /**
+     * 支付方式(1:月结)
+     */
+    private Integer paymentMethod;
+
+    /**
+     * 图片URL(多张 , 隔开)
+     */
+    private String image;
+
+    /**
+     * 备注
+     */
+    private String remarks;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门id
+     */
+    private Long deptId;
+
+    /**
+     * 租户id
+     */
+    private Integer tenantId;
+
+
+}

+ 116 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaFbdDocument.java

@@ -0,0 +1,116 @@
+package com.usky.oa.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 发布申请表
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OaFbdDocument implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 发布申请表主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 表单定义表主键
+     */
+    private Integer formId;
+
+    /**
+     * 单据编号
+     */
+    private String docNo;
+
+    /**
+     * 申请人id
+     */
+    private Long proposer;
+
+    /**
+     * 申请名称
+     */
+    private String applicationName;
+
+    /**
+     * 单据状态 (0:未提交,1:审批中,2:审批通过,3:审批不通过)
+     */
+    private Integer docStatus;
+
+    /**
+     * 申请发布时间
+     */
+    private LocalDateTime publishTime;
+
+    /**
+     * 发布项目名称
+     */
+    private String publishProject;
+
+    /**
+     * 项目类型(1:前端,2:后端)
+     */
+    private Integer projectType;
+
+    /**
+     * 上线功能
+     */
+    private String onlineFunction;
+
+    /**
+     * 上线前准备
+     */
+    private String preparation;
+
+    /**
+     * 附件
+     */
+    private String annex;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门id
+     */
+    private Long deptId;
+
+    /**
+     * 租户id
+     */
+    private Integer tenantId;
+
+
+}

+ 81 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaFlow.java

@@ -0,0 +1,81 @@
+package com.usky.oa.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * oa_审批流程表
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OaFlow implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 流程表主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 流程名称
+     */
+    private String flowName;
+
+    /**
+     * 表单标识
+     */
+    private String docType;
+
+    /**
+     * 流程说明
+     */
+    private String description;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门ID
+     */
+    private Long deptId;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+    /**
+     * 表单定义表主键id
+     */
+    private Integer formId;
+
+
+}

+ 0 - 5
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaFormDefinition.java

@@ -84,11 +84,6 @@ public class OaFormDefinition implements Serializable {
      */
     private Integer formStatus;
 
-    /*
-     * 单据编号
-     */
-    //private Integer docNo;
-
     /**
      * 可见部门id集合
      */

+ 75 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaNode.java

@@ -0,0 +1,75 @@
+package com.usky.oa.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * oa_流程节点表
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-06
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OaNode implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 节点表主键ID
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 流程ID
+     */
+    private Integer flowId;
+
+    /**
+     * 节点名称
+     */
+    private String nodeName;
+
+    /**
+     * 上级节点
+     */
+    private Integer parentId;
+
+    /**
+     * 节点类型 (1:审批节点 2:抄送节点)
+     */
+    private Integer nodeType;
+
+    /**
+     * 0:指定成员,1:部门主管,2:发起人自选,3:指定部门,4:指定职位
+     */
+    private Integer nodeScope;
+
+    /**
+     * 审批人id
+     */
+    private String proposer;
+
+    /**
+     * 审批部门id
+     */
+    private Integer deptId;
+
+    /**
+     * 职位id
+     */
+    private Integer jobId;
+
+    /**
+     * 节点编号
+     */
+    private String nodeNo;
+
+
+}

+ 101 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/SysDept.java

@@ -0,0 +1,101 @@
+package com.usky.oa.domain;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import java.time.LocalDateTime;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 部门表
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-25
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class SysDept implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 部门id
+     */
+    @TableId(value = "dept_id", type = IdType.AUTO)
+    private Long deptId;
+
+    /**
+     * 父部门id
+     */
+    private Long parentId;
+
+    /**
+     * 祖级列表
+     */
+    private String ancestors;
+
+    /**
+     * 部门名称
+     */
+    private String deptName;
+
+    /**
+     * 显示顺序
+     */
+    private Integer orderNum;
+
+    /**
+     * 负责人
+     */
+    private String leader;
+
+    /**
+     * 联系电话
+     */
+    private String phone;
+
+    /**
+     * 邮箱
+     */
+    private String email;
+
+    /**
+     * 部门状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    private String delFlag;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 租户ID
+     */
+    private Integer tenantId;
+
+
+}

+ 32 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/SysUserPost.java

@@ -0,0 +1,32 @@
+package com.usky.oa.domain;
+
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 用户与岗位关联表
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-24
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class SysUserPost implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 岗位ID
+     */
+    private Long postId;
+
+
+}

+ 18 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaCgdDocumentMapper.java

@@ -0,0 +1,18 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.OaCgdDocument;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 特殊用品采购单表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-14
+ */
+@Repository
+public interface OaCgdDocumentMapper extends CrudMapper<OaCgdDocument> {
+
+}

+ 16 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaFbdDocumentMapper.java

@@ -0,0 +1,16 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.OaFbdDocument;
+import com.usky.common.mybatis.core.CrudMapper;
+
+/**
+ * <p>
+ * 发布申请表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-20
+ */
+public interface OaFbdDocumentMapper extends CrudMapper<OaFbdDocument> {
+
+}

+ 19 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaFlowMapper.java

@@ -0,0 +1,19 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.OaFlow;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * oa_审批流程表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-06
+ */
+@Repository
+public interface OaFlowMapper extends CrudMapper<OaFlow> {
+
+}

+ 18 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaNodeMapper.java

@@ -0,0 +1,18 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.OaNode;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * oa_流程节点表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-06
+ */
+@Repository
+public interface OaNodeMapper extends CrudMapper<OaNode> {
+
+}

+ 16 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/SysDeptMapper.java

@@ -0,0 +1,16 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.SysDept;
+import com.usky.common.mybatis.core.CrudMapper;
+
+/**
+ * <p>
+ * 部门表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-25
+ */
+public interface SysDeptMapper extends CrudMapper<SysDept> {
+
+}

+ 16 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/SysUserPostMapper.java

@@ -0,0 +1,16 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.SysUserPost;
+import com.usky.common.mybatis.core.CrudMapper;
+
+/**
+ * <p>
+ * 用户与岗位关联表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-24
+ */
+public interface SysUserPostMapper extends CrudMapper<SysUserPost> {
+
+}

+ 11 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/DocumentDetailsService.java

@@ -0,0 +1,11 @@
+package com.usky.oa.service;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/3/6
+ */
+public interface DocumentDetailsService {
+    Object getDocumentDetails(String docNo);
+}

+ 5 - 2
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaApprovalService.java

@@ -27,7 +27,7 @@ public interface OaApprovalService extends CrudService<OaApproval> {
 
     /**
      * 审批列表
-     * @param queryType 查询类型(1:待处理,2:已处理,3:我收到)
+     * @param queryType 查询类型(1:待处理,2:已处理,3:我收到,4:我发起)
      * @param docNo 单据编号
      * @param formSign 单据类型(请假申请-QJD...按标识查询)
      * @param approvalStatus 审批状态(1:审批中,2:审批通过,3:审批不通过)
@@ -46,5 +46,8 @@ public interface OaApprovalService extends CrudService<OaApproval> {
      */
     void approve(Integer id, Integer approvalStatus, String opinion);
 
-    void analysisTest(Integer id);
+    String getFieldInfo(String docNo);
+
+    // xml 流程解析测试
+    // void analysisTest(Integer id);
 }

+ 27 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaCgdDocumentService.java

@@ -0,0 +1,27 @@
+package com.usky.oa.service;
+
+import com.usky.oa.domain.OaCgdDocument;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * 特殊用品采购单表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-14
+ */
+public interface OaCgdDocumentService extends CrudService<OaCgdDocument> {
+
+    /**
+     * 新增特殊用品采购采购
+     * @param oaCgdDocument
+     */
+    void add(OaCgdDocument oaCgdDocument);
+
+    /**
+     * 更新特殊用品采购采购
+     * @param oaCgdDocument
+     */
+    void update(OaCgdDocument oaCgdDocument);
+}

+ 31 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaFbdDocumentService.java

@@ -0,0 +1,31 @@
+package com.usky.oa.service;
+
+import com.usky.oa.domain.OaFbdDocument;
+import com.usky.common.mybatis.core.CrudService;
+import org.springframework.stereotype.Component;
+
+/**
+ * <p>
+ * 发布申请表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-20
+ */
+public interface OaFbdDocumentService extends CrudService<OaFbdDocument>{
+
+    /**
+     * 新增发布申请
+     * @param oaFbdDocument
+     */
+    void add(OaFbdDocument oaFbdDocument);
+
+    /**
+     * 更新发布申请
+     * @param oaFbdDocument
+     */
+    void update(OaFbdDocument oaFbdDocument);
+
+    // 获取审批表数据
+    void getOaApproval(OaFbdDocument oaFbdDocument);
+}

+ 16 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaFlowService.java

@@ -0,0 +1,16 @@
+package com.usky.oa.service;
+
+import com.usky.oa.domain.OaFlow;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * oa_审批流程表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-06
+ */
+public interface OaFlowService extends CrudService<OaFlow> {
+
+}

+ 16 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaNodeService.java

@@ -0,0 +1,16 @@
+package com.usky.oa.service;
+
+import com.usky.oa.domain.OaNode;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * oa_流程节点表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-06
+ */
+public interface OaNodeService extends CrudService<OaNode> {
+
+}

+ 16 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/SysDeptService.java

@@ -0,0 +1,16 @@
+package com.usky.oa.service;
+
+import com.usky.oa.domain.SysDept;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * 部门表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-25
+ */
+public interface SysDeptService extends CrudService<SysDept> {
+
+}

+ 16 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/SysUserPostService.java

@@ -0,0 +1,16 @@
+package com.usky.oa.service;
+
+import com.usky.oa.domain.SysUserPost;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * 用户与岗位关联表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-24
+ */
+public interface SysUserPostService extends CrudService<SysUserPost> {
+
+}

+ 5 - 4
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/enums/OaBuiltInDocument.java

@@ -14,7 +14,8 @@ import java.util.Map;
 public enum OaBuiltInDocument {
 
     QJD("QJD", "请假单"),
-    JBD("JBD", "加班单");
+    JBD("JBD", "加班单"),
+    FBD("FBD", "发布单"),
     // LZD("LZ", "离职单"),
     // CCD("CC", "出差单"),
     // WCD("WC", "外出单"),
@@ -24,11 +25,11 @@ public enum OaBuiltInDocument {
     // GDZC("ZCLY", "固定资产领用单"),
     // ZZJY("ZZJY", "印章资质借用单"),
     // HTJY("HTJY", "合同借用单"),
-    // //XMCG("XMCG", "项目采购表单")
+    // //XMCG("XMCG", "项目采购表单"),
     // // 项目采购;固定资产采购;行政(特殊)用品采购
-    // CGD("CGSQ", "采购单"),
     // //XZCG("XZCG", "行政(特殊)用品采购表单"),
-    // YYD("YYSQ", "用印申请单");
+    // YYD("YYSQ", "用印申请单"),
+    CGD("CGD", "行政(特殊)用品采购表单");
 
     private final String sign;
     private final String name;

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

@@ -8,29 +8,21 @@ 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.oa.domain.OaApproval;
-import com.usky.oa.domain.OaDocument;
-import com.usky.oa.domain.OaFormDefinition;
-import com.usky.oa.mapper.OaApprovalMapper;
-import com.usky.oa.mapper.OaDocumentMapper;
-import com.usky.oa.mapper.OaFormDefinitionMapper;
+import com.usky.oa.domain.*;
+import com.usky.oa.mapper.*;
 import com.usky.oa.service.OaApprovalService;
 import com.usky.common.mybatis.core.AbstractCrudService;
-import com.usky.oa.service.utils.OaProcessAnalysis;
+// import com.usky.oa.service.utils.OaProcessAnalysis;
 import com.usky.oa.service.utils.OaSendMessageCenter;
 import com.usky.oa.service.vo.OaApprovalCountVO;
 import com.usky.system.domain.SysUser;
 import org.apache.commons.lang3.StringUtils;
-import org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent.FutureOrPresentValidatorForReadableInstant;
 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;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -55,7 +47,16 @@ public class OaApprovalServiceImpl extends AbstractCrudService<OaApprovalMapper,
     private OaSendMessageCenter oaSendMessageCenter;
 
     @Autowired
-    private OaProcessAnalysis oaProcessAnalysis;
+    private SysUserMapper sysUserMapper;
+
+    @Autowired
+    private OaNodeMapper oaNodeMapper;
+
+    @Autowired
+    private SysUserPostMapper sysUserPostMapper;
+
+/*    @Autowired
+    private OaProcessAnalysis oaProcessAnalysis;*/
 
     @Autowired
     private OaFormDefinitionMapper oaFormDefinitionMapper;
@@ -96,46 +97,84 @@ public class OaApprovalServiceImpl extends AbstractCrudService<OaApprovalMapper,
 
         LambdaQueryWrapper<OaApproval> queryWrapper = Wrappers.lambdaQuery();
         queryWrapper.eq(OaApproval::getTenantId, tenantId)
-                .eq(OaApproval::getApprovalUid, userId).orderByDesc(OaApproval::getApprovalDate);
+                .eq(OaApproval::getApprovalUid, userId)
+                .orderByDesc(OaApproval::getId);
 
         switch (queryType) {
             case 1:
                 queryWrapper.eq(OaApproval::getApprovalStatus, 1)
                         .like(StringUtils.isNotBlank(docNo), OaApproval::getDocNo, docNo)
                         .like(StringUtils.isNotBlank(formSign), OaApproval::getDocNo, formSign)
-                        .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), OaApproval::getSubmitDate, startTime, endTime);
+                        .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), OaApproval::getSubmitDate, startTime, endTime)
+                        .orderByDesc(OaApproval::getSubmitDate);
                 break;
             case 2:
                 queryWrapper.like(StringUtils.isNotBlank(docNo), OaApproval::getDocNo, docNo)
                         .like(StringUtils.isNotBlank(formSign), OaApproval::getDocNo, formSign)
                         .eq(approvalStatus != null && approvalStatus > 1 && approvalStatus < 4, OaApproval::getApprovalStatus, approvalStatus)
                         .in(OaApproval::getApprovalStatus, processed)
-                        .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), OaApproval::getSubmitDate, startTime, endTime);
+                        .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), OaApproval::getSubmitDate, startTime, endTime)
+                        .orderByDesc(OaApproval::getApprovalDate);
                 break;
             case 3:
                 queryWrapper.like(StringUtils.isNotBlank(docNo), OaApproval::getDocNo, docNo)
                         .like(StringUtils.isNotBlank(formSign), OaApproval::getDocNo, formSign)
-                        .eq(OaApproval::getType, 1)
+                        .eq(OaApproval::getType, 2)
                         .eq(approvalStatus != null && approvalStatus > 0 && approvalStatus < 4, OaApproval::getApprovalStatus, approvalStatus)
-                        .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), OaApproval::getSubmitDate, startTime, endTime);
+                        .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), OaApproval::getSubmitDate, startTime, endTime)
+                        .orderByDesc(OaApproval::getSubmitDate);
                 break;
+            case 4:
+
             default:
                 throw new RuntimeException("查询类型参数错误");
         }
-        return ToCommonPage(oaApprovalMapper.selectPage(page, queryWrapper));
+
+        IPage<OaApproval> resultPage = oaApprovalMapper.selectPage(page, queryWrapper);
+
+        // 获取真实姓名
+        List<Long> userIds = resultPage.getRecords().stream()
+                .map(oaApproval -> ((long) oaApproval.getProposer()))
+                .distinct()
+                .collect(Collectors.toList());
+        if (!userIds.isEmpty()) {
+            LambdaQueryWrapper<SysUser> userQueryWrapper = Wrappers.lambdaQuery();
+            userQueryWrapper.in(SysUser::getUserId, userIds).select(SysUser::getUserId, SysUser::getNickName);
+            Map<Long, String> userNicknameMap = sysUserMapper.selectList(userQueryWrapper).stream()
+                    .collect(Collectors.toMap(SysUser::getUserId, SysUser::getNickName));
+            for (OaApproval oaApproval : resultPage.getRecords()) {
+                oaApproval.setCreateBy(userNicknameMap.get(oaApproval.getProposer().longValue()));
+            }
+        }
+
+        return ToCommonPage(resultPage);
     }
 
     // 审批
+    @Transactional
     @Override
     public void approve(Integer id, Integer approvalStatus, String opinion) {
-        LambdaQueryWrapper<OaApproval> queryWrapper = Wrappers.lambdaQuery();
-        queryWrapper.eq(OaApproval::getId, id);
-        OaApproval oaApproval = oaApprovalMapper.selectOne(queryWrapper);
+        Long userId = SecurityUtils.getUserId();
+        String username = SecurityUtils.getUsername();
+        LocalDateTime now = LocalDateTime.now();
+        Integer tenantId = SecurityUtils.getTenantId();
 
+        LambdaQueryWrapper<SysUser> userQuery = new LambdaQueryWrapper<>();
+        userQuery.select(SysUser::getUserId, SysUser::getDeptId)
+                .eq(SysUser::getTenantId, tenantId)
+                .eq(SysUser::getDelFlag, 0)
+                .eq(SysUser::getStatus, 0);
+        Map<Long, Long> userDeptMap = sysUserMapper.selectList(userQuery).stream()
+                .collect(Collectors.toMap(SysUser::getUserId, SysUser::getDeptId));
+
+        OaApproval oaApproval = oaApprovalMapper.selectOne(Wrappers.<OaApproval>lambdaQuery().eq(OaApproval::getId, id));
+
+        if (oaApproval == null) {
+            throw new BusinessException("审批信息不存在!请联系管理员");
+        }
         if (!oaApproval.getApprovalUid().equals(SecurityUtils.getUserId())) {
             throw new BusinessException("审批权限不足,暂时无法更改!");
         }
-
         if (oaApproval.getApprovalStatus() != 1) {
             throw new BusinessException("审批状态异常,暂时无法更改!");
         }
@@ -143,33 +182,117 @@ public class OaApprovalServiceImpl extends AbstractCrudService<OaApprovalMapper,
             throw new BusinessException("审批类型错误,请重试!");
         }
 
-        String username = SecurityUtils.getUsername();
-
-        LocalDateTime now = LocalDateTime.now();
-
+        oaApproval.setApprovalUid(userId);
         oaApproval.setApprovalStatus(approvalStatus);
-        oaApproval.setOpinion(opinion);
+        oaApproval.setOpinion(opinion == null ? "" : opinion);
         oaApproval.setApprovalDate(now);
         oaApproval.setUpdateBy(username);
         oaApproval.setUpdateTime(now);
         oaApprovalMapper.updateById(oaApproval);
 
-        int isPass = 1;
-        if (approvalStatus == 3) {
-            isPass = 0;
+        if (approvalStatus == 2) {
+            Integer nodeId = oaApprovalMapper.selectById(oaApproval.getId()).getNodeId();
+            List<OaNode> oaNodes = oaNodeMapper.selectList(Wrappers.<OaNode>lambdaQuery().eq(OaNode::getParentId, nodeId));
+            if (!oaNodes.isEmpty()) {
+                for (OaNode oaNode : oaNodes) {
+                    List<Long> userIds = new ArrayList<>();
+                    switch (oaNode.getNodeScope()) {
+                        case 0:
+                        case 1:
+                        case 2:
+                            userIds = Arrays.stream(oaNode.getProposer().split(",")).map(Long::parseLong).collect(Collectors.toList());
+                            break;
+                        case 3:
+                            LambdaQueryWrapper<SysUser> userQuery1 = new LambdaQueryWrapper<>();
+                            userQuery1.select(SysUser::getUserId, SysUser::getNickName, SysUser::getDeptId)
+                                    .eq(SysUser::getTenantId, tenantId)
+                                    .eq(SysUser::getDelFlag, 0)
+                                    .eq(SysUser::getStatus, 0)
+                                    .eq(SysUser::getDeptId, oaNode.getDeptId());
+                            userIds = sysUserMapper.selectList(userQuery1).stream().map(SysUser::getUserId).collect(Collectors.toList());
+                            break;
+                        case 4:
+                            LambdaQueryWrapper<SysUserPost> userRoleQuery = new LambdaQueryWrapper<>();
+                            userRoleQuery.eq(SysUserPost::getPostId, oaNode.getJobId());
+                            userIds = sysUserPostMapper.selectList(userRoleQuery).stream().map(SysUserPost::getUserId).collect(Collectors.toList());
+                            break;
+                    }
+
+                    if (userIds.isEmpty()) {
+                        log.error("审批节点无用户,审批失败!");
+                    } else {
+                        for (Long userId1 : userIds) {
+                            OaApproval approval = new OaApproval();
+                            approval.setDocNo(oaApproval.getDocNo());
+                            approval.setProposer(oaApproval.getProposer());
+                            approval.setApprovalUid(userId1);
+                            approval.setType(oaNode.getNodeType());
+                            approval.setApprovalStatus(1);
+                            approval.setSubmitDate(now);
+                            approval.setCreateTime(now);
+                            approval.setCreateBy(username);
+                            approval.setDeptId(userDeptMap.get(userId1));
+                            approval.setTenantId(tenantId);
+                            approval.setNodeId(oaNode.getId());
+                            oaApprovalMapper.insert(approval);
+
+                            // 发送消息通知下一步审批人
+                            oaSendMessageCenter.sendAsyncMessage(
+                                    oaApproval.getCreateBy(),
+                                    Long.valueOf(oaApproval.getProposer()),
+                                    approval.getId(),
+                                    userIds,
+                                    3,
+                                    getFieldInfo(oaApproval.getDocNo())
+                            );
+                        }
+                    }
+                }
+            }
+            // 后无节点,发送消息通知申请人审核通过
+            else {
+                Long proposerId = Long.valueOf(oaApproval.getProposer());
+                oaSendMessageCenter.sendAsyncMessage(
+                        oaApproval.getCreateBy(),
+                        proposerId,
+                        oaApproval.getId(),
+                        Collections.singletonList(proposerId),
+                        1,
+                        getFieldInfo(oaApproval.getDocNo())
+                );
+            }
+        } else if (oaApproval.getApprovalStatus() == 3) {
+            Long proposerId = Long.valueOf(oaApproval.getProposer());
+            // 发送消息通知申请人审核不通过
+            oaSendMessageCenter.sendAsyncMessage(
+                    oaApproval.getCreateBy(),
+                    proposerId,
+                    oaApproval.getId(),
+                    Collections.singletonList(proposerId),
+                    0,
+                    getFieldInfo(oaApproval.getDocNo())
+            );
         }
-
-        List<Long> receivers = Collections.singletonList(Long.valueOf(oaApproval.getProposer()));
-        oaSendMessageCenter.sendAsyncMessage(oaApproval.getCreateBy(), Long.valueOf(oaApproval.getProposer()), oaApproval.getId(), receivers, isPass);
     }
 
     @Override
+    public String getFieldInfo(String docNo) {
+        String sgin = docNo.split("-")[0];
+        LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.select(OaFormDefinition::getFieldInfo)
+                .eq(OaFormDefinition::getFormSign, sgin);
+        OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectOne(queryWrapper);
+        return oaFormDefinition.getFieldInfo();
+    }
+
+    // xml 流程解析测试
+/*    @Override
     public void analysisTest(Integer id) {
         LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
         queryWrapper.eq(OaFormDefinition::getId, id);
         String flowInfo = oaFormDefinitionMapper.selectOne(queryWrapper).getFlowInfo();
         oaProcessAnalysis.processAnalysis(flowInfo);
-    }
+    }*/
 
     // 待处理
     private List<OaApproval> getPendingSum(Integer tenantId, Long userId, LocalDateTime oneYearAgo, LocalDateTime now) {
@@ -227,7 +350,7 @@ public class OaApprovalServiceImpl extends AbstractCrudService<OaApprovalMapper,
         LambdaQueryWrapper<OaApproval> queryWrapper = Wrappers.lambdaQuery();
         queryWrapper.eq(OaApproval::getTenantId, tenantId)
                 .eq(OaApproval::getApprovalUid, userId)
-                .eq(OaApproval::getType, 1)
+                .eq(OaApproval::getType, 2)
                 .between(OaApproval::getSubmitDate, oneYearAgo, now);
         List<OaApproval> oaApprovals = oaApprovalMapper.selectList(queryWrapper);
         return oaApprovals == null ? Collections.emptyList() : oaApprovals;

+ 99 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaCgdDocumentServiceImpl.java

@@ -0,0 +1,99 @@
+package com.usky.oa.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.oa.domain.OaCgdDocument;
+import com.usky.oa.domain.OaDocument;
+import com.usky.oa.domain.OaFormDefinition;
+import com.usky.oa.mapper.OaCgdDocumentMapper;
+import com.usky.oa.mapper.OaDocumentMapper;
+import com.usky.oa.mapper.OaFormDefinitionMapper;
+import com.usky.oa.service.OaCgdDocumentService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * <p>
+ * 特殊用品采购单表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-14
+ */
+@Service
+public class OaCgdDocumentServiceImpl extends AbstractCrudService<OaCgdDocumentMapper, OaCgdDocument> implements OaCgdDocumentService {
+
+    @Autowired
+    private OaCgdDocumentMapper oaCgdDocumentMapper;
+
+    @Autowired
+    private OaFormDefinitionMapper oaFormDefinitionMapper;
+
+    @Autowired
+    private OaDocumentMapper oaDocumentMapper;
+
+
+    @Override
+    public void add(OaCgdDocument oaCgdDocument) {
+        if (StringUtils.isBlank(oaCgdDocument.getPurchaseDetails())){
+            throw new BusinessException("采购明细不能为空!");
+        } else if (StringUtils.isBlank(oaCgdDocument.getReason())){
+            throw new BusinessException("采购原因不能为空!");
+        } else if (StringUtils.isBlank(oaCgdDocument.getSupplier())){
+            throw new BusinessException("供应商不能为空!");
+        } else if (oaCgdDocument.getArrivalTime() == null){
+            throw new BusinessException("期望到货时间不能为空!");
+        } else if (oaCgdDocument.getPaymentMethod() == null){
+            throw new BusinessException("支付方式不能为空!");
+        }
+
+        String username = SecurityUtils.getUsername();
+        Long userId = SecurityUtils.getUserId();
+        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
+        Integer tenantId = SecurityUtils.getTenantId();
+        LocalDateTime now = LocalDateTime.now();
+
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHHmmss");
+        String formattedDate = now.format(formatter);
+
+        LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.select(OaFormDefinition::getFormSign).eq(OaFormDefinition::getId, oaCgdDocument.getFormId());
+        OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectOne(queryWrapper);
+        String sign = oaFormDefinition.getFormSign();
+        String docNo = sign + "-" + formattedDate;
+
+        oaCgdDocument.setDocNo(docNo);
+        oaCgdDocument.setCreateBy(username);
+        oaCgdDocument.setCreateTime(now);
+        oaCgdDocument.setProposer(userId);
+        oaCgdDocument.setDeptId(deptId);
+        oaCgdDocument.setTenantId(tenantId);
+        oaCgdDocumentMapper.insert(oaCgdDocument);
+
+        // 插入单据表数据
+        OaDocument oaDocument = new OaDocument();
+        oaDocument.setFormId(oaCgdDocument.getFormId());
+        oaDocument.setType(sign);
+        oaDocument.setDocNo(docNo);
+        oaDocument.setProposer(userId);
+        oaDocument.setDocStatus(oaCgdDocument.getDocStatus());
+        oaDocument.setCreateBy(username);
+        oaDocument.setCreateTime(oaCgdDocument.getCreateTime());
+        oaDocument.setDeptId(deptId);
+        oaDocument.setTenantId(tenantId);
+        oaDocumentMapper.insert(oaDocument);
+
+    }
+
+    @Override
+    public void update(OaCgdDocument oaCgdDocument) {
+
+    }
+}

+ 126 - 30
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaDocumentServiceImpl.java

@@ -10,11 +10,10 @@ import com.usky.common.core.exception.BusinessException;
 import com.usky.common.security.utils.SecurityUtils;
 import com.usky.oa.domain.*;
 import com.usky.oa.mapper.*;
-import com.usky.oa.service.OaDocumentService;
+import com.usky.oa.service.*;
 import com.usky.common.mybatis.core.AbstractCrudService;
-import com.usky.oa.service.OaJbdDocumentService;
-import com.usky.oa.service.OaQjdDocumentService;
 import com.usky.oa.service.utils.OaSendMessageCenter;
+import com.usky.system.domain.SysUser;
 import org.apache.commons.lang3.RandomUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -54,6 +53,12 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
     @Autowired
     private OaJbdDocumentMapper oaJbdDocumentMapper;
 
+    @Autowired
+    private OaCgdDocumentService oaCgdDocumentService;
+
+    @Autowired
+    private OaCgdDocumentMapper oaCgdDocumentMapper;
+
     @Autowired
     private OaDocumentMapper documentMapper;
 
@@ -66,24 +71,64 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
     @Autowired
     private OaSendMessageCenter oaSendMessageCenter;
 
+    @Autowired
+    private SysUserMapper sysUserMapper;
+
+    @Autowired
+    private OaFbdDocumentService oaFbdDocumentService;
+
+    @Autowired
+    private OaFbdDocumentMapper oaFbdDocumentMapper;
+
     private static final String TABLE_HEAD = "oa_";
     private static final String TABLE_SUFFIX = "_document";
+    // 消息通知:提醒
+    private static final int INFO_TYPE = 3;
 
     // 我的申请
     @Override
-    public CommonPage<OaDocument> myApplication(String docNo, String type, Integer status, String startTime, String endTime, Integer pageNum, Integer pageSize) {
+    public CommonPage<OaDocument> myApplication(String docNo, String type, Integer status,
+                                                String startTime, String endTime,
+                                                Integer pageNum, Integer pageSize) {
+        // 获取当前用户信息
         Long userId = SecurityUtils.getUserId();
         Integer tenantId = SecurityUtils.getTenantId();
+        String username = SecurityUtils.getLoginUser().getSysUser().getNickName();
+
+        // 设置默认分页参数
+        pageNum = (pageNum == null || pageNum <= 0) ? 1 : pageNum;
+        pageSize = (pageSize == null || pageSize <= 0) ? 10 : pageSize;
 
+        // 构建查询条件
         LambdaQueryWrapper<OaDocument> wrapper = Wrappers.lambdaQuery();
-        wrapper.eq(OaDocument::getTenantId, tenantId).eq(OaDocument::getProposer, userId)
+        wrapper.eq(OaDocument::getTenantId, tenantId)
+                .eq(OaDocument::getProposer, userId)
                 .like(StringUtils.isNotBlank(docNo), OaDocument::getDocNo, docNo)
                 .eq(StringUtils.isNotBlank(type), OaDocument::getType, type)
                 .eq(status != null, OaDocument::getDocStatus, status)
-                .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), OaDocument::getCreateTime, startTime, endTime)
+                .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime),
+                        OaDocument::getCreateTime, startTime, endTime)
                 .orderByDesc(OaDocument::getId);
 
-        return ToCommonPage(page(new Page<>(pageNum, pageSize), wrapper));
+        Page<OaDocument> page = new Page<>(pageNum, pageSize);
+        Page<OaDocument> resultPage = documentMapper.selectPage(page, wrapper);
+
+        if (resultPage.getRecords().isEmpty()) {
+            return new CommonPage<>();
+        }
+
+        resultPage.getRecords().forEach(document -> document.setCreateBy(username));
+
+        return toCommonPage(resultPage);
+    }
+
+    private CommonPage<OaDocument> toCommonPage(Page<OaDocument> page) {
+        return new CommonPage<>(
+                page.getRecords(),
+                page.getTotal(),
+                page.getSize(),
+                page.getCurrent()
+        );
     }
 
     // 单据详情
@@ -91,19 +136,45 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
     public Object documentDetails(String docNo) {
         Object documentDetails = null;
         String type = getFormSign(docNo);
+        String fieldInfo = oaFormDefinitionMapper.selectOne(Wrappers.lambdaQuery(OaFormDefinition.class).eq(OaFormDefinition::getFormSign, type)).getFieldInfo();
 
-        switch (type) {
+        switch (fieldInfo) {
             case "QJD":
-                documentDetails = oaQjdDocumentMapper.selectOne(Wrappers.lambdaQuery(OaQjdDocument.class).eq(OaQjdDocument::getDocNo, docNo));
+                OaQjdDocument oaQjdDocument = oaQjdDocumentMapper.selectOne(Wrappers.lambdaQuery(OaQjdDocument.class).eq(OaQjdDocument::getDocNo, docNo));
+                oaQjdDocument.setCreateBy(getNickName(oaQjdDocument.getProposer()));
+                documentDetails = oaQjdDocument;
                 break;
             case "JBD":
-                documentDetails = oaJbdDocumentMapper.selectOne(Wrappers.lambdaQuery(OaJbdDocument.class).eq(OaJbdDocument::getDocNo, docNo));
+                OaJbdDocument oaJbdDocument = oaJbdDocumentMapper.selectOne(Wrappers.lambdaQuery(OaJbdDocument.class).eq(OaJbdDocument::getDocNo, docNo));
+                oaJbdDocument.setCreateBy(getNickName(oaJbdDocument.getProposer()));
+                documentDetails = oaJbdDocument;
+                break;
+            case "CGD":
+                OaCgdDocument oaCgdDocument = oaCgdDocumentMapper.selectOne(Wrappers.lambdaQuery(OaCgdDocument.class).eq(OaCgdDocument::getDocNo, docNo));
+                oaCgdDocument.setCreateBy(getNickName(oaCgdDocument.getProposer()));
+                documentDetails = oaCgdDocument;
+                break;
+            case "FBD":
+                OaFbdDocument oaFbdDocument = oaFbdDocumentMapper.selectOne(Wrappers.lambdaQuery(OaFbdDocument.class).eq(OaFbdDocument::getDocNo, docNo));
+                oaFbdDocument.setCreateBy(getNickName(oaFbdDocument.getProposer()));
+                documentDetails = oaFbdDocument;
                 break;
         }
 
+        if (documentDetails == null) {
+            throw new BusinessException("单据不存在");
+        }
+
         return documentDetails;
     }
 
+    // 获取用户姓名
+    private String getNickName(Long userId) {
+        LambdaQueryWrapper<SysUser> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.select(SysUser::getNickName).eq(SysUser::getUserId, userId);
+        return sysUserMapper.selectOne(queryWrapper).getNickName();
+    }
+
     // 删除单据
     @Override
     public void delDocument(String docNo) {
@@ -115,16 +186,27 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
             case "JBD":
                 oaJbdDocumentMapper.delete(Wrappers.lambdaQuery(OaJbdDocument.class).eq(OaJbdDocument::getDocNo, docNo));
                 break;
+            case "CGD":
+                oaCgdDocumentMapper.delete(Wrappers.lambdaQuery(OaCgdDocument.class).eq(OaCgdDocument::getDocNo, docNo));
+                break;
+            case "FBD":
+                oaFbdDocumentMapper.delete(Wrappers.lambdaQuery(OaFbdDocument.class).eq(OaFbdDocument::getDocNo, docNo));
+                break;
         }
         oaDocumentMapper.delete(Wrappers.lambdaQuery(OaDocument.class).eq(OaDocument::getDocNo, docNo));
     }
 
     // 新增单据
+    @Transactional
     @Override
     public void addDoc(JSONObject oaDocument) {
         LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
         queryWrapper.select(OaFormDefinition::getFieldInfo).eq(OaFormDefinition::getId, oaDocument.get("formId"));
         OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectOne(queryWrapper);
+
+        if (oaFormDefinition == null) {
+            throw new BusinessException("新增表单模板不存在!请联系管理员");
+        }
         String sign = oaFormDefinition.getFieldInfo();
 
         switch (sign) {
@@ -134,10 +216,19 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
             case "JBD":
                 oaJbdDocumentService.add(JSON.parseObject(oaDocument.toJSONString(), OaJbdDocument.class));
                 break;
+            case "CGD":
+                oaCgdDocumentService.add(JSON.parseObject(oaDocument.toJSONString(), OaCgdDocument.class));
+                break;
+            case "FBD":
+                oaFbdDocumentService.add(JSON.parseObject(oaDocument.toJSONString(), OaFbdDocument.class));
+                break;
+            default:
+                throw new BusinessException("新增表单模板不存在!请联系管理员");
         }
     }
 
     // 更新单据
+    @Transactional
     @Override
     public void updateDoc(JSONObject jsonDocument) {
         LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
@@ -152,10 +243,19 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
             case "JBD":
                 oaJbdDocumentService.update(JSON.parseObject(jsonDocument.toJSONString(), OaJbdDocument.class));
                 break;
+            case "CGD":
+                oaCgdDocumentService.update(JSON.parseObject(jsonDocument.toJSONString(), OaCgdDocument.class));
+                break;
+            case "FBD":
+                oaFbdDocumentService.update(JSON.parseObject(jsonDocument.toJSONString(), OaFbdDocument.class));
+                break;
+            default:
+                throw new BusinessException("单据模板不存在!请联系管理员");
         }
     }
 
     // 提交单据
+    @Transactional
     @Override
     public void submit(String docNo, Integer docStatus) {
         if (docStatus != 1) {
@@ -176,6 +276,7 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
         LocalDateTime now = LocalDateTime.now();
 
         String formSign = getFormSign(docNo);
+        formSign = oaFormDefinitionMapper.selectOne(Wrappers.lambdaQuery(OaFormDefinition.class).eq(OaFormDefinition::getFormSign, formSign)).getFieldInfo();
 
         switch (formSign) {
             case "QJD":
@@ -192,32 +293,27 @@ public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper,
                         .set(OaJbdDocument::getUpdateTime, now)
                         .eq(OaJbdDocument::getDocNo, docNo));
                 break;
+            case "CGD":
+                oaCgdDocumentMapper.update(null, Wrappers.lambdaUpdate(OaCgdDocument.class)
+                        .set(OaCgdDocument::getDocStatus, docStatus)
+                        .set(OaCgdDocument::getUpdateBy, username)
+                        .set(OaCgdDocument::getUpdateTime, now)
+                        .eq(OaCgdDocument::getDocNo, docNo));
+                break;
+            case "FBD":
+                oaFbdDocumentMapper.update(null, Wrappers.lambdaUpdate(OaFbdDocument.class)
+                        .set(OaFbdDocument::getDocStatus, docStatus)
+                        .set(OaFbdDocument::getUpdateBy, username)
+                        .set(OaFbdDocument::getUpdateTime, now)
+                        .eq(OaFbdDocument::getDocNo, docNo));
+                oaFbdDocumentService.getOaApproval(oaFbdDocumentMapper.selectOne(Wrappers.lambdaQuery(OaFbdDocument.class).eq(OaFbdDocument::getDocNo, docNo)));
+                break;
         }
         oaDocumentMapper.update(null, Wrappers.lambdaUpdate(OaDocument.class)
                 .set(OaDocument::getDocStatus, docStatus)
                 .set(OaDocument::getUpdateBy, username)
                 .set(OaDocument::getUpdateTime, now)
                 .eq(OaDocument::getDocNo, docNo));
-
-        // 生成审批记录
-        OaApproval oaApproval = new OaApproval();
-        oaApproval.setDocNo(docNo);
-        oaApproval.setType(0);
-        oaApproval.setApprovalStatus(1);
-        // 随机选择一个审批人(涛、哲)
-        long approvalUid = RandomUtils.nextBoolean() ? 101 : 105;
-        oaApproval.setApprovalUid(approvalUid);
-        oaApproval.setProposer(Math.toIntExact(userId));
-        oaApproval.setCreateBy(username);
-        oaApproval.setCreateTime(now);
-        oaApproval.setSubmitDate(now);
-        oaApproval.setDeptId(deptId);
-        oaApproval.setTenantId(tenantId);
-        oaApprovalMapper.insert(oaApproval);
-
-        // 发送审批消息
-        List<Long> receivers = Collections.singletonList(oaApproval.getApprovalUid());
-        oaSendMessageCenter.sendAsyncMessage(oaApproval.getCreateBy(), userId, oaApproval.getId(), receivers,3);
     }
 
     // 获取单据类型

+ 241 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFbdDocumentServiceImpl.java

@@ -0,0 +1,241 @@
+package com.usky.oa.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.core.exception.BusinessException;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.oa.domain.*;
+import com.usky.oa.mapper.*;
+import com.usky.oa.service.OaApprovalService;
+import com.usky.oa.service.OaFbdDocumentService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.oa.service.utils.OaApprovalGeneration;
+import com.usky.oa.service.utils.OaSendMessageCenter;
+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;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 发布申请表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-20
+ */
+@Service
+public class OaFbdDocumentServiceImpl extends AbstractCrudService<OaFbdDocumentMapper, OaFbdDocument> implements OaFbdDocumentService {
+
+    @Autowired
+    private OaFormDefinitionMapper oaFormDefinitionMapper;
+
+    @Autowired
+    private OaDocumentMapper oaDocumentMapper;
+
+    @Autowired
+    private OaFbdDocumentMapper oaFbdDocumentMapper;
+
+    @Autowired
+    private OaApprovalMapper oaApprovalMapper;
+
+    @Autowired
+    private SysUserMapper sysUserMapper;
+
+    @Autowired
+    private SysUserPostMapper sysUserPostMapper;
+
+    @Autowired
+    private OaApprovalGeneration oaApprovalGeneration;
+
+    @Autowired
+    private OaSendMessageCenter oaSendMessageCenter;
+
+    @Autowired
+    private OaApprovalService oaApprovalService;
+
+    @Override
+    public void add(OaFbdDocument oaFbdDocument) {
+        // 校验表单数据
+        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);
+        }
+    }
+
+    // 获取审批表数据
+    @Override
+    public void getOaApproval(OaFbdDocument oaFbdDocument) {
+        String docNo = oaFbdDocument.getDocNo();
+        String formSign = docNo.split("-")[0];
+        OaFlow oaFlow = oaApprovalGeneration.selectBySign(formSign);
+        OaNode oaNode = oaApprovalGeneration.selectByFlowId(oaFlow.getId());
+
+        List<Long> userIds = new ArrayList<>();
+
+        switch (oaNode.getNodeScope()) {
+            case 0:
+            case 1:
+            case 2:
+                userIds = Arrays.stream(oaNode.getProposer().split(",")).map(Long::parseLong).collect(Collectors.toList());
+                break;
+            case 3:
+                LambdaQueryWrapper<SysUser> userQuery = new LambdaQueryWrapper<>();
+                userQuery.select(SysUser::getUserId)
+                        .eq(SysUser::getTenantId, oaFlow.getTenantId())
+                        .eq(SysUser::getDelFlag, 0)
+                        .eq(SysUser::getStatus, 0)
+                        .eq(SysUser::getDeptId, oaNode.getDeptId());
+                userIds = sysUserMapper.selectList(userQuery).stream().map(SysUser::getUserId).collect(Collectors.toList());
+                break;
+            case 4:
+                LambdaQueryWrapper<SysUserPost> userRoleQuery = new LambdaQueryWrapper<>();
+                userRoleQuery.eq(SysUserPost::getPostId, oaNode.getJobId());
+                userIds = sysUserPostMapper.selectList(userRoleQuery).stream().map(SysUserPost::getUserId).collect(Collectors.toList());
+                break;
+        }
+
+        for (Long userId1 : userIds) {
+            OaApproval approval = new OaApproval();
+            approval.setDocNo(docNo);
+            approval.setProposer(Math.toIntExact(oaFbdDocument.getProposer()));
+            approval.setType(oaNode.getNodeType());
+            approval.setApprovalStatus(1);
+            approval.setApprovalUid(userId1);
+            approval.setSubmitDate(oaFbdDocument.getCreateTime());
+            approval.setCreateTime(oaFbdDocument.getCreateTime());
+            approval.setCreateBy(oaFbdDocument.getCreateBy());
+            approval.setDeptId(oaFbdDocument.getDeptId());
+            approval.setTenantId(oaFbdDocument.getTenantId());
+            approval.setNodeId(oaNode.getId());
+            oaApprovalMapper.insert(approval);
+        }
+
+        oaSendMessageCenter.sendAsyncMessage(
+                oaFbdDocument.getCreateBy(),
+                oaFbdDocument.getProposer(),
+                oaFbdDocument.getId(),
+                userIds,
+                3,
+                oaApprovalService.getFieldInfo(oaFbdDocument.getDocNo())
+        );
+    }
+
+    /**
+     * 校验表单数据
+     * @param oaFbdDocument
+     */
+    private void validateDocument(OaFbdDocument oaFbdDocument) {
+        if (StringUtils.isBlank(oaFbdDocument.getApplicationName())) {
+            throw new BusinessException("申请名称不能为空!");
+        } else if (oaFbdDocument.getApplicationName().length() > 16) {
+            throw new BusinessException("申请名称长度不能超过16个字符!");
+        } else if (oaFbdDocument.getPublishTime() == null) {
+            throw new BusinessException("发布时间不能为空!");
+        } else if (oaFbdDocument.getPublishTime().isBefore(LocalDateTime.now())) {
+            throw new BusinessException("发布时间不能早于当前时间!");
+        } else if (oaFbdDocument.getApplicationName().length() > 15) {
+            throw new BusinessException("申请名称长度不能超过15个字符!");
+        } else if (StringUtils.isBlank(oaFbdDocument.getPublishProject())) {
+            throw new BusinessException("发布项目不能为空!");
+        } else if (oaFbdDocument.getPublishProject().length() > 64) {
+            throw new BusinessException("发布项目名称长度不能超过64个字符!");
+        } else if (oaFbdDocument.getProjectType() == null) {
+            throw new BusinessException("项目类型不能为空!");
+        } else if (oaFbdDocument.getProjectType() < 1 || oaFbdDocument.getProjectType() > 2) {
+            throw new BusinessException("项目类型传参有误!");
+        } else if (StringUtils.isBlank(oaFbdDocument.getOnlineFunction())) {
+            throw new BusinessException("上线功能不能为空!");
+        } else if (oaFbdDocument.getOnlineFunction().length() > 250) {
+            throw new BusinessException("上线功能长度不能超过250个字!");
+        } else if (oaFbdDocument.getPreparation() != null && oaFbdDocument.getPreparation().length() > 64) {
+            throw new BusinessException("上线前准备不能超过250个字!");
+        } else if (oaFbdDocument.getAnnex() != null && oaFbdDocument.getAnnex().length() > 500) {
+            throw new BusinessException("附件上传数量超!");
+        }
+    }
+
+
+}

+ 20 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFlowServiceImpl.java

@@ -0,0 +1,20 @@
+package com.usky.oa.service.impl;
+
+import com.usky.oa.domain.OaFlow;
+import com.usky.oa.mapper.OaFlowMapper;
+import com.usky.oa.service.OaFlowService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * oa_审批流程表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-06
+ */
+@Service
+public class OaFlowServiceImpl extends AbstractCrudService<OaFlowMapper, OaFlow> implements OaFlowService {
+
+}

+ 68 - 9
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFormDefinitionServiceImpl.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.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
@@ -8,15 +9,13 @@ import com.ruoyi.common.datascope.context.DataScopeContextHolder;
 import com.usky.common.core.bean.CommonPage;
 import com.usky.common.core.exception.BusinessException;
 import com.usky.common.security.utils.SecurityUtils;
-import com.usky.oa.domain.OaDocument;
-import com.usky.oa.domain.OaFormDefinition;
-import com.usky.oa.mapper.OaDocumentMapper;
-import com.usky.oa.mapper.OaFormDefinitionMapper;
-import com.usky.oa.service.OaDocumentService;
+import com.usky.oa.domain.*;
+import com.usky.oa.mapper.*;
 import com.usky.oa.service.OaFormDefinitionService;
 import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.oa.service.utils.OaApprovalGeneration;
 import com.usky.oa.service.vo.OaFormNameResponseVO;
-import lombok.extern.slf4j.Slf4j;
+import com.usky.system.domain.SysUser;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -42,6 +41,17 @@ public class OaFormDefinitionServiceImpl extends AbstractCrudService<OaFormDefin
     @Autowired
     private OaDocumentMapper oaDocumentMapper;
 
+    @Autowired
+    private OaFlowMapper oaFlowMapper;
+
+    @Autowired
+    private SysUserMapper sysUserMapper;
+
+    @Autowired
+    private OaNodeMapper nodeMapper;
+    @Autowired
+    private OaApprovalGeneration oaApprovalGeneration;
+
     /**
      * 新增/更新 表单
      * 此方法负责验证表单定义的合法性,包括表单名称和标识的唯一性、长度限制,并最终保存合法的表单定义
@@ -70,7 +80,6 @@ public class OaFormDefinitionServiceImpl extends AbstractCrudService<OaFormDefin
         validFromScope(oaFormDefinition);
 
         // 获取用户基本信息
-        Long userId = SecurityUtils.getUserId();
         Integer tenantId = SecurityUtils.getTenantId();
         String username = SecurityUtils.getUsername();
         Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
@@ -81,7 +90,6 @@ public class OaFormDefinitionServiceImpl extends AbstractCrudService<OaFormDefin
             // BeanUtils.copyBeanProp(oaFormDefinition, oaFormDefinition);
             // 判断表单名称和标识是否重复
             selectByNameOrSign(formName, formSign);
-
             oaFormDefinition.setCreateBy(username);
             oaFormDefinition.setDeptId(deptId);
             oaFormDefinition.setTenantId(tenantId);
@@ -89,6 +97,7 @@ public class OaFormDefinitionServiceImpl extends AbstractCrudService<OaFormDefin
             oaFormDefinition.setFormVersion(1);
             oaFormDefinition.setFormStatus(2);
             oaFormDefinitionMapper.insert(oaFormDefinition);
+            oaApprovalGeneration.addGenerate(oaFormDefinition);
         } else {
             oaFormDefinition.setUpdateBy(username);
             oaFormDefinition.setUpdateTime(now);
@@ -102,7 +111,21 @@ public class OaFormDefinitionServiceImpl extends AbstractCrudService<OaFormDefin
                 throw new BusinessException("表单标识不可修改!");
             }
 
+            // 校验是否能够进行修改
+            selectIsHaveDocument(formSign, tenantId);
             oaFormDefinitionMapper.updateById(oaFormDefinition);
+            oaApprovalGeneration.updateGenerate(oaFormDefinition);
+        }
+    }
+
+    // 更新时表单下存在已生成单据时,不允许修改表单任何信息
+    private void selectIsHaveDocument(String formSign, Integer tenantId) {
+        LambdaQueryWrapper<OaDocument> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(OaDocument::getTenantId, tenantId)
+                .eq(OaDocument::getType, formSign);
+        List<OaDocument> oaDocument = oaDocumentMapper.selectList(queryWrapper);
+        if (!oaDocument.isEmpty()) {
+            throw new BusinessException("当前表单下已存在单据,不可修改!");
         }
     }
 
@@ -146,7 +169,43 @@ public class OaFormDefinitionServiceImpl extends AbstractCrudService<OaFormDefin
                 .orderByDesc(OaFormDefinition::getId)
                 // 数据权限控制
                 .apply(Objects.nonNull(DataScopeContextHolder.getDataScopeSql()), DataScopeContextHolder.getDataScopeSql());
-        return ToCommonPage(oaFormDefinitionMapper.selectPage(page, queryWrapper));
+        page = oaFormDefinitionMapper.selectPage(page, queryWrapper);
+        setCreateByNickName(page.getRecords());
+
+        return new CommonPage<>(page.getRecords(), page.getTotal(), pageSize, pageNum);
+    }
+
+    // 真实姓名替换创建人userName
+    private void setCreateByNickName(List<OaFormDefinition> records) {
+        if (records == null || records.isEmpty()) {
+            return;
+        }
+
+        List<String> createByList = records.stream()
+                .map(OaFormDefinition::getCreateBy)
+                .filter(StringUtils::isNotBlank)
+                .distinct()
+                .collect(Collectors.toList());
+
+        Map<String, String> createByNickNameMap = new HashMap<>();
+        if (!createByList.isEmpty()) {
+            LambdaQueryWrapper<SysUser> userQueryWrapper = Wrappers.lambdaQuery();
+            userQueryWrapper.in(SysUser::getUserName, createByList)
+                    .eq(SysUser::getTenantId, SecurityUtils.getTenantId())
+                    .eq(SysUser::getDelFlag, 0)
+                    .eq(SysUser::getStatus, 0)
+                    .select(SysUser::getUserName, SysUser::getNickName);
+            List<SysUser> sysUsers = sysUserMapper.selectList(userQueryWrapper);
+            createByNickNameMap = sysUsers.stream()
+                    .collect(Collectors.toMap(SysUser::getUserName, SysUser::getNickName));
+        }
+
+        for (OaFormDefinition record : records) {
+            String createBy = record.getCreateBy();
+            if (StringUtils.isNotBlank(createBy) && createByNickNameMap.containsKey(createBy)) {
+                record.setCreateBy(createByNickNameMap.get(createBy));
+            }
+        }
     }
 
     // 表单管理-修改表单状态

+ 1 - 49
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaJbdDocumentServiceImpl.java

@@ -83,28 +83,6 @@ public class OaJbdDocumentServiceImpl extends AbstractCrudService<OaJbdDocumentM
         oaDocument.setDeptId(deptId);
         oaDocument.setTenantId(tenantId);
         oaDocumentMapper.insert(oaDocument);
-
-        // 如果直接提交则生成一条单据记录
-        Integer docStatus = oaJbdDocument.getDocStatus();
-        if (docStatus.equals(1)) {
-            // 生成一条审批记录数据
-            OaApproval oaApproval = new OaApproval();
-            oaApproval.setDocNo(oaJbdDocument.getDocNo());
-            oaApproval.setType(0);
-            oaApproval.setApprovalStatus(1);
-            oaApproval.setApprovalUid(105L);
-            oaApproval.setProposer(Math.toIntExact(userId));
-            oaApproval.setCreateBy(oaJbdDocument.getCreateBy());
-            oaApproval.setCreateTime(now);
-            oaApproval.setSubmitDate(now);
-            oaApproval.setDeptId(oaJbdDocument.getDeptId());
-            oaApproval.setTenantId(oaJbdDocument.getTenantId());
-            oaApprovalMapper.insert(oaApproval);
-
-            // 发送审批消息
-            List<Long> receivers = Collections.singletonList(oaApproval.getApprovalUid());
-            oaSendMessageCenter.sendAsyncMessage(oaApproval.getCreateBy(), userId, oaApproval.getId(), receivers, 3);
-        }
     }
 
     @Override
@@ -124,30 +102,9 @@ public class OaJbdDocumentServiceImpl extends AbstractCrudService<OaJbdDocumentM
         oaDocumentMapper.update(null, Wrappers.lambdaUpdate(OaDocument.class)
                 .eq(OaDocument::getDocNo, oaJbdDocument.getDocNo())
                 .set(OaDocument::getDocStatus, oaJbdDocument.getDocStatus())
-                .set(OaDocument::getUpdateBy, oaJbdDocument.getCreateBy())
+                .set(OaDocument::getUpdateBy, oaJbdDocument.getUpdateBy())
                 .set(OaDocument::getUpdateTime, oaJbdDocument.getUpdateTime())
         );
-
-        Integer docStatus = oaJbdDocument.getDocStatus();
-        if (docStatus.equals(1)) {
-            // 生成一条审批记录数据
-            OaApproval oaApproval = new OaApproval();
-            oaApproval.setDocNo(oaJbdDocument.getDocNo());
-            oaApproval.setType(0);
-            oaApproval.setApprovalStatus(1);
-            oaApproval.setApprovalUid(105L);
-            oaApproval.setProposer(Math.toIntExact(userId));
-            oaApproval.setCreateBy(oaJbdDocument.getCreateBy());
-            oaApproval.setCreateTime(now);
-            oaApproval.setSubmitDate(now);
-            oaApproval.setDeptId(oaJbdDocument.getDeptId());
-            oaApproval.setTenantId(oaJbdDocument.getTenantId());
-            oaApprovalMapper.insert(oaApproval);
-
-            // 发送审批消息
-            List<Long> receivers = Collections.singletonList(oaApproval.getApprovalUid());
-            oaSendMessageCenter.sendAsyncMessage(oaApproval.getCreateBy(), userId, oaApproval.getId(), receivers, 3);
-        }
     }
 
     /**
@@ -191,11 +148,6 @@ public class OaJbdDocumentServiceImpl extends AbstractCrudService<OaJbdDocumentM
 
     @Override
     public void delByDocNo(String docNo) {
-
-        if (StringUtils.isBlank(docNo)) {
-            throw new BusinessException("加班单据编号不能为空!");
-        }
-
         Integer tenantId = SecurityUtils.getTenantId();
         Long userId = SecurityUtils.getUserId();
 

+ 20 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaNodeServiceImpl.java

@@ -0,0 +1,20 @@
+package com.usky.oa.service.impl;
+
+import com.usky.oa.domain.OaNode;
+import com.usky.oa.mapper.OaNodeMapper;
+import com.usky.oa.service.OaNodeService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * oa_流程节点表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-06
+ */
+@Service
+public class OaNodeServiceImpl extends AbstractCrudService<OaNodeMapper, OaNode> implements OaNodeService {
+
+}

+ 1 - 41
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaQjdDocumentServiceImpl.java

@@ -98,26 +98,6 @@ public class OaQjdDocumentServiceImpl extends AbstractCrudService<OaQjdDocumentM
         oaDocument.setDeptId(deptId);
         oaDocument.setTenantId(tenantId);
         oaDocumentMapper.insert(oaDocument);
-
-        if (oaQjdDocument.getDocStatus().equals(1)) {
-            // 生成一条审批记录数据
-            OaApproval oaApproval = new OaApproval();
-            oaApproval.setDocNo(docNo);
-            oaApproval.setType(0);
-            oaApproval.setApprovalStatus(1);
-            oaApproval.setApprovalUid(101L);
-            oaApproval.setProposer(Math.toIntExact(userId));
-            oaApproval.setCreateBy(username);
-            oaApproval.setCreateTime(now);
-            oaApproval.setSubmitDate(now);
-            oaApproval.setDeptId(deptId);
-            oaApproval.setTenantId(tenantId);
-            oaApprovalMapper.insert(oaApproval);
-
-            // 发送审批消息
-            List<Long> receivers = Collections.singletonList(oaApproval.getApprovalUid());
-            oaSendMessageCenter.sendAsyncMessage(oaApproval.getCreateBy(), userId, oaApproval.getId(), receivers, 3);
-        }
     }
 
     @Override
@@ -144,26 +124,6 @@ public class OaQjdDocumentServiceImpl extends AbstractCrudService<OaQjdDocumentM
                 .set(OaDocument::getUpdateBy, username)
                 .set(OaDocument::getUpdateTime, oaQjdDocument.getUpdateTime())
         );
-
-        if (oaQjdDocument.getDocStatus().equals(1)) {
-            // 生成一条审批记录数据
-            OaApproval oaApproval = new OaApproval();
-            oaApproval.setDocNo(oaQjdDocument.getDocNo());
-            oaApproval.setType(0);
-            oaApproval.setApprovalStatus(1);
-            oaApproval.setApprovalUid(101L);
-            oaApproval.setProposer(Math.toIntExact(userId));
-            oaApproval.setCreateBy(username);
-            oaApproval.setCreateTime(now);
-            oaApproval.setSubmitDate(now);
-            oaApproval.setDeptId(deptId);
-            oaApproval.setTenantId(tenantId);
-            oaApprovalMapper.insert(oaApproval);
-
-            // 发送审批消息
-            List<Long> receivers = Collections.singletonList(oaApproval.getApprovalUid());
-            oaSendMessageCenter.sendAsyncMessage(oaApproval.getCreateBy(), userId, oaApproval.getId(), receivers, 3);
-        }
     }
 
     /**
@@ -174,7 +134,7 @@ public class OaQjdDocumentServiceImpl extends AbstractCrudService<OaQjdDocumentM
      * @param: [oaQjDocument]
      * @return: void
      **/
-    public void validateOaQjDocument(OaQjdDocument oaQjdDocument) {
+    private void validateOaQjDocument(OaQjdDocument oaQjdDocument) {
 
         if (oaQjdDocument.getFormId() == null || oaQjdDocument.getFormId() <= 0) {
             throw new BusinessException("表单ID不能为空或小于等于0");

+ 20 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/SysDeptServiceImpl.java

@@ -0,0 +1,20 @@
+package com.usky.oa.service.impl;
+
+import com.usky.oa.domain.SysDept;
+import com.usky.oa.mapper.SysDeptMapper;
+import com.usky.oa.service.SysDeptService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 部门表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-25
+ */
+@Service
+public class SysDeptServiceImpl extends AbstractCrudService<SysDeptMapper, SysDept> implements SysDeptService {
+
+}

+ 20 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/SysUserPostServiceImpl.java

@@ -0,0 +1,20 @@
+package com.usky.oa.service.impl;
+
+import com.usky.oa.domain.SysUserPost;
+import com.usky.oa.mapper.SysUserPostMapper;
+import com.usky.oa.service.SysUserPostService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * 用户与岗位关联表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-02-24
+ */
+@Service
+public class SysUserPostServiceImpl extends AbstractCrudService<SysUserPostMapper, SysUserPost> implements SysUserPostService {
+
+}

+ 238 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaApprovalGeneration.java

@@ -0,0 +1,238 @@
+package com.usky.oa.service.utils;
+
+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;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.oa.domain.*;
+import com.usky.oa.mapper.OaFlowMapper;
+import com.usky.oa.mapper.OaNodeMapper;
+import com.usky.oa.mapper.SysDeptMapper;
+import com.usky.oa.mapper.SysUserMapper;
+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.util.List;
+import java.util.stream.Collectors;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/2/21
+ */
+@Slf4j
+@Service
+public class OaApprovalGeneration {
+
+    @Autowired
+    private OaFlowMapper oaFlowMapper;
+
+    @Autowired
+    private OaNodeMapper oaNodeMapper;
+
+    @Autowired
+    private SysDeptMapper sysDeptMapper;
+
+    @Autowired
+    private SysUserMapper sysUserMapper;
+
+    @Autowired
+    private OaSendMessageCenter oaSendMessageCenter;
+
+    /**
+     * @description: 新增流程与节点信息
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/2/21 19:23
+     * @param: [oaFormDefinition]
+     * @return: void
+     **/
+    @Async
+    public void addGenerate(OaFormDefinition oaFormDefinition) {
+        // 新增流程数据
+        OaFlow oaFlow = new OaFlow();
+        oaFlow.setFormId(oaFormDefinition.getId());
+        oaFlow.setFlowName(oaFormDefinition.getFormName() + "的流程");
+        oaFlow.setDocType(oaFormDefinition.getFormSign());
+        oaFlow.setDescription(oaFormDefinition.getFormExplain());
+        oaFlow.setCreateBy(oaFormDefinition.getCreateBy());
+        oaFlow.setCreateTime(oaFormDefinition.getCreateTime());
+        oaFlow.setDeptId(oaFormDefinition.getDeptId());
+        oaFlow.setTenantId(oaFormDefinition.getTenantId());
+        oaFlowMapper.insert(oaFlow);
+
+        String flowInfo = oaFormDefinition.getFlowInfo();
+        Integer flowId = oaFlow.getId();
+
+        // 获取JSON字符串内的node节点信息
+        if (StringUtils.isBlank(flowInfo)) {
+            throw new BusinessException("节点信息为空!请联系管理员");
+        }
+        JSONObject jsonObject = JSONObject.parseObject(flowInfo);
+        if (jsonObject.containsKey("node")) {
+            List<JSONObject> nodeList = jsonObject.getJSONArray("node").toJavaList(JSONObject.class);
+            // 用于记录上一个节点的 ID
+            Integer lastNodeId = null;
+
+            for (JSONObject node : nodeList) {
+                String nodeNo = node.getString("nodebh");
+                String nodeName = node.getString("nodeName");
+                Integer nodeType = node.getInteger("nodeType");
+                Integer nodeScope = node.getInteger("nodeScope");
+                String proposer = null;
+                Integer deptId2 = null;
+                Integer jobId = null;
+
+                switch (nodeScope) {
+                    case 0:
+                    case 2:
+                        proposer = node.getString("appointApprover");
+                        break;
+                    case 1:
+                        Long deptLeader = getDeptLeader();
+                        if (deptLeader != null) {
+                            proposer = deptLeader.toString();
+                        }
+                        break;
+                    case 3:
+                        deptId2 = node.getInteger("deptId");
+                        break;
+                    case 4:
+                        jobId = node.getInteger("jobId");
+                        break;
+                    default:
+                        throw new BusinessException("节点权限范围不正确");
+                }
+
+                OaNode oaNode = new OaNode();
+                oaNode.setFlowId(flowId);
+                oaNode.setNodeNo(nodeNo);
+                oaNode.setNodeName(nodeName);
+                oaNode.setNodeType(nodeType);
+                oaNode.setNodeScope(nodeScope);
+                oaNode.setProposer(proposer);
+                oaNode.setDeptId(deptId2);
+                oaNode.setJobId(jobId);
+                // 使用上一个节点的 ID 作为父节点,第一个节点的父节点 ID 设置为 0
+                oaNode.setParentId(lastNodeId == null ? 0 : lastNodeId);
+                oaNodeMapper.insert(oaNode);
+
+                // 更新 lastNodeId 为当前节点的 ID
+                lastNodeId = oaNode.getId();
+            }
+        }
+    }
+
+    @Async
+    public void updateGenerate(OaFormDefinition oaFormDefinition) {
+        Integer formId = oaFormDefinition.getId();
+        OaFlow flow = oaFlowMapper.selectOne(Wrappers.lambdaQuery(OaFlow.class).eq(OaFlow::getFormId, formId));
+        Integer flowId = flow.getId();
+
+        flow.setFlowName(oaFormDefinition.getFormName() + "的流程");
+        flow.setDescription(oaFormDefinition.getFormExplain());
+        flow.setUpdateBy(oaFormDefinition.getUpdateBy());
+        flow.setUpdateTime(oaFormDefinition.getUpdateTime());
+        oaFlowMapper.updateById(flow);
+
+        String flowInfo = oaFormDefinition.getFlowInfo();
+        JSONObject jsonObject = JSONObject.parseObject(flowInfo);
+        if (jsonObject.containsKey("node")) {
+            List<JSONObject> nodeList = jsonObject.getJSONArray("node").toJavaList(JSONObject.class);
+            // 用于记录上一个节点的 ID
+            Integer lastNodeId = null;
+
+            for (JSONObject node : nodeList) {
+                String nodeNo = node.getString("nodebh");
+                String nodeName = node.getString("nodeName");
+                Integer nodeType = node.getInteger("nodeType");
+                Integer nodeScope = node.getInteger("nodeScope");
+                String proposer = null;
+                Integer deptId2 = null;
+                Integer jobId = null;
+
+                switch (nodeScope) {
+                    case 0:
+                    case 2:
+                        proposer = node.getString("appointApprover");
+                        break;
+                    case 1:
+                        Long deptLeader = getDeptLeader();
+                        if (deptLeader != null) {
+                            proposer = deptLeader.toString();
+                        }
+                        break;
+                    case 3:
+                        deptId2 = node.getInteger("deptId");
+                        break;
+                    case 4:
+                        jobId = node.getInteger("jobId");
+                        break;
+                    default:
+                        throw new BusinessException("节点权限范围不正确");
+                }
+
+                OaNode oaNode = new OaNode();
+                oaNode.setNodeName(nodeName);
+                oaNode.setNodeType(nodeType);
+                oaNode.setNodeScope(nodeScope);
+                oaNode.setProposer(proposer);
+                oaNode.setDeptId(deptId2);
+                oaNode.setJobId(jobId);
+                oaNode.setParentId(lastNodeId);
+                oaNodeMapper.update(oaNode, new LambdaQueryWrapper<OaNode>().eq(OaNode::getFlowId, flowId).eq(OaNode::getNodeNo, nodeNo));
+                lastNodeId = oaNode.getId();
+            }
+        }
+    }
+
+    private Long getDeptLeader() {
+        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
+        Integer tenantId = SecurityUtils.getTenantId();
+
+        LambdaQueryWrapper<SysDept> deptLeaderQuery = new LambdaQueryWrapper<>();
+        deptLeaderQuery.eq(SysDept::getTenantId, tenantId)
+                .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<>();
+
+    }
+
+    // 根据单据类型获取流程信息
+    public OaFlow selectBySign(String sign) {
+        return oaFlowMapper.selectOne(Wrappers.lambdaQuery(OaFlow.class).eq(OaFlow::getDocType, sign));
+    }
+
+    // 根据流程ID获取节点信息
+    public OaNode selectByFlowId(Integer flowId) {
+        LambdaQueryWrapper<OaNode> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(OaNode::getFlowId, flowId)
+                .orderByAsc(OaNode::getId);
+        return oaNodeMapper.selectList(queryWrapper).get(0);
+    }
+
+}

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

@@ -1,3 +1,4 @@
+/*
 package com.usky.oa.service.utils;
 
 import com.usky.common.core.exception.BusinessException;
@@ -6,26 +7,30 @@ import org.dom4j.DocumentException;
 import org.dom4j.Element;
 import org.dom4j.io.SAXReader;
 
-import java.io.StringReader;
-
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.context.annotation.Configuration;
 
+*/
 /**
  *
  * @author fyc
  * @email yuchuan.fu@chinausky.com
  * @date 2025/1/23
- */
+ *//*
+
 @Slf4j
 @Configuration
 public class OaProcessAnalysis {
     public void processAnalysis(String xmlString) {
         try {
-            // 创建 SAXReader 对象
+            // 移除潜在的空格/BOM
+            xmlString = xmlString.trim().replaceFirst("^\uFEFF", "");
+            // 替换HTML实体
+            // xmlString = xmlString.replace("&#34;", "\"");
+
             SAXReader reader = new SAXReader();
             // 将 XML 字符串解析为 Document 对象
-            Document document = reader.read(new StringReader(xmlString));
+            Document document = reader.read(new java.io.StringReader(xmlString));
 
             // 获取根元素
             Element root = document.getRootElement();
@@ -51,3 +56,4 @@ public class OaProcessAnalysis {
         });
     }
 }
+*/

+ 13 - 4
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaSendMessageCenter.java

@@ -5,13 +5,17 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.usky.common.core.bean.ApiResult;
 import com.usky.common.core.exception.BusinessException;
+import com.usky.oa.domain.OaFormDefinition;
+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.SysUser;
 import lombok.extern.slf4j.Slf4j;
 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 java.util.*;
 import java.util.stream.Collectors;
@@ -23,7 +27,7 @@ import java.util.stream.Collectors;
  * @date 2025/1/9
  */
 @Slf4j
-@Configuration
+@Component
 public class OaSendMessageCenter {
 
     @Autowired
@@ -32,8 +36,11 @@ public class OaSendMessageCenter {
     @Autowired
     private SysUserMapper sysUserMapper;
 
+    @Autowired
+    private OaFormDefinitionMapper oaFormDefinitionMapper;
+
     private static final String INFO_TITLE = "审批提醒";
-    private static final String INFO_CONTENT = "的申请";
+    private static final String INFO_CONTENT = "待审批";
     private static final String INFO_APPROVE_FAIL = "审核不通过";
     private static final String INFO_APPROVE_SUCCESS = "审核通过";
     private static final int INFO_TYPE = 3;
@@ -48,7 +55,7 @@ public class OaSendMessageCenter {
      * @param isPass 是否通过(0:不通过,1:通过)
      */
     @Async
-    public void sendAsyncMessage(String username, Long submitterId, Integer id, List<Long> receivers, Integer isPass) {
+    public void sendAsyncMessage(String username, Long submitterId, Integer id, List<Long> receivers, Integer isPass, String sign) {
 
         log.info(username + "的申请开始发送消息中心-----------------------------------");
 
@@ -67,7 +74,9 @@ public class OaSendMessageCenter {
                 jsonObject.put("infoContent", nickName.getNickName() + INFO_APPROVE_SUCCESS);
                 break;
             default:
-                jsonObject.put("infoContent", nickName.getNickName() + INFO_CONTENT);
+                OaBuiltInDocument oaBuiltInDocument = OaBuiltInDocument.valueOf(sign);
+                String name = oaBuiltInDocument.getName();
+                jsonObject.put("infoContent", nickName.getNickName() + "的" + name + INFO_CONTENT);
         }
 
         jsonObject.put("infoType", INFO_TYPE);

+ 44 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/vo/OaApprovalGenerationRequestVO.java

@@ -0,0 +1,44 @@
+package com.usky.oa.service.vo;
+
+import lombok.Data;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/2/21
+ */
+@Data
+public class OaApprovalGenerationRequestVO {
+
+    // 表单标识
+    private String sign;
+
+    // 单据编号
+    private String docNo;
+
+    // 审批类型
+    private Integer type;
+
+    // 审批状态
+    private Integer approvalStatus;
+
+    // 审批意见
+    private String opinion;
+
+    // 审批人
+    private Long approvalUid;
+
+    // 发起人
+    private Integer proposer;
+
+    // 提交时间
+    private String submitDate;
+
+    // 部门id
+    private String deptId;
+
+    // 租户id
+    private String tenantId;
+
+}

+ 1 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/OaApprovalMapper.xml

@@ -19,6 +19,7 @@
         <result column="update_time" property="updateTime" />
         <result column="dept_id" property="deptId" />
         <result column="tenant_id" property="tenantId" />
+        <result column="node_id" property="nodeId" />
     </resultMap>
 
 </mapper>

+ 27 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/OaCgdDocumentMapper.xml

@@ -0,0 +1,27 @@
+<?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.usky.oa.mapper.OaCgdDocumentMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.OaCgdDocument">
+        <id column="id" property="id" />
+        <result column="form_id" property="formId" />
+        <result column="doc_no" property="docNo" />
+        <result column="proposer" property="proposer" />
+        <result column="doc_status" property="docStatus" />
+        <result column="purchase_details" property="purchaseDetails" />
+        <result column="reason" property="reason" />
+        <result column="supplier" property="supplier" />
+        <result column="arrival_time" property="arrivalTime" />
+        <result column="payment_method" property="paymentMethod" />
+        <result column="image" property="image" />
+        <result column="remarks" property="remarks" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="dept_id" property="deptId" />
+        <result column="tenant_id" property="tenantId" />
+    </resultMap>
+
+</mapper>

+ 27 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/OaFbdDocumentMapper.xml

@@ -0,0 +1,27 @@
+<?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.usky.oa.mapper.OaFbdDocumentMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.OaFbdDocument">
+        <id column="id" property="id" />
+        <result column="form_id" property="formId" />
+        <result column="doc_no" property="docNo" />
+        <result column="proposer" property="proposer" />
+        <result column="application_name" property="applicationName" />
+        <result column="doc_status" property="docStatus" />
+        <result column="publish_time" property="publishTime" />
+        <result column="publish_project" property="publishProject" />
+        <result column="project_type" property="projectType" />
+        <result column="online_function" property="onlineFunction" />
+        <result column="preparation" property="preparation" />
+        <result column="annex" property="annex" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="dept_id" property="deptId" />
+        <result column="tenant_id" property="tenantId" />
+    </resultMap>
+
+</mapper>

+ 20 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/OaFlowMapper.xml

@@ -0,0 +1,20 @@
+<?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.usky.oa.mapper.OaFlowMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.OaFlow">
+        <id column="id" property="id" />
+        <result column="flow_name" property="flowName" />
+        <result column="doc_type" property="docType" />
+        <result column="description" property="description" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="dept_id" property="deptId" />
+        <result column="tenant_id" property="tenantId" />
+        <result column="form_id" property="formId" />
+    </resultMap>
+
+</mapper>

+ 19 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/OaNodeMapper.xml

@@ -0,0 +1,19 @@
+<?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.usky.oa.mapper.OaNodeMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.OaNode">
+        <id column="id" property="id" />
+        <result column="flow_id" property="flowId" />
+        <result column="node_name" property="nodeName" />
+        <result column="parent_id" property="parentId" />
+        <result column="node_type" property="nodeType" />
+        <result column="node_scope" property="nodeScope" />
+        <result column="proposer" property="proposer" />
+        <result column="dept_id" property="deptId" />
+        <result column="job_id" property="jobId" />
+        <result column="node_no" property="nodeNo" />
+    </resultMap>
+
+</mapper>

+ 24 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/SysDeptMapper.xml

@@ -0,0 +1,24 @@
+<?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.usky.oa.mapper.SysDeptMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.SysDept">
+        <id column="dept_id" property="deptId" />
+        <result column="parent_id" property="parentId" />
+        <result column="ancestors" property="ancestors" />
+        <result column="dept_name" property="deptName" />
+        <result column="order_num" property="orderNum" />
+        <result column="leader" property="leader" />
+        <result column="phone" property="phone" />
+        <result column="email" property="email" />
+        <result column="status" property="status" />
+        <result column="del_flag" property="delFlag" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+        <result column="tenant_id" property="tenantId" />
+    </resultMap>
+
+</mapper>

+ 11 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/SysUserPostMapper.xml

@@ -0,0 +1,11 @@
+<?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.usky.oa.mapper.SysUserPostMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.SysUserPost">
+        <id column="user_id" property="userId" />
+        <result column="post_id" property="postId" />
+    </resultMap>
+
+</mapper>