소스 검색

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

hanzhengyi 3 달 전
부모
커밋
67fe7e995b
38개의 변경된 파일2410개의 추가작업 그리고 15개의 파일을 삭제
  1. 9 13
      service-oa/service-oa-biz/pom.xml
  2. 0 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/MybatisGeneratorUtils.java
  3. 0 2
      service-oa/service-oa-biz/src/main/java/com/usky/oa/ServiceOaApplication.java
  4. 108 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/MybatisGeneratorUtils.java
  5. 83 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaApprovalController.java
  6. 54 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaDocumentController.java
  7. 93 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaFormDefinitionController.java
  8. 44 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaJbdDocumentController.java
  9. 50 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaQjdDocumentController.java
  10. 110 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaApproval.java
  11. 86 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaDocument.java
  12. 135 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaFormDefinition.java
  13. 116 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaJbdDocument.java
  14. 119 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaQjdDocument.java
  15. 18 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaApprovalMapper.java
  16. 16 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaDocumentMapper.java
  17. 18 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaFormDefinitionMapper.java
  18. 18 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaJbdDocumentMapper.java
  19. 18 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/mapper/OaQjdDocumentMapper.java
  20. 27 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaApprovalService.java
  21. 50 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaDocumentService.java
  22. 72 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaFormDefinitionService.java
  23. 46 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaJbdDocumentService.java
  24. 46 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaQjdDocumentService.java
  25. 49 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/enums/OaBuiltInDocument.java
  26. 76 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaApprovalServiceImpl.java
  27. 96 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaDocumentServiceImpl.java
  28. 313 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaFormDefinitionServiceImpl.java
  29. 145 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaJbdDocumentServiceImpl.java
  30. 161 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaQjdDocumentServiceImpl.java
  31. 33 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaDefinitionDocumentInfo.java
  32. 54 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/vo/OaApprovalCountVO.java
  33. 19 0
      service-oa/service-oa-biz/src/main/java/com/usky/oa/service/vo/OaFormNameResponseVO.java
  34. 25 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/OaApprovalMapper.xml
  35. 21 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/OaDocumentMapper.xml
  36. 30 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/OaFormDefinitionMapper.xml
  37. 26 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/OaJbdDocumentMapper.xml
  38. 26 0
      service-oa/service-oa-biz/src/main/resources/mapper/oa/OaQjdDocumentMapper.xml

+ 9 - 13
service-oa/service-oa-biz/pom.xml

@@ -78,10 +78,7 @@
             <artifactId>weixin-java-mp</artifactId>
             <version>4.3.0</version>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-amqp</artifactId>
-        </dependency>
+
         <dependency>
             <groupId>com.usky</groupId>
             <artifactId>service-alarm-api</artifactId>
@@ -94,18 +91,17 @@
             <artifactId>ruoyi-common-core</artifactId>
         </dependency>
 
-        <!--钉钉-->
-        <!--获取企业accessToken(企业内部应用) 新版SDK-->
         <dependency>
-            <groupId>com.aliyun</groupId>
-            <artifactId>dingtalk</artifactId>
-            <version>2.1.34</version>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <version>1.18.22</version>
+            <scope>provided</scope>
         </dependency>
-        <!--旧版SDK-->
         <dependency>
-            <groupId>com.aliyun</groupId>
-            <artifactId>alibaba-dingtalk-service-sdk</artifactId>
-            <version>2.0.0</version>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+            <version>1.70</version>
+            <scope>compile</scope>
         </dependency>
 
     </dependencies>

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


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

@@ -3,7 +3,6 @@ import io.swagger.annotations.SwaggerDefinition;
 import org.mybatis.spring.annotation.MapperScan;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.amqp.rabbit.annotation.EnableRabbit;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.openfeign.EnableFeignClients;
@@ -24,7 +23,6 @@ import java.net.UnknownHostException;
 @MapperScan(value = "com.usky.oa.mapper")
 @ComponentScan("com.usky")
 @SpringBootApplication
-@EnableRabbit
 public class ServiceOaApplication
 {
     private static final Logger LOGGER = LoggerFactory.getLogger(ServiceOaApplication.class);

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

@@ -0,0 +1,108 @@
+package com.usky.oa.controller;// package com.usky.iot.controller;//package com.usky.dm.controller.web.business;//package com.usky.dm.controller.web;
+
+
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
+import com.baomidou.mybatisplus.generator.AutoGenerator;
+import com.baomidou.mybatisplus.generator.InjectionConfig;
+import com.baomidou.mybatisplus.generator.config.*;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author yq
+ * @date 2021/7/6 11:42
+ */
+public class MybatisGeneratorUtils {
+    public static void main(String[] args) {
+
+        shell("service-oa", "service-oa-biz");
+    }
+
+    private static void shell(String parentName, String model) {
+
+        AutoGenerator mpg = new AutoGenerator();
+        // 1、全局配置
+        GlobalConfig gc = new GlobalConfig();
+//        File file = new File(model);
+//        String path = file.getAbsolutePath();
+        String projectPath = System.getProperty("user.dir");
+        projectPath += "/" + parentName;
+        projectPath += "/" + model;
+        gc.setOutputDir(projectPath + "/src/main/java");  // 生成路径(一般都是生成在此项目的src/main/java下面)
+        // 修改为自己的名字
+        gc.setAuthor("fu"); // 设置作者
+        gc.setOpen(false);
+        gc.setFileOverride(true); // 第二次生成会把第一次生成的覆盖掉
+        gc.setServiceName("%sService"); // 生成的service接口名字首字母是否为I,这样设置就没有
+        gc.setBaseResultMap(true); // 生成resultMap
+        mpg.setGlobalConfig(gc);
+
+        // 2、数据源配置
+        // 修改数据源
+        DataSourceConfig dsc = new DataSourceConfig();
+        dsc.setUrl("jdbc:mysql://192.168.10.165:3306/usky-cloud?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
+        dsc.setDriverName("com.mysql.jdbc.Driver");
+        dsc.setUsername("root");
+        dsc.setPassword("yt123456");
+        mpg.setDataSource(dsc);
+
+        // 3、包配置
+        PackageConfig pc = new PackageConfig();
+        pc.setParent("com.usky.oa");
+        pc.setController("controller.web");
+        pc.setEntity("domain");
+        pc.setMapper("mapper");
+        pc.setService("service");
+        pc.setServiceImpl("service.impl");
+//        pc.setXml("mapper.demo");
+        // pc.setModuleName("test");
+        mpg.setPackageInfo(pc);
+
+        // 4、策略配置
+        StrategyConfig strategy = new StrategyConfig();
+        strategy.setNaming(NamingStrategy.underline_to_camel);
+        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
+        strategy.setSuperMapperClass("com.usky.common.mybatis.core.CrudMapper");
+        strategy.setSuperServiceClass("com.usky.common.mybatis.core.CrudService");
+        strategy.setSuperServiceImplClass("com.usky.common.mybatis.core.AbstractCrudService");
+        // strategy.setTablePrefix("t_"); // 表名前缀
+        strategy.setEntityLombokModel(true); // 使用lombok
+        // 修改自己想要生成的表
+        strategy.setInclude("oa_jb_document");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
+        mpg.setStrategy(strategy);
+
+        // 关闭默认 xml 生成,调整生成 至 根目录
+        // 修改对应的模块名称
+        TemplateConfig tc = new TemplateConfig();
+        // 自定义配置
+        InjectionConfig cfg = new InjectionConfig() {
+            @Override
+            public void initMap() {
+                // to do nothing
+            }
+        };
+        // 如果模板引擎是 velocity
+        String templatePath = "/templates/mapper.xml.vm";
+        // 自定义输出配置
+        List<FileOutConfig> focList = new ArrayList<>();
+        // 自定义配置会被优先输出
+        String finalProjectPath = projectPath;
+        focList.add(new FileOutConfig(templatePath) {
+            @Override
+            public String outputFile(TableInfo tableInfo) {
+                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
+                return finalProjectPath + "/src/main/resources/mapper/oa" + "/"
+                        + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
+            }
+        });
+        cfg.setFileOutConfigList(focList);
+        mpg.setCfg(cfg);
+        tc.setXml(null);
+        mpg.setTemplate(tc);
+        // 5、执行
+        mpg.execute();
+    }
+}

+ 83 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaApprovalController.java

@@ -0,0 +1,83 @@
+package com.usky.oa.controller.web;
+
+
+import com.usky.oa.domain.OaDocument;
+import com.usky.oa.service.OaApprovalService;
+import com.usky.oa.service.vo.OaApprovalCountVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import org.springframework.stereotype.Controller;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 审批表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@RestController
+@RequestMapping("/oaApproval")
+public class OaApprovalController {
+
+    @Autowired
+    private OaApprovalService oaApprovalService;
+
+    /**
+     * @description: 新增审批
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/30 16:18
+     * @param: []
+     * @return: void
+     **/
+    @PostMapping("/add")
+    public void addApproval() {
+
+    }
+
+    /**
+     * @description: 修改审批
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/30 16:19
+     * @param: []
+     * @return: void
+     **/
+    @PostMapping("/update")
+    public void updateApproval() {
+
+    }
+
+    /**
+     * @description: 删除审批
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/30 16:19
+     * @param: []
+     * @return: void
+     **/
+    @DeleteMapping("/del")
+    public void delApproval() {
+
+    }
+
+    /**
+     * @description: 获取审批数量
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/30 16:19
+     * @param: []
+     * @return: void
+     **/
+    @GetMapping("/approvalCount")
+    public OaApprovalCountVO approvalCount() {
+        return oaApprovalService.approvalCount();
+    }
+
+
+}
+

+ 54 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaDocumentController.java

@@ -0,0 +1,54 @@
+package com.usky.oa.controller.web;
+
+
+import com.usky.common.core.bean.CommonPage;
+import com.usky.oa.domain.OaDocument;
+import com.usky.oa.service.OaDocumentService;
+import com.usky.oa.service.vo.OaApprovalCountVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import org.springframework.stereotype.Controller;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 单据总表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-26
+ */
+@RestController
+@RequestMapping("/oaDocument")
+public class OaDocumentController {
+
+    @Autowired
+    private OaDocumentService oaDocumentService;
+
+    @PostMapping("/myApplication")
+    public CommonPage<OaDocument> myApplication(@RequestParam(value = "docNo", required = false) String docNo,
+                                                @RequestParam(value = "type", required = false) String type,
+                                                @RequestParam(value = "status", required = false) Integer status,
+                                                @RequestParam(value = "startTime", required = false) String startTime,
+                                                @RequestParam(value = "endTime", required = false) String endTime,
+                                                @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+                                                @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
+        return oaDocumentService.myApplication(docNo, type, status, startTime, endTime, pageNum, pageSize);
+    }
+
+    @GetMapping("/documentDetails")
+    public Object documentDetails(@RequestParam(value = "docNo") String docNo,
+                                  @RequestParam(value = "type") String type) {
+        return oaDocumentService.documentDetails(docNo, type);
+    }
+
+    @DeleteMapping("/delDocument")
+    public void delDocument(@RequestParam(value = "type") String type,
+                            @RequestParam(value = "docNo") String docNo) {
+        oaDocumentService.delDocument(type, docNo);
+    }
+
+}
+

+ 93 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaFormDefinitionController.java

@@ -0,0 +1,93 @@
+package com.usky.oa.controller.web;
+
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
+import com.usky.oa.domain.OaFormDefinition;
+import com.usky.oa.service.OaFormDefinitionService;
+import com.usky.oa.service.enums.OaBuiltInDocument;
+import com.usky.oa.service.utils.OaDefinitionDocumentInfo;
+import com.usky.oa.service.vo.OaFormNameResponseVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 表单定义表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@RestController
+@RequestMapping("/oaFormDefinition")
+public class OaFormDefinitionController {
+
+    @Autowired
+    private OaFormDefinitionService oaFormDefinitionService;
+
+    // 新增、修改表单
+    @Log(title = "新增/修改表单", businessType = BusinessType.INSERT)
+    @PostMapping("/addForm")
+    public void addForm(@RequestBody OaFormDefinition oaFormDefinition) {
+        oaFormDefinitionService.addForm(oaFormDefinition);
+    }
+
+    // 表单状态修改(启用、停用)
+    @Log(title = "启停用表单", businessType = BusinessType.UPDATE)
+    @GetMapping("/updateStatus")
+    public void updateStatus(@RequestParam(value = "formId") Integer formId,
+                             @RequestParam(value = "formStatus") Integer formStatus) {
+        oaFormDefinitionService.validUpdateStatus(formId, formStatus);
+    }
+
+    // 删除表单
+    @Log(title = "删除表单", businessType = BusinessType.DELETE)
+    @DeleteMapping("{delForm}")
+    public void delForm(@RequestParam Integer formId) {
+        oaFormDefinitionService.delForm(formId);
+    }
+
+    // 表单管理-分页
+    @GetMapping("/manageForm")
+    public ApiResult<CommonPage<OaFormDefinition>> manageForm(@RequestParam(value = "formName", required = false) String formName,
+                                                              @RequestParam(value = "formId", required = false) Integer formId,
+                                                              @RequestParam(value = "formGroup", required = false) Integer formGroup,
+                                                              @RequestParam(value = "formStatus", required = false) Integer formStatus,
+                                                              @RequestParam(value = "pageNum", required = false, defaultValue = "1") Integer pageNum,
+                                                              @RequestParam(value = "pageSize", required = false, defaultValue = "10") Integer pageSize) {
+        return ApiResult.success(oaFormDefinitionService.pageList(formId, formName, formGroup, formStatus, pageNum, pageSize));
+    }
+
+    // 内置单据枚举列表
+    @GetMapping("/builtInFormEnums")
+    public List<OaDefinitionDocumentInfo> getBuiltInDocumentList(String sign, String name) {
+        return Arrays.stream(OaBuiltInDocument.values())
+                .map(doc -> new OaDefinitionDocumentInfo(doc.getSign(), doc.getName()))
+                .filter(docInfo -> (sign == null || docInfo.getSign().equals(sign))
+                        && (name == null || docInfo.getName().contains(name)))
+                .collect(Collectors.toList());
+    }
+
+    // 我的申请-依据权限展示表单
+    @GetMapping("/myForm")
+    public List<OaFormDefinition> myForm(String formSign) {
+        return oaFormDefinitionService.selectByScope(formSign);
+    }
+
+    // 表单名称列表
+    @GetMapping("/getFormName")
+    public List<OaFormNameResponseVO> getFormName() {
+        return oaFormDefinitionService.getFormName();
+    }
+
+
+}
+

+ 44 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/controller/web/OaJbdDocumentController.java

@@ -0,0 +1,44 @@
+package com.usky.oa.controller.web;
+
+
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
+import com.usky.oa.domain.OaJbdDocument;
+import com.usky.oa.service.OaJbdDocumentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * <p>
+ * 加班单据表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2025-01-02
+ */
+@RestController
+@RequestMapping("/oaJbDocument")
+public class OaJbdDocumentController {
+
+    @Autowired
+    private OaJbdDocumentService oaJbdDocumentService;
+
+    @Log(title = "新增加班单", businessType = BusinessType.INSERT)
+    @PostMapping("/add")
+    public void addJbDocument(@RequestBody OaJbdDocument oaJbdDocument) {
+        oaJbdDocumentService.add(oaJbdDocument);
+    }
+
+    @Log(title = "更新加班单", businessType = BusinessType.UPDATE)
+    @PostMapping("/update")
+    public void updateJbDocument(OaJbdDocument oaJbdDocument) {
+        oaJbdDocumentService.update(oaJbdDocument);
+    }
+
+    @Log(title = "删除加班单", businessType = BusinessType.DELETE)
+    @DeleteMapping("/del/{docNo}")
+    public void delJbDocument(@PathVariable String docNo) {
+        oaJbdDocumentService.delByDocNo(docNo);
+    }
+
+}

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

@@ -0,0 +1,50 @@
+package com.usky.oa.controller.web;
+
+
+import com.usky.common.core.bean.ApiResult;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
+import com.usky.oa.domain.OaQjdDocument;
+import com.usky.oa.service.OaQjdDocumentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * <p>
+ * 请假单据表 前端控制器
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@RestController
+@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);
+    }
+
+}
+

+ 110 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaApproval.java

@@ -0,0 +1,110 @@
+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 com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 审批表
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OaApproval implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 审批表主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 单据id
+     */
+    private Integer docId;
+
+    /**
+     * 流程id
+     */
+    private Integer flowId;
+
+    /**
+     * 审批节点id
+     */
+    private Integer nodeId;
+
+    /**
+     * 审批人id
+     */
+    private Long approvalUid;
+
+    /**
+     * 审批类型(0:审批,1:知会)
+     */
+    private Integer type;
+
+    /**
+     * 审批状态(0:审批中, 1:审批通过, 2:审批不通过, 3:撤销)
+     */
+    private Integer status;
+
+    /**
+     * 审批意见
+     */
+    private String opinion;
+
+    /**
+     * 提交时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime submitDate;
+
+    /**
+     * 审批时间
+     */
+    private LocalDateTime approvalDate;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门id
+     */
+    private Long deptId;
+
+    /**
+     * 租户id
+     */
+    private Integer tenantId;
+
+
+}

+ 86 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaDocument.java

@@ -0,0 +1,86 @@
+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 2024-12-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OaDocument implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 单据总表主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 表单定义表主键
+     */
+    private Integer formId;
+
+    /**
+     * 表单标识
+     */
+    private String type;
+
+    /**
+     * 单据编号
+     */
+    private String docNo;
+
+    /**
+     * 申请人id
+     */
+    private Long proposer;
+
+    /**
+     * 单据状态 (0:未提交可以修改,1:审批中,2:审批通过,3:审批不通过)
+     */
+    private Integer status;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门id
+     */
+    private Long deptId;
+
+    /**
+     * 租户id
+     */
+    private Integer tenantId;
+
+
+}

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

@@ -0,0 +1,135 @@
+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 com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 表单定义表
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OaFormDefinition implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 表单定义表主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 表单名称
+     */
+    private String formName;
+
+    /**
+     * 所在分组
+     */
+    private Integer formGroup;
+
+    /**
+     * 表单说明
+     */
+    private String formExplain;
+
+    /**
+     * 单据类型(0:内置表单据;1:自定义表单据)
+     */
+    private Integer formType;
+
+    /**
+     * 表单设计器配置数据
+     */
+    private String fieldInfo;
+
+    /**
+     * 流程设计器配置数据
+     */
+    private String flowInfo;
+
+    /**
+     * 表单版本
+     */
+    private Integer formVersion;
+
+    /**
+     * 表单标识(必须字母,小于4位)
+     */
+    private String formSign;
+
+    /**
+     * 表单图标
+     */
+    private String formImage;
+
+    /**
+     * 表单权限范围(0:指定部门可见;1:全员可见;2:指定人可见)
+     */
+    private Integer formScope;
+
+    /**
+     * 表单状态(1:启用;2:停用)
+     */
+    private Integer formStatus;
+
+    /*
+     * 单据编号
+     */
+    //private Integer docNo;
+
+    /**
+     * 可见部门id集合
+     */
+    private String deptIds;
+
+    /**
+     * 可见人id集合
+     */
+    private String userIds;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    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/OaJbdDocument.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 com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 加班单据表
+ * </p>
+ *
+ * @author fu
+ * @since 2025-01-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OaJbdDocument 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:审批不通过,4:撤销)
+     */
+    private Integer status;
+
+    /**
+     * 开始日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime startTime;
+
+    /**
+     * 结束日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime endTime;
+
+    /**
+     * 加班时长(小时)
+     */
+    private Integer duration;
+
+    /**
+     * 核算方式(默认 0:申请调休)
+     */
+    private Integer accountingMethod;
+
+    /**
+     * 加班原因
+     */
+    private String reason;
+
+    /**
+     * 图片URL(打卡记录及日报)
+     */
+    private String image;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门id
+     */
+    private Long deptId;
+
+    /**
+     * 租户id
+     */
+    private Integer tenantId;
+
+
+}

+ 119 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/domain/OaQjdDocument.java

@@ -0,0 +1,119 @@
+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 com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 请假单据表
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+public class OaQjdDocument implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 请假单据表主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 表单id
+     */
+    private Integer formId;
+
+    /**
+     * 1:事假,2:病假(后续附上病假单、挂号单、病历册),3:年假(连续在我司工作一年以上的,才可享受),4:调休(有已获批准的加班流程),
+     * 5:婚假(附上结婚证),6:产假(后续附上出生证明),7:陪产假(后续附上出生证明),8:丧假(父母、配偶、子女死亡可申请3天),9:工伤假,
+     * 10:孕检假(后续附上挂号单、病例册)
+     */
+    private String type;
+
+    /**
+     * 单据编号
+     */
+    private String docNo;
+
+    /**
+     * 申请人id
+     */
+    private Long proposer;
+
+    /**
+     * 单据状态 (0:未提交可以修改,1:审批中,2:审批通过,3:审批不通过,4:撤销)
+     */
+    private Integer status;
+
+    /**
+     * 开始日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime startTime;
+
+    /**
+     * 结束日期
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime endTime;
+
+    /**
+     * 请假时长(小时)
+     */
+    private Integer duration;
+
+    /**
+     * 请假事由
+     */
+    private String reason;
+
+    /**
+     * 图片URL
+     */
+    private String image;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;
+
+    /**
+     * 部门id
+     */
+    private Long deptId;
+
+    /**
+     * 租户id
+     */
+    private Integer tenantId;
+
+
+}

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

@@ -0,0 +1,18 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.OaApproval;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 审批表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@Repository
+public interface OaApprovalMapper extends CrudMapper<OaApproval> {
+
+}

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

@@ -0,0 +1,16 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.OaDocument;
+import com.usky.common.mybatis.core.CrudMapper;
+
+/**
+ * <p>
+ * 单据总表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-26
+ */
+public interface OaDocumentMapper extends CrudMapper<OaDocument> {
+
+}

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

@@ -0,0 +1,18 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.OaFormDefinition;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 表单定义表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@Repository
+public interface OaFormDefinitionMapper extends CrudMapper<OaFormDefinition> {
+
+}

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

@@ -0,0 +1,18 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.OaJbdDocument;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 加班单据表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2025-01-02
+ */
+@Repository
+public interface OaJbdDocumentMapper extends CrudMapper<OaJbdDocument> {
+
+}

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

@@ -0,0 +1,18 @@
+package com.usky.oa.mapper;
+
+import com.usky.oa.domain.OaQjdDocument;
+import com.usky.common.mybatis.core.CrudMapper;
+import org.springframework.stereotype.Repository;
+
+/**
+ * <p>
+ * 请假单据表 Mapper 接口
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@Repository
+public interface OaQjdDocumentMapper extends CrudMapper<OaQjdDocument> {
+
+}

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

@@ -0,0 +1,27 @@
+package com.usky.oa.service;
+
+import com.usky.oa.domain.OaApproval;
+import com.usky.common.mybatis.core.CrudService;
+import com.usky.oa.domain.OaDocument;
+import com.usky.oa.service.vo.OaApprovalCountVO;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 审批表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+public interface OaApprovalService extends CrudService<OaApproval> {
+
+    /**
+     * 审批统计
+     * @return OaApprovalCountVO
+     */
+    OaApprovalCountVO approvalCount();
+
+}

+ 50 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaDocumentService.java

@@ -0,0 +1,50 @@
+package com.usky.oa.service;
+
+import com.usky.common.core.bean.CommonPage;
+import com.usky.oa.domain.OaDocument;
+import com.usky.common.mybatis.core.CrudService;
+import com.usky.oa.service.vo.OaApprovalCountVO;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 单据总表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-26
+ */
+public interface OaDocumentService extends CrudService<OaDocument> {
+
+    /**
+     * @description: 我的申请
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/31 13:17
+     * @param: []
+     * @return: java.util.List<com.usky.oa.domain.OaDocument>
+     **/
+    CommonPage<OaDocument> myApplication(String docNo, String type, Integer status, String startTime, String endTime, Integer pageNum, Integer pageSize);
+
+    /**
+     * @description: 单据详情
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/31 13:17
+     * @param: []
+     * @return: java.util.List<com.usky.oa.domain.OaDocument>
+     **/
+    Object documentDetails(String docNo, String type);
+
+    /**
+     * @description: 删除单据
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/31 13:17
+     * @param: []
+     * @return: java.util.List<com.usky.oa.domain.OaDocument>
+     **/
+    void delDocument(String type, String docNo);
+
+}

+ 72 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaFormDefinitionService.java

@@ -0,0 +1,72 @@
+package com.usky.oa.service;
+
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.log.annotation.Log;
+import com.usky.common.log.enums.BusinessType;
+import com.usky.oa.domain.OaFormDefinition;
+import com.usky.common.mybatis.core.CrudService;
+import com.usky.oa.service.vo.OaFormNameResponseVO;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 表单定义表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+public interface OaFormDefinitionService extends CrudService<OaFormDefinition> {
+
+    /**
+     * 新增/更新 表单
+     * @param oaFormDefinition
+     */
+    void addForm(OaFormDefinition oaFormDefinition);
+
+    /**
+     * 删除表单
+     * @param formId
+     */
+    void delForm(Integer formId);
+
+    /**
+     * 分页查询表单列表
+     * @param formName 表单名称
+     * @param pageNum 页码
+     * @param pageSize 页大小
+     * @return
+     */
+    CommonPage<OaFormDefinition> pageList(Integer formId, String formName, Integer formGroup, Integer formStatus, Integer pageNum, Integer pageSize);
+
+    /**
+     * 更新表单状态并校验
+     * @param formId
+     * @param formStatus
+     */
+    void validUpdateStatus(Integer formId, Integer formStatus);
+
+    /**
+     * @description: 根据表单标识查询表单信息-数据权限
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/1/3 14:07
+     * @param: [formSign]
+     * @return: java.util.List<com.usky.oa.domain.OaFormDefinition>
+     **/
+    List<OaFormDefinition> selectByScope(String formSign);
+
+    /**
+     * @description: 获取表单名称列表
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/1/3 14:07
+     * @param: []
+     * @return: java.util.Map<java.lang.Integer,java.lang.String>
+     **/
+    List<OaFormNameResponseVO> getFormName();
+
+}

+ 46 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaJbdDocumentService.java

@@ -0,0 +1,46 @@
+package com.usky.oa.service;
+
+import com.usky.oa.domain.OaJbdDocument;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * 加班单据表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2025-01-02
+ */
+public interface OaJbdDocumentService extends CrudService<OaJbdDocument> {
+
+    /**
+     * @description: 新增加班单据
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/1/2 14:00
+     * @param: [oaJbDocument]
+     * @return: void
+     **/
+    void add(OaJbdDocument oaJbdDocument);
+
+    /**
+     * @description: 更新加班单据
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/1/2 15:43
+     * @param: [oaJbDocument]
+     * @return: void
+     **/
+    void update(OaJbdDocument oaJbdDocument);
+
+    /**
+     * @description: 删除加班单据
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/1/2 15:43
+     * @param: [id]
+     * @return: void
+     **/
+    void delByDocNo(String docNo);
+
+}

+ 46 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/OaQjdDocumentService.java

@@ -0,0 +1,46 @@
+package com.usky.oa.service;
+
+import com.usky.oa.domain.OaQjdDocument;
+import com.usky.common.mybatis.core.CrudService;
+
+/**
+ * <p>
+ * 请假单据表 服务类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+
+public interface OaQjdDocumentService extends CrudService<OaQjdDocument> {
+
+    /**
+     * @description: 新增请假单据
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/26 14:15
+     * @param: [oaQjDocument]
+     * @return: void
+     **/
+    void addQjDocument(OaQjdDocument oaQjdDocument);
+
+    /**
+     * @description: 修改请假单据
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/26 14:15
+     * @param: [oaQjDocument]
+     * @return: void
+     **/
+    void updateQjDocument(OaQjdDocument oaQjdDocument);
+
+    /**
+     * @description: 删除请假单据
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/26 15:20
+     * @param: [id]
+     * @return: void
+     **/
+    void delQjDocument(String docNo);
+}

+ 49 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/enums/OaBuiltInDocument.java

@@ -0,0 +1,49 @@
+package com.usky.oa.service.enums;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2024/12/25
+ */
+public enum OaBuiltInDocument {
+
+    QJD("QJD", "请假单"),
+    JBD("JBD", "加班单");
+    // LZD("LZ", "离职单"),
+    // CCD("CC", "出差单"),
+    // WCD("WC", "外出单"),
+    // BHSQ("BHSQ", "项目编号申请单"),
+    // MPD("MPYS", "名片印刷单"),
+    // JPD("DJP", "机票单"),
+    // GDZC("ZCLY", "固定资产领用单"),
+    // ZZJY("ZZJY", "印章资质借用单"),
+    // HTJY("HTJY", "合同借用单"),
+    // //XMCG("XMCG", "项目采购表单");
+    // // 项目采购;固定资产采购;行政(特殊)用品采购
+    // CGD("CGSQ", "采购单"),
+    // //XZCG("XZCG", "行政(特殊)用品采购表单"),
+    // YYD("YYSQ", "用印申请单");
+
+    private final String sign;
+    private final String name;
+
+    OaBuiltInDocument(String sign, String name) {
+        this.sign = sign;
+        this.name = name;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+}

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

@@ -0,0 +1,76 @@
+package com.usky.oa.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.oa.domain.OaApproval;
+import com.usky.oa.domain.OaDocument;
+import com.usky.oa.mapper.OaApprovalMapper;
+import com.usky.oa.service.OaApprovalService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.oa.service.vo.OaApprovalCountVO;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * 审批表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@Service
+public class OaApprovalServiceImpl extends AbstractCrudService<OaApprovalMapper, OaApproval> implements OaApprovalService {
+
+    @Autowired
+    private OaApprovalMapper oaApprovalMapper;
+
+    @Override
+    public OaApprovalCountVO approvalCount() {
+        Long userId = SecurityUtils.getUserId();
+        String username = SecurityUtils.getUsername();
+        Integer tenantId = SecurityUtils.getTenantId();
+
+        OaApprovalCountVO oaApprovalCountVO = new OaApprovalCountVO();
+        oaApprovalCountVO.setPendingSum(getPendingSum().size());
+
+        LambdaQueryWrapper<OaApproval> queryWrapper1 = Wrappers.lambdaQuery();
+        queryWrapper1.eq(OaApproval::getTenantId, tenantId)
+                .eq(OaApproval::getApprovalUid, userId)
+                .and(wrapper -> wrapper
+                        .eq(OaApproval::getStatus, 1)
+                        .or()
+                        .eq(OaApproval::getStatus, 2));
+        Integer count1 = oaApprovalMapper.selectCount(queryWrapper1);
+        oaApprovalCountVO.setAlreadySum(count1);
+
+        LambdaQueryWrapper<OaApproval> queryWrapper2 = Wrappers.lambdaQuery();
+        queryWrapper2.eq(OaApproval::getTenantId, tenantId).eq(OaApproval::getCreateBy, username);
+        Integer count2 = oaApprovalMapper.selectCount(queryWrapper2);
+        oaApprovalCountVO.setMyInitiated(count2);
+
+        LambdaQueryWrapper<OaApproval> queryWrapper3 = Wrappers.lambdaQuery();
+        queryWrapper3.eq(OaApproval::getTenantId, tenantId)
+                .eq(OaApproval::getApprovalUid, userId);
+        Integer count3 = oaApprovalMapper.selectCount(queryWrapper3);
+        oaApprovalCountVO.setMyReceived(count3);
+
+        return oaApprovalCountVO;
+    }
+
+    private List<OaApproval> getPendingSum(){
+        LambdaQueryWrapper<OaApproval> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(OaApproval::getTenantId, SecurityUtils.getTenantId())
+                .eq(OaApproval::getApprovalUid, SecurityUtils.getUserId())
+                .eq(OaApproval::getStatus, 0);
+        List<OaApproval> oaApprovals = oaApprovalMapper.selectList(queryWrapper);
+        return oaApprovals == null ? Collections.emptyList() : oaApprovals;
+    }
+
+}

+ 96 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaDocumentServiceImpl.java

@@ -0,0 +1,96 @@
+package com.usky.oa.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.usky.common.core.bean.CommonPage;
+import com.usky.common.security.utils.SecurityUtils;
+import com.usky.oa.domain.OaDocument;
+import com.usky.oa.domain.OaJbdDocument;
+import com.usky.oa.domain.OaQjdDocument;
+import com.usky.oa.mapper.OaDocumentMapper;
+import com.usky.oa.mapper.OaJbdDocumentMapper;
+import com.usky.oa.mapper.OaQjdDocumentMapper;
+import com.usky.oa.service.OaDocumentService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.oa.service.vo.OaApprovalCountVO;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * <p>
+ * 单据总表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-26
+ */
+@Service
+public class OaDocumentServiceImpl extends AbstractCrudService<OaDocumentMapper, OaDocument> implements OaDocumentService {
+
+    @Autowired
+    private OaDocumentMapper oaDocumentMapper;
+
+    @Autowired
+    private OaQjdDocumentMapper oaQjdDocumentMapper;
+
+    @Autowired
+    private OaJbdDocumentMapper oaJbdDocumentMapper;
+
+    // 我的申请
+    @Override
+    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();
+
+        LambdaQueryWrapper<OaDocument> wrapper = Wrappers.lambdaQuery();
+        wrapper.like(StringUtils.isNotBlank(docNo), OaDocument::getDocNo, docNo)
+                .eq(StringUtils.isNotBlank(type), OaDocument::getType, type)
+                .eq(status != null, OaDocument::getStatus, status)
+                .between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), OaDocument::getCreateTime, startTime, endTime);
+        List<OaDocument> oaDocuments = oaDocumentMapper.selectList(wrapper);
+        if (oaDocuments.isEmpty()) {
+            return null;
+        } else {
+            wrapper.eq(OaDocument::getTenantId, tenantId).eq(OaDocument::getProposer, userId).orderByDesc(OaDocument::getId);
+            ;
+        }
+        return ToCommonPage(page(new Page<>(pageNum, pageSize), wrapper));
+    }
+
+    @Override
+    public Object documentDetails(String docNo, String type) {
+
+        Object documentDetails = null;
+        switch (type) {
+            case "QJD":
+                documentDetails = oaQjdDocumentMapper.selectOne(Wrappers.lambdaQuery(OaQjdDocument.class).eq(OaQjdDocument::getDocNo, docNo));
+                break;
+            case "JBD":
+                documentDetails = oaJbdDocumentMapper.selectOne(Wrappers.lambdaQuery(OaJbdDocument.class).eq(OaJbdDocument::getDocNo, docNo));
+                break;
+        }
+
+        return documentDetails;
+    }
+
+    @Override
+    public void delDocument(String type, String docNo) {
+
+        switch (type) {
+            case "QJD":
+                oaQjdDocumentMapper.delete(Wrappers.lambdaQuery(OaQjdDocument.class).eq(OaQjdDocument::getDocNo, docNo));
+                break;
+            case "JBD":
+                oaJbdDocumentMapper.delete(Wrappers.lambdaQuery(OaJbdDocument.class).eq(OaJbdDocument::getDocNo, docNo));
+                break;
+        }
+        oaDocumentMapper.delete(Wrappers.lambdaQuery(OaDocument.class).eq(OaDocument::getDocNo, docNo));
+    }
+
+}

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

@@ -0,0 +1,313 @@
+package com.usky.oa.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+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.service.OaFormDefinitionService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.oa.service.vo.OaFormNameResponseVO;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 表单定义表 服务实现类
+ * </p>
+ *
+ * @author fu
+ * @since 2024-12-10
+ */
+@Service
+public class OaFormDefinitionServiceImpl extends AbstractCrudService<OaFormDefinitionMapper, OaFormDefinition> implements OaFormDefinitionService {
+
+    @Autowired
+    private OaFormDefinitionMapper oaFormDefinitionMapper;
+
+    @Autowired
+    private OaDocumentMapper oaDocumentMapper;
+
+    /**
+     * 新增/更新 表单
+     * 此方法负责验证表单定义的合法性,包括表单名称和标识的唯一性、长度限制,并最终保存合法的表单定义
+     * @param oaFormDefinition 表单定义对象,包含表单的详细信息
+     * @throws BusinessException 当表单名称或标识不符合规范或已存在时抛出
+     */
+    @Override
+    public void addForm(OaFormDefinition oaFormDefinition) {
+
+        String formName = oaFormDefinition.getFormName();
+        String formSign = oaFormDefinition.getFormSign();
+        String formExplain = oaFormDefinition.getFormExplain();
+        // 判断 表单名称、标识、说明 是否为空或超长
+        validateFormProperties(formName, formSign, formExplain);
+
+        // 判断 表单分组 是否为空、有效
+        isValidFormGroup(oaFormDefinition.getFormGroup());
+
+        if (Objects.isNull(oaFormDefinition.getFormType())) {
+            throw new BusinessException("表单字段信息不能为空");
+        } else if (oaFormDefinition.getFormType() < 0 || oaFormDefinition.getFormType() > 1) {
+            throw new BusinessException("表单类型不正确");
+        }
+
+        // 判断 表单可见范围 是否为空、有效
+        validFromScope(oaFormDefinition);
+
+        // 获取用户基本信息
+        Long userId = SecurityUtils.getUserId();
+        Integer tenantId = SecurityUtils.getTenantId();
+        String username = SecurityUtils.getUsername();
+        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
+        LocalDateTime now = LocalDateTime.now();
+
+        // 判断表单是新增或者修改
+        if (oaFormDefinition.getId() == null) {
+            // BeanUtils.copyBeanProp(oaFormDefinition, oaFormDefinition);
+            // 判断表单名称和标识是否重复
+            selectByNameOrSign(formName, formSign);
+
+            oaFormDefinition.setCreateBy(username);
+            oaFormDefinition.setDeptId(deptId);
+            oaFormDefinition.setTenantId(tenantId);
+            oaFormDefinition.setCreateTime(now);
+            oaFormDefinition.setFormVersion(1);
+            oaFormDefinition.setFormStatus(2);
+            oaFormDefinitionMapper.insert(oaFormDefinition);
+        } else {
+            oaFormDefinition.setUpdateBy(username);
+            oaFormDefinition.setUpdateTime(now);
+
+            OaFormDefinition oaFormDefinition1 = oaFormDefinitionMapper.selectById(oaFormDefinition.getId());
+            // 判断表单版本号是否需要更新
+            if (versionUpdateValid(oaFormDefinition)) {
+                oaFormDefinition.setFormVersion(oaFormDefinition1.getFormVersion() + 1);
+            }
+
+            oaFormDefinitionMapper.updateById(oaFormDefinition);
+        }
+    }
+
+    /**
+     * 删除表单
+     * @param formId 表单ID,用于删除特定的表单定义
+     */
+    @Override
+    public void delForm(Integer formId) {
+        if (formId > 0) {
+            OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectById(formId);
+            if (oaFormDefinition == null) {
+                throw new BusinessException("表单不存在!");
+            }
+            if (!validDelete(formId).isEmpty()) {
+                throw new BusinessException("当前表单下已生成单据,不可删除!");
+            }
+            oaFormDefinitionMapper.deleteById(oaFormDefinition);
+        } else {
+            throw new BusinessException("表单ID不能为空或者小于0");
+        }
+    }
+
+    // 判断表单下是否存在已生成单据
+    private List<OaDocument> validDelete(Integer formId) {
+        LambdaQueryWrapper<OaDocument> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(OaDocument::getFormId, formId);
+        return oaDocumentMapper.selectList(queryWrapper);
+    }
+
+
+    // 表单管理-分页查询
+    @Override
+    public CommonPage<OaFormDefinition> pageList(Integer formId, String formName, Integer formGroup, Integer formStatus, Integer pageNum, Integer pageSize) {
+        IPage<OaFormDefinition> page = new Page<>(pageNum, pageSize);
+        LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(formId != null, OaFormDefinition::getId, formId)
+                .like(StringUtils.isNotBlank(formName), OaFormDefinition::getFormName, formName)
+                .eq(formGroup != null, OaFormDefinition::getFormGroup, formGroup)
+                .eq(formStatus != null, OaFormDefinition::getFormStatus, formStatus)
+                .orderByDesc(OaFormDefinition::getId)
+                // 数据权限控制
+                .apply(Objects.nonNull(DataScopeContextHolder.getDataScopeSql()), DataScopeContextHolder.getDataScopeSql());
+        return ToCommonPage(oaFormDefinitionMapper.selectPage(page, queryWrapper));
+    }
+
+    // 表单管理-修改表单状态
+    @Override
+    public void validUpdateStatus(Integer formId, Integer formStatus) {
+        if (formId == null || formId <= 0) {
+            throw new BusinessException("表单ID不能为空或者小于0!");
+        }
+        OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectById(formId);
+        if (oaFormDefinition == null) {
+            throw new BusinessException("表单不存在!");
+        }
+
+        if (formStatus == null || formStatus < 1 || formStatus > 2) {
+            throw new BusinessException("表单状态为空或不在设定值范围!");
+        }
+        oaFormDefinition.setFormStatus(formStatus);
+        oaFormDefinitionMapper.updateById(oaFormDefinition);
+    }
+
+    // 我的申请-根据权限查询表单
+    @Override
+    public List<OaFormDefinition> selectByScope(String formSign) {
+        Long userId = SecurityUtils.getUserId();
+        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
+        Integer tenantId = SecurityUtils.getTenantId();
+
+        List<OaFormDefinition> oaFormDefinitions = new ArrayList<>();
+
+        LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(OaFormDefinition::getTenantId, tenantId);
+
+        if (StringUtils.isNotBlank(formSign)) {
+            queryWrapper.eq(OaFormDefinition::getFormSign, formSign);
+            OaFormDefinition oaFormDefinition = oaFormDefinitionMapper.selectOne(queryWrapper);
+            if (oaFormDefinition != null) {
+                oaFormDefinitions.add(oaFormDefinition);
+            }
+            return oaFormDefinitions;
+        }
+
+        queryWrapper.eq(OaFormDefinition::getFormStatus, 1)
+                .and(qw -> qw
+                        .eq(OaFormDefinition::getFormScope, 1)
+                        .or()
+                        .apply("FIND_IN_SET('" + deptId + "', dept_ids) > 0")
+                        .or()
+                        .apply("FIND_IN_SET('" + userId + "', user_ids) > 0"));
+        oaFormDefinitions = oaFormDefinitionMapper.selectList(queryWrapper);
+        return oaFormDefinitions;
+    }
+
+    @Override
+    public List<OaFormNameResponseVO> getFormName() {
+        LambdaQueryWrapper<OaFormDefinition> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(OaFormDefinition::getTenantId, SecurityUtils.getTenantId())
+                .select(OaFormDefinition::getId, OaFormDefinition::getFormName);
+        List<OaFormDefinition> oaFormDefinitions = oaFormDefinitionMapper.selectList(queryWrapper);
+
+        List<OaFormNameResponseVO> formNameList = new ArrayList<>();
+        for (OaFormDefinition oaFormDefinition : oaFormDefinitions) {
+            OaFormNameResponseVO oaFormNameResponseVO = new OaFormNameResponseVO();
+            oaFormNameResponseVO.setFormId(oaFormDefinition.getId());
+            oaFormNameResponseVO.setFormName(oaFormDefinition.getFormName());
+            formNameList.add(oaFormNameResponseVO);
+        }
+        return formNameList;
+    }
+
+
+    // 表单版本更新验证
+    private Boolean versionUpdateValid(OaFormDefinition oaFormDefinition) {
+        boolean update = false;
+        OaFormDefinition selectOne = oaFormDefinitionMapper.selectById(oaFormDefinition.getId());
+        if (!selectOne.getFlowInfo().equals(oaFormDefinition.getFlowInfo()) || !selectOne.getFormExplain().equals(oaFormDefinition.getFormExplain())) {
+            update = true;
+        }
+        return update;
+    }
+
+    /**
+     * 根据表单id、名称查询
+     * @param formName 表单名称,用于查询特定的表单定义
+     * @return 返回查询到的表单定义对象,如果没有找到匹配的表单,则返回null
+     */
+    public void selectByNameOrSign(String formName, String formSign) {
+        LambdaQueryWrapper<OaFormDefinition> queryName = Wrappers.lambdaQuery();
+        queryName.eq(StringUtils.isNotBlank(formName), OaFormDefinition::getFormName, formName);
+        OaFormDefinition fromByName = oaFormDefinitionMapper.selectOne(queryName);
+
+        LambdaQueryWrapper<OaFormDefinition> querySign = Wrappers.lambdaQuery();
+        querySign.eq(StringUtils.isNotBlank(formSign), OaFormDefinition::getFormSign, formSign);
+        OaFormDefinition fromBySign = oaFormDefinitionMapper.selectOne(querySign);
+
+        if (fromByName != null) {
+            throw new BusinessException("表单名称已存在,请更换");
+        } else if (fromBySign != null) {
+            throw new BusinessException("表单标识已存在,请更换");
+        }
+    }
+
+    // 表单管理-表单属性(表单名称、标识、说明)验证
+    private void validateFormProperties(String formName, String formSign, String formExplain) {
+        // 判断表单名称是否为空或者超长
+        if (StringUtils.isBlank(formName) || formName.length() > 50) {
+            throw new BusinessException("表单名称不能为空或空字符串");
+        }
+
+        // 判断表单标识是否为空或者超长
+        if (StringUtils.isBlank(formSign)) {
+            throw new BusinessException("表单标识不能为空");
+        } else if (formSign.length() < 3 || formSign.length() > 4) {
+            throw new BusinessException("表单标识长度不能少于3个字符或超过4个字符");
+        } else if (!formSign.matches("^[A-Z]+$")) {
+            throw new BusinessException("表单标识只能包含大写字母!");
+        }
+
+        // 判断表单说明是否超长
+        if (StringUtils.isNotBlank(formExplain) && formExplain.length() > 100) {
+            throw new BusinessException("表单说明长度不能超过100个字符");
+        }
+    }
+
+    // 判断表单所在分组是否有效
+    private void isValidFormGroup(Integer formGroup) {
+        if (formGroup == null) {
+            throw new BusinessException("表单所在分组不能为空");
+        } else if (formGroup < 0 || formGroup > 6) {
+            throw new BusinessException("表单所在分组异常!请联系管理员");
+        }
+    }
+
+    // 校验表单可见范围是否有效
+    private void validFromScope(OaFormDefinition oaFormDefinition) {
+        if (oaFormDefinition.getFormScope() == null) {
+            throw new BusinessException("表单可见范围不能为空");
+        } else {
+            Integer formScope = oaFormDefinition.getFormScope();
+            String deptIds = oaFormDefinition.getDeptIds();
+            String userIds = oaFormDefinition.getUserIds();
+            switch (formScope) {
+                case 0:
+                    if (StringUtils.isBlank(deptIds)) {
+                        throw new BusinessException("表单可见范围为部门,部门集合不能为空");
+                    } else if (!deptIds.matches("^(?:\\d+)(,\\d+)*$")) {
+                        throw new BusinessException("部门集合格式不正确!");
+                    }
+                    break;
+
+                case 1:
+                    break;
+
+                case 2:
+                    if (StringUtils.isBlank(userIds)) {
+                        throw new BusinessException("表单可见范围为人员,人员集合不能为空");
+                    } else if (!userIds.matches("^(?:\\d+)(,\\d+)*$")) {
+                        throw new BusinessException("人员集合格式不正确!");
+                    }
+                    break;
+                default:
+                    throw new BusinessException("表单可见范围为异常!请联系管理员");
+            }
+        }
+
+    }
+
+}

+ 145 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaJbdDocumentServiceImpl.java

@@ -0,0 +1,145 @@
+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.OaDocument;
+import com.usky.oa.domain.OaJbdDocument;
+import com.usky.oa.mapper.OaDocumentMapper;
+import com.usky.oa.mapper.OaJbdDocumentMapper;
+import com.usky.oa.service.OaJbdDocumentService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.oa.service.enums.OaBuiltInDocument;
+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-01-02
+ */
+@Service
+public class OaJbdDocumentServiceImpl extends AbstractCrudService<OaJbdDocumentMapper, OaJbdDocument> implements OaJbdDocumentService {
+
+    @Autowired
+    private OaJbdDocumentMapper oaJbdDocumentMapper;
+    @Autowired
+    private OaDocumentMapper oaDocumentMapper;
+
+    @Override
+    public void add(OaJbdDocument oaJbdDocument) {
+        Long userId = SecurityUtils.getUserId();
+        String username = SecurityUtils.getUsername();
+        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
+        Integer tenantId = SecurityUtils.getTenantId();
+
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+        LocalDateTime now = LocalDateTime.now();
+        String formattedDate = now.format(formatter);
+        String sign = OaBuiltInDocument.JBD.getSign();
+        String docNo = sign + "-" + formattedDate;
+
+        validateOaJbDocument(oaJbdDocument);
+
+        oaJbdDocument.setDocNo(docNo);
+        oaJbdDocument.setStatus(0);
+        oaJbdDocument.setAccountingMethod(0);
+        oaJbdDocument.setProposer(userId);
+        oaJbdDocument.setCreateBy(username);
+        oaJbdDocument.setCreateTime(now);
+        oaJbdDocument.setDeptId(deptId);
+        oaJbdDocument.setTenantId(tenantId);
+        oaJbdDocumentMapper.insert(oaJbdDocument);
+
+        OaDocument oaDocument = new OaDocument();
+        oaDocument.setFormId(oaJbdDocument.getFormId());
+        oaDocument.setType(sign);
+        oaDocument.setDocNo(docNo);
+        oaDocument.setProposer(userId);
+        oaDocument.setStatus(oaJbdDocument.getStatus());
+        oaDocument.setCreateBy(username);
+        oaDocument.setCreateTime(oaJbdDocument.getCreateTime());
+        oaDocument.setDeptId(deptId);
+        oaDocument.setTenantId(tenantId);
+        oaDocumentMapper.insert(oaDocument);
+    }
+
+    @Override
+    public void update(OaJbdDocument oaJbdDocument) {
+        if (StringUtils.isBlank(oaJbdDocument.getDocNo())) {
+            throw new BusinessException("更新单据编号传参异常!");
+        }
+        validateOaJbDocument(oaJbdDocument);
+        oaJbdDocument.setUpdateBy(SecurityUtils.getUsername());
+        oaJbdDocument.setUpdateTime(LocalDateTime.now());
+        oaJbdDocumentMapper.updateById(oaJbdDocument);
+
+        oaDocumentMapper.update(null, Wrappers.lambdaUpdate(OaDocument.class)
+                .set(OaDocument::getStatus, oaJbdDocument.getStatus())
+                .set(OaDocument::getUpdateBy, oaJbdDocument.getCreateBy())
+                .set(OaDocument::getUpdateTime, oaJbdDocument.getUpdateTime())
+        );
+    }
+
+    /**
+     * @description: 验证加班单据参数
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/1/2 18:29
+     * @param: [oaJbdDocument]
+     * @return: void
+     **/
+    private void validateOaJbDocument(OaJbdDocument oaJbdDocument) {
+        if (oaJbdDocument.getFormId() == null || oaJbdDocument.getFormId() <= 0) {
+            throw new BusinessException("表单ID必须大于0!");
+        }
+        if (oaJbdDocument.getStartTime() == null || oaJbdDocument.getEndTime() == null || oaJbdDocument.getStartTime().isAfter(oaJbdDocument.getEndTime())) {
+            throw new BusinessException("加班开始时间或结束时间输入异常!");
+        }
+        if (oaJbdDocument.getDuration() == null || oaJbdDocument.getDuration() <= 0) {
+            throw new BusinessException("加班时长必须大于0!");
+        }
+        if (StringUtils.isBlank(oaJbdDocument.getReason())) {
+            throw new BusinessException("加班原因不能为空!");
+        } else if (oaJbdDocument.getReason().length() > 255) {
+            throw new BusinessException("加班原因超出字数限制,请重试!");
+        }
+        if (oaJbdDocument.getImage() == null) {
+            throw new BusinessException("打卡记录及日报图片不能为空!");
+        } else if (oaJbdDocument.getImage().length() > 500) {
+            throw new BusinessException("上传图片数量超出限制,请重试!");
+        }
+    }
+
+    @Override
+    public void delByDocNo(String docNo) {
+
+        if (StringUtils.isBlank(docNo)) {
+            throw new BusinessException("加班单据编号不能为空!");
+        }
+
+        Integer tenantId = SecurityUtils.getTenantId();
+        Long userId = SecurityUtils.getUserId();
+
+        LambdaQueryWrapper<OaJbdDocument> jbdDeleteWrapper = new LambdaQueryWrapper<>();
+        jbdDeleteWrapper.eq(OaJbdDocument::getTenantId, tenantId)
+                .eq(OaJbdDocument::getProposer, userId)
+                .eq(OaJbdDocument::getDocNo, docNo);
+        oaJbdDocumentMapper.delete(jbdDeleteWrapper);
+
+        LambdaQueryWrapper<OaDocument> deleteWrapper = new LambdaQueryWrapper<>();
+        deleteWrapper.eq(OaDocument::getTenantId, tenantId)
+                .eq(OaDocument::getProposer, userId)
+                .eq(OaDocument::getDocNo, docNo);
+        oaDocumentMapper.delete(deleteWrapper);
+    }
+
+}

+ 161 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/impl/OaQjdDocumentServiceImpl.java

@@ -0,0 +1,161 @@
+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.OaDocument;
+import com.usky.oa.domain.OaQjdDocument;
+import com.usky.oa.mapper.OaDocumentMapper;
+import com.usky.oa.mapper.OaQjdDocumentMapper;
+import com.usky.oa.service.OaQjdDocumentService;
+import com.usky.common.mybatis.core.AbstractCrudService;
+import com.usky.oa.service.enums.OaBuiltInDocument;
+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 2024-12-10
+ */
+@Service
+public class OaQjdDocumentServiceImpl extends AbstractCrudService<OaQjdDocumentMapper, OaQjdDocument> implements OaQjdDocumentService {
+
+    @Autowired
+    private OaQjdDocumentMapper oaQjdDocumentMapper;
+
+    @Autowired
+    private OaDocumentMapper oaDocumentMapper;
+
+    @Override
+    public void addQjDocument(OaQjdDocument oaQjdDocument) {
+
+        // 校验表单数据
+        validateOaQjDocument(oaQjdDocument);
+
+        Long userId = SecurityUtils.getUserId();
+        String username = SecurityUtils.getUsername();
+        Long deptId = SecurityUtils.getLoginUser().getSysUser().getDeptId();
+        Integer tenantId = SecurityUtils.getTenantId();
+
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
+        LocalDateTime now = LocalDateTime.now();
+        String formattedDate = now.format(formatter);
+        String sign = OaBuiltInDocument.QJD.getSign();
+        String docNo = sign + "-" + formattedDate;
+
+        // 插入请假表数据
+        oaQjdDocument.setDocNo(docNo);
+        oaQjdDocument.setProposer(userId);
+        oaQjdDocument.setStatus(0);
+        oaQjdDocument.setCreateBy(username);
+        oaQjdDocument.setCreateTime(now);
+        oaQjdDocument.setDeptId(deptId);
+        oaQjdDocument.setTenantId(tenantId);
+        oaQjdDocumentMapper.insert(oaQjdDocument);
+
+        // 插入单据表数据
+        OaDocument oaDocument = new OaDocument();
+        oaDocument.setFormId(oaQjdDocument.getFormId());
+        oaDocument.setType(sign);
+        oaDocument.setDocNo(docNo);
+        oaDocument.setProposer(userId);
+        oaDocument.setStatus(oaQjdDocument.getStatus());
+        oaDocument.setCreateBy(username);
+        oaDocument.setCreateTime(oaQjdDocument.getCreateTime());
+        oaDocument.setDeptId(deptId);
+        oaDocument.setTenantId(tenantId);
+        oaDocumentMapper.insert(oaDocument);
+    }
+
+    @Override
+    public void updateQjDocument(OaQjdDocument oaQjdDocument) {
+
+        if (StringUtils.isBlank(oaQjdDocument.getDocNo())){
+            throw new BusinessException("请假单据ID为空或异常");
+        }
+
+        validateOaQjDocument(oaQjdDocument);
+        String username = SecurityUtils.getUsername();
+        LocalDateTime now = LocalDateTime.now();
+        oaQjdDocument.setUpdateBy(username);
+        oaQjdDocument.setUpdateTime(now);
+        oaQjdDocumentMapper.updateById(oaQjdDocument);
+
+        oaDocumentMapper.update(null, Wrappers.lambdaUpdate(OaDocument.class)
+                .set(OaDocument::getStatus, oaQjdDocument.getStatus())
+                .set(OaDocument::getUpdateBy, username)
+                .set(OaDocument::getUpdateTime, oaQjdDocument.getUpdateTime())
+        );
+    }
+
+    /**
+     * @description: 校验请假单据表数据
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2024/12/27 10:04
+     * @param: [oaQjDocument]
+     * @return: void
+     **/
+    public static void validateOaQjDocument(OaQjdDocument oaQjdDocument) throws BusinessException {
+        if (oaQjdDocument.getFormId() == null || oaQjdDocument.getFormId() <= 0) {
+            throw new BusinessException("表单ID不能为空或小于等于0");
+        }
+
+        if (StringUtils.isBlank(oaQjdDocument.getType())) {
+            throw new BusinessException("请假类型不能为空");
+        }
+
+        if (oaQjdDocument.getType().length() > 4) {
+            throw new BusinessException("请假类型长度不能超过4个字符");
+        }
+
+        if (oaQjdDocument.getStartTime() == null || oaQjdDocument.getEndTime() == null) {
+            throw new BusinessException("请假开始时间或结束时间不能为空");
+        }
+
+        if (oaQjdDocument.getStartTime().isAfter(oaQjdDocument.getEndTime())) {
+            throw new BusinessException("请假开始时间不能大于结束时间");
+        }
+
+        if (oaQjdDocument.getDuration() == null || oaQjdDocument.getDuration() <= 0) {
+            throw new BusinessException("请假时长不能为空或小于等于0");
+        }
+
+        if (StringUtils.isBlank(oaQjdDocument.getReason())) {
+            throw new BusinessException("请假原因不能为空");
+        }
+
+        if (oaQjdDocument.getReason().length() > 255) {
+            throw new BusinessException("请假原因超出字数限制,请重试");
+        }
+
+        if (oaQjdDocument.getImage() != null && oaQjdDocument.getImage().length() > 500) {
+            throw new BusinessException("上传图片数量超出限制,请重试");
+        }
+    }
+
+    @Override
+    public void delQjDocument(String docNo) {
+
+        if (StringUtils.isBlank(docNo)){
+            throw new BusinessException("请假单据编号不能为空!");
+        }
+
+        LambdaQueryWrapper<OaQjdDocument> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(OaQjdDocument::getDocNo, docNo);
+        oaQjdDocumentMapper.delete(queryWrapper);
+
+        LambdaQueryWrapper<OaDocument> deleteWrapper = Wrappers.lambdaQuery();
+        deleteWrapper.eq(OaDocument::getDocNo, docNo);
+        oaDocumentMapper.delete(deleteWrapper);
+    }
+}

+ 33 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/utils/OaDefinitionDocumentInfo.java

@@ -0,0 +1,33 @@
+package com.usky.oa.service.utils;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2024/12/25
+ */
+public class OaDefinitionDocumentInfo {
+    private String sign;
+    private String name;
+
+    public OaDefinitionDocumentInfo(String sign, String name) {
+        this.sign = sign;
+        this.name = name;
+    }
+
+    public String getSign() {
+        return sign;
+    }
+
+    public void setSign(String sign) {
+        this.sign = sign;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

+ 54 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/vo/OaApprovalCountVO.java

@@ -0,0 +1,54 @@
+package com.usky.oa.service.vo;
+
+import lombok.Data;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2024/12/30
+ */
+@Data
+public class OaApprovalCountVO {
+
+    /**
+     * @description: 待处理
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/1/2 9:54
+     * @param:
+     * @return:
+     **/
+    private Integer pendingSum;
+
+    /**
+     * @description: 已处理
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/1/2 9:54
+     * @param:
+     * @return:
+     **/
+    private Integer alreadySum;
+
+    /**
+     * @description: 已发起
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/1/2 9:54
+     * @param:
+     * @return:
+     **/
+    private Integer myInitiated;
+
+    /**
+     * @description: 我收到的
+     * @author: fyc
+     * @email yuchuan.fu@chinausky.com
+     * @date: 2025/1/2 9:54
+     * @param:
+     * @return:
+     **/
+    private Integer myReceived;
+
+}

+ 19 - 0
service-oa/service-oa-biz/src/main/java/com/usky/oa/service/vo/OaFormNameResponseVO.java

@@ -0,0 +1,19 @@
+package com.usky.oa.service.vo;
+
+import lombok.Data;
+
+/**
+ *
+ * @author fyc
+ * @email yuchuan.fu@chinausky.com
+ * @date 2025/1/3
+ */
+@Data
+public class OaFormNameResponseVO {
+
+    /** 表单id */
+    private Integer formId;
+    /** 表单名 */
+    private String formName;
+
+}

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

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.oa.mapper.OaApprovalMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.OaApproval">
+        <id column="id" property="id" />
+        <result column="doc_id" property="docId" />
+        <result column="flow_id" property="flowId" />
+        <result column="node_id" property="nodeId" />
+        <result column="approval_uid" property="approvalUid" />
+        <result column="type" property="type" />
+        <result column="status" property="status" />
+        <result column="opinion" property="opinion" />
+        <result column="submit_date" property="submitDate" />
+        <result column="approval_date" property="approvalDate" />
+        <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>

+ 21 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/OaDocumentMapper.xml

@@ -0,0 +1,21 @@
+<?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.OaDocumentMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.OaDocument">
+        <id column="id" property="id" />
+        <result column="form_id" property="formId" />
+        <result column="type" property="type" />
+        <result column="doc_no" property="docNo" />
+        <result column="proposer" property="proposer" />
+        <result column="status" property="status" />
+        <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>

+ 30 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/OaFormDefinitionMapper.xml

@@ -0,0 +1,30 @@
+<?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.OaFormDefinitionMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.OaFormDefinition">
+        <id column="id" property="id" />
+        <result column="form_name" property="formName" />
+        <result column="form_group" property="formGroup" />
+        <result column="form_explain" property="formExplain" />
+        <result column="form_type" property="formType" />
+        <result column="field_info" property="fieldInfo" />
+        <result column="flow_info" property="flowInfo" />
+        <result column="form_version" property="formVersion" />
+        <result column="form_sign" property="formSign" />
+        <result column="form_image" property="formImage" />
+        <result column="form_scope" property="formScope" />
+        <result column="form_status" property="formStatus" />
+        <!--<result column="doc_no" property="docNo" />-->
+        <result column="dept_ids" property="deptIds" />
+        <result column="user_ids" property="userIds" />
+        <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>

+ 26 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/OaJbdDocumentMapper.xml

@@ -0,0 +1,26 @@
+<?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.OaJbdDocumentMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.OaJbdDocument">
+        <id column="id" property="id" />
+        <result column="form_id" property="formId" />
+        <result column="doc_no" property="docNo" />
+        <result column="proposer" property="proposer" />
+        <result column="status" property="status" />
+        <result column="start_time" property="startTime" />
+        <result column="end_time" property="endTime" />
+        <result column="duration" property="duration" />
+        <result column="accounting_method" property="accountingMethod" />
+        <result column="reason" property="reason" />
+        <result column="image" property="image" />
+        <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>

+ 26 - 0
service-oa/service-oa-biz/src/main/resources/mapper/oa/OaQjdDocumentMapper.xml

@@ -0,0 +1,26 @@
+<?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.OaQjdDocumentMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.oa.domain.OaQjdDocument">
+        <id column="id" property="id" />
+        <result column="type" property="type" />
+        <result column="node_id" property="nodeId" />
+        <result column="doc_no" property="docNo" />
+        <result column="proposer" property="proposer" />
+        <result column="status" property="status" />
+        <result column="start_time" property="startTime" />
+        <result column="end_time" property="endTime" />
+        <result column="duration" property="duration" />
+        <result column="reason" property="reason" />
+        <result column="image" property="image" />
+        <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>