浏览代码

Merge remote-tracking branch 'origin/master'

yusm 1 周之前
父节点
当前提交
7bea5f9216
共有 100 个文件被更改,包括 8200 次插入0 次删除
  1. 二进制
      fhKeeper/formulahousekeeper/management-platform-mld/0AAE1300
  2. 二进制
      fhKeeper/formulahousekeeper/management-platform-mld/ED622300
  3. 1 0
      fhKeeper/formulahousekeeper/management-platform-mld/build_package.bat
  4. 56 0
      fhKeeper/formulahousekeeper/management-platform-mld/my_prod.cnf
  5. 二进制
      fhKeeper/formulahousekeeper/management-platform-mld/opencv/opencv-420.jar
  6. 二进制
      fhKeeper/formulahousekeeper/management-platform-mld/opencv/x64/opencv_java420.dll
  7. 二进制
      fhKeeper/formulahousekeeper/management-platform-mld/opencv/x86/opencv_java420.dll
  8. 321 0
      fhKeeper/formulahousekeeper/management-platform-mld/pom.xml
  9. 42 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/PlatformStartApplication.java
  10. 82 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/aop/AopLogConfiguration.java
  11. 59 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/aop/LimitRequestAspect.java
  12. 97 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/aop/SensitiveWordConfig.java
  13. 35 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/BeanConfig.java
  14. 67 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/Config.java
  15. 42 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/LdapConfig.java
  16. 12 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/LimitRequest.java
  17. 19 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/PropertyMsg.java
  18. 88 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/RefererInterceptor.java
  19. 23 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/RefererProperties.java
  20. 22 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/SchedulerConfig.java
  21. 28 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/WebConfig.java
  22. 50 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/WebMvcConfig.java
  23. 66 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/constant/Constant.java
  24. 27 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/constant/MybatisPlusPageConfig.java
  25. 44 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/constant/Parameter.java
  26. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/AlertTimeController.java
  27. 129 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/AuditWorkflowSettingController.java
  28. 152 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/AuditWorkflowTimeSettingController.java
  29. 471 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/AuthRedirectController.java
  30. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/BeisenConfigController.java
  31. 37 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/BonusExcludeProjectController.java
  32. 101 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/BusinessTripController.java
  33. 39 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/BustripAuditLogController.java
  34. 118 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/BustripProjectController.java
  35. 54 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CategoryRatioTblSettingController.java
  36. 119 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CommonUploadController.java
  37. 110 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyCertController.java
  38. 232 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyController.java
  39. 43 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyCustomerContactController.java
  40. 58 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyDictController.java
  41. 116 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyDingdingController.java
  42. 81 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyReportController.java
  43. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContactSyncLogController.java
  44. 63 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractBonusDetailController.java
  45. 46 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractBonusSummaryController.java
  46. 137 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractController.java
  47. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractCustomController.java
  48. 81 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractDocumentController.java
  49. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractLogController.java
  50. 37 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractModifyRecordController.java
  51. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractPayCustomizedController.java
  52. 55 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractPaymentController.java
  53. 52 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractTypeController.java
  54. 55 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractTypeSecController.java
  55. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CorpwxJobResultController.java
  56. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CorpwxPreAuthCodeController.java
  57. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CorpwxRegisterCodeController.java
  58. 63 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CostProjectSettingController.java
  59. 191 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CustomerInfoController.java
  60. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DdBillInfoController.java
  61. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DdCallbackController.java
  62. 151 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentController.java
  63. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentDingdingController.java
  64. 37 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentEnableController.java
  65. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentFeishuController.java
  66. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentOtherManagerController.java
  67. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentWxController.java
  68. 69 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DeviceController.java
  69. 53 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DeviceCostController.java
  70. 83 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DeviceLogController.java
  71. 314 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DingDingController.java
  72. 47 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DirtyCleanController.java
  73. 101 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/EarningSnapshotController.java
  74. 47 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/EquipmentOwnerController.java
  75. 32 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ErpOrderInfoController.java
  76. 55 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/EstimateTimeSettingController.java
  77. 63 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpenseAuditSettingController.java
  78. 121 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpenseItemController.java
  79. 193 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpenseMainTypeController.java
  80. 37 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpensePayWayController.java
  81. 191 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpenseSheetController.java
  82. 118 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpenseTypeController.java
  83. 1034 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FeishuInfoController.java
  84. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FeishuSendController.java
  85. 48 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceAuditorController.java
  86. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceCalculateController.java
  87. 187 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceController.java
  88. 43 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceExcludeProjectController.java
  89. 23 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceFixedcolnameController.java
  90. 97 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceImportController.java
  91. 61 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceMonthlyWorktimeController.java
  92. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceProjectsController.java
  93. 201 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceTblcuscolController.java
  94. 81 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinancialAuditController.java
  95. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FmwDetailController.java
  96. 299 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/GroupBudgetReviewController.java
  97. 48 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/GroupParticipatorController.java
  98. 125 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/GroupTemplateController.java
  99. 21 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/GroupTmpstagesController.java
  100. 0 0
      fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/GtemplateTaskController.java

二进制
fhKeeper/formulahousekeeper/management-platform-mld/0AAE1300


二进制
fhKeeper/formulahousekeeper/management-platform-mld/ED622300


+ 1 - 0
fhKeeper/formulahousekeeper/management-platform-mld/build_package.bat

@@ -0,0 +1 @@
+mvn package

+ 56 - 0
fhKeeper/formulahousekeeper/management-platform-mld/my_prod.cnf

@@ -0,0 +1,56 @@
+# For advice on how to change settings please see
+# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html
+[mysqld_multi]
+
+mysqld =/usr/sbin/mysqld
+mysqladmin = /usr/bin/mysqladmin
+[mysqld]
+#
+# Remove leading # and set to the amount of RAM for the most important data
+# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
+# innodb_buffer_pool_size = 128M
+#
+# Remove leading # to turn on a very important data integrity option: logging
+# changes to the binary log between backups.
+# log_bin
+#
+# Remove leading # to set options mainly useful for reporting servers.
+# The server defaults are faster for transactions and fast SELECTs.
+# Adjust sizes as needed, experiment to find the optimal values.
+# join_buffer_size = 128M
+# sort_buffer_size = 2M
+# read_rnd_buffer_size = 2M
+port=7644
+datadir=/var/lib/mysql
+socket=/var/lib/mysql/mysql.sock
+server_id=2 
+# Disabling symbolic-links is recommended to prevent assorted security risks
+symbolic-links=0
+
+max_allowed_packet = 10M
+
+log-error=/var/log/mysqld.log
+pid-file=/var/run/mysqld/mysqld.pid
+sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
+[mysqld1] 
+basedir=/usr
+
+datadir = /data/mysql1      
+
+port = 3307
+server_id=3
+socket = /tmp/mysql3307.sock
+
+skip-host-cache
+
+skip-name-resolve
+
+character-set-server=utf8
+
+sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
+
+wait_timeout=2147483 
+
+interactive_timeout=2147483
+
+max_allowed_packet = 10M

二进制
fhKeeper/formulahousekeeper/management-platform-mld/opencv/opencv-420.jar


二进制
fhKeeper/formulahousekeeper/management-platform-mld/opencv/x64/opencv_java420.dll


二进制
fhKeeper/formulahousekeeper/management-platform-mld/opencv/x86/opencv_java420.dll


+ 321 - 0
fhKeeper/formulahousekeeper/management-platform-mld/pom.xml

@@ -0,0 +1,321 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>formulahousekeeper</artifactId>
+        <groupId>com.hssx.parent</groupId>
+        <version>1.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.hssx.parent</groupId>
+    <artifactId>timesheet</artifactId>
+    <version>3.4.0</version>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>com.github.wechatpay-apiv3</groupId>
+            <artifactId>wechatpay-java</artifactId>
+            <version>0.2.17</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.microsoft.sqlserver</groupId>
+            <artifactId>mssql-jdbc</artifactId>
+            <version>10.2.1.jre8</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-compress</artifactId>
+            <version>1.21</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+            <version>3.4.1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>javase</artifactId>
+            <version>3.4.1</version>
+        </dependency>
+
+<!--        <dependency>-->
+<!--            <groupId>cn.hutool</groupId>-->
+<!--            <artifactId>hutool-all</artifactId>-->
+<!--            <version>5.8.9</version>-->
+<!--        </dependency>-->
+<!--        <dependency>-->
+<!--            <groupId>commons-codec</groupId>-->
+<!--            <artifactId>commons-codec</artifactId>-->
+<!--            <version>1.10</version>-->
+<!--        </dependency>-->
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <!--easyExcel-->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+            <version>2.2.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+        </dependency>
+        <!--Map依赖 -->
+        <dependency>
+            <groupId>net.jodah</groupId>
+            <artifactId>expiringmap</artifactId>
+            <version>0.5.10</version>
+        </dependency>
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+        </dependency>
+        <!-- mybatis-plus代码生成器依赖 -->
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-generator</artifactId>
+        </dependency>
+
+        <!-- velocity模板引擎 -->
+        <dependency>
+            <groupId>org.apache.velocity</groupId>
+            <artifactId>velocity-engine-core</artifactId>
+        </dependency>
+
+        <!-- freemarker 模板引擎-->
+        <dependency>
+            <groupId>org.freemarker</groupId>
+            <artifactId>freemarker</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <!-- fastjson -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+
+        <!-- openoffice -->
+        <dependency>
+            <groupId>com.artofsolving</groupId>
+            <artifactId>jodconverter</artifactId>
+            <version>2.2.1</version>
+        </dependency>
+        <dependency>
+            <groupId>org.artofsolving</groupId>
+            <artifactId>jodconverter-core-3.0.jar</artifactId>
+            <version>1.0</version>
+            <scope>system</scope>
+            <systemPath>${basedir}/src/main/resources/lib/jodconverter-core-3.0.jar</systemPath>
+        </dependency>
+        <dependency>
+            <groupId>com.dingtalk</groupId>
+            <artifactId>taobao-sdk-java-auto_1479188381469-20210623.jar</artifactId>
+            <version>1.0</version>
+            <scope>system</scope>
+            <systemPath>${basedir}/src/main/resources/lib/taobao-sdk-java-auto_1479188381469-20210623.jar</systemPath>
+        </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.aliyun</groupId>-->
+<!--            <artifactId>dingtalk</artifactId>-->
+<!--            <version>1.1.50</version>-->
+<!--        </dependency>-->
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>dingtalk</artifactId>
+            <version>2.2.15</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baidu.aip</groupId>
+            <artifactId>java-sdk</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+        </dependency>
+        <!--开启aop支持-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-aop</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+        </dependency>
+
+        <!-- logback -->
+        <!--<dependency>
+            <groupId>net.logstash.logback</groupId>
+            <artifactId>logstash-logback-encoder</artifactId>
+            <version>6.3</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>1.2.3</version>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-core</artifactId>
+            <version>1.2.3</version>
+        </dependency>-->
+
+
+        <!--     tess4j相关依赖   -->
+        <!-- https://mvnrepository.com/artifact/net.sourceforge.tess4j/tess4j -->
+        <dependency>
+            <groupId>net.sourceforge.tess4j</groupId>
+            <artifactId>tess4j</artifactId>
+        </dependency>
+
+        <!--手动引入opencv 否则无法maven打包-->
+        <dependency>
+            <groupId>org.opencv</groupId>
+            <artifactId>opencv</artifactId>
+            <version>4.2.0</version>
+            <scope>system</scope>
+            <systemPath>${basedir}/opencv/opencv-420.jar</systemPath>
+        </dependency>
+
+        <!--微信模版消息推送三方sdk-->
+        <dependency>
+            <groupId>com.github.binarywang</groupId>
+            <artifactId>weixin-java-mp</artifactId>
+            <version>3.3.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.jcraft</groupId>
+            <artifactId>jsch</artifactId>
+            <version>0.1.55</version>
+        </dependency>
+
+        <!--ladp集成 AD域认证-->
+        <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-ldap</artifactId>
+        <version>2.3.12.RELEASE</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>dysmsapi20170525</artifactId>
+            <version>2.0.4</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <!-- 获取客户端信息 -->
+        <!-- https://mvnrepository.com/artifact/eu.bitwalker/UserAgentUtils -->
+        <dependency>
+            <groupId>eu.bitwalker</groupId>
+            <artifactId>UserAgentUtils</artifactId>
+            <version>1.21</version>
+        </dependency>
+        <!--热部署-->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <version>2.0.1.RELEASE</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <!--配置阿里云仓库-->
+    <repositories>
+        <repository>
+            <id>public</id>
+            <name>aliyun nexus</name>
+            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+        <repository>
+            <id>bintray-qcloud-maven-repo</id>
+            <name>qcloud-maven-repo</name>
+            <url>https://dl.bintray.com/qcloud/maven-repo/</url>
+            <layout>default</layout>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </repository>
+    </repositories>
+
+    <pluginRepositories>
+        <pluginRepository>
+            <id>public</id>
+            <name>aliyun nexus</name>
+            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+            <snapshots>
+                <enabled>false</enabled>
+            </snapshots>
+        </pluginRepository>
+    </pluginRepositories>
+</project>

+ 42 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/PlatformStartApplication.java

@@ -0,0 +1,42 @@
+package com.management.platform;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+/**
+ * Author: 吴涛涛
+ * Date : 2019 - 12 - 31 9:23
+ * Description:<描述>
+ * Version: 1.0
+ */
+@SpringBootApplication
+@MapperScan("com.management.platform.mapper")
+@EnableTransactionManagement //开启事务支持
+@EnableAsync
+public class PlatformStartApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(PlatformStartApplication.class, args);
+        //ldap ssl链接很关键的
+        System.setProperty("com.sun.jndi.ldap.object.disableEndpointIdentification","true");
+    }
+
+    //防止存入redis数据后乱码
+    @Bean(name = "redisTemplate")
+    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
+        RedisTemplate<String, String> template = new RedisTemplate<>();
+        template.setConnectionFactory(factory);
+        template.setKeySerializer(new StringRedisSerializer());
+        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
+        template.setHashKeySerializer(new GenericJackson2JsonRedisSerializer());
+        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
+        template.afterPropertiesSet();
+        return template;
+    }
+}

+ 82 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/aop/AopLogConfiguration.java

@@ -0,0 +1,82 @@
+package com.management.platform.aop;
+
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.*;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Stream;
+
+/**
+ * Author: 吴涛涛 cuiyi@itany.com
+ * Date : 2019 - 08 - 30 13:59
+ * Description:<描述> 开启aop配置
+ * Version: 1.0
+ */
+@Slf4j
+@Aspect
+@Configuration
+public class AopLogConfiguration {
+    public static String[] methods = {"importData", "exportReport", "editReport", "approve", "deny", "cancel", "batchApproveReport", "batchDenyReport"
+            , "loginByUserId", "getUserByCode"};
+    public static List<String> printMethods = new ArrayList<String>();
+    static {
+        printMethods = Arrays.asList(methods);
+    }
+    ;
+    //切入点表达式
+    @Pointcut("execution(public * com.management.*.controller.*.*(..))")
+    public void logPointcut(){
+
+    }
+
+    /**
+     * 前置通知
+     */
+    @Before("logPointcut()")
+    public void  methodBefore(JoinPoint joinPoint){
+        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
+        if (requestAttributes == null) return;
+        HttpServletRequest request = requestAttributes.getRequest();
+        //打印请求内容
+        String methodName = joinPoint.getSignature().getName();
+        if (printMethods.contains(methodName)) {
+            String reqUrl = request.getRequestURL().toString().replaceAll("http://localhost:10010/","");
+            log.info("请求方法:"+reqUrl+", 参数: "+Arrays.toString(joinPoint.getArgs()));
+        }
+    }
+
+    /**
+     * 后置通知
+     */
+    @AfterReturning(returning = "o",pointcut = "logPointcut()")
+    public void methodAfterReturning(Object o){
+        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
+        if (requestAttributes == null) return;
+
+    }
+
+    /**
+     * 异常通知
+     */
+    @AfterThrowing(pointcut = "logPointcut()",throwing = "e")
+    public void logThrowing(JoinPoint joinPoint,Throwable e){
+        ServletRequestAttributes requestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
+        if (requestAttributes == null) {
+            return ;
+        }
+
+        log.info("***************抛出异常***************");
+        log.info("请求类方法:"+joinPoint.getSignature().getName());
+        log.info("异常内容:"+e);
+        log.info("***************抛出异常***************");
+    }
+
+}

+ 59 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/aop/LimitRequestAspect.java

@@ -0,0 +1,59 @@
+package com.management.platform.aop;
+
+import com.management.platform.config.LimitRequest;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import net.jodah.expiringmap.ExpirationPolicy;
+import net.jodah.expiringmap.ExpiringMap;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+
+@Aspect
+@Component
+public class LimitRequestAspect {
+    private static ConcurrentHashMap<String, ExpiringMap<String, Integer>> book = new ConcurrentHashMap<>();
+    // 定义切点
+    // 让所有有@LimitRequest注解的方法都执行切面方法
+    @Pointcut("@annotation(limitRequest)")
+    public void excudeService(LimitRequest limitRequest) {
+    }
+
+    @Around("excudeService(limitRequest)")
+    public HttpRespMsg doAround(ProceedingJoinPoint pjp, LimitRequest limitRequest) throws Throwable {
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        // 获得request对象
+        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
+        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
+        HttpServletRequest request = sra.getRequest();
+
+        // 获取Map对象, 如果没有则返回默认值
+        // 第一个参数是key, 第二个参数是默认值
+        ExpiringMap<String, Integer> map = book.getOrDefault(request.getRequestURI(), ExpiringMap.builder().variableExpiration().build());
+        Integer uCount = map.getOrDefault(request.getRemoteAddr(), 0);
+        if (uCount >= limitRequest.count()) { // 超过次数,不执行目标方法
+            //这里的返回对象类型根据controller方法的返回方式一致
+            httpRespMsg.setError(MessageUtils.message("request.countLimit"));
+            return httpRespMsg;
+        } else if (uCount == 0){ // 第一次请求时,设置开始有效时间
+            map.put(request.getRemoteAddr(), uCount + 1, ExpirationPolicy.CREATED, limitRequest.time(), TimeUnit.MILLISECONDS);
+        } else { // 未超过次数, 记录数据加一
+            map.put(request.getRemoteAddr(), uCount + 1);
+        }
+        book.put(request.getRequestURI(), map);
+
+        // result的值就是被拦截方法的返回值
+        httpRespMsg.data= pjp.proceed();
+        return httpRespMsg;
+    }
+
+}

+ 97 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/aop/SensitiveWordConfig.java

@@ -0,0 +1,97 @@
+package com.management.platform.aop;
+
+import com.management.platform.util.RedisUtil;
+import com.management.platform.util.WordFilter;
+import lombok.SneakyThrows;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.time.LocalDate;
+
+/**
+ * 敏感词过滤
+ */
+//@Aspect
+//@Component
+public class SensitiveWordConfig {
+    @Autowired
+    RedisUtil redisUtils;
+    @Autowired
+    WordFilter wordFilter;
+
+    @Around("@annotation(org.springframework.web.bind.annotation.RequestMapping)||@annotation(org.springframework.web.bind.annotation.PutMapping)||@annotation(org.springframework.web.bind.annotation.PostMapping)")
+    @SneakyThrows
+    public Object doBefore(ProceedingJoinPoint point) {
+        System.out.println("####################进入敏感词检测#######");
+        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+        if (request.getRequestURI().contains("/word/sensitiveword")) {
+            return point.proceed();
+        }
+        //所有的参数对象
+        boolean hasSentiveWords = false;
+        for (int i=0;i<point.getArgs().length; i++) {
+            Object arg = point.getArgs()[i];
+            //参数对象,通过反射将String类型的值进行敏感词过滤
+            System.out.println("获取到参数:");
+            if (arg != null) {
+                Class<?> aClass = arg.getClass();
+                System.out.println("获取到aClass:"+aClass);
+                if(aClass == String.class) {
+                    //本身就是string类型
+                    String afterValue = wordFilter.replaceWords((String)(arg));
+                    System.out.println("替换后=" + afterValue);
+                    point.getArgs()[i] = afterValue;
+                    if (!afterValue.equals(arg)) {
+                        hasSentiveWords = true;
+                        break;
+                    }
+                } else if (aClass != Integer.class && aClass != LocalDate.class) {
+                    //递归遍历,将所有String参数进行敏感词匹配
+                    foundString(aClass,arg);
+                }
+            }
+        }
+        return  point.proceed(point.getArgs());
+    }
+
+    /**
+     * 递归将string替换
+     * @param clazz
+     * @param arg
+     * @return
+     */
+    @SneakyThrows
+    public Class<?> foundString(Class clazz,Object arg ){
+        Field[] declaredFields = clazz.getDeclaredFields();
+        for (Field declaredField : declaredFields) {
+            Class<?> type = declaredField.getType();
+            if (type==String.class&&!Modifier.toString(declaredField.getModifiers()).contains("final")){
+                //如果是String类型,进行关键词匹配 且要排除final修饰的字段
+                declaredField.setAccessible(true);
+                String value=(String)declaredField.get(arg);
+                System.out.println("参数值:"+value);
+                declaredField.set(arg, wordFilter.replaceWords(value));
+            }else if (type.getPackage()!=null&&type.getPackage().getName().contains("com.bysk")){
+                Method[] methods = clazz.getMethods();
+                for (Method method : methods) {
+                    String name = method.getName();
+                    if (name.toLowerCase().contains("get"+declaredField.getName().toLowerCase())){
+                        Object invoke = method.invoke(arg);
+                        this.foundString(type,invoke);
+                        break;
+                    }
+                }
+            }
+        }
+        return  clazz;
+    }
+}

+ 35 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/BeanConfig.java

@@ -0,0 +1,35 @@
+package com.management.platform.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.task.TaskExecutor;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.ThreadPoolExecutor;
+
+@Configuration
+@EnableAsync
+public class BeanConfig {
+
+    @Bean(name = "taskExecutor")
+    public TaskExecutor taskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        // 设置核心线程数
+        executor.setCorePoolSize(5);
+        // 设置最大线程数
+        executor.setMaxPoolSize(10);
+        // 设置队列容量
+        executor.setQueueCapacity(20);
+        // 设置线程活跃时间(秒)
+        executor.setKeepAliveSeconds(60);
+        // 设置默认线程名称
+        executor.setThreadNamePrefix("worktime-");
+        // 设置拒绝策略
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        // 等待所有任务结束后再关闭线程池
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        System.out.println("初始化TaskExecutor");
+        return executor;
+    }
+}

+ 67 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/Config.java

@@ -0,0 +1,67 @@
+package com.management.platform.config;
+
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.config.RequestConfig;
+import org.apache.http.config.Registry;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.conn.ssl.NoopHostnameVerifier;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.ssl.SSLContexts;
+import org.apache.tomcat.jni.SSL;
+import org.springframework.boot.web.client.RestTemplateBuilder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
+
+import javax.net.ssl.SSLContext;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+
+@Configuration
+public class Config {
+
+  @Bean
+  public RestTemplate restTemplate()
+  {
+    ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient());
+    System.out.println("@@@===初始化RestRemplate===@@");
+    return new RestTemplate(requestFactory);
+  }
+  /**
+   * Apache HttpClient
+   *
+   * @return
+   * @see [类、类#方法、类#成员]
+   */
+  private HttpClient httpClient()
+  {
+    // 支持HTTP、HTTPS
+    Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create()
+            .register("http", PlainConnectionSocketFactory.getSocketFactory())
+            .register("https", SSLConnectionSocketFactory.getSocketFactory())
+            .build();
+    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
+    connectionManager.setMaxTotal(200);
+    connectionManager.setDefaultMaxPerRoute(100);
+    connectionManager.setValidateAfterInactivity(2000);
+    RequestConfig requestConfig = RequestConfig.custom()
+            // 服务器返回数据(response)的时间,超时抛出read timeout
+            .setSocketTimeout(65000)
+            // 连接上服务器(握手成功)的时间,超时抛出connect timeout
+            .setConnectTimeout(5000)
+            // 从连接池中获取连接的超时时间,超时抛出ConnectionPoolTimeoutException
+            .setConnectionRequestTimeout(1000)
+            .build();
+    return HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setConnectionManager(connectionManager).build();
+  }
+}

+ 42 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/LdapConfig.java

@@ -0,0 +1,42 @@
+package com.management.platform.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.support.LdapContextSource;
+
+@Configuration
+public class LdapConfig {
+    @Value("${spring.ldap.urls}")
+    private String ldapUrl;
+    @Value("${spring.ldap.username}")
+    private String userName;
+    @Value("${spring.ldap.password}")
+    private String passWord;
+    @Value("${spring.ldap.base.dcFirst}")
+    private String dcFirst;
+    @Value("${spring.ldap.base.dcSecond}")
+    private String dcSecond;
+
+
+
+    @Bean
+    public LdapContextSource ldapContextSource(){
+        LdapContextSource source = new LdapContextSource();
+        source.setBase("DC="+dcFirst+",DC="+dcSecond);
+        source.setUrl(ldapUrl);
+        source.setPassword(passWord);
+        source.setUserDn(userName);
+        source.setReferral("follow");
+        return source;
+    }
+
+    @Bean
+    public LdapTemplate ldapTemplate(){
+        return new LdapTemplate(ldapContextSource());
+    }
+
+
+}
+

+ 12 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/LimitRequest.java

@@ -0,0 +1,12 @@
+package com.management.platform.config;
+
+import java.lang.annotation.*;
+
+@Documented
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LimitRequest {
+    //毫秒,分钟,小时 之间的转换用算数
+    long time() default 60000; // 限制时间 单位:毫秒
+    int count() default Integer.MAX_VALUE; // 允许请求的次数
+}

+ 19 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/PropertyMsg.java

@@ -0,0 +1,19 @@
+package com.management.platform.config;
+
+import java.lang.annotation.*;
+
+/**
+ *  属性信息注解,仅仅可以用于域声明
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+public @interface PropertyMsg {
+    /**
+     * 提示语,用于标记哪个字段发生变更
+     *
+     * @return 提示语
+     */
+    String value();
+}

+ 88 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/RefererInterceptor.java

@@ -0,0 +1,88 @@
+package com.management.platform.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.StringUtils;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.net.MalformedURLException;
+
+public class RefererInterceptor extends HandlerInterceptorAdapter {
+    static final Logger LOGGER = LoggerFactory.getLogger(RefererInterceptor.class);
+
+    // URL匹配器
+    private AntPathMatcher matcher = new AntPathMatcher();
+    @Resource
+    private RefererProperties properties;
+
+    @Value(value = "${excludeUrls}")
+    private String excludeUrls;
+    @Value("${configEnv.isDev}")
+    public boolean isDev;
+
+    @Override
+    public boolean preHandle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception {
+        if (isDev) return true;
+        String referer = req.getHeader("referer");
+        String host = req.getServerName();
+        //对外开放的回调url排除在外
+        String reqUrl = req.getRequestURI();
+//        System.out.println(reqUrl);
+        if (!StringUtils.isEmpty(excludeUrls)) {
+            String[] split = excludeUrls.split(",");
+            boolean isPass = false;
+            for (String pattern: split) {
+                if (matcher.match(pattern, reqUrl)) {
+                    isPass = true;
+                    break;
+                }
+            }
+            if (isPass) {
+                return true;
+            }
+        }
+        // 只验证POST请求
+        if ("POST".equals(req.getMethod())) {
+            //本地开发环境不验证
+            if (referer == null) {
+                System.out.println("===referer为Null, 返回404,拦截==");
+                // 状态置为404
+                resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
+                return false;
+            }
+            java.net.URL url = null;
+            try {
+                url = new java.net.URL(referer);
+            } catch (MalformedURLException e) {
+                // URL解析异常,也置为404
+                resp.setStatus(HttpServletResponse.SC_NOT_FOUND);
+                return false;
+            }
+            boolean isSame = false;
+            if (host.equals(url.getHost())) {
+                isSame = true;
+            }
+            // 首先判断请求域名和referer域名是否相同
+            if (!isSame) {
+                // 如果不等,判断是否在白名单中
+                if (properties.getRefererDomain() != null) {
+                    for (String s : properties.getRefererDomain()) {
+                        if (s.equals(url.getHost())) {
+                            return true;
+                        }
+                    }
+                }
+                LOGGER.warn("请求来源IP不在白名单中, refer host="+url.getHost());
+                return false;
+            }
+        }
+        return true;
+    }
+}
+

+ 23 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/RefererProperties.java

@@ -0,0 +1,23 @@
+package com.management.platform.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+@Component
+@ConfigurationProperties(prefix = "referer")
+public class RefererProperties {
+    // 白名单域名
+    private List<String> refererDomain;
+    //setter,getter方法
+
+
+    public List<String> getRefererDomain() {
+        return refererDomain;
+    }
+
+    public void setRefererDomain(List<String> refererDomain) {
+        this.refererDomain = refererDomain;
+    }
+}

+ 22 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/SchedulerConfig.java

@@ -0,0 +1,22 @@
+package com.management.platform.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+
+@Configuration
+@EnableScheduling
+public class SchedulerConfig {
+    @Bean
+    public TaskScheduler taskScheduler() {
+        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
+        //线程池大小
+        scheduler.setPoolSize(10);
+        //线程名字前缀
+        scheduler.setThreadNamePrefix("spring-task-thread");
+        return scheduler;
+    }
+}
+

+ 28 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/WebConfig.java

@@ -0,0 +1,28 @@
+package com.management.platform.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@EnableWebMvc
+@Configuration
+public class WebConfig implements WebMvcConfigurer {
+
+    @Bean
+    public RefererInterceptor refererInterceptor() {
+        return new RefererInterceptor();
+    }
+
+    /**
+     * 注册拦截器
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        //referer拦截
+        registry.addInterceptor(refererInterceptor());
+    }
+
+
+}

+ 50 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/config/WebMvcConfig.java

@@ -0,0 +1,50 @@
+package com.management.platform.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.LocaleResolver;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+import org.springframework.web.servlet.i18n.CookieLocaleResolver;
+import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
+
+import java.util.Locale;
+
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+    /**
+     * 国际化配置
+     */
+    @Bean
+    public LocaleResolver localeResolver(){
+//		SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
+//		sessionLocaleResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
+//		return sessionLocaleResolver;
+        //使用CookieLocaleResolver,也可使用SessionLocaleResolver,区别在于一个使用Cookie存储Locale信息,一个使用Session
+        CookieLocaleResolver localeResolver = new CookieLocaleResolver();
+        localeResolver.setCookieName("localeCookie");
+        //设置默认区域
+        localeResolver.setDefaultLocale(Locale.SIMPLIFIED_CHINESE);
+        localeResolver.setCookieMaxAge(3600);//设置cookie有效期.
+        return localeResolver;
+    }
+
+    /**
+     *
+     * 添加Locale 拦截器,从请求参数lang中获取参数值,这样我们可以通过lang RequestParam来切换Locale信息
+     */
+    @Bean
+    public LocaleChangeInterceptor localeChangeInterceptor(){
+        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
+//        localeChangeInterceptor.setParamName("lang");
+        return localeChangeInterceptor;
+    }
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        //添加locale拦截器
+        registry.addInterceptor(localeChangeInterceptor());
+    }
+
+}
+

+ 66 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/constant/Constant.java

@@ -0,0 +1,66 @@
+package com.management.platform.constant;
+
+import org.springframework.stereotype.Component;
+
+/**
+ * Author: 吴涛涛
+ * Date : 2019 - 07 - 24 16:00
+ * Description:<描述>常量配置类
+ * Version: 1.0
+ */
+@Component
+public class Constant {
+//    public static final String API_KEY = "gtImOYhgcFBzwuT29tB7tM0Z";//百度文字识别apiKey
+//    public static final String SECRET_KEY = "RipT5kfF3Zqp7S2vTXPlNcMiYcA76jfq";//百度文字识别secretKey
+    public static final String API_KEY = "UgceK95dGkVbQKicVDU9D6s2";//百度文字识别apiKey
+    public static final String SECRET_KEY = "fGCbfC9CR1v8Pf1u6kG4fM9KEXHgitAA";//百度文字识别secretKey
+    public static final Integer UN_HANDLE = 0;//定时任务未处理的状态码
+    public static final String PIC_PATH_PREFIX = "";//定时任务未处理的状态码
+    public static final String COMMON_SOFTWARE_KEYWORDS = "keyWords";//常用软件关键字
+    public static final String[] keyWords = new String[]{"IntelliJ IDEA","Eclipse",
+            "Postman","MyEclipse","Visual Studio Code",
+            "Navicat","Pycharm","Android Studio",
+            "WebStorm","SQLyog","PhpStorm",
+            "JetBrains Datagrip","JetBrains Rider",
+            "Android Studio","Photoshop","Illustrator",
+            "Adobe After Effects","Axure RP","Sketch"};//定时任务未处理的状态码
+//    public static final String ACCESS_KEY = "280d6f0e4a774117905ba789a9f0b978";//百度图像识别accessKey
+//    public static final String SECRET_KEY = "43b460e124eb474c8cdb7441dc30d66d";//百度图像识别secretKey
+    //角色定义
+    public static final String[] ROLE_NAMES = {"普通员工","超级管理员", "系统管理员", "无","财务管理员","项目管理员","公司领导","项目经理"};
+
+    public static final String ROLE_SUPER_MANAGER = "超级管理员";
+
+    public static final String[] DEFAULT_BASE_COST_ITEMS = {"人工成本","一般费用","外包费用","其他"};
+
+    public static final String[] LEAVE_TYPES = {"事假","病假","年假","产假","婚假","丧假","调休假","陪产假","其他"};
+
+    public static final String[] EXPENSE_TYPES = {"材料费","办公用品","培训费","打印费","快递费","制作费","律师费","水费","电费","团建费","其他",
+                                        "城市间交通费","住宿费","伙食补助费","市内交通费","其他差旅费","项目外包费","劳务外包费","其他外包费"};
+
+    //项目报告审核通知
+    public static final String[] PROJECT_REPORT_CHECK = {"审核结果","项目名称","填报人员","工作日期"};
+    //工作日报漏填提醒
+    public static final String[] WORK_REPORT_MISSING_FILLING = {"提示"};
+    //新任务通知
+    public static final String[] NEW_TASK = {"任务内容"};
+    //日报待审核提醒
+    public static final String[] REPORT_WAIT_CHECK = {"待审核数量"};
+    //日报审核通过提醒
+    public static final String[] REPORT_CHECK_PASS = {"审核人","日期"};
+    //日报审核通过提醒(带评价)
+    public static final String[] REPORT_CHECK_PASS_WITH_APPRAISE = {"审核人","评价","日期"};
+    //任务进展通知
+    public static final String[] TASK_EVOLVE= {"项目名称","任务名称","进展内容","任务状态"};
+    //费用报销待审核提醒
+    public static final String[] EXPENSE_REIMBURSEMENT_WAIT_CHECK= {"报销人","填报日期","票据类型","金额","备注"};
+    //员工请假待审核
+    public static final String[] LEAVE_WAIT_CHECK= {"请假人","请假类型","请假时间","备注"};
+    //请假审核通知
+    public static final String[] LEAVE_CHECK= {"审核结果","审核人","请假时间","备注"};
+    
+    public static final int ZHE_ZHONG_COMPANY_ID=4811;
+    public static final int MLD_COMPANY_ID=876;
+    //泓浒
+    public static final int HONG_HU_COMPANY_ID=7536;
+}

+ 27 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/constant/MybatisPlusPageConfig.java

@@ -0,0 +1,27 @@
+package com.management.platform.constant;
+
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+//Spring boot方式
+@EnableTransactionManagement
+@Configuration
+@MapperScan("com.management.platform.mapper")
+public class MybatisPlusPageConfig {
+
+    @Bean
+    public PaginationInterceptor paginationInterceptor() {
+        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
+        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
+        // paginationInterceptor.setOverflow(false);
+        // 设置最大单页限制数量,默认 500 条,-1 不受限制
+        // paginationInterceptor.setLimit(500);
+        // 开启 count 的 join 优化,只针对部分 left join
+        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
+        return paginationInterceptor;
+    }
+}

+ 44 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/constant/Parameter.java

@@ -0,0 +1,44 @@
+package com.management.platform.constant;
+
+/**
+ * Author: 吴涛涛
+ * Date : 2020 - 01 - 06 11:19
+ * Description:<描述> 参数枚举
+ * Version: 1.0
+ */
+public enum Parameter {
+    //accessToken
+    ACCESS_TOKEN("accessToken", "accessToken"),
+    //accessToken 的有效时间 单位:s
+    EXPIRES_IN("expiresIn", "expiresIn");
+
+    private String code;
+    private String name;
+
+    private Parameter(String code, String name) {
+        this.code = code;
+//        this.name = name();
+        this.name = name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+//    public static void main(String[] args) {
+//        System.out.println(Parameter.API_KEY.getName());
+//    }
+
+}

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/AlertTimeController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-05-31
+ */
+@RestController
+@RequestMapping("/alert-time")
+public class AlertTimeController {
+
+}
+

+ 129 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/AuditWorkflowSettingController.java

@@ -0,0 +1,129 @@
+package com.management.platform.controller;
+
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.AuditWorkflowSetting;
+import com.management.platform.entity.AuditWorkflowSetting;
+import com.management.platform.entity.Department;
+import com.management.platform.entity.Report;
+import com.management.platform.mapper.*;
+import com.management.platform.service.AuditWorkflowSettingService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-03-28
+ */
+@RestController
+@RequestMapping("/audit-workflow-setting")
+public class AuditWorkflowSettingController {
+    public static final int TYPE_LEAVE = 1;//请假
+    public static final int TYPE_BUSTRIP = 2;//出差
+    public static final int TYPE_EXPENSE = 3;//费用报销
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    AuditWorkflowSettingMapper auditWorkflowSettingMapper;
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    AuditWorkflowSettingService auditWorkflowSettingService;
+
+    @RequestMapping("/add")
+    public HttpRespMsg add(String json, Integer deptId, @RequestParam Integer type) {
+        String token = request.getHeader("TOKEN");
+        Integer companyId = userMapper.selectById(token).getCompanyId();
+        QueryWrapper<AuditWorkflowSetting> eq = new QueryWrapper<AuditWorkflowSetting>().eq("dept_id", deptId).eq("type", type);
+        List<AuditWorkflowSetting> oldAuditSettingList = auditWorkflowSettingMapper.selectList(eq);
+        JSONArray array = JSONArray.parseArray(json);
+        //检查是否有重复的部门
+        List<Integer> auditDeptIds = new ArrayList<>();
+        for (int i=0;i<array.size(); i++) {
+            JSONObject obj = array.getJSONObject(i);
+            AuditWorkflowSetting auditWorkflowTimeSetting = JSONObject.toJavaObject(obj, AuditWorkflowSetting.class);
+            if (auditWorkflowTimeSetting.getAuditDeptId() != null) {
+                if (auditDeptIds.contains(auditWorkflowTimeSetting.getAuditDeptId())) {
+                    HttpRespMsg msg = new HttpRespMsg();
+                    msg.setError(MessageUtils.message("department.duplicateError", auditWorkflowTimeSetting.getAuditDeptName()));
+                    return msg;
+                } else {
+                    auditDeptIds.add(auditWorkflowTimeSetting.getAuditDeptId());
+                }
+            }
+        }
+
+        //
+        List<Integer> existingIds = new ArrayList<>();
+        for (int i=0;i<array.size(); i++) {
+            JSONObject obj = array.getJSONObject(i);
+            AuditWorkflowSetting auditWorkflowTimeSetting = JSONObject.toJavaObject(obj, AuditWorkflowSetting.class);
+            auditWorkflowTimeSetting.setCompanyId(companyId);
+            auditWorkflowTimeSetting.setType(type);
+            auditWorkflowTimeSetting.setSeq(i+1);
+            if (i == array.size() -1) {
+                auditWorkflowTimeSetting.setIsFinal(1);
+            } else {
+                auditWorkflowTimeSetting.setIsFinal(0);
+            }
+            auditWorkflowTimeSetting.setDeptId(deptId);
+            if (auditWorkflowTimeSetting.getId() == null) {
+                auditWorkflowSettingMapper.insert(auditWorkflowTimeSetting);
+            } else {
+                auditWorkflowSettingMapper.updateById(auditWorkflowTimeSetting);
+                existingIds.add(auditWorkflowTimeSetting.getId());
+            }
+        }
+
+        //移除不在本次保存范围内的已有节点数据
+        if (oldAuditSettingList.size() > 0) {
+            List<Integer> collect = oldAuditSettingList.stream().map(AuditWorkflowSetting::getId).filter(oldId -> !existingIds.stream().anyMatch(ex -> ex.equals(oldId))).collect(Collectors.toList());
+            if (collect.size() > 0) {
+                auditWorkflowSettingMapper.deleteBatchIds(collect);
+            }
+        }
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/checkNodeInUse")
+    public HttpRespMsg checkNodeInUse(String auditDeptId, Integer deptId, Integer type) {
+        String token = request.getHeader("TOKEN");
+        HttpRespMsg msg = new HttpRespMsg();
+        List<AuditWorkflowSetting> targetNode = auditWorkflowSettingMapper.selectList(new QueryWrapper<AuditWorkflowSetting>().eq("dept_id", deptId).eq("audit_dept_id", auditDeptId).eq("type", type));
+        if (targetNode.size() > 0) {
+
+        }
+
+        return msg;
+    }
+
+    @RequestMapping("/get")
+    public HttpRespMsg get(String userId, Integer deptId, @RequestParam Integer type) {
+        HttpRespMsg msg = new HttpRespMsg();
+        //按照传入的用户取他的部门
+        if (!StringUtils.isEmpty(userId)) {
+            deptId = userMapper.selectById(userId).getDepartmentId();
+        }
+        msg.data = auditWorkflowSettingService.get(deptId, type);
+        return msg;
+    }
+
+}
+

+ 152 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/AuditWorkflowTimeSettingController.java

@@ -0,0 +1,152 @@
+package com.management.platform.controller;
+
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.api.R;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.*;
+import com.management.platform.service.ReportService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDateTime;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-07-25
+ */
+@RestController
+@RequestMapping("/audit-workflow-time-setting")
+public class AuditWorkflowTimeSettingController {
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    AuditWorkflowTimeSettingMapper auditWorkflowTimeSettingMapper;
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    DepartmentMapper departmentMapper;
+    @Resource
+    ReportMapper reportMapper;
+    @Resource
+    TimeTypeMapper timeTypeMapper;
+    @Resource
+    ReportService reportService;
+
+
+    @RequestMapping("/add")
+    public HttpRespMsg add(String json, Integer deptId) {
+        String token = request.getHeader("TOKEN");
+        Integer companyId = userMapper.selectById(token).getCompanyId();
+        auditWorkflowTimeSettingMapper.delete(new QueryWrapper<AuditWorkflowTimeSetting>().eq("dept_id", deptId));
+        JSONArray array = JSONArray.parseArray(json);
+
+        if (array.size() == 1 && array.getJSONObject(0).getInteger("isDeptAudit") == 0) {
+            //只有一个项目负责人审核,不保存
+        } else {
+            //检查是否有重复的部门
+            List<Integer> auditDeptIds = new ArrayList<>();
+            for (int i=0;i<array.size(); i++) {
+                JSONObject obj = array.getJSONObject(i);
+                AuditWorkflowTimeSetting auditWorkflowTimeSetting = JSONObject.toJavaObject(obj, AuditWorkflowTimeSetting.class);
+                if (auditDeptIds.contains(auditWorkflowTimeSetting.getAuditDeptId())) {
+                    HttpRespMsg msg = new HttpRespMsg();
+                    msg.setError(MessageUtils.message("department.duplicateError",auditWorkflowTimeSetting.getAuditDeptName()));
+                    return msg;
+                } else {
+                    auditDeptIds.add(auditWorkflowTimeSetting.getAuditDeptId());
+                }
+            }
+
+            for (int i=0;i<array.size(); i++) {
+                JSONObject obj = array.getJSONObject(i);
+                AuditWorkflowTimeSetting auditWorkflowTimeSetting = JSONObject.toJavaObject(obj, AuditWorkflowTimeSetting.class);
+                auditWorkflowTimeSetting.setCompanyId(companyId);
+                auditWorkflowTimeSetting.setSeq(i+1);
+                if (i == array.size() -1) {
+                    auditWorkflowTimeSetting.setIsFinal(1);
+                } else {
+                    auditWorkflowTimeSetting.setIsFinal(0);
+                }
+                auditWorkflowTimeSetting.setDeptId(deptId);
+                auditWorkflowTimeSettingMapper.insert(auditWorkflowTimeSetting);
+            }
+        }
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/checkNodeInUse")
+    public HttpRespMsg checkNodeInUse(String auditDeptId, Integer deptId) {
+        String token = request.getHeader("TOKEN");
+        Integer companyId = userMapper.selectById(token).getCompanyId();
+        HttpRespMsg msg = new HttpRespMsg();
+        List<AuditWorkflowTimeSetting> targetNode = auditWorkflowTimeSettingMapper.selectList(new QueryWrapper<AuditWorkflowTimeSetting>().eq("dept_id", deptId).eq("audit_dept_id", auditDeptId));
+        if (targetNode.size() > 0) {
+            //要删除的部门节点是存在的,需要检测是否有待审核的走到这个流程点了
+            long num = reportMapper.selectCount(new QueryWrapper<Report>().eq("state", 0).eq("is_dept_audit", 1).eq("audit_deptid", auditDeptId));
+            if (num > 0) {
+                msg.setError(MessageUtils.message("department.reviewedError"));
+            }
+        }
+        return msg;
+    }
+
+    @RequestMapping("/approveDeptAuditReport")
+    public HttpRespMsg approveDeptAuditReport(String auditDeptId) {
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        return reportService.approveDeptAuditReport(user, auditDeptId);
+    }
+
+    @RequestMapping("/get")
+    public HttpRespMsg get(Integer deptId) {
+        String token = request.getHeader("TOKEN");
+        Integer companyId = userMapper.selectById(token).getCompanyId();
+        List<AuditWorkflowTimeSetting> auditWorkflowTimeSettings = auditWorkflowTimeSettingMapper.selectList(new QueryWrapper<AuditWorkflowTimeSetting>().eq("dept_id", deptId).orderByAsc("seq"));
+        HttpRespMsg msg = new HttpRespMsg();
+        if (auditWorkflowTimeSettings.size() == 0) {
+            int seq = 1;
+            //未独立设置,获取默认的设置,默认直接就是项目负责人审批
+            Department dept = departmentMapper.selectById(deptId);
+            AuditWorkflowTimeSetting setting = new AuditWorkflowTimeSetting();
+            setting.setSeq(seq);
+            setting.setCompanyId(companyId);
+            setting.setDeptId(dept.getDepartmentId());
+            setting.setIsFinal(1);
+            setting.setIsDeptAudit(0);
+            auditWorkflowTimeSettings.add(setting);
+//            while (dept.getSuperiorId() != null && dept.getSuperiorId() > 0) {
+//                seq++;
+//                dept = departmentMapper.selectById(dept.getSuperiorId());
+//                setting = new AuditWorkflowTimeSetting();
+//                setting.setCompanyId(companyId);
+//                setting.setDeptId(dept.getDepartmentId());
+//                setting.setSeq(seq);
+//                setting.setAuditDeptId(dept.getDepartmentId());
+//                setting.setAuditDeptName(dept.getDepartmentName());
+//                auditWorkflowTimeSettings.add(setting);
+//            }
+
+        }
+        msg.data = auditWorkflowTimeSettings;
+        return msg;
+    }
+
+
+}
+

+ 471 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/AuthRedirectController.java

@@ -0,0 +1,471 @@
+package com.management.platform.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.*;
+import com.management.platform.entity.vo.UserVO;
+import com.management.platform.mapper.*;
+import com.management.platform.service.FeishuInfoService;
+import com.management.platform.service.UserService;
+import com.management.platform.service.WxCorpInfoService;
+import com.management.platform.service.impl.FeishuInfoServiceImpl;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import com.management.platform.util.UserAgentUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.*;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.servlet.ModelAndView;
+import org.springframework.web.servlet.view.RedirectView;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Controller
+public class AuthRedirectController {
+    @Resource
+    HttpServletRequest request;
+    @Value("${suitId}")
+    private String suitId;
+    @Value("${suitSecret}")
+    private String suitSecret;
+    @Value("${privateDeployURL.pcUrl}")
+    private String pcUrl;
+    @Value("${privateDeployURL.mobUrl}")
+    private String mobUrl;
+    @Value("${corpId}")
+    private String corpId;
+
+    @Resource
+    SysConfigMapper sysConfigMapper;
+    @Autowired
+    RestTemplate restTemplate;
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    WxCorpInfoMapper wxCorpInfoMapper;
+    @Resource
+    CompanyMapper companyMapper;
+    @Resource
+    WxCorpInfoService wxCorpInfoService;
+    @Resource
+    FeishuInfoServiceImpl feishuInfoService;
+    @Resource
+    UserLoginInfoMapper userLoginInfoMapper;
+
+
+    @RequestMapping("/corpWXAuth")
+    public ModelAndView auth(String code, String state) {
+        Map<String,Object> reqParam = new HashMap<String,Object>(16);
+        String userAgent = request.getHeader("User-Agent");
+        //获取设备类型
+        String deviceType = UserAgentUtils.getDeviceType(userAgent);
+        boolean isMobile = "MOBILE".equals(deviceType);
+        String url = WeiXinCorpController.GET_CORP_USERINFO_URL.replace("SUITE_ACCESS_TOKEN", getSuiteAccessToken()).replace("CODE", code);
+        String forObject = this.restTemplate.getForObject(url, String.class);
+        JSONObject obj = JSONObject.parseObject(forObject);
+        System.out.println(obj.toString());
+        String wxUserId = obj.getString("UserId");
+        String openUserId = obj.getString("open_userid");
+        String corpId = obj.getString("CorpId");
+
+        System.out.println("登录 wxUserId="+wxUserId+", openUserId="+openUserId);
+        List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("corpwx_userid", openUserId));
+        Integer companyId = 0;
+        if (userList.size() > 0) {
+            //该用户已存在
+            User curUser = userList.get(0);
+            System.out.println("找到用户corpwxUserid=="+curUser.getCorpwxUserid());
+            companyId = curUser.getCompanyId();
+            if (curUser.getIsActive() == 1) {
+                reqParam.put("userId", curUser.getId());
+            } else {
+                //提示账号已停用
+                //reqParam.put("errorMsg", "您的账号已停用,无法登录");
+                reqParam.put("errorMsg", MessageUtils.message("user.inactive"));
+            }
+        } else {
+            //使用UserId比对,之前有的老用户存的是UserId
+            WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectById(corpId);
+            if (wxCorpInfo == null) {
+                reqParam.put("errorMsg", MessageUtils.message("user.accountNoExist"));
+            } else {
+                User curUser = userMapper.selectOne(new QueryWrapper<User>().eq("company_id", wxCorpInfo.getCompanyId()).eq("corpwx_userid", wxUserId));
+                if (curUser == null) {
+//                    reqParam.put("errorMsg", MessageUtils.message("user.accountNoExist"));
+                    //用户不存在,去生成该用户
+                    if (wxCorpInfo.getSaasSyncContact() == 1) {
+                        curUser = wxCorpInfoService.generateUserInfo(wxCorpInfo.getCompanyId(), openUserId);
+                    }
+                }
+                if (curUser != null) {
+                    if (curUser.getIsActive() == 1) {
+                        companyId = curUser.getCompanyId();
+                        reqParam.put("userId", curUser.getId());
+                    } else {
+                        //提示账号已停用
+                        //reqParam.put("errorMsg", "您的账号已停用,无法登录");
+                        reqParam.put("errorMsg", MessageUtils.message("user.inactive"));
+                    }
+                } else {
+                    System.err.println("==生成企业微信User失败==");
+                    reqParam.put("errorMsg", "尚未绑定企业微信,请使用账号密码登录。");
+                }
+
+            }
+        }
+        reqParam.put("hasTriedAutoLogin", 1);
+        if (!StringUtils.isEmpty(state) && state.length() > 1) {
+            reqParam.put("path", state);
+        }
+
+        String redirecUrl = null;
+        String router = "index";
+        if (companyId > 0) {
+            HashMap compExpireInfo = getCompExpireInfo(companyId);
+            if (compExpireInfo != null) {
+                //过期了
+                router = "expire";
+                reqParam.put("expDate", compExpireInfo.get("expDate"));
+                reqParam.put("version", compExpireInfo.get("version"));
+            }
+        }
+        if (isMobile) {
+            redirecUrl = "https://mobworktime.ttkuaiban.com/#/" + router;
+        } else {
+            redirecUrl = "https://worktime.ttkuaiban.com/#/" + router;
+        }
+        //定制化风格
+        if (corpId.equals("wpy9TkCAAAvjmvQuz0IH9iosxBXrqcdA")) {
+            //中辰华典
+            reqParam.put("style", "new");
+        }
+        ModelAndView modelAndView = new ModelAndView(
+                new RedirectView(redirecUrl), reqParam);
+
+        //存储该公司第一次登录所使用的设备
+        if (!reqParam.containsKey("errorMsg")){
+            Integer company = userLoginInfoMapper.selectCount(new QueryWrapper<UserLoginInfo>().eq("company_id",companyId));
+            if (company.equals(0)){
+                UserLoginInfo userLoginInfo = new UserLoginInfo();
+                userLoginInfo.setCompanyId(companyId);
+                userLoginInfo.setFirstLoginDevice(deviceType);
+                userLoginInfo.setWxUserId(wxUserId);
+                userLoginInfoMapper.insert(userLoginInfo);
+                System.err.println(userLoginInfo.toString());
+            }
+        }
+        return modelAndView;
+    }
+
+
+    @RequestMapping("/corpWXScanningAuth")
+    public ModelAndView scanningAuth(String auth_code, String state)throws Exception {
+        Map<String,Object> reqParam = new HashMap<String,Object>(16);
+        String userAgent = request.getHeader("User-Agent");
+        //获取设备类型
+        String deviceType = UserAgentUtils.getDeviceType(userAgent);
+        boolean isMobile = "MOBILE".equals(deviceType);
+        String url = WeiXinCorpController.GET_CORP_SCANNING_CODE_LOGININFO_URL.replace("PROVIDER_ACCESS_TOKEN",wxCorpInfoService.getProviderAccessToken());
+        HttpHeaders headers = new HttpHeaders();
+        RestTemplate restTemplate = new RestTemplate();
+        MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
+        headers.setContentType(type);
+        headers.add("Accept", MediaType.APPLICATION_JSON.toString());
+        JSONObject ob = new JSONObject();
+        ob.put("auth_code", auth_code);
+        HttpEntity<JSONObject> Entity = new HttpEntity<>(ob, headers);
+        ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, Entity, String.class);
+        String redirecUrl = null;
+        if (responseEntity.getStatusCode() == HttpStatus.OK) {
+            String resp = responseEntity.getBody();
+            System.err.println(resp);
+            JSONObject obj = JSONObject.parseObject(resp);
+            if (obj.getIntValue("errcode") == 0) {
+                JSONObject userInfo = obj.getJSONObject("user_info");
+                System.out.println(obj.toString());
+                String wxUserId = userInfo.getString("userid");
+                String openUserId = userInfo.getString("open_userid");
+                JSONObject corpInfo = obj.getJSONObject("corp_info");
+                String corpId = corpInfo.getString("corpid");
+                System.out.println("登录 wxUserId="+wxUserId+", openUserId="+openUserId);
+                List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("corpwx_userid", openUserId));
+                Integer companyId = 0;
+                if (userList.size() > 0) {
+                    //该用户已存在
+                    User curUser = userList.get(0);
+                    System.out.println("找到用户corpwxUserid=="+curUser.getCorpwxUserid());
+                    companyId = curUser.getCompanyId();
+                    if (curUser.getIsActive() == 1) {
+                        reqParam.put("userId", curUser.getId());
+                    } else {
+                        //提示账号已停用
+                        //reqParam.put("errorMsg", "您的账号已停用,无法登录");
+                        reqParam.put("errorMsg", MessageUtils.message("user.inactive"));
+                    }
+                } else {
+                    //使用UserId比对,之前有的老用户存的是UserId
+                    WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectById(corpId);
+                    if (wxCorpInfo == null) {
+                        reqParam.put("errorMsg", MessageUtils.message("user.accountNoExist"));
+                    } else {
+                        User curUser = userMapper.selectOne(new QueryWrapper<User>().eq("company_id", wxCorpInfo.getCompanyId()).eq("corpwx_userid", wxUserId));
+                        if (curUser == null) {
+//                    reqParam.put("errorMsg", MessageUtils.message("user.accountNoExist"));
+                            //用户不存在,去生成该用户
+                            if (wxCorpInfo.getSaasSyncContact() == 1) {
+                                curUser = wxCorpInfoService.generateUserInfo(wxCorpInfo.getCompanyId(), openUserId);
+                            }
+                        }
+                        if (curUser != null) {
+                            if (curUser.getIsActive() == 1) {
+                                companyId = curUser.getCompanyId();
+                                reqParam.put("userId", curUser.getId());
+                            } else {
+                                //提示账号已停用
+                                //reqParam.put("errorMsg", "您的账号已停用,无法登录");
+                                reqParam.put("errorMsg", MessageUtils.message("user.inactive"));
+                            }
+                        } else {
+                            System.err.println("==生成企业微信User失败==");
+                            reqParam.put("errorMsg", "尚未绑定企业微信,请使用账号密码登录。");
+                        }
+
+                    }
+                }
+                if (!StringUtils.isEmpty(state) && state.length() > 1) {
+                    reqParam.put("path", state);
+                }
+                String router = "login";
+                if (companyId > 0) {
+                    HashMap compExpireInfo = getCompExpireInfo(companyId);
+                    if (compExpireInfo != null) {
+                        //过期了
+                        router = "expire";
+                        reqParam.put("expDate", compExpireInfo.get("expDate"));
+                        reqParam.put("version", compExpireInfo.get("version"));
+                    }
+                }
+                redirecUrl = "https://worktime.ttkuaiban.com/#/" + router;
+            }
+        }
+        ModelAndView modelAndView = new ModelAndView(
+                new RedirectView(redirecUrl), reqParam);
+
+        return modelAndView;
+    }
+
+
+    //企业内部应用登录接口
+    @RequestMapping("/corpInsideWXAuth")
+    public ModelAndView authInside(String code, String state) throws Exception{
+        Map<String,Object> reqParam = new HashMap<String,Object>(16);
+        String userAgent = request.getHeader("User-Agent");
+        //获取设备类型
+        String deviceType = UserAgentUtils.getDeviceType(userAgent);
+        boolean isMobile = "MOBILE".equals(deviceType);
+        WxCorpInfo corpInfo = wxCorpInfoMapper.selectById(corpId);
+        String url = WeiXinCorpController.GET_CORP_INSIDE_USERINFO_URL.replace("ACCESS_TOKEN",getCorpConcactAccessToken(corpInfo)).replace("CODE", code);
+        String forObject = this.restTemplate.getForObject(url, String.class);
+        JSONObject obj = JSONObject.parseObject(forObject);
+        String wxUserId = obj.getString("userid");
+//        String openUserId = obj.getString("open_userid");
+//        String corpId = obj.getString("CorpId");
+
+        System.out.println("wxUserId="+wxUserId);
+        System.out.println(obj.toString());
+        List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("corpwx_userid", wxUserId).eq("company_id", corpInfo.getCompanyId()));
+        Integer companyId = 0;
+        if (userList.size() > 0) {
+            //该用户已存在
+            User curUser = userList.get(0);
+            companyId = curUser.getCompanyId();
+            if (curUser.getIsActive() == 1) {
+                reqParam.put("userId", curUser.getId());
+            } else {
+                //提示账号已停用
+                //reqParam.put("errorMsg", "您的账号已停用,无法登录");
+                reqParam.put("errorMsg", MessageUtils.message("user.inactive"));
+            }
+        } else {
+            //使用UserId比对,之前有的老用户存的是UserId
+            WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectById(corpId);
+            if (wxCorpInfo == null) {
+                reqParam.put("errorMsg", MessageUtils.message("user.accountNoExist"));
+            } else {
+                User curUser = userMapper.selectOne(new QueryWrapper<User>().eq("company_id", wxCorpInfo.getCompanyId()).eq("corpwx_userid", wxUserId));
+                if (curUser == null) {
+                    reqParam.put("errorMsg", MessageUtils.message("user.accountNoExist"));
+                }
+                if (curUser != null) {
+                    if (curUser.getIsActive() == 1) {
+                        companyId = curUser.getCompanyId();
+                        reqParam.put("userId", curUser.getId());
+                    } else {
+                        //提示账号已停用
+                        reqParam.put("errorMsg", MessageUtils.message("user.inactive"));
+                    }
+                } else {
+                    reqParam.put("errorMsg", MessageUtils.message("user.accountNoExist"));
+                }
+
+            }
+        }
+        reqParam.put("hasTriedAutoLogin", 1);
+        if (!StringUtils.isEmpty(state) && state.length() > 1) {
+            reqParam.put("path", state);
+        }
+
+        String redirecUrl = null;
+        String router = "login";
+        if (companyId > 0) {
+            HashMap compExpireInfo = getCompExpireInfo(companyId);
+            if (compExpireInfo != null) {
+                //过期了
+                router = "expire";
+                reqParam.put("expDate", compExpireInfo.get("expDate"));
+                reqParam.put("version", compExpireInfo.get("version"));
+            }
+        }
+        if (isMobile) {
+            redirecUrl = mobUrl + router;
+        } else {
+            redirecUrl = pcUrl + router;
+        }
+        ModelAndView modelAndView = new ModelAndView(
+                new RedirectView(redirecUrl), reqParam);
+        reqParam.put("isPrivateCorpWX", 1);
+        if (reqParam.containsKey("errorMsg")) {
+            System.out.println(reqParam.get("errorMsg"));
+        }
+        return modelAndView;
+    }
+
+    private HashMap getCompExpireInfo(Integer companyId) {
+        Company company = companyMapper.selectById(companyId);
+        int version = 1;
+        if (company.getPackageProject() == 1) {
+            version = 2;
+        }
+        if (company.getPackageOa() == 1) {
+            version = 3;
+        }
+        if (company.getPackageEngineering() == 1) {
+            version = 4;
+        }
+        boolean hasExp = false;
+        LocalDateTime expirationDate = company.getExpirationDate();
+        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        if (null != company.getExpirationDate()) {
+            if (expirationDate.isBefore(LocalDateTime.now())) {
+                hasExp = true;
+            }
+        }
+
+        if (hasExp) {
+            String format = dtf.format(expirationDate);
+            HashMap map = new HashMap();
+            map.put("version", version);
+            map.put("expDate", format);
+            return map;
+        } else {
+            return null;
+        }
+    }
+
+    @GetMapping("testClient")
+    @ResponseBody
+    public String test(HttpServletRequest request) {
+        String userAgent = request.getHeader("user-agent");
+        System.out.println("agent: " + userAgent);
+        if (userAgent.toLowerCase().contains("micromessenger")) {
+            System.out.println("===微信平台");
+        } else if (userAgent.toLowerCase().contains("wxwork")) {
+            System.out.println("===企业微信平台");
+        }
+        System.out.println("浏览器组:" + UserAgentUtils.getBorderGroup(userAgent));
+        System.out.println("浏览器名字:" + UserAgentUtils.getBorderName(userAgent));
+        System.out.println("浏览器类型" + UserAgentUtils.getBorderType(userAgent));
+        System.out.println("浏览器生产商:" + UserAgentUtils.getBrowserManufacturer(userAgent));
+        System.out.println("浏览器版本:" + UserAgentUtils.getBrowserVersion(userAgent));
+        System.out.println("设备生产厂商:" + UserAgentUtils.getDeviceManufacturer(userAgent));
+        System.out.println("设备类型:" + UserAgentUtils.getDeviceType(userAgent));
+        System.out.println("设备操作系统:" + UserAgentUtils.getOs(userAgent));
+        System.out.println("操作系统的名字:" + UserAgentUtils.getOsName(userAgent));
+        System.out.println("操作系统的版本号:" + UserAgentUtils.getOsVersion(userAgent));
+        System.out.println("操作系统浏览器的渲染引擎:" + UserAgentUtils.getBorderRenderingEngine(userAgent));
+        String os = UserAgentUtils.getOs(userAgent);
+        if (os.contains("Windows")) {
+            System.out.println("是Windows");
+        } else if (os.contains("Linux")) {
+            System.out.println("是Linux");
+        } else {
+            System.out.println("无法匹配: {" + os + "}");
+        }
+
+        return "Success";
+    }
+
+    //获取第三方应用临时凭证
+    private String getSuiteAccessToken() {
+        if (WeiXinCorpController.SUITE_ACCESS_TOKEN == null || WeiXinCorpController.suiteTokenExpireTime < System.currentTimeMillis()) {
+            //失效了,需要重新获取
+            HttpHeaders headers = new HttpHeaders();
+            headers.setContentType(MediaType.APPLICATION_JSON);
+            JSONObject reqParam = new JSONObject();
+            reqParam.put("suite_id",  suitId);
+            reqParam.put("suite_secret", suitSecret);
+            SysConfig param = sysConfigMapper.selectOne(new QueryWrapper<SysConfig>().eq("param_key", "wx_suite_ticket"));
+            if (param != null) {
+                reqParam.put("suite_ticket",param.getParamValue());
+            }
+
+            HttpEntity<String> requestEntity = new HttpEntity<String>(reqParam.toJSONString(), headers);
+            ResponseEntity<String> responseEntity = this.restTemplate.exchange(WeiXinCorpController.GET_SUITE_ACCESS_TOKEN_URL,
+                    HttpMethod.POST, requestEntity, String.class);
+            if (responseEntity.getStatusCode() == HttpStatus.OK) {
+                String resp = responseEntity.getBody();
+                System.out.println("获取企业微信suitAccessToken返回"+resp);
+                JSONObject obj = JSONObject.parseObject(resp);
+                if (obj.getIntValue("errcode") == 0) {
+                    WeiXinCorpController.SUITE_ACCESS_TOKEN = obj.getString("suite_access_token");
+                    WeiXinCorpController.suiteTokenExpireTime = System.currentTimeMillis() + obj.getIntValue("expires_in")*1000;
+                }
+            }
+        }
+        return WeiXinCorpController.SUITE_ACCESS_TOKEN;
+    }
+
+
+    //获取企业通讯录的accessToken,在私有化部署的企业内部服务器上跑
+    private String getCorpConcactAccessToken(WxCorpInfo corpInfo) throws Exception {
+        String url = WeiXinCorpController.GET_CORP_TOKEN.replace("ID", corpInfo.getCorpid()).replace("SECRET", corpInfo.getContactSecret());
+        ResponseEntity<String> responseEntity = this.restTemplate.exchange(url,
+                HttpMethod.GET, null, String.class);
+        if (responseEntity.getStatusCode() == HttpStatus.OK) {
+            String resp = responseEntity.getBody();
+            JSONObject json = JSONObject.parseObject(resp);
+            if (json.getIntValue("errcode") == 0) {
+                String access_token = json.getString("access_token");
+                corpInfo.setAccessToken(access_token);
+            } else {
+                throw new Exception(json.toJSONString());
+            }
+        }
+        return corpInfo.getAccessToken();
+    }
+
+}

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/BeisenConfigController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-13
+ */
+@RestController
+@RequestMapping("/beisen-config")
+public class BeisenConfigController {
+
+}
+

+ 37 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/BonusExcludeProjectController.java

@@ -0,0 +1,37 @@
+package com.management.platform.controller;
+
+import com.management.platform.entity.bo.AddOrUpdateBonusExcludeProjectBO;
+import com.management.platform.service.BonusExcludeProjectService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping("/bonusExcludeProject")
+public class BonusExcludeProjectController {
+
+    @Resource
+    private BonusExcludeProjectService bonusExcludeProjectService;
+
+
+    @PostMapping("/addOrUpdateProjects")
+    public HttpRespMsg addOrUpdateProjects(AddOrUpdateBonusExcludeProjectBO bo, HttpServletRequest request) {
+        return bonusExcludeProjectService.addOrUpdateProjects(bo,request);
+    }
+
+    @GetMapping("/getProjects")
+    public HttpRespMsg getProjects(HttpServletRequest request){
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            msg = bonusExcludeProjectService.getProjects(request);
+        } catch (Exception e) {e.printStackTrace();
+            msg.setError(MessageUtils.message("other.error"));
+            return msg;
+        }
+        return msg;
+    }
+
+}

+ 101 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/BusinessTripController.java

@@ -0,0 +1,101 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.BusinessTrip;
+import com.management.platform.entity.LeaveSheet;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.BusinessTripService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-04-08
+ */
+@RestController
+@RequestMapping("/business-trip")
+public class BusinessTripController {
+
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    BusinessTripService businessTripService;
+    @Resource
+    private HttpServletRequest request;
+
+
+
+    @RequestMapping("/add")
+    public HttpRespMsg add(BusinessTrip sheet) {
+        return businessTripService.add(sheet);
+
+    }
+
+    @RequestMapping("/modifyProject")
+    public HttpRespMsg modifyProject(BusinessTrip sheet) {
+        return businessTripService.modifyProject(sheet);
+
+    }
+
+
+    @RequestMapping("/cancel")
+    public HttpRespMsg cancel(Integer id) {
+        String userId = request.getHeader("Token");
+        return businessTripService.cancel(id, userId);
+    }
+
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        return businessTripService.delete(id);
+    }
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(BusinessTrip sheet, @RequestParam Integer pageIndex, @RequestParam Integer pageSize,@RequestParam(defaultValue = "0") Integer checkState) {
+        return businessTripService.queryList(sheet, pageIndex, pageSize,checkState);
+    }
+
+    @RequestMapping("/auditList")
+    public HttpRespMsg auditList(BusinessTrip sheet, @RequestParam Integer pageIndex, @RequestParam Integer pageSize, @RequestParam(defaultValue = "0") Integer checkState) {
+        return businessTripService.auditList(sheet, pageIndex, pageSize, checkState);
+    }
+
+    @RequestMapping("/approve")
+    public HttpRespMsg approve(Integer id) {
+        return businessTripService.approve(id);
+    }
+    @RequestMapping("/deny")
+    public HttpRespMsg deny(Integer id, String reason) {
+        return businessTripService.deny(id, reason);
+
+    }
+
+    /**
+     *
+     * @param keyword 姓名(模糊匹配)
+     * @param startDate 开始日期
+     * @param endDate 结束日期
+     * @return
+     */
+    @RequestMapping("/summaryData")
+    public HttpRespMsg summaryData(String keyword, String startDate, String endDate) {
+        String userId = request.getHeader("Token");
+        return businessTripService.summaryData(keyword, startDate, endDate, userId);
+
+    }
+    @RequestMapping("/exportData")
+    public HttpRespMsg exportData(BusinessTrip sheet,@RequestParam(defaultValue = "0") Integer keyword, String startDate, String endDate){
+        String userId = request.getHeader("Token");
+        return businessTripService.exportData(sheet,keyword, startDate, endDate, userId);
+    }
+}
+

+ 39 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/BustripAuditLogController.java

@@ -0,0 +1,39 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.BustripAuditLog;
+import com.management.platform.entity.LeaveAuditLog;
+import com.management.platform.mapper.BustripAuditLogMapper;
+import com.management.platform.mapper.LeaveAuditLogMapper;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-12
+ */
+@RestController
+@RequestMapping("/bustrip-audit-log")
+public class BustripAuditLogController {
+    @Resource
+    BustripAuditLogMapper bustripAuditLogMapper;
+
+    @RequestMapping("/getBySheetId")
+    public HttpRespMsg getBySheetId(int sheetId) {
+        List<BustripAuditLog> list = bustripAuditLogMapper.selectList(new QueryWrapper<BustripAuditLog>().eq("sheet_id", sheetId));
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = list;
+        return msg;
+    }
+}
+

+ 118 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/BustripProjectController.java

@@ -0,0 +1,118 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.BusinessTrip;
+import com.management.platform.entity.BustripProject;
+import com.management.platform.entity.Project;
+import com.management.platform.entity.ReportExtraDegree;
+import com.management.platform.mapper.BusinessTripMapper;
+import com.management.platform.mapper.ProjectMapper;
+import com.management.platform.mapper.ReportExtraDegreeMapper;
+import com.management.platform.service.BusinessTripService;
+import com.management.platform.service.BustripProjectService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-05-17
+ */
+@RestController
+@RequestMapping("/bustrip-project")
+public class BustripProjectController {
+    @Resource
+    BustripProjectService bustripProjectService;
+    @Resource
+    ReportExtraDegreeMapper reportExtraDegreeMapper;
+    @Resource
+    ProjectMapper projectMapper;
+    @Resource
+    BusinessTripMapper businessTripMapper;
+
+    @RequestMapping("/addOrMod")
+    public HttpRespMsg addOrMod(BustripProject item) {
+        HttpRespMsg msg = new HttpRespMsg();
+        BusinessTrip businessTrip = businessTripMapper.selectById(item.getBustripId());
+        //检查时间段不能超出总时间段的显示
+        if (item.getStartDate() == null || item.getEndDate() == null) {
+            //msg.setError("开始日期和结束日期不能为空");
+            msg.setError(MessageUtils.message("date.dateNullError"));
+        } else {
+            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+            //校验比对日期
+            if (item.getStartDate().isBefore(businessTrip.getStartDate())) {
+                //msg.setError("开始日期不得早于"+dtf.format(businessTrip.getStartDate()));
+                msg.setError(MessageUtils.message("date.startDateError",dtf.format(businessTrip.getStartDate())));
+            } else if (item.getEndDate().isAfter(businessTrip.getEndDate())) {
+                //msg.setError("结束日期不得晚于"+dtf.format(businessTrip.getEndDate()));
+                msg.setError(MessageUtils.message("date.endDateError",dtf.format(businessTrip.getEndDate())));
+            } else {
+                if (item.getDegreeId() != null) {
+                    String name = reportExtraDegreeMapper.selectById(item.getDegreeId()).getName();
+                    item.setDegreeName(name);
+                }
+                bustripProjectService.saveOrUpdate(item);
+                //检查出差的关联标记
+                if (businessTrip.getIsLinked() == 0) {
+                    businessTrip.setIsLinked(1);
+                    businessTripMapper.updateById(businessTrip);
+                }
+            }
+        }
+
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        BustripProject bp = bustripProjectService.getById(id);
+        bustripProjectService.removeById(id);
+        int leftCount = bustripProjectService.count(new QueryWrapper<BustripProject>().eq("bustrip_id", bp.getBustripId()));
+        //检查出差的关联标记
+        if (leftCount == 0) {
+            BusinessTrip businessTrip = new BusinessTrip();
+            businessTrip.setId(bp.getBustripId());
+            businessTrip.setIsLinked(0);//没有关联的项目了
+            businessTripMapper.updateById(businessTrip);
+        }
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(Integer bustripId) {
+        List<BustripProject> list = bustripProjectService.list(new QueryWrapper<BustripProject>().eq("bustrip_id", bustripId));
+        List<Integer> collect = list.stream().map(BustripProject::getProjectId).collect(Collectors.toList());
+        if (collect.size() > 0) {
+            List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().in("id", collect));
+            list.forEach(li->{
+                if (li.getProjectId() != null) {
+                    Optional<Project> first = projectList.stream().filter(p -> p.getId().equals(li.getProjectId())).findFirst();
+                    if (first.isPresent()) {
+                        li.setProjectName(first.get().getProjectName());
+                    }
+                }
+            });
+        }
+
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = list;
+        return msg;
+    }
+
+}
+

+ 54 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CategoryRatioTblSettingController.java

@@ -0,0 +1,54 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.CategoryRatioTblSetting;
+import com.management.platform.service.CategoryRatioTblSettingService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-01-01
+ */
+@RestController
+@RequestMapping("/category-ratio-tbl-setting")
+public class CategoryRatioTblSettingController {
+
+    @Resource
+    private HttpServletRequest request;
+
+    @Resource
+    private CategoryRatioTblSettingService categoryRatioTblSettingService;
+
+    @RequestMapping("/get")
+    public HttpRespMsg get(Integer companyId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        CategoryRatioTblSetting byId = categoryRatioTblSettingService.getById(companyId);
+        if (byId == null) {
+            byId = new CategoryRatioTblSetting();
+            byId.setCompanyId(companyId);
+        }
+        msg.setData(byId);
+        return msg;
+    }
+
+    @RequestMapping("/update")
+    public HttpRespMsg update(CategoryRatioTblSetting categoryRatioTblSetting) {
+        HttpRespMsg msg = new HttpRespMsg();
+        categoryRatioTblSettingService.saveOrUpdate(categoryRatioTblSetting);
+        return msg;
+    }
+
+
+}
+

+ 119 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CommonUploadController.java

@@ -0,0 +1,119 @@
+package com.management.platform.controller;
+
+import com.management.platform.task.SFTPAsyncUploader;
+import com.management.platform.util.HttpRespMsg;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.UUID;
+
+@RestController
+@RequestMapping("/common")
+public class CommonUploadController {
+
+    Logger logger = LogManager.getLogger(org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME);
+    @Value(value = "${upload.path}")
+    private String path;
+    @Autowired
+    public SFTPAsyncUploader sftpAsyncUploader;
+
+    @RequestMapping(value="uploadFile")
+    public HttpRespMsg uploadFile(MultipartFile multipartFile) {
+        HttpRespMsg msg = new HttpRespMsg();
+
+        //然后处理文件
+        String fileName = multipartFile.getOriginalFilename();
+        String[] split = fileName.split("\\.");
+        String serverName = UUID.randomUUID().toString().replaceAll("-", "") + "."+split[split.length-1];
+
+        //检查目录
+        File dir = new File(path);
+        if (!dir.exists()) {
+            dir.mkdir();
+        }
+        File file = new File(dir, serverName);
+        InputStream inputStream = null;
+        OutputStream outputStream = null;
+        try {
+            inputStream = multipartFile.getInputStream();
+            outputStream = new FileOutputStream(file);
+            byte[] buffer = new byte[4096];
+            int temp = 0;
+            while ((temp = inputStream.read(buffer, 0, 4096)) != -1) {
+                outputStream.write(buffer, 0, temp);
+            }
+            inputStream.close();
+            outputStream.close();
+            msg.data = serverName;
+
+            // 上传到SFTP服务器
+            sftpAsyncUploader.uploadFileAsync(file);
+
+        } catch (Exception exception) {
+            exception.printStackTrace();
+            logger.error(exception.getMessage());
+        }
+
+        return msg;
+    }
+
+    @RequestMapping(value="uploadFileArray")
+    public HttpRespMsg uploadFileArray(List<MultipartFile> multipartFiles) {
+        HttpRespMsg msg = new HttpRespMsg();
+        StringBuilder stringBuilder=new StringBuilder();
+
+        for (int i = 0; i < multipartFiles.size(); i++) {
+            MultipartFile multipartFile=multipartFiles.get(i);
+            //然后处理文件
+            String fileName = multipartFile.getOriginalFilename();
+            String[] split = fileName.split("\\.");
+            String serverName = UUID.randomUUID().toString().replaceAll("-", "") + "."+split[split.length-1];
+
+            //检查目录
+            File dir = new File(path);
+            if (!dir.exists()) {
+                dir.mkdir();
+            }
+            File file = new File(dir, serverName);
+            InputStream inputStream = null;
+            OutputStream outputStream = null;
+            try {
+                inputStream = multipartFile.getInputStream();
+                outputStream = new FileOutputStream(file);
+                byte[] buffer = new byte[4096];
+                int temp = 0;
+                while ((temp = inputStream.read(buffer, 0, 4096)) != -1) {
+                    outputStream.write(buffer, 0, temp);
+                }
+                inputStream.close();
+                outputStream.close();
+                if(i==multipartFiles.size()-1){
+                    stringBuilder.append(serverName);
+                }else {
+                    stringBuilder.append(serverName+";");
+                }
+
+                // 上传到SFTP服务器
+                sftpAsyncUploader.uploadFileAsync(file);
+
+            } catch (Exception exception) {
+                exception.printStackTrace();
+                logger.error(exception.getMessage());
+            }
+        }
+        msg.data = stringBuilder.toString();
+        return msg;
+    }
+}

+ 110 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyCertController.java

@@ -0,0 +1,110 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.CompanyCert;
+import com.management.platform.entity.Project;
+import com.management.platform.entity.CompanyCert;
+import com.management.platform.entity.UserCert;
+import com.management.platform.mapper.*;
+import com.management.platform.mapper.CompanyCertMapper;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-04-15
+ */
+@RestController
+@RequestMapping("/company-cert")
+public class CompanyCertController {
+
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    CompanyCertMapper companyCertMapper;
+    @Resource
+    UserCertMapper userCertMapper;
+
+    @RequestMapping("/addOrMod")
+    public HttpRespMsg addOrMod(CompanyCert setting) {
+        HttpRespMsg msg = new HttpRespMsg();
+        if (StringUtils.isEmpty(setting.getName())) {
+            //msg.setError("名称不能为空");
+            msg.setError(MessageUtils.message("Company.nullNameError"));
+            return msg;
+        }
+        Integer companyId = userMapper.selectById(request.getHeader("TOKEN")).getCompanyId();
+        if (setting.getId() == null) {
+            setting.setCompanyId(companyId);
+            int count = companyCertMapper.selectCount(new QueryWrapper<CompanyCert>().eq("name", setting.getName()).eq("company_id", setting.getCompanyId()));
+            if (count > 0) {
+                //msg.setError("该名称已存在");
+                msg.setError(MessageUtils.message("Company.nameRepeat"));
+            } else {
+                companyCertMapper.insert(setting);
+                msg.data = companyCertMapper.selectList(new QueryWrapper<CompanyCert>().eq("company_id", companyId));
+            }
+        } else {
+            int count = companyCertMapper.selectCount(new QueryWrapper<CompanyCert>().eq("name", setting.getName())
+                    .eq("company_id", companyId).ne("id", setting.getId()));
+            if (count > 0) {
+                //msg.setError("该名称已存在");
+                msg.setError(MessageUtils.message("Company.nameRepeat"));
+            } else {
+                //检查名称是否有变化
+                CompanyCert oldSetting = companyCertMapper.selectById(setting.getId());
+                if (!setting.getName().equals(oldSetting.getName())) {
+                    companyCertMapper.updateById(setting);
+                    UserCert cost = new UserCert();
+                    cost.setCertName(setting.getName());
+                    userCertMapper.update(cost, new QueryWrapper<UserCert>().eq("cert_id", setting.getId()));
+                }
+                msg.data = companyCertMapper.selectList(new QueryWrapper<CompanyCert>().eq("company_id", companyId));
+            }
+        }
+
+        return msg;
+    }
+
+    @RequestMapping("/list")
+    public HttpRespMsg list() {
+        HttpRespMsg msg = new HttpRespMsg();
+
+        Integer companyId = userMapper.selectById(request.getHeader("TOKEN")).getCompanyId();
+        List<CompanyCert> list = companyCertMapper.selectList(new QueryWrapper<CompanyCert>().eq("company_id", companyId));
+        msg.data = list;
+
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        CompanyCert CompanyCert = companyCertMapper.selectById(id);
+        Integer companyId = userMapper.selectById(request.getHeader("TOKEN")).getCompanyId();
+        if (!CompanyCert.getCompanyId().equals(companyId)) {
+            //msg.setError("无权操作");
+            msg.setError(MessageUtils.message("Company.accessError"));
+        } else {
+            companyCertMapper.deleteById(id);
+        }
+
+        return msg;
+    }
+}
+

+ 232 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyController.java

@@ -0,0 +1,232 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.constant.Constant;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.*;
+import com.management.platform.service.CompanyService;
+import com.management.platform.service.DingDingService;
+import com.management.platform.service.ExpenseMainTypeService;
+import com.management.platform.service.ExpenseTypeService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import com.taobao.api.ApiException;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author 吴涛涛
+ * @since 2020-01-13
+ */
+@RestController
+@RequestMapping("/company")
+public class CompanyController {
+    @Resource
+    private HttpServletRequest request;
+
+    @Resource
+    private CompanyService companyService;
+    @Resource
+    private DingDingService dingDingService;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private CompanyDingdingMapper companyDingdingMapper;
+    @Resource
+    private ExpenseTypeService expenseTypeService;
+    @Resource
+    private ContactSyncLogMapper contactSyncLogMapper;
+    @Resource
+    private CompanyMapper companyMapper;
+    @Resource
+    private ExpenseMainTypeService expenseMainTypeService;
+
+    @RequestMapping("/testTimeout")
+    public HttpRespMsg testTimeout(){
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            Thread.sleep(90*1000);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+        return msg;
+    }
+
+    @RequestMapping("/getStaffCountMax")
+    public HttpRespMsg getStaffCountMax(Integer companyId){
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = companyService.getById(companyId).getStaffCountMax();
+        return msg;
+    }
+
+    @RequestMapping("/dataMigration")
+    public HttpRespMsg dataMigration(Integer oldCompanyId,Integer targetCompanyId){
+       return companyService.dataMigration(oldCompanyId,targetCompanyId);
+    }
+
+    @RequestMapping("/getSyncInfo")
+    public HttpRespMsg getSyncInfo(){
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        String token = request.getHeader("token");
+        User user = userMapper.selectById(token);
+        ContactSyncLog contactSyncLog1 = contactSyncLogMapper.selectOne(new QueryWrapper<ContactSyncLog>().eq("company_id", user.getCompanyId()).orderByDesc("id").last("limit 1"));
+        httpRespMsg.data = contactSyncLog1;
+        return httpRespMsg;
+    }
+
+    //同步钉钉
+    @RequestMapping("/syncCorpMembs")
+    public HttpRespMsg syncCorpMembs() {
+        try {
+            HttpRespMsg msg = new HttpRespMsg();
+            String token = request.getHeader("TOKEN");
+            User user = userMapper.selectById(token);
+            Company company = companyMapper.selectOne(new QueryWrapper<Company>().eq("id", user.getCompanyId()));
+            Integer employeeCnt = userMapper.selectCount(new QueryWrapper<User>().eq("company_id", company.getId()).eq("is_active",1));
+            if (employeeCnt > company.getStaffCountMax()){
+                //公司人员已达上限,请联系客服提高人数上限。
+                msg.setError(MessageUtils.message("wx.employeeFull"));
+                return msg;
+            }
+            CompanyDingding companyDingding = companyDingdingMapper.selectOne(new QueryWrapper<CompanyDingding>().eq("company_id", user.getCompanyId()));
+            if (companyDingding != null) {
+                System.out.println("===========同步钉钉===========");
+                String rest = dingDingService.syncCorpMembs(companyDingding.getCorpid());
+                /*syncLog.remove(user.getCompanyId()+"_status");*/
+                if (rest.startsWith("调用失败")) {
+                    msg.setError(rest);
+                } else {
+                    msg.data = rest;
+                }
+            } else {
+                //msg.setError("非钉钉企业,无法同步");
+                msg.setError(MessageUtils.message("Company.sysDDError"));
+            }
+            return msg;
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.err.println(e.getMessage());
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError(e.getMessage());
+            return msg;
+        }
+    }
+    @RequestMapping("/settingExpenseType")
+    public HttpRespMsg settingExpenseType(){
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        //生成费用报销默认条目
+        String[] expenseTypes = Constant.EXPENSE_TYPES;
+        List<String> commonly = new ArrayList<>();
+        //commonly.add("材料费");
+        commonly.add(MessageUtils.message("entry.materialCost"));
+        //commonly.add("办公用品");
+        commonly.add(MessageUtils.message("entry.workCost"));
+        //commonly.add("培训费");
+        commonly.add(MessageUtils.message("entry.trainCost"));
+        //commonly.add("打印费");
+        commonly.add(MessageUtils.message("entry.printCost"));
+        //commonly.add("快递费");
+        commonly.add(MessageUtils.message("entry.expressCost"));
+        //commonly.add("制作费");
+        commonly.add(MessageUtils.message("entry.makeCost"));
+        //commonly.add("律师费");
+        commonly.add(MessageUtils.message("entry.lawyerCost"));
+        //commonly.add("水费");
+        commonly.add(MessageUtils.message("entry.waterCost"));
+        //commonly.add("电费");
+        commonly.add(MessageUtils.message("entry.electricCost"));
+        //commonly.add("团建费");
+        commonly.add(MessageUtils.message("entry.leagueCost"));
+        //commonly.add("其他");
+        commonly.add(MessageUtils.message("entry.other"));
+        List<String> travel  = new ArrayList<>();
+        //travel.add("城市间交通费");
+        travel.add(MessageUtils.message("entry.cityTrafficCost"));
+        //travel.add("住宿费");
+        travel.add(MessageUtils.message("entry.liveCost"));
+        //travel.add("伙食补助费");
+        travel.add(MessageUtils.message("entry.eatCost"));
+        //travel.add("市内交通费");
+        travel.add(MessageUtils.message("entry.insideCityCost"));
+        //travel.add("其他差旅费");
+        travel.add(MessageUtils.message("entry.otherLiveTraCost"));
+        List<String> outsource = new ArrayList<>();
+        //outsource.add("项目外包费");
+        outsource.add(MessageUtils.message("entry.projectCost"));
+        //outsource.add("劳务外包费");
+        outsource.add(MessageUtils.message("entry.labourCost"));
+        //outsource.add("其他外包费");
+        outsource.add(MessageUtils.message("entry.OtherOutsourceCost"));
+        List<ExpenseType> expenseTypeList=new ArrayList<>();
+        List<ExpenseMainType> expenseMainTypes=new ArrayList<>();
+        ExpenseMainType expenseMainType=new ExpenseMainType();
+        expenseMainType.setName("一般费用");
+        expenseMainType.setCompanyId(user.getCompanyId());
+        ExpenseMainType expenseMainType1=new ExpenseMainType();
+        expenseMainType1.setName("差旅费用");
+        expenseMainType1.setCompanyId(user.getCompanyId());
+        ExpenseMainType expenseMainType2=new ExpenseMainType();
+        expenseMainType2.setName("外包费用");
+        expenseMainType2.setCompanyId(user.getCompanyId());
+        expenseMainTypes.add(expenseMainType);
+        expenseMainTypes.add(expenseMainType1);
+        expenseMainTypes.add(expenseMainType2);
+        expenseMainTypeService.saveBatch(expenseMainTypes);
+        for (String expenseType : expenseTypes) {
+            ExpenseType item=new ExpenseType();
+            item.setCompanyId(user.getCompanyId());
+            item.setTypeName(expenseType);
+            if(commonly.contains(expenseType)){
+                item.setMainType(expenseMainType.getId());
+            }
+            if(travel.contains(expenseType)){
+                item.setMainType(expenseMainType1.getId());
+            }
+            if(outsource.contains(expenseType)){
+                item.setMainType(expenseMainType2.getId());
+            }
+            expenseTypeList.add(item);
+        }
+        if(!expenseTypeService.saveBatch(expenseTypeList)){
+            //httpRespMsg.setError("验证失败");
+            httpRespMsg.setError(MessageUtils.message("Company.validationError"));
+            return httpRespMsg;
+        }
+        return httpRespMsg;
+    }
+
+    @RequestMapping("/editCompanyName")
+    public HttpRespMsg editCompanyName(String name,HttpServletRequest request){
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("token");
+        User user = userMapper.selectById(token);
+        if (StringUtils.isBlank(name)){
+            msg.setError("公司名称不可为空");
+            return msg;
+        }
+        if ("超级管理员".equals(user.getRoleName())){
+            Company company = companyMapper.selectById(user.getCompanyId());
+            company.setCompanyName(name);
+            companyMapper.updateById(company);
+            msg.msg = "修改成功";
+        }else {
+            msg.setError("无权修改");
+        }
+        return msg;
+    }
+
+}
+

+ 43 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyCustomerContactController.java

@@ -0,0 +1,43 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.service.CompanyCustomerContactService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-04-07
+ */
+@RestController
+@RequestMapping("/company-customer-contact")
+public class CompanyCustomerContactController {
+
+    @Resource
+    CompanyCustomerContactService companyCustomerContactService;
+
+    /**
+     * 获取公司列表
+     */
+    @RequestMapping("/getList")
+    public HttpRespMsg getList(Integer pageIndex, Integer pageSize) {
+        return companyCustomerContactService.getList(pageIndex, pageSize);
+    }
+
+    /**
+     * 处理,标记为联系
+     */
+    @RequestMapping("/handle")
+    public HttpRespMsg handle(Integer companyId, String feedback) {
+        return companyCustomerContactService.handle(companyId, feedback);
+    }
+}
+

+ 58 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyDictController.java

@@ -0,0 +1,58 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.CompanyDict;
+import com.management.platform.mapper.CompanyDictMapper;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-12-05
+ */
+@RestController
+@RequestMapping("/company-dict")
+public class CompanyDictController {
+
+    @Resource
+    private CompanyDictMapper companyDictMapper;
+
+    //新增保存公司字典
+    @RequestMapping("/save")
+    public HttpRespMsg save(CompanyDict companyDict) {
+        HttpRespMsg msg = new HttpRespMsg();
+        if (companyDict.getId() != null) {
+            companyDictMapper.updateById(companyDict);
+        } else {
+            companyDictMapper.insert(companyDict);
+        }
+        return msg;
+    }
+
+    //删除公司字典
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        companyDictMapper.deleteById(id);
+        return msg;
+    }
+
+    //获取字典
+    @RequestMapping("/getAll")
+    public HttpRespMsg getAll(String code, Integer companyId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.setData(companyDictMapper.selectList(new QueryWrapper<>(new CompanyDict().setCode(code).setCompanyId(companyId))));
+        return msg;
+    }
+
+}
+

+ 116 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyDingdingController.java

@@ -0,0 +1,116 @@
+package com.management.platform.controller;
+
+
+import com.aliyun.dingtalkcontact_1_0.models.SearchUserResponse;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.dingtalk.api.request.OapiMessageCorpconversationAsyncsendV2Request;
+import com.management.platform.entity.CompanyDingding;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.CompanyDingdingMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.CompanyDingdingService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-27
+ */
+@RestController
+@RequestMapping("/company-dingding")
+public class CompanyDingdingController {
+    @Resource
+    private CompanyDingdingService companyDingdingService;
+    @Resource
+    private CompanyDingdingMapper companyDingdingMapper;
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private UserMapper userMapper;
+
+    @RequestMapping("/getSyncContact")
+    public HttpRespMsg getSyncContact() {
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        HttpRespMsg msg = new HttpRespMsg();
+        CompanyDingding dd = companyDingdingMapper.selectOne(new QueryWrapper<CompanyDingding>().eq("company_id", user.getCompanyId()));
+        msg.data = dd.getSyncContact();
+
+        return msg;
+    }
+
+
+    @RequestMapping("/setSyncContact")
+    public HttpRespMsg setSyncContact(Integer isSync) {
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        HttpRespMsg msg = new HttpRespMsg();
+        CompanyDingding dd = companyDingdingMapper.selectOne(new QueryWrapper<CompanyDingding>().eq("company_id", user.getCompanyId()));
+        if (dd != null) {
+            CompanyDingding companyDingding = new CompanyDingding();
+            companyDingding.setCorpid(dd.getCorpid());
+            companyDingding.setSyncContact(isSync);
+            companyDingdingMapper.updateById(companyDingding);
+        } else {
+            msg.setError("未找到公司钉钉配置");
+        }
+
+        return msg;
+    }
+
+    @RequestMapping("/pushAlertMsg")
+    public HttpRespMsg pushAlertMsg(String corpid, String userDingId) {
+        CompanyDingding companyDingding = companyDingdingMapper.selectById(corpid);
+        companyDingdingService.sendFillReportAlertMsg(companyDingding.getCompanyId(), companyDingding.getAgentId(), "填入日报哦", "040534176023851922");
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/pushFinishMileStoneMsg")
+    public HttpRespMsg pushFinishMileStoneMsg(String corpid, String userDingId, Integer projectId, String projectName) {
+        CompanyDingding companyDingding = companyDingdingMapper.selectById(corpid);
+        LocalDate now = LocalDate.now();
+        String finishDate = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(now);
+        companyDingdingService.sendFinishMileStoneMsg(companyDingding, userDingId, "测试里程碑", projectId,projectName, finishDate);
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/sendOAMsg")
+    public HttpRespMsg sendOAMsg(String corpid, String userDingId) {
+        CompanyDingding companyDingding = companyDingdingMapper.selectById(corpid);
+        List<OapiMessageCorpconversationAsyncsendV2Request.Form> form=new ArrayList<>();
+        OapiMessageCorpconversationAsyncsendV2Request.Form item=new OapiMessageCorpconversationAsyncsendV2Request.Form();
+        item.setKey("测试");
+        item.setValue("试试成功没");
+        form.add(item);
+        companyDingdingService.sendOAMsg(companyDingding, "040534176023851922", "OA提醒测试","这是一次测试",form,null);
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/searchUserInfo")
+    public HttpRespMsg searchUserInfo(String userName) throws Exception {
+        HttpRespMsg msg=new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        CompanyDingding dd = companyDingdingMapper.selectOne(new QueryWrapper<CompanyDingding>().eq("company_id", user.getCompanyId()));
+        HttpRespMsg searchUserInfo = companyDingdingService.getSearchUserInfo(dd, userName, 0);
+        SearchUserResponse searchUserResponse = (SearchUserResponse) searchUserInfo.data;
+        List<String> list = searchUserResponse.body.list;
+        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().in(User::getDingdingUserid, list));
+        msg.setData(userList);
+        return msg;
+    }
+}
+

+ 81 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CompanyReportController.java

@@ -0,0 +1,81 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.CompanyReport;
+import com.management.platform.entity.ReportForm;
+import com.management.platform.service.CompanyReportService;
+import com.management.platform.service.ReportFormService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-08-03
+ */
+@RestController
+@RequestMapping("/company-report")
+public class CompanyReportController {
+    @Autowired
+    private CompanyReportService companyReportService;
+    @Resource
+    private ReportFormService reportFormService;
+
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(Integer companyId){
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        List<CompanyReport> companyReportList = companyReportService.list(new QueryWrapper<CompanyReport>().eq("company_id", companyId));
+        List<ReportForm> reportFormList = reportFormService.list();
+        for (ReportForm reportForm : reportFormList) {
+            boolean b = companyReportList.stream().anyMatch(cr -> cr.getReportFormId().equals(reportForm.getId()));
+            if(b){
+                reportForm.setOwned(1);
+            }
+        }
+        httpRespMsg.data=reportFormList;
+        return httpRespMsg;
+    }
+
+    @RequestMapping("/update")
+    public HttpRespMsg update(Integer companyId,String formIds){
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        if(companyReportService.remove(new QueryWrapper<CompanyReport>().eq("company_id", companyId))){
+            //httpRespMsg.setError("更新失败");
+            httpRespMsg.setError(MessageUtils.message("Company.update"));
+            return httpRespMsg;
+        }
+        List<CompanyReport> updateList=new ArrayList<>();
+        if(formIds!=null&&!StringUtils.isEmpty(formIds)){
+            String[] split = formIds.split(",");
+            List<String> list = Arrays.asList(split);
+            for (String s : list) {
+                CompanyReport companyReport=new CompanyReport();
+                companyReport.setCompanyId(companyId);
+                companyReport.setReportFormId(Integer.parseInt(s));
+                updateList.add(companyReport);
+            }
+            if(!companyReportService.saveBatch(updateList)){
+                //httpRespMsg.setError("更新失败");
+                httpRespMsg.setError(MessageUtils.message("Company.update"));
+            }
+        }
+        return httpRespMsg;
+    }
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContactSyncLogController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-14
+ */
+@RestController
+@RequestMapping("/contact-sync-log")
+public class ContactSyncLogController {
+
+}
+

+ 63 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractBonusDetailController.java

@@ -0,0 +1,63 @@
+package com.management.platform.controller;
+
+import com.management.platform.service.ContractBonusDetailService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@RestController
+@RequestMapping("/contractBonusDetail")
+public class ContractBonusDetailController {
+    @Resource
+    private ContractBonusDetailService contractBonusDetailService;
+
+
+    /**导入模板数据*/
+    @PostMapping("/transTemplateData")
+    public HttpRespMsg transTemplateData(String startYM, String endYM
+            , String bonusType, @RequestParam(value = "file") MultipartFile file
+            , HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            httpRespMsg = contractBonusDetailService.transTemplateData(startYM,endYM,bonusType,file,request);
+        } catch (Exception e) {
+            e.printStackTrace();
+            httpRespMsg.setError(MessageUtils.message("other.error"));
+        }
+        return httpRespMsg;
+    }
+
+    /**获取合同主体奖金*/
+    @PostMapping("/getContractBonus")
+    public HttpRespMsg getContractBonus(@RequestParam(value = "year")Integer year
+            , HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            httpRespMsg = contractBonusDetailService.getContractBonus(year,request);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return httpRespMsg;
+    }
+
+    @PostMapping("/exportContractBonus")
+    public void exportContractBonus(@RequestParam(value = "year")Integer year
+            , HttpServletRequest request, HttpServletResponse response) {
+        try {
+           contractBonusDetailService.exportContractBonus(year,request,response);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+
+
+}

+ 46 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractBonusSummaryController.java

@@ -0,0 +1,46 @@
+package com.management.platform.controller;
+
+import com.management.platform.service.ContractBonusSummaryService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping("/contractBonusSummary")
+public class ContractBonusSummaryController {
+    @Resource
+    private ContractBonusSummaryService contractBonusSummaryService;
+
+    /**获取奖金概要数据*/
+    @PostMapping("/getBonusSummary")
+    public HttpRespMsg getBonusSummary(@RequestParam(value = "ym")String ym, HttpServletRequest request){
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            httpRespMsg = contractBonusSummaryService.getBonusSummary(ym,request);
+        } catch (Exception e) {
+            e.printStackTrace();
+            httpRespMsg.setError(MessageUtils.message("other.error"));
+        }
+        return httpRespMsg;
+    }
+
+    /**删除奖金概要数据【级联】*/
+    @PostMapping("/deleteBonusSummary")
+    public HttpRespMsg deleteBonusSummary(String ids, HttpServletRequest request){
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            httpRespMsg = contractBonusSummaryService.deleteBonusSummary(ids,request);
+        } catch (Exception e) {
+            e.printStackTrace();
+            httpRespMsg.setError(MessageUtils.message("other.error"));
+        }
+        return httpRespMsg;
+    }
+
+}

+ 137 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractController.java

@@ -0,0 +1,137 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.ProjectMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.ContractService;
+import com.management.platform.service.ContractTypeService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.http.HttpRequest;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+@RestController
+@RequestMapping("/contract")
+public class ContractController {
+    @Resource
+    private ContractService contractService;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private ProjectMapper projectMapper;
+
+    /**
+     * 分页查询合同
+     */
+    @RequestMapping("/getContractPage")
+    public HttpRespMsg getContractPage (HttpServletRequest request, @RequestParam Integer pageIndex, @RequestParam Integer pageSize, String number,String name,String typeName,Integer status,
+                                        String startDate,String endDate, String paymentStartDate, String paymentEndDate, Integer secTypeId,@RequestParam(required = false) String customerOrg,@RequestParam(required = false) Integer finishStatus){
+        return contractService.getContractPage(request,pageIndex,pageSize,number,name,typeName,status,startDate,endDate, paymentStartDate, paymentEndDate, secTypeId,customerOrg,finishStatus);
+    }
+
+    /**
+     * 导出合同
+     */
+    @RequestMapping("/exportContract")
+    public HttpRespMsg exportContract (HttpServletRequest request, String number,String name,String typeName,Integer status,String startDate,
+                                       String endDate, String paymentStartDate, String paymentEndDate, Integer secTypeId,@RequestParam(required = false) String customerOrg,@RequestParam(required = false) Integer finishStatus){
+        return contractService.ExportContract(request,number,name,typeName,status,startDate,endDate, paymentStartDate, paymentEndDate, secTypeId,customerOrg,finishStatus);
+    }
+
+    /**
+     * 导出合同
+     */
+    @RequestMapping("/exportContractOneToMany")
+    public HttpRespMsg exportContractOneToMany (HttpServletRequest request, String number,String name,String typeName,Integer status,String startDate,
+                                                String endDate, String paymentStartDate, String paymentEndDate, Integer secTypeId,@RequestParam(required = false) String customerOrg,@RequestParam(required = false) Integer finishStatus){
+        return contractService.exportContractOneToMany(request,number,name,typeName,status,startDate,endDate, paymentStartDate, paymentEndDate, secTypeId,customerOrg,finishStatus);
+    }
+
+    /**
+     * 导入合同
+     */
+    @RequestMapping("/importContract")
+    public HttpRespMsg importContract (HttpServletRequest request, MultipartFile file){
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        if (user.getCompanyId() == 10 || user.getCompanyId() == 4215) {
+            return contractService.importContractCustom(request,file);
+        } else {
+            return contractService.importContract(request,file);
+        }
+    }
+
+    /**
+     * 新增合同
+     */
+    @RequestMapping("/addContract")
+    public HttpRespMsg addContract (HttpServletRequest request, Contract contract, ContractCustom custom, String paymentListStr){
+        return contractService.addContract(request,contract, custom, paymentListStr);
+    }
+
+    /**
+     * 编辑合同
+     */
+    @RequestMapping("/editContract")
+    public HttpRespMsg editContract (HttpServletRequest request,Contract contract,ContractCustom custom, String paymentListStr){
+        return contractService.editContract(request,contract, custom, paymentListStr);
+    }
+
+    /**
+     * 审核合同
+     */
+    @RequestMapping("/processContract")
+    public HttpRespMsg processContract (HttpServletRequest request,Integer id,Integer status,String msg){
+        return contractService.processContract(request,id,status,msg);
+    }
+
+    /**
+     * 删除合同
+     * @param request
+     * @param id
+     * @return
+     */
+    @RequestMapping("/deleteContract")
+    public HttpRespMsg deleteContract (HttpServletRequest request,Integer id){
+        return contractService.deleteContract(request,id);
+    }
+
+
+    /**
+     * 返回该合同的附件列表
+     */
+    @RequestMapping("/contractFile")
+    public HttpRespMsg contractFile (HttpServletRequest request,Integer id){
+        return contractService.contractFile(request,id);
+    }
+
+    @RequestMapping("/getProjectList")
+    public HttpRespMsg getProjectList (HttpServletRequest request){
+        HttpRespMsg msg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().select("id, project_code, project_name, contract_amount").eq("company_id", user.getCompanyId()));
+        msg.data = projectList;
+        return msg;
+    }
+
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractCustomController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-09-09
+ */
+@RestController
+@RequestMapping("/contract-custom")
+public class ContractCustomController {
+
+}
+

+ 81 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractDocumentController.java

@@ -0,0 +1,81 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.vo.ContractFileDelVO;
+import com.management.platform.service.ContractDocumentService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-09
+ */
+@RestController
+@RequestMapping("/contract-document")
+public class ContractDocumentController {
+    @Resource
+    private ContractDocumentService contractDocumentService;
+
+    /**
+     * 上传附件
+     * @param request
+     * @param ContractId
+     * @param folderId
+     * @param files
+     * @return
+     */
+    @RequestMapping("/fileUpload")
+    public HttpRespMsg fileUpload (HttpServletRequest request, @RequestParam Integer ContractId, @RequestParam(required=false) Integer folderId, @RequestParam("file") MultipartFile[] files){
+        return contractDocumentService.fileUpload(request,ContractId,folderId,files);
+    }
+
+    /**
+     * 下载文件
+     * @param request
+     * @param response
+     * @param folderId
+     * @param contractId
+     * @param fileId
+     * @return
+     */
+    @RequestMapping("/fileDown")
+    public HttpRespMsg fileDown (HttpServletRequest request, HttpServletResponse response, @RequestParam(required=false) Integer folderId, Integer contractId, Integer fileId){
+        return contractDocumentService.fileDown(request,response,folderId,contractId,fileId);
+    }
+
+    /**
+     * 删除文件
+     * @param request
+     * @param contractFileDelVo
+     * @return
+     */
+    @RequestMapping("/fileDelete")
+    public HttpRespMsg fileDelete (HttpServletRequest request, ContractFileDelVO contractFileDelVo){
+        return contractDocumentService.fileDelete(request,contractFileDelVo);
+    }
+
+    /**
+     * 在线预览
+     * @param inputFilePath
+     * @return
+     */
+    @RequestMapping("/onlineShow")
+    public HttpRespMsg onlineShow (@RequestParam String inputFilePath){
+        return contractDocumentService.onlineShow(inputFilePath);
+    }
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractLogController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-12-16
+ */
+@RestController
+@RequestMapping("/contract-log")
+public class ContractLogController {
+
+}
+

+ 37 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractModifyRecordController.java

@@ -0,0 +1,37 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.ContractModifyRecord;
+import com.management.platform.service.ContractModifyRecordService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-07-26
+ */
+@RestController
+@RequestMapping("/contract-modify-record")
+public class ContractModifyRecordController {
+    @Autowired
+    private ContractModifyRecordService contractModifyRecordService;
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(Integer projectId){
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        List<ContractModifyRecord> contractModifyRecordList = contractModifyRecordService.list(new QueryWrapper<ContractModifyRecord>().eq("project_id", projectId));
+        httpRespMsg.data=contractModifyRecordList;
+        return httpRespMsg;
+    }
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractPayCustomizedController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-09-23
+ */
+@RestController
+@RequestMapping("/contract-pay-customized")
+public class ContractPayCustomizedController {
+
+}
+

+ 55 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractPaymentController.java

@@ -0,0 +1,55 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.ContractPayCustomized;
+import com.management.platform.entity.ContractPayment;
+import com.management.platform.entity.User;
+import com.management.platform.service.ContractPayCustomizedService;
+import com.management.platform.service.ContractPaymentService;
+import com.management.platform.service.UserService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-05-26
+ */
+@RestController
+@RequestMapping("/contract-payment")
+public class ContractPaymentController {
+
+    @Resource
+    private ContractPaymentService contractPaymentService;
+
+    @Resource
+    private UserService userService;
+
+    @Resource
+    private ContractPayCustomizedService payCustomizedService;
+
+    @RequestMapping("/getList")
+    public HttpRespMsg getList(HttpServletRequest request,Integer contractId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("token");
+        User user = userService.getById(token);
+        if (user.getCompanyId()!=4215){
+            msg.data = contractPaymentService.list(new QueryWrapper<ContractPayment>().eq("contract_id", contractId));
+        }else {
+            msg.data = payCustomizedService.list(new QueryWrapper<ContractPayCustomized>().eq("contract_id", contractId));
+        }
+        return msg;
+    }
+
+
+}
+

+ 52 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractTypeController.java

@@ -0,0 +1,52 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.ContractType;
+import com.management.platform.service.ContractTypeService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-29
+ */
+@RestController
+@RequestMapping("/contractType")
+public class ContractTypeController {
+    @Resource
+    private ContractTypeService contractTypeService;
+
+    /**
+     * 返回公司自定义合同类型
+     */
+    @RequestMapping("/getContractType")
+    public HttpRespMsg getContractType (HttpServletRequest request){
+        return contractTypeService.getContractType(request);
+    }
+
+    /**
+     * 新增、修改合同类型
+     */
+    @RequestMapping("/changeContractType")
+    public HttpRespMsg changeContractType (HttpServletRequest request, ContractType contractType){
+        return contractTypeService.changeContractType(request,contractType);
+    }
+
+    /**
+     * 删除合同类型
+     */
+    @RequestMapping("/deleteContractType")
+    public HttpRespMsg deleteContractType (HttpServletRequest request, Integer deleteId){
+        return contractTypeService.deleteContractType(request,deleteId);
+    }
+}
+

+ 55 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ContractTypeSecController.java

@@ -0,0 +1,55 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.ContractType;
+import com.management.platform.entity.ContractTypeSec;
+import com.management.platform.service.ContractTypeSecService;
+import com.management.platform.service.ContractTypeService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-09-14
+ */
+@RestController
+@RequestMapping("/contract-type-sec")
+public class ContractTypeSecController {
+    @Resource
+    private ContractTypeSecService contractTypeSecService;
+
+    /**
+     * 返回公司自定义合同类型
+     */
+    @RequestMapping("/getContractType")
+    public HttpRespMsg getContractType (HttpServletRequest request){
+
+        return contractTypeSecService.getContractType(request);
+    }
+
+    /**
+     * 新增、修改合同类型
+     */
+    @RequestMapping("/changeContractType")
+    public HttpRespMsg changeContractType (HttpServletRequest request, ContractTypeSec contractType){
+        return contractTypeSecService.changeContractType(request,contractType);
+    }
+
+    /**
+     * 删除合同类型
+     */
+    @RequestMapping("/deleteContractType")
+    public HttpRespMsg deleteContractType (HttpServletRequest request, Integer deleteId){
+        return contractTypeSecService.deleteContractType(request,deleteId);
+    }
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CorpwxJobResultController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-10-06
+ */
+@RestController
+@RequestMapping("/corpwx-job-result")
+public class CorpwxJobResultController {
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CorpwxPreAuthCodeController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-22
+ */
+@RestController
+@RequestMapping("/corpwx-pre-auth-code")
+public class CorpwxPreAuthCodeController {
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CorpwxRegisterCodeController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-22
+ */
+@RestController
+@RequestMapping("/corpwx-register-code")
+public class CorpwxRegisterCodeController {
+
+}
+

+ 63 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CostProjectSettingController.java

@@ -0,0 +1,63 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.CostProjectSetting;
+import com.management.platform.entity.Project;
+import com.management.platform.service.CostProjectSettingService;
+import com.management.platform.service.ProjectService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-03-14
+ */
+@RestController
+@RequestMapping("/cost-project-setting")
+public class CostProjectSettingController {
+
+    @Resource
+    private CostProjectSettingService costProjectSettingService;
+    @Resource
+    private ProjectService projectService;
+
+    @RequestMapping("/get")
+    public HttpRespMsg getCostProjectSetting(Integer companyId, String ymonth){
+        HttpRespMsg msg = new HttpRespMsg();
+        List<CostProjectSetting> list  = costProjectSettingService.list(new QueryWrapper<CostProjectSetting>().eq("company_id",companyId).eq("ymonth",ymonth));
+        HashMap ret = new HashMap();
+        if (list.size() > 0){
+            CostProjectSetting item = list.get(0);
+            ret.put("setting", item);
+        }
+        List<Project> allProjectList = projectService.list(new QueryWrapper<Project>().select("id", "project_code", "project_name").eq("company_id", companyId));
+
+        ret.put("allProjectList", allProjectList);
+        msg.data = ret;
+        return msg;
+    }
+
+    @RequestMapping("/save")
+    public HttpRespMsg saveCostProjectSetting(CostProjectSetting costProjectSetting){
+        HttpRespMsg msg = new HttpRespMsg();
+        if (costProjectSetting.getId() == null) {
+            costProjectSettingService.save(costProjectSetting);
+        } else {
+            costProjectSettingService.updateById(costProjectSetting);
+        }
+        return msg;
+    }
+
+}
+

+ 191 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/CustomerInfoController.java

@@ -0,0 +1,191 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.management.platform.entity.CustomerInfo;
+import com.management.platform.entity.Project;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.CustomerInfoMapper;
+import com.management.platform.mapper.ProjectMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.CustomerInfoService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-07-31
+ */
+@RestController
+@RequestMapping("/customer-info")
+public class CustomerInfoController {
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    ProjectMapper projectMapper;
+    @Resource
+    CustomerInfoMapper customerInfoMapper;
+    @Resource
+    CustomerInfoService customerInfoService;
+
+    @RequestMapping("/addOrMod")
+    public HttpRespMsg addOrMod(CustomerInfo info) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        List<CustomerInfo> customerInfoMapperAll = customerInfoMapper.getAll(user.getCompanyId());
+        List<String> nameList=new ArrayList<>();
+        List<String> codeList=new ArrayList<>();
+        customerInfoMapperAll.forEach(cu->{
+            nameList.add(cu.getCustomerName());
+            if(cu.getCustomerCode()!=null){
+                codeList.add(cu.getCustomerCode());
+            }
+        });
+        if (info.getId() == null) {
+            if(nameList.contains(info.getCustomerName())){
+                //msg.setError("客户名称已存在");
+                msg.setError(MessageUtils.message("customer.nameRepeat"));
+                return msg;
+            }
+            if(codeList.contains(info.getCustomerCode())){
+                //msg.setError("客户编号已存在");
+                msg.setError(MessageUtils.message("customer.noRepeat"));
+                return msg;
+            }
+            info.setCompanyId(user.getCompanyId());
+            customerInfoMapper.insert(info);
+        } else {
+            CustomerInfo customerInfo = customerInfoMapper.selectById(info.getId());
+            nameList.remove(customerInfo.getCustomerName());
+            codeList.remove(customerInfo.getCustomerCode());
+            if(nameList.contains(info.getCustomerName())){
+                //msg.setError("客户名称已存在");
+                msg.setError(MessageUtils.message("customer.nameRepeat"));
+                return msg;
+            }
+            if(codeList.contains(info.getCustomerCode())){
+                //msg.setError("客户编号已存在");
+                msg.setError(MessageUtils.message("customer.noRepeat"));
+                return msg;
+            }
+            info.setCompanyId(user.getCompanyId());
+            customerInfoMapper.updateById(info);
+            //更新项目表中的客户名称
+            Project p = new Project();
+            p.setCustomerName(info.getCustomerName());
+            projectMapper.update(p, new QueryWrapper<Project>().eq("customer_id", info.getId()));
+        }
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        int r = customerInfoMapper.delete(new QueryWrapper<CustomerInfo>().eq("id", id).eq("company_id", user.getCompanyId()));
+        if (r <= 0) {
+            //msg.setError("无权删除");
+            msg.setError(MessageUtils.message("customer.accessError"));
+        }
+        return msg;
+    }
+    @RequestMapping("/batchDelete")
+    public HttpRespMsg batchDelete(String batchIds) {
+        HttpRespMsg msg = new HttpRespMsg();
+        if(!batchIds.equals("")&&!StringUtils.isEmpty(batchIds)){
+            String[] split = batchIds.split(",");
+            List<String> list = Arrays.asList(split);
+            String token = request.getHeader("TOKEN");
+            User user = userMapper.selectById(token);
+            List<Project> projectList = projectMapper.selectList(new QueryWrapper<Project>().in("customer_id", list).eq("company_id", user.getCompanyId()));
+            System.out.println(projectList);
+            if(projectList.size()>0){
+                List<String> collect = projectList.stream().map(pro -> pro.getCustomerName()).collect(Collectors.toList());
+                String s = String.valueOf(collect);
+                //msg.setError("客户"+s+"已被使用");
+                msg.setError(MessageUtils.message("customer.UsedError",s));
+                return msg;
+            }
+            int r = customerInfoMapper.delete(new QueryWrapper<CustomerInfo>().eq("id", list.get(0)).eq("company_id", user.getCompanyId()));
+            if (r <= 0) {
+                //msg.setError("无权删除");
+                msg.setError(MessageUtils.message("customer.accessError"));
+                return msg;
+            }
+            customerInfoMapper.deleteBatchIds(list);
+        }
+        return msg;
+    }
+
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(@RequestParam Integer pageIndex, @RequestParam Integer pageSize, String keyword, String sortProp, Integer sortOrder) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        QueryWrapper<CustomerInfo> queryWrapper = new QueryWrapper<CustomerInfo>().eq("company_id", user.getCompanyId());
+        if (!StringUtils.isEmpty(keyword)) {
+            queryWrapper.like("customer_name", keyword);
+        }
+        if (!StringUtils.isEmpty(sortProp)) {
+            if (sortOrder == 0) {
+                //降序
+                queryWrapper.orderByDesc(sortProp);
+            } else {
+                queryWrapper.orderByAsc(sortProp);
+            }
+        } else {
+            queryWrapper.orderByDesc("id");
+        }
+        IPage<CustomerInfo> projectIPage = customerInfoMapper.selectPage(new Page<>(pageIndex, pageSize),
+                queryWrapper);
+        List<CustomerInfo> list = projectIPage.getRecords();
+        Long total = projectIPage.getTotal();
+        Map<String, Object> map = new HashMap<>();
+        map.put("records", list);
+        map.put("total", total);
+        msg.data = map;
+        return msg;
+    }
+
+    @RequestMapping("/getAll")
+    public HttpRespMsg getAll() {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        List<CustomerInfo> all = customerInfoMapper.getAll(user.getCompanyId());
+        msg.data = all;
+        return msg;
+    }
+    @RequestMapping("/importData")
+    public HttpRespMsg importData(HttpServletRequest request, MultipartFile file){
+        return customerInfoService.importData(request,file);
+    }
+
+    @RequestMapping("/exportData")
+    public HttpRespMsg exportData(){
+        return customerInfoService.exportData(request);
+    }
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DdBillInfoController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-01-26
+ */
+@RestController
+@RequestMapping("/dd-bill-info")
+public class DdBillInfoController {
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DdCallbackController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-01
+ */
+@RestController
+@RequestMapping("/dd-callback")
+public class DdCallbackController {
+
+}
+

+ 151 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentController.java

@@ -0,0 +1,151 @@
+package com.management.platform.controller;
+
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.management.platform.entity.vo.DepartmentVO;
+import com.management.platform.service.DepartmentService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+
+/**
+ * <p>
+ * 部门 前端控制器
+ * </p>
+ *
+ * @author 吴涛涛
+ * @since 2020-02-11
+ */
+@RestController
+@RequestMapping("/department")
+public class DepartmentController {
+
+    @Autowired
+    private DepartmentService departmentService;
+    @Resource
+    private HttpServletRequest request;
+    /**
+     * 获取带有层级的部门列表
+     */
+    @RequestMapping("/list")
+    public HttpRespMsg getDepartment(HttpServletRequest request) {
+        return departmentService.getDepartmentList(request);
+    }
+
+    /**
+     * 对部门进行排序
+     * @param request
+     * @return
+     */
+    @RequestMapping("/sortList")
+    public HttpRespMsg sortList(HttpServletRequest request,String list) {
+        List<DepartmentVO> departmentVOS = JSONArray.parseArray(list, DepartmentVO.class);
+        return departmentService.sortList(request,departmentVOS);
+    }
+
+    @RequestMapping("/listAllMemb")
+    public HttpRespMsg listAllMemb(HttpServletRequest request,String keyword,String cursor,@RequestParam(defaultValue = "0") Integer queryType) throws Exception {
+        return departmentService.listAllMemb(request,keyword,cursor,queryType);
+    }
+
+    //获取我可以管辖到的人员列表,进行代填时选择的人员列表用到
+    @RequestMapping("/listMyMembs")
+    public HttpRespMsg listMyMembs(HttpServletRequest request) {
+        return departmentService.listMyMembs(request);
+    }
+
+    /**
+     * 获取不带有层级的部门列表
+     */
+    @RequestMapping("/normalList")
+    public HttpRespMsg getDepartmentNormal(HttpServletRequest request) {
+        return departmentService.getNormalDepartmentList(request);
+    }
+
+
+    /**
+     * 新增部门
+     * name 部门名称
+     * parentId 父级部门id
+     */
+    @RequestMapping("/add")
+    public HttpRespMsg insertDepartment(@RequestParam String name, Integer parentId, String managerId, String reportAuditUserid,String otherManagerIds, Integer isEnableMulti,String deptCode,HttpServletRequest request) {
+        return departmentService.insertDepartment(name, parentId, managerId, reportAuditUserid,otherManagerIds, isEnableMulti, deptCode, request);
+    }
+
+    /**
+     * 修改部门名称
+     * id 部门id
+     * name 部门名称
+     */
+    @RequestMapping("/edit")
+    public HttpRespMsg updateDepartment(@RequestParam Integer id, @RequestParam String name, String managerId, String reportAuditUserid,String otherManagerIds,Integer pushToSap, Integer isEnableMulti, String deptCode, HttpServletRequest request) {
+        return departmentService.updateDepartment(id, name, managerId, reportAuditUserid,otherManagerIds,pushToSap,isEnableMulti, deptCode, request);
+    }
+
+    /**
+     * 删除部门
+     * id 部门id
+     */
+    @RequestMapping("/delete")
+    public HttpRespMsg deleteDepartment(@RequestParam Integer id, HttpServletRequest request) {
+        return departmentService.deleteDepartment(id, request);
+    }
+
+    /**
+     * 获取部门的统计工时成本
+     */
+    @RequestMapping("/departmentStatistic")
+    public HttpRespMsg getDepartmentStatistics(Integer parentDeptId, String startDate, String endDate, HttpServletRequest request) {
+        return departmentService.getDepartmentStatistics(parentDeptId, startDate, endDate, request);
+    }
+
+    /**
+     * 获取某个部门或者公司全部的人员的统计
+     * departmentId 要查询的项目
+     */
+    @RequestMapping("/userStatistic")
+    public HttpRespMsg getUserStatistics(String startDate, String endDate, Integer departmentId, HttpServletRequest request) {
+        return departmentService.getUserStatistics(startDate, endDate, departmentId, request);
+    }
+
+    @RequestMapping("/getUserCustomDataStatistic")
+    public HttpRespMsg getUserCustomDataStatistic(String startDate, String endDate, Integer departmentId, HttpServletRequest request) {
+        return departmentService.getUserCustomDataStatistic(startDate, endDate, departmentId, request);
+    }
+
+    @RequestMapping("/getDeptCustomDataStatistic")
+    public HttpRespMsg getDeptCustomDataStatistic(String startDate, String endDate, Integer departmentId, HttpServletRequest request){
+        return departmentService.getDeptCustomDataStatistic(startDate,endDate,departmentId,request);
+    }
+
+    /**
+     * 按人员导出工时统计,可选人员
+     * departmentId 要查询的项目
+     */
+    @RequestMapping("/exportUserStatistic")
+    public HttpRespMsg exportUserStatistic(boolean mainProjectColumn, String startDate, String endDate, String userIds, HttpServletRequest request) {
+        return departmentService.exportUserStatistic(mainProjectColumn, startDate, endDate, userIds, request);
+    }
+
+
+    @RequestMapping("/exportDeptStatistic")
+    public HttpRespMsg exportDeptStatistic(String startDate, String endDate, HttpServletRequest request) {
+        return departmentService.exportDeptStatistic(startDate, endDate, request);
+    }
+
+
+    @RequestMapping("/exportCustomDataSum")
+    public HttpRespMsg exportCustomDataSum(String startDate, String endDate) {
+        return departmentService.exportCustomDataSum(startDate, endDate, request);
+    }
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentDingdingController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-27
+ */
+@RestController
+@RequestMapping("/department-dingding")
+public class DepartmentDingdingController {
+
+}
+

+ 37 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentEnableController.java

@@ -0,0 +1,37 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.DepartmentEnable;
+import com.management.platform.mapper.DepartmentEnableMapper;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-02-06
+ */
+@RestController
+@RequestMapping("/department-enable")
+public class DepartmentEnableController {
+
+    private final DepartmentEnableMapper departmentEnableMapper;
+
+    public DepartmentEnableController(DepartmentEnableMapper departmentEnableMapper) {
+        this.departmentEnableMapper = departmentEnableMapper;
+    }
+
+    @RequestMapping("/get")
+    public HttpRespMsg get(Integer departmentId) {
+        DepartmentEnable departmentEnable = departmentEnableMapper.selectById(departmentId);
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = departmentEnable;
+        return msg;
+    }
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentFeishuController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-03-01
+ */
+@RestController
+@RequestMapping("/department-feishu")
+public class DepartmentFeishuController {
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentOtherManagerController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-07-26
+ */
+@RestController
+@RequestMapping("/department-other-manager")
+public class DepartmentOtherManagerController {
+
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DepartmentWxController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-11-28
+ */
+@RestController
+@RequestMapping("/department-wx")
+public class DepartmentWxController {
+
+}
+

+ 69 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DeviceController.java

@@ -0,0 +1,69 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.Device;
+import com.management.platform.service.DeviceService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-10-08
+ */
+@RestController
+@RequestMapping("/device")
+public class DeviceController {
+
+    @Resource
+    private DeviceService deviceService;
+
+    @RequestMapping("/getDevicePage")
+    public HttpRespMsg getDevicePage (HttpServletRequest request, @RequestParam Integer pageIndex, @RequestParam Integer pageSize,@RequestParam(required = false) String deviceCode,@RequestParam(required = false) String deviceName){
+        return deviceService.getDevicePage(request,pageIndex,pageSize,deviceCode,deviceName);
+    }
+
+    @RequestMapping("/updateOrInsert")
+    public HttpRespMsg updateOrInsert (HttpServletRequest request, @RequestParam(required = false) Integer id,
+                                       @RequestParam(required = false) String deviceCode,
+                                       @RequestParam(required = false) String deviceName,
+                                       @RequestParam(required = false) String deviceModel,
+                                       @RequestParam(required = false) String manufacturer,
+                                       @RequestParam(required = false) String purchaseDate,
+                                       @RequestParam(required = false) String maintenanceDate
+                                       ){
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        LocalDate parse_purchaseDate = LocalDate.parse(purchaseDate, formatter);
+        LocalDate parse_maintenanceDate = LocalDate.parse(maintenanceDate, formatter);
+        return deviceService.updateOrInsert(request,id,deviceCode,deviceName,deviceModel,manufacturer,parse_purchaseDate,parse_maintenanceDate);
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete (HttpServletRequest request, Device device){
+        return deviceService.delete(request,device);
+    }
+
+    @RequestMapping("/getDeviceDetail")
+    public HttpRespMsg getDeviceDetail (HttpServletRequest request, Device device){
+        return deviceService.getDeviceDetail(request,device);
+    }
+
+    @RequestMapping("/exportDevice")
+    public HttpRespMsg exportDevice (HttpServletRequest request,@RequestParam(required = false) String deviceCode,@RequestParam(required = false) String deviceName){
+        return deviceService.exportDevice(request,deviceCode,deviceName);
+    }
+
+}
+

+ 53 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DeviceCostController.java

@@ -0,0 +1,53 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.DeviceCost;
+import com.management.platform.entity.User;
+import com.management.platform.service.DeviceCostService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-10-08
+ */
+@RestController
+@RequestMapping("/device-cost")
+public class DeviceCostController {
+
+    @Resource
+    private DeviceCostService deviceCostService;
+
+    @RequestMapping("/getDeviceCostPage")
+    public HttpRespMsg getDeviceCostPage (HttpServletRequest request, DeviceCost deviceCost){
+        return deviceCostService.getDeviceCostPage(request,deviceCost);
+    }
+
+    @RequestMapping("/edit")
+    public HttpRespMsg edit (DeviceCost deviceCost){
+        return deviceCostService.edit(deviceCost);
+    }
+
+    @RequestMapping("/deleteBatch")
+    public HttpRespMsg deleteBatch (String ids){
+        return deviceCostService.deleteBatch(ids);
+    }
+
+    @RequestMapping("/importDeviceCost")
+    public HttpRespMsg importDeviceCost (HttpServletRequest request, MultipartFile file,String ymonthStr){
+        return deviceCostService.importDeviceCost(request,file,ymonthStr);
+    }
+
+}
+

+ 83 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DeviceLogController.java

@@ -0,0 +1,83 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.Device;
+import com.management.platform.entity.DeviceCost;
+import com.management.platform.entity.DeviceLog;
+import com.management.platform.service.DeviceLogService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-10-08
+ */
+@RestController
+@RequestMapping("/device-log")
+public class DeviceLogController {
+
+    @Resource
+    private DeviceLogService deviceLogService;
+
+    /**
+     * 传参 参数: startTime,endTime 字符串
+     * @param request
+     * @param deviceLog
+     * @return
+     */
+    @RequestMapping("/getDeviceLogList")
+    public HttpRespMsg getDeviceLogList (HttpServletRequest request, DeviceLog deviceLog){
+        return deviceLogService.getDeviceLogList(request,deviceLog);
+    }
+
+    /**
+     * 传参 参数: startTime,endTime字符串,id
+     * @param request
+     * @param deviceLog
+     * @return
+     */
+    @RequestMapping("/getDeviceLogDetail")
+    public HttpRespMsg getDeviceLogDetail (HttpServletRequest request, DeviceLog deviceLog){
+        return deviceLogService.getDeviceLogDetail(request,deviceLog);
+    }
+
+
+    /**
+     * 参数 id,projectId,startTime,deviceLogId,startOrEnd,useTime
+     * @param request
+     * @param device
+     * @return
+     */
+    @RequestMapping("/updateDeviceUsageStatus")
+    @Transactional(rollbackFor = Exception.class)
+    public HttpRespMsg updateDeviceUsageStatus (HttpServletRequest request, Device device){
+        return deviceLogService.updateDeviceUsageStatus(request,device);
+    }
+
+    @RequestMapping("/getDeviceTimeCost")
+    public HttpRespMsg getDeviceTimeCost(HttpServletRequest request,String startDate, String endDate, Integer projectId) {
+        return deviceLogService.getDeviceTimeCost(request,startDate, endDate,projectId);
+    }
+
+    @RequestMapping("/exportDeviceTimeCost")
+    public HttpRespMsg exportDeviceTimeCost(HttpServletRequest request,String startDate, String endDate, Integer projectId) {
+        return deviceLogService.exportDeviceTimeCost(request,startDate, endDate,projectId);
+    }
+
+    @RequestMapping("/exportDeviceTimeCostByMonth")
+    public HttpRespMsg exportDeviceTimeCostByMonth(HttpServletRequest request,String date, Integer projectId) {
+        return deviceLogService.exportDeviceTimeCostByMonth(request,date,projectId);
+    }
+
+}
+

+ 314 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DingDingController.java

@@ -0,0 +1,314 @@
+package com.management.platform.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.*;
+import com.management.platform.service.CompanyDingdingService;
+import com.management.platform.service.DingDingService;
+import com.management.platform.service.impl.*;
+import com.management.platform.util.*;
+import com.taobao.api.ApiException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.time.format.DateTimeFormatter;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("/dingding")
+public class DingDingController {
+
+    private final Logger bizLogger = LoggerFactory.getLogger(getClass());
+
+    String aesKey = "ktmbamhymjsf60ndwp6n81mnu92847oynsgj9e0zr9v";
+    String token = "cf776d62c5fb3508b5d8c2cbb9f3df0c";
+
+    String suiteKey = "suitejwoq9dw4bxv4stdb";
+    String suiteSecret = "o-TWFLkFe8YbJsa_025JOj_JEWydP5GR3eigt1Yn1rtx5dTcryTJiSA6KEih3Bi4";
+
+    @Value("${configEnv.isPrivateDeploy}")
+    private boolean isPrivateDeploy;
+
+    @Resource
+    private DingDingService dingDingService;
+    static ExecutorService executorService = Executors.newCachedThreadPool();
+    @Resource
+    private CompanyDingdingService companyDingdingService;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private CompanyDingdingMapper companyDingdingMapper;
+    @Resource
+    private TimeTypeMapper timeTypeMapper;
+    @Resource
+    private CompanyMapper companyMapper;
+
+
+    @RequestMapping("/callback")
+    public Map<String, String> dingCallback(
+            @RequestParam(value = "signature") String signature,
+            @RequestParam(value = "timestamp") String timestamp,
+            @RequestParam(value = "nonce") String nonce,
+            @RequestBody(required = false) JSONObject body,
+            @RequestParam(value = "innerAppKey", required = false) String innerAppKey
+    ) {
+        System.out.println("接收到ding call back"+(isPrivateDeploy?", innerAppKey="+innerAppKey:""));
+        if (body == null) {
+            DingCallbackCrypto callbackCrypto = null;
+            try {
+                callbackCrypto = new DingCallbackCrypto(token, aesKey, isPrivateDeploy?innerAppKey:suiteKey);
+                Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
+                LocalDateTime now = LocalDateTime.now();
+                DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
+                System.out.println(dtf.format(now)+" 给钉钉返回数据了:"+successMap);
+                return successMap;
+            } catch (DingCallbackCrypto.DingTalkEncryptException e) {
+                e.printStackTrace();
+            }
+        }
+        try {
+            // 1. 从http请求中获取加解密参数
+
+            // 2. 使用加解密类型
+            // Constant.OWNER_KEY 说明:
+            // 1、开发者后台配置的订阅事件为应用级事件推送,
+            //      此时OWNER_KEY为应用的APP_KEY(企业内部应用)或SUITE_KEY(三方应用)。
+            // 2、调用订阅事件接口订阅的事件为企业级事件推送,
+            //      此时OWNER_KEY为:企业的CORP_ID(企业内部应用)或SUITE_KEY(三方应用)
+            DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(token, aesKey, isPrivateDeploy?innerAppKey:suiteKey);
+            String encryptMsg = body.getString("encrypt");
+            String decryptMsg = callbackCrypto.getDecryptMsg(signature, timestamp, nonce, encryptMsg);
+            dingDingService.asyncHandleMsg(decryptMsg);
+
+            // 5. 返回success的加密数据
+            Map<String, String> successMap = callbackCrypto.getEncryptedMap("success");
+            LocalDateTime now = LocalDateTime.now();
+            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
+            System.out.println(dtf.format(now)+" 给钉钉返回数据了:"+successMap);
+            return successMap;
+        } catch (DingCallbackCrypto.DingTalkEncryptException e) {
+            e.printStackTrace();
+            System.out.println(e.getMessage());
+        }
+        return null;
+    }
+
+    @RequestMapping("/inactiveUserNotInAuthRange")
+    public HttpRespMsg inactiveUserNotInAuthRange(String corpid) {
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = dingDingService.inactiveUserNotInAuthRange(corpid);
+        return msg;
+    }
+
+    @RequestMapping("/syncCorpMembs")
+    public HttpRespMsg syncCorpMembs(String corpid) {
+        try {
+            System.out.println("===========手动调用syncCorpMembs请求接口===========");
+            String rest = dingDingService.syncCorpMembs(corpid);
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.data = rest;
+            return msg;
+        } catch (Exception e) {
+            CompanyDingding dingding = companyDingdingMapper.selectById(corpid);
+            Company company = companyMapper.selectById(dingding.getCompanyId());
+            String token=company.getCompanyName();
+            //移除锁
+            DingDingServiceImpl.syncLog.remove(token);
+            DingDingServiceImpl.syncLog.remove(company.getId()+"_status");
+
+            e.printStackTrace();
+            System.err.println(e.getMessage());
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError(e.getMessage());
+            return msg;
+        }
+    }
+
+    @RequestMapping("/getUserByCode")
+    public HttpRespMsg getUserByCode(String code, String corpid) {
+        return dingDingService.getUserByCode(code, corpid);
+    }
+
+    @RequestMapping("/syncCorpInfo")
+    public HttpRespMsg syncCorpInfo(String corpid) {
+        return dingDingService.syncCorpInfo(corpid);
+    }
+
+    @RequestMapping("/syncCorpAgent")
+    public HttpRespMsg syncCorpAgent(String corpid) {
+        return dingDingService.syncCorpAgent(corpid);
+    }
+
+    @RequestMapping("/getUnActiveCorp")
+    public HttpRespMsg getUnActiveCorp() {
+        return dingDingService.getUnActiveCorp();
+    }
+
+    @RequestMapping("/reAuthCorp")
+    public HttpRespMsg reAuthCorp(String corpid) {
+        return dingDingService.reAuthCorp(corpid);
+    }
+    @RequestMapping("/getAuthInfo")
+    public HttpRespMsg getAuthInfo(String corpid) {
+        try {
+            return dingDingService.getAuthInfo(corpid);
+        } catch (Exception e) {
+            e.printStackTrace();
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError(e.getMessage());
+            return msg;
+        }
+    }
+
+    @RequestMapping("/pushLeaveAuditAlert")
+    public HttpRespMsg pushLeaveAuditAlert(String userId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        User user = userMapper.selectById(userId);
+        System.out.println("测试发送审批给=="+user.getName());
+        CompanyDingding dingding = companyDingdingService.getOne(new QueryWrapper<CompanyDingding>().eq("company_id", user.getCompanyId()));
+        companyDingdingService.sendLeaveApplyAlertMsg(dingding.getCompanyId(), dingding.getAgentId(), "", user.getDingdingUserid());
+        return msg;
+    }
+
+    @RequestMapping("/syncCardTime")
+    public HttpRespMsg syncCardTime(Integer companyId, String userId, String startDate, String endDate) {
+        dingDingService.syncCardTime(companyId, userId, startDate, endDate);
+        return new HttpRespMsg();
+    }
+    @RequestMapping("/refreshUserCardTime")
+    public HttpRespMsg refreshUserCardTime(Integer companyId, String userId, String date) {
+        return dingDingService.refreshUserCardTime(companyId, userId, date);
+    }
+    @RequestMapping("/listUserScheduleByDay")
+    public HttpRespMsg listUserScheduleByDay(Integer companyId, String userId, String date) {
+        HttpRespMsg msg = new HttpRespMsg();
+        UserDingdingTime time = dingDingService.listUserScheduleByDay(companyId, userId, date);
+        msg.data = time;
+        return msg;
+    }
+
+//
+//    @RequestMapping("/syncLeaveTime")
+//    public HttpRespMsg syncLeaveTime(Integer companyId, String userId, String startDate, String endDate) {
+//        dingDingService.syncLeaveTime(companyId, userId, startDate, endDate);
+//        return new HttpRespMsg();
+//    }
+
+    @RequestMapping("/fixAttendance")
+    public HttpRespMsg fixAttendance(Integer companyId) {
+        return dingDingService.fixAttendance(companyId);
+    }
+
+
+
+    @RequestMapping("/syncUserWorkData")
+    public HttpRespMsg syncUserWorkData(Integer companyId, String userId, String startDate, String endDate, @RequestParam(required = false, defaultValue = "false") boolean onlySyncAttendance) {
+        CompanyDingding dingding = companyDingdingMapper.selectOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId).isNotNull("inner_appkey"));
+        HttpRespMsg msg = new HttpRespMsg();
+        if (startDate.compareTo(endDate) > 0) {
+            //msg.setError("开始日期不能晚于结束日期");
+            msg.setError(MessageUtils.message("DD.dateError"));
+            return msg;
+        }
+
+        if (companyId != null) {
+            if (dingding == null) {
+                //msg.setError("该公司没有设置innerAppkey和innerAppSecrt");
+                msg.setError(MessageUtils.message("DD.keyAndSecretError"));
+                return msg;
+            } else {
+                long t1 = System.currentTimeMillis();
+                dingDingService.syncUserWorkData(dingding, userId, startDate, endDate, true, onlySyncAttendance);
+                long t2 = System.currentTimeMillis();
+                System.out.println("总共耗时:"+(t2-t1)+"ms");
+            }
+        } else {
+            List<TimeType> timeTypeList = timeTypeMapper.selectList(new QueryWrapper<TimeType>().eq("sync_dingding", 1));
+            List<Integer> compIds = timeTypeList.stream().map(TimeType::getCompanyId).collect(Collectors.toList());
+            //企业内部应用才有权限调用
+            List<CompanyDingding> dingdingList = companyDingdingMapper.selectList(new QueryWrapper<CompanyDingding>().in("company_id", compIds)
+                    .isNotNull("inner_appkey"));
+            System.out.println("==========获取钉钉内部应用的数量是:"+dingdingList.size());
+            if (dingdingList.size() == 0) {
+                //msg.setError("没有设置innerAppkey和innerAppSecrt的数据");
+                msg.setError(MessageUtils.message("DD.keyAndSecretError"));
+                return msg;
+            } else {
+                long t1 = System.currentTimeMillis();
+                for (int i=0;i<dingdingList.size(); i++) {
+                    dingDingService.syncUserWorkData(dingdingList.get(i), userId, startDate, endDate, true, onlySyncAttendance);
+                }
+                long t2 = System.currentTimeMillis();
+                System.out.println("总共耗时:"+(t2-t1)+"ms");
+            }
+        }
+
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/testWaitingApply")
+    public HttpRespMsg testWaitingApply(Integer companyId) {
+        CompanyDingding companyDingding = companyDingdingService.getOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId));
+        companyDingdingService.sendReportWaitingApplyMsg(companyId, companyDingding.getAgentId(),
+                4L, "040534176023851922");
+        return new HttpRespMsg();
+    }
+//
+    @RequestMapping("/syncLeaveQuotaData")
+    public HttpRespMsg syncLeaveQuotaData(Integer companyId, HttpServletRequest request) {
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        return dingDingService.syncLeaveQuotaData(companyId);
+    }
+
+    @RequestMapping("/testSendBusTripLink")
+    public HttpRespMsg testSendBusTripLink(Integer companyId) {
+        CompanyDingding dingding = companyDingdingMapper.selectOne(new QueryWrapper<CompanyDingding>().eq("company_id", companyId));
+
+        companyDingdingService.sendBusinessTripSettingMsg(companyId, dingding.getAgentId(), "040534176023851922");
+        return new HttpRespMsg();
+    }
+
+    /**
+     * 初始化内部应用的系统数据
+     * @return
+     */
+    @RequestMapping("/initSystem")
+    public HttpRespMsg initSystem(String corpid) {
+        try {
+            return dingDingService.initSystem(corpid);
+        } catch (ApiException e) {
+            e.printStackTrace();
+            String errMsg = e.getErrMsg();
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError(errMsg);
+            return msg;
+        }
+    }
+
+    @RequestMapping("/removeCompInfo")
+    public HttpRespMsg removeCompInfo(String corpid) {
+        return dingDingService.removeCompInfo(corpid);
+    }
+
+    @RequestMapping("/initSuperManager")
+    public HttpRespMsg initSuperManager(String corpid, String name) {
+        return dingDingService.initSuperManager(corpid, name);
+    }
+
+}

+ 47 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/DirtyCleanController.java

@@ -0,0 +1,47 @@
+package com.management.platform.controller;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.Report;
+import com.management.platform.mapper.ReportMapper;
+import com.management.platform.service.ReportService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.ListUtil;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+@RestController
+@RequestMapping("/clean")
+public class DirtyCleanController {
+    @Resource
+    private ReportService reportService;
+    @Resource
+    private ReportMapper reportMapper;
+
+
+
+    @RequestMapping("/removeDuplicate")
+    public HttpRespMsg removeDuplicate(Integer companyId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        List<Map<String, Object>> list = reportMapper.getDuplicate(companyId);
+        System.out.println("共=="+list.size()+"条重复记录");
+        List<Integer> reportIds = new ArrayList<>();
+        for(int i=0;i<list.size(); i++) {
+            Map map = list.get(i);
+            String ids = (String)map.get("reportIds");
+            reportIds.addAll(ListUtil.convertIntegerIdsArrayToList(ids));
+        }
+        System.out.println(reportIds);
+        System.out.println("日报记录report ="+reportIds.size());
+//        QueryWrapper<Report> queryWrapper = new QueryWrapper<Report>().in("id", reportIds).eq("company_id", companyId);
+//        reportMapper.delete(queryWrapper);
+//        List<Report> rList = reportMapper.selectList();
+//        System.out.println("去查找的日报数量="+rList.size());
+
+        return msg;
+    }
+}

+ 101 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/EarningSnapshotController.java

@@ -0,0 +1,101 @@
+package com.management.platform.controller;
+
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.EarningSnapshot;
+import com.management.platform.entity.Project;
+import com.management.platform.entity.ProjectBasecost;
+import com.management.platform.entity.User;
+import com.management.platform.entity.vo.SysRichFunction;
+import com.management.platform.mapper.ProjectMapper;
+import com.management.platform.mapper.SysFunctionMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.EarningSnapshotService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.ListUtil;
+import com.management.platform.util.MessageUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-05-15
+ */
+@RestController
+@RequestMapping("/earning-snapshot")
+public class EarningSnapshotController {
+    @Resource
+    private HttpServletRequest request;
+
+    @Resource
+    private EarningSnapshotService earningSnapshotService;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private ProjectMapper projectMapper;
+    @Resource
+    SysFunctionMapper sysFunctionMapper;
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(Integer projectId) {
+        String userId = request.getHeader("Token");
+        User user = userMapper.selectById(userId);
+        HttpRespMsg msg = new HttpRespMsg();
+        Project project = projectMapper.selectById(projectId);
+
+        List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看成本基线");
+        if (userId.equals(project.getInchargerId()) || userId.equals(project.getCreatorId()) || functionList.size() > 0) {
+            List<EarningSnapshot> list = earningSnapshotService.list(new QueryWrapper<EarningSnapshot>().eq("project_id", projectId).orderByDesc("id"));
+            for (EarningSnapshot snapshot : list) {
+                if (snapshot.getCostData() != null) {
+                    JSONArray array = JSONArray.parseArray(snapshot.getCostData());
+                    List<ProjectBasecost> costList = new ArrayList<>();
+                    for (int i=0;i<array.size();i++) {
+                        ProjectBasecost projectBasecost = JSONObject.toJavaObject(array.getJSONObject(i), ProjectBasecost.class);
+                        costList.add(projectBasecost);
+                    }
+                    snapshot.setCostList(costList);
+                    snapshot.setCostData(null);
+                }
+            }
+            msg.data = list;
+        } else {
+
+            //msg.setError("无权查看");
+            msg.setError(MessageUtils.message("access.viewError"));
+        }
+
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer projectId, String ids) {
+        String userId = request.getHeader("Token");
+        User user = userMapper.selectById(userId);
+
+        List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "校正成本基线");
+        HttpRespMsg msg = new HttpRespMsg();
+        Project project = projectMapper.selectById(projectId);
+        if (userId.equals(project.getInchargerId()) || userId.equals(project.getCreatorId()) || functionList.size() > 0) {
+            List<Integer> idArray = ListUtil.convertIntegerIdsArrayToList(ids);
+            earningSnapshotService.removeByIds(idArray);
+        } else {
+            //msg.setError("无权操作");
+            msg.setError(MessageUtils.message("access.operationError"));
+        }
+
+        return msg;
+    }
+}
+

+ 47 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/EquipmentOwnerController.java

@@ -0,0 +1,47 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.EquipmentOwner;
+import com.management.platform.service.EquipmentOwnerService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-02-21
+ */
+@RestController
+@RequestMapping("/equipment-owner")
+public class EquipmentOwnerController {
+
+    @Resource
+    private EquipmentOwnerService equipmentOwnerService;
+
+    @Resource
+    private HttpServletRequest request;
+    @RequestMapping("/addOrUpdate")
+    public HttpRespMsg addOrUpdate(EquipmentOwner equipmentOwner){
+        return equipmentOwnerService.addOrUpdate(equipmentOwner, request);
+    }
+
+    @RequestMapping("/getList")
+    public HttpRespMsg getList(){
+        return equipmentOwnerService.getList(request);
+    }
+
+    @RequestMapping("/removeEquipmentOwner")
+    public HttpRespMsg removeEquipmentOwner(Integer id){
+        return equipmentOwnerService.removeEquipmentOwner(id,request);
+    }
+
+}
+

+ 32 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ErpOrderInfoController.java

@@ -0,0 +1,32 @@
+package com.management.platform.controller;
+
+import com.management.platform.entity.ErpOrderInfo;
+import com.management.platform.service.ErpOrderInfoService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping("/erpOrderInfo")
+public class ErpOrderInfoController {
+
+
+    @Resource
+    private ErpOrderInfoService erpOrderInfoService;
+
+    @RequestMapping("/getInfoPage")
+    public HttpRespMsg getInfoPage(ErpOrderInfo erpOrderInfo, HttpServletRequest request) {
+        return erpOrderInfoService.getInfoPage(erpOrderInfo,request);
+    }
+
+
+    @RequestMapping("/getInfoByProjectId")
+    public HttpRespMsg getInfoByProjectId(@RequestParam String projectId, HttpServletRequest request) {
+        return erpOrderInfoService.getInfoByProjectId(projectId,request);
+    }
+
+}

+ 55 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/EstimateTimeSettingController.java

@@ -0,0 +1,55 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.EstimateTimeSettingMapper;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-11-19
+ */
+@RestController
+@RequestMapping("/estimate-time-setting")
+public class EstimateTimeSettingController {
+
+    @Resource
+    private EstimateTimeSettingMapper estimateTimeSettingMapper;
+
+    @RequestMapping("/get")
+    public HttpRespMsg get(Integer companyId) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        EstimateTimeSetting estimateTimeSetting = estimateTimeSettingMapper.selectById(companyId);
+        if (estimateTimeSetting == null) {
+            estimateTimeSetting = new EstimateTimeSetting();
+            estimateTimeSetting.setCompanyId(companyId);
+            estimateTimeSettingMapper.insert(estimateTimeSetting);
+            estimateTimeSetting = estimateTimeSettingMapper.selectById(companyId);
+        }
+        httpRespMsg.data = estimateTimeSetting;
+        return httpRespMsg;
+    }
+
+    @RequestMapping("/save")
+    public HttpRespMsg save(EstimateTimeSetting record) {
+        Boolean success = estimateTimeSettingMapper.updateById(record) > 0;
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        if (!success) {
+            httpRespMsg.setError(MessageUtils.message("other.saveError"));
+        }
+        return httpRespMsg;
+    }
+}
+

+ 63 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpenseAuditSettingController.java

@@ -0,0 +1,63 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.ExpenseAuditSetting;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.ExpenseAuditSettingService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-07-20
+ */
+@RestController
+@RequestMapping("/expense-audit-setting")
+public class ExpenseAuditSettingController {
+
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private ExpenseAuditSettingService expenseAuditSettingService;
+    @Resource
+    private UserMapper userMapper;
+
+    @RequestMapping("get")
+    public HttpRespMsg get() {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("Token");
+        User user = userMapper.selectById(token);
+        Integer companyId = user.getCompanyId();
+        ExpenseAuditSetting byId = expenseAuditSettingService.getById(companyId);
+        if (byId == null) {
+            //给默认值
+            byId = new ExpenseAuditSetting();
+            byId.setCompanyId(companyId);
+            byId.setAuditType(0);
+        }
+        msg.data = byId;
+        return msg;
+    }
+
+    @RequestMapping("update")
+    public HttpRespMsg update(ExpenseAuditSetting setting) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("Token");
+        User user = userMapper.selectById(token);
+        Integer companyId = user.getCompanyId();
+        setting.setCompanyId(companyId);
+        expenseAuditSettingService.saveOrUpdate(setting);
+        return msg;
+    }
+}
+

+ 121 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpenseItemController.java

@@ -0,0 +1,121 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.CompanyDingding;
+import com.management.platform.entity.ExpenseItem;
+import com.management.platform.entity.WxCorpInfo;
+import com.management.platform.entity.vo.ExpenseItemVO;
+import com.management.platform.mapper.CompanyDingdingMapper;
+import com.management.platform.mapper.ExpenseItemMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.mapper.WxCorpInfoMapper;
+import com.management.platform.service.ExcelExportService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-05-17
+ */
+@RestController
+@RequestMapping("/expense-item")
+public class ExpenseItemController {
+
+    @Resource
+    private ExpenseItemMapper expenseItemMapper;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private WxCorpInfoMapper wxCorpInfoMapper;
+    @Resource
+    private CompanyDingdingMapper companyDingdingMapper;
+    @Resource
+    private ExcelExportService excelExportService;
+    @Value(value = "${upload.path}")
+    private String path;
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(Integer projectId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        List<ExpenseItemVO> userExpenseDetail = expenseItemMapper.getUserExpenseDetail(projectId);
+        msg.data = userExpenseDetail;
+        return msg;
+    }
+
+    @RequestMapping("/exportData")
+    public HttpRespMsg exportData(Integer projectId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId,companyId));
+        CompanyDingding dingding = companyDingdingMapper.selectOne(new LambdaQueryWrapper<CompanyDingding>().eq(CompanyDingding::getCompanyId,companyId));
+        HttpRespMsg data = list(projectId);
+        List<ExpenseItemVO> itemVOS = (List<ExpenseItemVO>) data.getData();
+        List<List<String>> dataList=new ArrayList<>();
+        List<String> titleList=new ArrayList<>();
+        titleList.add("员工姓名");
+        titleList.add("所在部门");
+        titleList.add("费用日期");
+        titleList.add("费用类型");
+        titleList.add("票据类型");
+        titleList.add("金额(含税)");
+        titleList.add("税额");
+        titleList.add("金额(不含税)");
+        titleList.add("备注");
+        dataList.add(titleList);
+        for (ExpenseItemVO itemVO : itemVOS) {
+            List<String> item=new ArrayList<>();
+            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                String userName ="$userName="+String.valueOf(itemVO.getCorpwxUserId())+"$";
+                String deptName ="$departmentName="+String.valueOf(itemVO.getCorpwxDeptId())+"$";
+                item.add(userName);
+                item.add(deptName);
+            }else {
+                if(dingding!=null&&dingding.getContactNeedTranslate()==1){
+                    item.add("$userName="+itemVO.getUsername()+"$");
+                    item.add("$departmentName="+String.valueOf(itemVO.getCorpDdDeptId())+"$");
+                }else {
+                    item.add(itemVO.getUsername());
+                    item.add(itemVO.getDepartmentName());
+                }
+
+            }
+            item.add(itemVO.getHappenDate());
+            item.add(itemVO.getExpenseType());
+            item.add(itemVO.getInvoiceType()==null?"":(itemVO.getInvoiceType()==0?"增值税专用发票":"增值税普通发票"));
+            BigDecimal decimal = new BigDecimal(itemVO.getAmount()==null?0:itemVO.getAmount());
+            item.add(String.valueOf(itemVO.getAmount()==null?"0":itemVO.getAmount()));
+            item.add(String.valueOf(itemVO.getTaxValue()==null?"0":itemVO.getTaxValue()));
+            decimal=decimal.subtract(new BigDecimal(itemVO.getTaxValue()==null?0:itemVO.getTaxValue())).setScale(2,BigDecimal.ROUND_HALF_UP);
+            item.add(String.valueOf(decimal.doubleValue()));
+            item.add(itemVO.getRemark()==null?"":itemVO.getRemark());
+            dataList.add(item);
+        }
+        String fileUrlSuffix = "费用报销明细表_" + System.currentTimeMillis();
+        try {
+           return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding, fileUrlSuffix, dataList, path);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return msg;
+    }
+}
+
+

+ 193 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpenseMainTypeController.java

@@ -0,0 +1,193 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.*;
+import com.management.platform.service.ExpenseMainTypeService;
+import com.management.platform.service.ExpenseSheetService;
+import com.management.platform.service.ExpenseTypeService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-04-06
+ */
+@RestController
+@RequestMapping("/expense-main-type")
+public class ExpenseMainTypeController {
+
+    @Autowired
+    private ExpenseMainTypeService expenseMainTypeService;
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private ExpenseTypeMapper expenseTypeMapper;
+    @Resource
+    private ExpenseSheetMapper expenseSheetMapper;
+    @Resource
+    private CompanyMapper companyMapper;
+    @Resource
+    private ExpenseSheetService expenseSheetService;
+    @Resource
+    private ExpenseTypeService expenseTypeService;
+    @Resource
+    private ProjectBasecostSettingMapper projectBasecostSettingMapper;
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(){
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("token"));
+        List<ExpenseMainType> expenseMainTypes = expenseMainTypeService.list(new QueryWrapper<ExpenseMainType>().eq("company_id", user.getCompanyId()));
+        //获取basecostSetting名称
+        List<ProjectBasecostSetting> settings = projectBasecostSettingMapper.selectList(new QueryWrapper<ProjectBasecostSetting>().eq("company_id", user.getCompanyId()).eq("alarm_type", 0));
+        for (ExpenseMainType expenseMainType : expenseMainTypes) {
+            if (expenseMainType.getBasecostSettingId() != null) {
+                Stream<ProjectBasecostSetting> projectBasecostSettingStream = settings.stream().filter(setting -> setting.getId().equals(expenseMainType.getBasecostSettingId()));
+                Optional<ProjectBasecostSetting> first = projectBasecostSettingStream.findFirst();
+                if (first.isPresent()) {
+                    expenseMainType.setBasecostSettingName(first.get().getName());
+                }
+            }
+        }
+        httpRespMsg.data=expenseMainTypes;
+        return httpRespMsg;
+    }
+
+    @RequestMapping("/addOrMod")
+    public HttpRespMsg addOrMod(ExpenseMainType setting) {
+        Integer companyId = userMapper.selectById(request.getHeader("TOKEN")).getCompanyId();
+        HttpRespMsg msg = new HttpRespMsg();
+        if (StringUtils.isEmpty(setting.getName())) {
+            //msg.setError("名称不能为空");
+            msg.setError(MessageUtils.message("Company.nullNameError"));
+            return msg;
+        }
+        if (setting.getId() == null) {
+            setting.setCompanyId(companyId);
+            int num = expenseMainTypeService.count(new QueryWrapper<ExpenseMainType>().eq("company_id", setting.getCompanyId()));
+            if(num>=10){
+                msg.setError("已有类型上限为10");
+                return msg;
+            }
+            int count = expenseMainTypeService.count(new QueryWrapper<ExpenseMainType>().eq("name", setting.getName()).eq("company_id", setting.getCompanyId()));
+            if (count > 0) {
+                //msg.setError("该名称已存在");
+                msg.setError(MessageUtils.message("Company.nameRepeat"));
+            } else {
+                expenseMainTypeService.save(setting);
+                msg.data = expenseMainTypeService.list(new QueryWrapper<ExpenseMainType>().eq("company_id", setting.getCompanyId()));
+            }
+        } else {
+            int count = expenseMainTypeService.count(new QueryWrapper<ExpenseMainType>().eq("name", setting.getName())
+                    .eq("company_id", setting.getCompanyId()).ne("id", setting.getId()));
+            if (count > 0) {
+                //msg.setError("该名称已存在");
+                msg.setError(MessageUtils.message("Company.nameRepeat"));
+            } else {
+                expenseMainTypeService.updateById(setting);
+                msg.data = expenseMainTypeService.list(new QueryWrapper<ExpenseMainType>().eq("company_id", setting.getCompanyId()));
+            }
+        }
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        ExpenseMainType expenseMainType = expenseMainTypeService.getById(id);
+        Integer count = expenseTypeMapper.selectCount(new QueryWrapper<ExpenseType>().eq("main_type", expenseMainType.getId()));
+        Integer count1 = expenseSheetMapper.selectCount(new QueryWrapper<ExpenseSheet>().eq("type", expenseMainType.getId()));
+        if (count > 0||count1>0) {
+            httpRespMsg.setError("当前费用类型[" + expenseMainType.getName() + "]已被使用");
+            return httpRespMsg;
+        }
+        expenseMainType.deleteById(id);
+        return httpRespMsg;
+    }
+
+    @RequestMapping("/dataBuild")
+    public HttpRespMsg dataBuild(){
+        List<Company> companyList = companyMapper.selectList(null);
+        for (Company company : companyList) {
+            List<ExpenseMainType> expenseMainTypes=new ArrayList<>();
+            ExpenseMainType expenseMainType=new ExpenseMainType();
+            expenseMainType.setName("一般费用");
+            expenseMainType.setCompanyId(company.getId());
+            ExpenseMainType expenseMainType1=new ExpenseMainType();
+            expenseMainType1.setName("差旅费用");
+            expenseMainType1.setCompanyId(company.getId());
+            ExpenseMainType expenseMainType2=new ExpenseMainType();
+            expenseMainType2.setName("外包费用");
+            expenseMainType2.setCompanyId(company.getId());
+            expenseMainTypes.add(expenseMainType);
+            expenseMainTypes.add(expenseMainType1);
+            expenseMainTypes.add(expenseMainType2);
+            expenseMainTypeService.saveBatch(expenseMainTypes);
+            List<ExpenseType> expenseTypeList = expenseTypeMapper.selectList(new QueryWrapper<ExpenseType>().eq("company_id", company.getId()).eq("main_type", 1111111));
+            expenseTypeList.forEach(et->{
+                et.setMainType(expenseMainType.getId());
+            });
+            List<ExpenseSheet> expenseSheetList = expenseSheetMapper.selectList(new QueryWrapper<ExpenseSheet>().eq("company_id", company.getId()).eq("type", 1111111));
+            expenseSheetList.forEach(es->{
+                es.setType(expenseMainType.getId());
+            });
+            List<ExpenseType> expenseTypeList1 = expenseTypeMapper.selectList(new QueryWrapper<ExpenseType>().eq("company_id", company.getId()).eq("main_type", 2222222));
+            expenseTypeList1.forEach(et->{
+                et.setMainType(expenseMainType1.getId());
+            });
+            List<ExpenseSheet> expenseSheetList1 = expenseSheetMapper.selectList(new QueryWrapper<ExpenseSheet>().eq("company_id", company.getId()).eq("type", 2222222));
+            expenseSheetList1.forEach(es->{
+                es.setType(expenseMainType1.getId());
+            });
+            List<ExpenseType> expenseTypeList2 = expenseTypeMapper.selectList(new QueryWrapper<ExpenseType>().eq("company_id", company.getId()).eq("main_type", 3333333));
+            expenseTypeList2.forEach(et->{
+                et.setMainType(expenseMainType2.getId());
+            });
+            List<ExpenseSheet> expenseSheetList2 = expenseSheetMapper.selectList(new QueryWrapper<ExpenseSheet>().eq("company_id", company.getId()).eq("type", 3333333));
+            expenseSheetList2.forEach(es->{
+                es.setType(expenseMainType2.getId());
+            });
+            if(expenseSheetList.size()>0){
+                expenseSheetService.updateBatchById(expenseSheetList);
+            }
+            if(expenseTypeList.size()>0){
+                expenseTypeService.updateBatchById(expenseTypeList);
+            }
+            if(expenseSheetList1.size()>0){
+                expenseSheetService.updateBatchById(expenseSheetList1);
+            }
+            if(expenseTypeList1.size()>0){
+                expenseTypeService.updateBatchById(expenseTypeList1);
+            }if(expenseSheetList2.size()>0){
+                expenseSheetService.updateBatchById(expenseSheetList2);
+            }
+            if(expenseTypeList2.size()>0){
+                expenseTypeService.updateBatchById(expenseTypeList2);
+            }
+
+        }
+        return new HttpRespMsg();
+    }
+
+}
+

+ 37 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpensePayWayController.java

@@ -0,0 +1,37 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.ExpensePayWay;
+import com.management.platform.service.ExpensePayWayService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-01-09
+ */
+@RestController
+@RequestMapping("/expense-pay-way")
+public class ExpensePayWayController {
+
+    @Resource
+    private ExpensePayWayService expensePayWayService;
+    @RequestMapping("/get")
+    public HttpRespMsg get(Integer companyId) {
+        List<ExpensePayWay> data = expensePayWayService.list(new QueryWrapper<ExpensePayWay>().eq("company_id", companyId));
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = data;
+        return msg;
+    }
+}
+

+ 191 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpenseSheetController.java

@@ -0,0 +1,191 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.ExpensePayWay;
+import com.management.platform.entity.ExpenseSheet;
+import com.management.platform.entity.User;
+import com.management.platform.entity.vo.SysRichFunction;
+import com.management.platform.mapper.SysFunctionMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.ExpensePayWayService;
+import com.management.platform.service.ExpenseSheetService;
+import com.management.platform.util.FileZipUtil;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-05-17
+ */
+@RestController
+@RequestMapping("/expense-sheet")
+public class ExpenseSheetController {
+    @Resource
+    UserMapper userMapper;
+    @Resource
+    ExpenseSheetService expenseSheetService;
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    SysFunctionMapper sysFunctionMapper;
+    @Resource
+    ExpensePayWayService expensePayWayService;
+
+    @Value(value = "${upload.path}")
+    private String uploadPath;
+
+    @RequestMapping("/getNextCode")
+    public HttpRespMsg getNextCode() {
+        String userId = request.getHeader("Token");
+        return expenseSheetService.getNextCode(userId);
+    }
+
+    @RequestMapping("/add")
+    public HttpRespMsg add(ExpenseSheet sheet, String items) {
+        String userId = request.getHeader("Token");
+        try {
+            return expenseSheetService.add(sheet, items, userId);
+        } catch (Exception e) {
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError("验证失败:"+e.getMessage());
+            return msg;
+        }
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        return expenseSheetService.delete(id);
+
+    }
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(ExpenseSheet sheet,Integer sendState,Integer projectId,String startDate, String endDate, @RequestParam Integer pageIndex, @RequestParam Integer pageSize) {
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全部报销单");
+        if (functionList.size() == 0) {
+            //普通员工只能看自己的
+            if (sheet.getStatus() == null) {
+                sheet.setOwnerId(user.getId());
+            }
+        }
+        sheet.setCompanyId(user.getCompanyId());
+        return expenseSheetService.queryList(sheet,projectId, startDate, endDate, pageIndex, pageSize);
+    }
+
+    @RequestMapping("/getDetail")
+    public HttpRespMsg getDetail(Integer id,Integer projectId) {
+
+        return expenseSheetService.getDetail(id,projectId);
+
+    }
+    /**
+     * 导出
+     */
+    @RequestMapping("/export")
+    public void getExport(ExpenseSheet sheet,Integer sendState,Integer projectId,String startDate, String endDate,HttpServletResponse response) throws Exception {
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全部报销单");
+        if (functionList.size() == 0) {
+            //普通员工只能看自己的
+            if (sheet.getStatus() == null) {
+                sheet.setOwnerId(user.getId());
+            }
+        }
+        sheet.setCompanyId(user.getCompanyId());
+        List<String> fileNames= expenseSheetService.queryExportFileZipList(sheet,projectId, startDate, endDate);
+        /*List<String> fileNames=new ArrayList<>();
+        fileNames.add("头像.png");
+        fileNames.add("日报统计表_.xlsx");*/
+        if (!fileNames.isEmpty()){
+            FileZipUtil.exportZip(response,uploadPath ,fileNames, "报销凭证压缩包", ".zip");
+        }else return;
+    }
+
+
+    @RequestMapping("/approve")
+    public HttpRespMsg approve(Integer id) {
+
+        return expenseSheetService.approve(id);
+
+    }
+
+    @RequestMapping("/approveSingleProject")
+    public HttpRespMsg approveSingleProject(Integer id) {
+        return expenseSheetService.approveSingleProject(id);
+
+    }
+
+    @RequestMapping("/denySingleProject")
+    public HttpRespMsg denySingleProject(Integer id,String denyReason) {
+
+        return expenseSheetService.denySingleProject(id,denyReason);
+
+    }
+
+    @RequestMapping("/deny")
+    public HttpRespMsg deny(Integer id,String denyReason) {
+
+        return expenseSheetService.deny(id,denyReason);
+
+    }
+
+    @RequestMapping("/importData")
+    public HttpRespMsg importData(HttpServletRequest request,MultipartFile[] files){
+        return expenseSheetService.importData(request,files);
+    }
+
+    @RequestMapping("/exportList")
+    public HttpRespMsg exportList(ExpenseSheet sheet,Integer projectId ,String startDate, String endDate) {
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全部报销单");
+        if (functionList.size() == 0) {
+            //普通员工只能看自己的
+            sheet.setOwnerId(user.getId());
+        }
+        sheet.setCompanyId(user.getCompanyId());
+        return expenseSheetService.exportList(sheet,projectId, startDate, endDate);
+    }
+
+    @RequestMapping("/editSendExpense")
+    public HttpRespMsg sendExpense(String expenseIds,Integer sendState, Integer payWayId){
+        HttpRespMsg msg=new HttpRespMsg();
+        String[] split = expenseIds.split(",");
+        List<String> asList = Arrays.asList(split);
+        List<Integer> ids = asList.stream().map(i -> Integer.parseInt(i)).collect(Collectors.toList());
+        ids.add(-1);
+        ExpensePayWay payway = expensePayWayService.getById(payWayId);
+        List<ExpenseSheet> expenseSheets = expenseSheetService.list(new QueryWrapper<ExpenseSheet>().in("id", ids));
+        expenseSheets.forEach(e->{
+            e.setSendState(sendState);
+            if (payway != null) {
+                e.setPayWayId(payWayId);
+                e.setPayWayName(payway.getName());
+            }
+        });
+        if(!expenseSheetService.updateBatchById(expenseSheets)){
+            msg.setError("验证失败");
+        }
+        return msg;
+    }
+}
+

+ 118 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/ExpenseTypeController.java

@@ -0,0 +1,118 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.ExpenseItem;
+import com.management.platform.entity.ExpenseMainType;
+import com.management.platform.entity.ExpenseType;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.ExpenseItemMapper;
+import com.management.platform.mapper.ExpenseTypeMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.ExpenseMainTypeService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-06-18
+ */
+@RestController
+@RequestMapping("/expense-type")
+public class ExpenseTypeController {
+    @Resource
+    private ExpenseTypeMapper expenseTypeMapper;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private ExpenseItemMapper expenseItemMapper;
+    @Resource
+    private ExpenseMainTypeService expenseMainTypeService;
+
+    @RequestMapping("/getList")
+    public HttpRespMsg getList() {
+        User user = userMapper.selectById(request.getHeader("token"));
+        HttpRespMsg msg = new HttpRespMsg();
+        List<ExpenseType> expenseTypeList = expenseTypeMapper.selectList(new QueryWrapper<ExpenseType>().eq("company_id", user.getCompanyId()).orderByAsc("main_type"));
+        List<ExpenseMainType> expenseMainTypes = expenseMainTypeService.list(new QueryWrapper<ExpenseMainType>().eq("company_id", user.getCompanyId()).or().eq("is_system",1));
+        expenseTypeList.forEach(re->{
+            Optional<ExpenseMainType> first = expenseMainTypes.stream().filter(et -> et.getId().equals(re.getMainType())).findFirst();
+            if(first.isPresent()){
+                re.setExpenseMainTypeName(first.get().getName());
+            }
+        });
+        msg.data=expenseTypeList;
+        return msg;
+    }
+
+    @RequestMapping("/addOrMod")
+    public HttpRespMsg addOrMod(ExpenseType setting) {
+        HttpRespMsg msg = new HttpRespMsg();
+        if (StringUtils.isEmpty(setting.getTypeName())) {
+            //msg.setError("名称不能为空");
+            msg.setError(MessageUtils.message("Company.nullNameError"));
+            return msg;
+        }
+        Integer companyId = userMapper.selectById(request.getHeader("TOKEN")).getCompanyId();
+        if (setting.getId() == null) {
+            setting.setCompanyId(companyId);
+            int count = expenseTypeMapper.selectCount(new QueryWrapper<ExpenseType>().eq("type_name", setting.getTypeName()).eq("company_id", setting.getCompanyId()));
+            if (count > 0) {
+                //msg.setError("该名称已存在");
+                msg.setError(MessageUtils.message("Company.nameRepeat"));
+            } else {
+                expenseTypeMapper.insert(setting);
+                msg.data = expenseTypeMapper.selectList(new QueryWrapper<ExpenseType>().eq("company_id", companyId));
+            }
+        } else {
+            int count = expenseTypeMapper.selectCount(new QueryWrapper<ExpenseType>().eq("type_name", setting.getTypeName())
+                    .eq("company_id", companyId).ne("id", setting.getId()));
+            if (count > 0) {
+                //msg.setError("该名称已存在");
+                msg.setError(MessageUtils.message("Company.nameRepeat"));
+            } else {
+                expenseTypeMapper.updateById(setting);
+                msg.data = expenseTypeMapper.selectList(new QueryWrapper<ExpenseType>().eq("company_id", companyId));
+            }
+        }
+
+        return msg;
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        ExpenseType expenseType = expenseTypeMapper.selectById(id);
+        Integer companyId = userMapper.selectById(request.getHeader("TOKEN")).getCompanyId();
+//        Integer cut = expenseItemMapper.selectCount(new QueryWrapper<ExpenseItem>().eq("expense_type", expenseType.getTypeName()));
+//        if(cut>0){
+//            //msg.setError("删除失败,已绑定费用报销数据");
+//            msg.setError(MessageUtils.message("expense.deleteError"));
+//            return msg;
+//        }
+        if (!expenseType.getCompanyId().equals(companyId)) {
+            //msg.setError("无权操作");
+            msg.setError(MessageUtils.message("access.operationError"));
+        } else {
+            expenseTypeMapper.deleteById(id);
+        }
+
+        return msg;
+    }
+
+}
+

文件差异内容过多而无法显示
+ 1034 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FeishuInfoController.java


+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FeishuSendController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-03-02
+ */
+@RestController
+@RequestMapping("/feishu-send")
+public class FeishuSendController {
+
+}
+

+ 48 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceAuditorController.java

@@ -0,0 +1,48 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.Finance;
+import com.management.platform.entity.FinanceAuditor;
+import com.management.platform.mapper.FinanceAuditorMapper;
+import com.management.platform.service.FinanceAuditorService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-03-22
+ */
+@RestController
+@RequestMapping("/finance-auditor")
+public class FinanceAuditorController {
+
+    @Resource
+    private FinanceAuditorService financeAuditorService;
+    @Resource
+    private HttpServletRequest request;
+
+    @RequestMapping("/save")
+    public HttpRespMsg save(FinanceAuditor item) {
+        HttpRespMsg msg = new HttpRespMsg();
+        financeAuditorService.saveOrUpdate(item);
+        return msg;
+    }
+
+    @RequestMapping("/get")
+    public HttpRespMsg get(Integer companyId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        FinanceAuditor item = financeAuditorService.getById(companyId);
+        msg.data = item;
+        return msg;
+    }
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceCalculateController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-04-13
+ */
+@RestController
+@RequestMapping("/finance-calculate")
+public class FinanceCalculateController {
+
+}
+

+ 187 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceController.java

@@ -0,0 +1,187 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.Company;
+import com.management.platform.entity.FinanceFixedcolname;
+import com.management.platform.entity.FinanceTblcuscol;
+import com.management.platform.entity.TimeType;
+import com.management.platform.mapper.CompanyMapper;
+import com.management.platform.mapper.FinanceTblcuscolMapper;
+import com.management.platform.mapper.TimeTypeMapper;
+import com.management.platform.mapper.WxCorpInfoMapper;
+import com.management.platform.service.ExcelExportService;
+import com.management.platform.service.FinanceFixedcolnameService;
+import com.management.platform.service.FinanceService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import com.management.platform.util.UserNotFoundException;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-02-18
+ */
+@RestController
+@RequestMapping("/finance")
+public class FinanceController {
+
+    @Resource
+    private FinanceService financeService;
+    @Resource
+    private FinanceTblcuscolMapper financeTblcuscolMapper;
+    @Resource
+    private CompanyMapper companyMapper;
+    @Resource
+    private FinanceFixedcolnameService financeFixedcolnameService;
+    @Resource
+    private TimeTypeMapper timeTypeMapper;
+    @Resource
+    private WxCorpInfoMapper wxCorpInfoMapper;
+    @Resource
+    private ExcelExportService excelExportService;
+
+    @Value(value = "${upload.path}")
+    private String path;
+
+    @RequestMapping("/getByMonth")
+    public HttpRespMsg getByMonth(Integer companyId, String yearMonth) {
+        return financeService.getByMonth(companyId, yearMonth);
+    }
+
+    @RequestMapping("/getProjects")
+    public HttpRespMsg getProjects(Integer companyId, String yearMonth) {
+        return financeService.getProjects(companyId, yearMonth);
+    }
+
+    @RequestMapping("/importData")
+    public HttpRespMsg importData(Integer companyId, String yearMonth,
+                                  Boolean syncUserCost, Boolean syncHistoryReport,
+                                  MultipartFile file, HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            return financeService.importData(companyId, yearMonth, syncUserCost, syncHistoryReport, file, request);
+        } catch (IOException e) {
+            e.printStackTrace();
+            //msg.setError("文件处理出错");
+            msg.setError(MessageUtils.message("file.error"));
+            return msg;
+        } catch (UserNotFoundException e) {
+            e.printStackTrace();
+            msg.setError(e.getMessage());
+            return msg;
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+            //msg.setError("数据格式有误或存在空数据 导入失败");
+            msg.setError(MessageUtils.message("file.dataFormatError"));
+            return msg;
+        } catch (Exception e) {
+            e.printStackTrace();
+            //msg.setError("发生其他错误");
+            msg.setError(MessageUtils.message("other.error"));
+            return msg;
+        }
+    }
+
+    //导出分摊数据
+    @RequestMapping("/exportData")
+    public HttpRespMsg exportData(@RequestParam(required = false, defaultValue = "0") Integer groupByCategory,
+                                  @RequestParam(defaultValue = "0")Integer onlyTotal,
+                                  @RequestParam String date, Boolean assignNoProUser,HttpServletRequest request) {
+        return financeService.exportData(groupByCategory,onlyTotal, date, assignNoProUser, request);
+    }
+
+    /**
+     * 导出薪资数据
+     * @param date
+     * @param request
+     * @return
+     */
+    @RequestMapping("/exportFinance")
+    public HttpRespMsg exportFinance(@RequestParam String date, HttpServletRequest request) {
+        return financeService.exportFinance(date, request);
+    }
+
+    //按照项目分配财务成本
+    @RequestMapping("/getTimeCost")
+    public HttpRespMsg getTimeCost(String yearMonth, Boolean assignNoProUser,HttpServletRequest request) {
+        return financeService.getTimeCost(yearMonth, assignNoProUser,request);
+    }
+
+    @RequestMapping("/getNoProjectUsers")
+    public HttpRespMsg getNoProjectUsers(String yearMonth, HttpServletRequest request) {
+        return financeService.getNoProjectUsers(yearMonth, request);
+    }
+
+
+    /**
+     * 获取财务报表模板
+     * @param companyId
+     * @return
+     */
+    @RequestMapping("/getTemplate")
+    public HttpRespMsg getTemplate(Integer companyId) throws Exception {
+        List<FinanceTblcuscol> list = financeTblcuscolMapper.selectList(new QueryWrapper<FinanceTblcuscol>().eq("company_id", companyId));
+        HttpRespMsg msg = new HttpRespMsg();
+        FinanceFixedcolname item = financeFixedcolnameService.getById(companyId);
+
+        List<String> heads = new ArrayList<>();
+        Company company = companyMapper.selectById(companyId);
+//        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", companyId));
+        //判断是否启用了工号模式
+        TimeType timeType = timeTypeMapper.selectById(companyId);
+        if (timeType.getFinanceJobnumEnabled() == 1) {
+            //heads.add("工号");
+            heads.add(MessageUtils.message("entry.No"));
+        }
+        //heads.add("姓名");
+        heads.add(MessageUtils.message("entry.name"));
+        heads.add(item.getMonthCost());//heads.add("工资");
+        heads.add(item.getBonus());//heads.add("奖金");
+        heads.add(item.getAllowance());//heads.add("津贴");
+        heads.add(item.getInsuranceOld());//heads.add("养老保险");
+        heads.add(item.getInsuranceMedical());//heads.add("医疗保险");
+        heads.add(item.getInsuranceLosejob());//heads.add("失业保险");
+        heads.add(item.getInsuranceInjury());//heads.add("工伤保险");
+        heads.add(item.getHouseFund());//heads.add("住房公积金");
+        if (list.size() > 0) {
+            List<String> collect = list.stream().map(FinanceTblcuscol::getFieldName).collect(Collectors.toList());
+            heads.addAll(collect);
+        }
+        List<List<String>> allList = new ArrayList<>();
+        allList.add(heads);
+        //String fileName = company.getCompanyName()+"_财务人员成本模板";
+        String fileName = MessageUtils.message("fileName.financialCost",company.getCompanyName());
+        //导出模板不需要转译,不传wxCorpInfo
+        return excelExportService.exportGeneralExcelByTitleAndList(null,null, fileName, allList, path);
+    }
+    @RequestMapping("/batchRemove")
+    public HttpRespMsg batchRemove(String ids){
+        HttpRespMsg msg=new HttpRespMsg();
+        String[] split = ids.split(",");
+        List<String> list = Arrays.asList(split);
+        if(financeService.removeByIds(list)){
+            return msg;
+        }
+        //msg.setError("删除失败");
+        msg.setError(MessageUtils.message("file.deleteError"));
+        return msg;
+    }
+}
+

+ 43 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceExcludeProjectController.java

@@ -0,0 +1,43 @@
+package com.management.platform.controller;
+
+import com.management.platform.entity.bo.AddOrUpdateFinanceExcludeProjectBO;
+import com.management.platform.service.FinanceExcludeProjectService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping("/financeExcludeProject")
+public class FinanceExcludeProjectController {
+
+    @Resource
+    private FinanceExcludeProjectService financeExcludeProjectService;
+
+    @GetMapping("/getProjects")
+    public HttpRespMsg getProjects(@RequestParam(value = "useYM")String useYM, HttpServletRequest request){
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            msg = financeExcludeProjectService.getProjects(useYM,request);
+        } catch (Exception e) {e.printStackTrace();
+            msg.setError(MessageUtils.message("other.error"));
+            return msg;
+        }
+        return msg;
+    }
+
+    @PostMapping("/addOrUpdateProjects")
+    public HttpRespMsg addProjects(AddOrUpdateFinanceExcludeProjectBO addBO, HttpServletRequest request){
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            msg = financeExcludeProjectService.addOrUpdateProjects(addBO,request);
+        } catch (Exception e) {e.printStackTrace();
+            msg.setError(MessageUtils.message("other.error"));
+            return msg;
+        }
+        return msg;
+    }
+
+}

+ 23 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceFixedcolnameController.java

@@ -0,0 +1,23 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-03-15
+ */
+@RestController
+@RequestMapping("/finance-fixedcolname")
+public class FinanceFixedcolnameController {
+
+}
+

+ 97 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceImportController.java

@@ -0,0 +1,97 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.FinanceImport;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.FinanceImportService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-03-22
+ */
+@RestController
+@RequestMapping("/finance-import")
+public class FinanceImportController {
+
+    @Resource
+    private FinanceImportService financeImportService;
+    @Resource
+    private UserMapper userMapper;
+
+    @RequestMapping("submitImport")
+    public HttpRespMsg submitImport(Integer companyId, String yearMonth,
+                                  Boolean syncUserCost, Boolean syncHistoryReport,
+                                  MultipartFile file, HttpServletRequest request) {
+        return financeImportService.submitImport(companyId, yearMonth, syncUserCost, syncHistoryReport, file, request);
+    }
+
+    @RequestMapping("list")
+    public HttpRespMsg list(Integer companyId, HttpServletRequest request) {
+        return financeImportService.list(companyId, request);
+    }
+
+    @RequestMapping("/agree")
+    public HttpRespMsg agree(Integer id, HttpServletRequest request) {
+
+        return financeImportService.agree(id, request);
+    }
+
+    @RequestMapping("/getStatus")
+    public HttpRespMsg getStatus(Integer companyId, String yearMonth) {
+        FinanceImport item = financeImportService.getOne(new QueryWrapper<FinanceImport>().eq("company_id", companyId).eq("ymonth", yearMonth).orderByDesc("indate").last("limit 1"));
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = item;
+        return msg;
+    }
+
+    @RequestMapping("/deny")
+    public HttpRespMsg deny(Integer id, HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        FinanceImport item = new FinanceImport();
+        item.setId(id);
+        item.setState(2);
+        FinanceImport old = financeImportService.getById(id);
+        if (old.getState() == 0) {
+            User auditor = userMapper.selectById(request.getHeader("TOKEN"));
+            item.setAuditorId(auditor.getId());
+            item.setAuditorName(auditor.getName());
+            financeImportService.updateById(item);
+        } else {
+            //msg.setError("只有待审核状态才可以操作");
+            msg.setError(MessageUtils.message("finance.operationStateError"));
+        }
+        return msg;
+    }
+
+    @RequestMapping("/cancel")
+    public HttpRespMsg cancel(Integer id, HttpServletRequest request) {
+        HttpRespMsg msg = new HttpRespMsg();
+        FinanceImport item = new FinanceImport();
+        item.setId(id);
+        item.setState(-1);
+        FinanceImport old = financeImportService.getById(id);
+        if (old.getState() == 1) {
+            financeImportService.updateById(item);
+        } else {
+            //msg.setError("只有审核通过状态才可以撤销");
+            msg.setError(MessageUtils.message("finance.revokeStateError"));
+        }
+        return msg;
+    }
+}
+

+ 61 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceMonthlyWorktimeController.java

@@ -0,0 +1,61 @@
+package com.management.platform.controller;
+
+
+import com.management.platform.entity.FmwDetail;
+import com.management.platform.service.FinanceMonthlyWorktimeService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-04-16
+ */
+@RestController
+@RequestMapping("/finance-monthly-worktime")
+public class FinanceMonthlyWorktimeController {
+
+    @Resource
+    private FinanceMonthlyWorktimeService financeMonthlyWorktimeService;
+
+    @RequestMapping("/send")
+    public HttpRespMsg send(@RequestParam("id")String id, @RequestParam("timesheetDate") String timesheetDate, HttpServletRequest request) {
+        return financeMonthlyWorktimeService.send(id,timesheetDate,request);
+    }
+
+    @RequestMapping("/getByMonth")
+    public HttpRespMsg getByMonth(Integer companyId, String ymonth, @RequestParam(required = false, defaultValue = "0" ) Integer reGenerate,HttpServletRequest request) {
+        try {
+            return financeMonthlyWorktimeService.getByMonth(companyId, ymonth,reGenerate, request);
+        } catch (Exception e) {
+            e.printStackTrace();
+            HttpRespMsg msg = new HttpRespMsg();
+            msg.setError(e.getMessage());
+            return msg;
+        }
+    }
+
+    @RequestMapping("/setTimesheetDate")
+    public HttpRespMsg setTimesheetDate(Integer id, String timesheetDate, HttpServletRequest request) {
+        return financeMonthlyWorktimeService.setTimesheetDate(id, timesheetDate,request);
+    }
+
+    @RequestMapping("/changeWorktime")
+    public HttpRespMsg changeWorktime(FmwDetail detail, HttpServletRequest request) {
+        return financeMonthlyWorktimeService.changeWorktime(detail,request);
+    }
+
+    @RequestMapping("/setStatusFinal")
+    public HttpRespMsg setStatusFinal(Integer id, HttpServletRequest request) {
+        return financeMonthlyWorktimeService.setStatusFinal(id,request);
+    }
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceProjectsController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-02-26
+ */
+@RestController
+@RequestMapping("/finance-projects")
+public class FinanceProjectsController {
+
+}
+

+ 201 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinanceTblcuscolController.java

@@ -0,0 +1,201 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.Finance;
+import com.management.platform.entity.FinanceCalculate;
+import com.management.platform.entity.FinanceFixedcolname;
+import com.management.platform.entity.FinanceTblcuscol;
+import com.management.platform.mapper.FinanceCalculateMapper;
+import com.management.platform.mapper.FinanceFixedcolnameMapper;
+import com.management.platform.mapper.FinanceTblcuscolMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.FinanceCalculateService;
+import com.management.platform.service.FinanceFixedcolnameService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-12-17
+ */
+@RestController
+@RequestMapping("/finance-tblcuscol")
+public class FinanceTblcuscolController {
+
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private FinanceTblcuscolMapper financeTblcuscolMapper;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private FinanceFixedcolnameService financeFixedcolnameService;
+    @Resource
+    private FinanceCalculateMapper financeCalculateMapper;
+    @Resource
+    private FinanceCalculateService financeCalculateService;
+
+//    @RequestMapping("/get")
+//    public HttpRespMsg get(Integer companyId) {
+//        List<FinanceTblcuscol> list = financeTblcuscolMapper.selectList(new QueryWrapper<FinanceTblcuscol>().eq("company_id", companyId));
+//        HttpRespMsg msg = new HttpRespMsg();
+//        msg.data = list;
+//        return msg;
+//    }
+
+    @RequestMapping("/getAll")
+    public HttpRespMsg getAll(Integer companyId) {
+        List<FinanceTblcuscol> list = financeTblcuscolMapper.selectList(new QueryWrapper<FinanceTblcuscol>().eq("company_id", companyId));
+        HttpRespMsg msg = new HttpRespMsg();
+        FinanceFixedcolname item = financeFixedcolnameService.getFixed(companyId);
+        if (list.size() > 0) {
+            item.setField1(list.get(0).getFieldName());
+            item.setField1Calculate(list.get(0).getNeedCalculate());
+        }
+        if (list.size() > 1) {
+            item.setField2(list.get(1).getFieldName());
+            item.setField2Calculate(list.get(1).getNeedCalculate());
+        }
+        if (list.size() > 2) {
+            item.setField3(list.get(2).getFieldName());
+            item.setField3Calculate(list.get(2).getNeedCalculate());
+        }
+        if (list.size() > 3) {
+            item.setField4(list.get(3).getFieldName());
+            item.setField4Calculate(list.get(3).getNeedCalculate());
+        }
+        if (list.size() > 4) {
+            item.setField5(list.get(4).getFieldName());
+            item.setField5Calculate(list.get(4).getNeedCalculate());
+        }
+        if (list.size() > 5) {
+            item.setField6(list.get(5).getFieldName());
+            item.setField6Calculate(list.get(5).getNeedCalculate());
+        }
+        if (list.size() > 6) {
+            item.setField7(list.get(6).getFieldName());
+            item.setField7Calculate(list.get(6).getNeedCalculate());
+        }
+        msg.data = item;
+
+        return msg;
+    }
+//
+//    @RequestMapping("/getFixed")
+//    public HttpRespMsg getFixed(Integer companyId) {
+//        HttpRespMsg msg = new HttpRespMsg();
+//        msg.data = financeFixedcolnameService.getFixed(companyId);
+//        return msg;
+//    }
+
+    @RequestMapping("/save")
+    public HttpRespMsg addOrMod(FinanceFixedcolname item) {
+        String token = request.getHeader("TOKEN");
+        int companyId = userMapper.selectById(token).getCompanyId();
+        financeTblcuscolMapper.delete(new QueryWrapper<FinanceTblcuscol>().eq("company_id", companyId));
+        if (!StringUtils.isEmpty(item.getField1())) {
+            FinanceTblcuscol col = new FinanceTblcuscol();
+            col.setCompanyId(companyId);
+            col.setFieldName(item.getField1());
+            col.setNeedCalculate(item.getField1Calculate());
+            financeTblcuscolMapper.insert(col);
+        }
+        financeCalculateMapper.delete(new QueryWrapper<FinanceCalculate>().eq("company_id", companyId));
+
+
+        if (!StringUtils.isEmpty(item.getField2())) {
+            FinanceTblcuscol col = new FinanceTblcuscol();
+            col.setCompanyId(companyId);
+            col.setFieldName(item.getField2());
+            col.setNeedCalculate(item.getField2Calculate());
+            financeTblcuscolMapper.insert(col);
+        }
+
+        if (!StringUtils.isEmpty(item.getField3())) {
+            FinanceTblcuscol col = new FinanceTblcuscol();
+            col.setCompanyId(companyId);
+            col.setFieldName(item.getField3());
+            col.setNeedCalculate(item.getField3Calculate());
+            financeTblcuscolMapper.insert(col);
+        }
+
+        if (!StringUtils.isEmpty(item.getField4())) {
+            FinanceTblcuscol col = new FinanceTblcuscol();
+            col.setCompanyId(companyId);
+            col.setFieldName(item.getField4());
+            col.setNeedCalculate(item.getField4Calculate());
+            financeTblcuscolMapper.insert(col);
+        }
+
+        if (!StringUtils.isEmpty(item.getField5())) {
+            FinanceTblcuscol col = new FinanceTblcuscol();
+            col.setCompanyId(companyId);
+            col.setFieldName(item.getField5());
+            col.setNeedCalculate(item.getField5Calculate());
+            financeTblcuscolMapper.insert(col);
+        }
+
+        if (!StringUtils.isEmpty(item.getField6())) {
+            FinanceTblcuscol col = new FinanceTblcuscol();
+            col.setCompanyId(companyId);
+            col.setFieldName(item.getField6());
+            col.setNeedCalculate(item.getField6Calculate());
+            financeTblcuscolMapper.insert(col);
+        }
+
+        if (!StringUtils.isEmpty(item.getField7())) {
+            FinanceTblcuscol col = new FinanceTblcuscol();
+            col.setCompanyId(companyId);
+            col.setFieldName(item.getField7());
+            col.setNeedCalculate(item.getField7Calculate());
+            financeTblcuscolMapper.insert(col);
+        }
+
+        //存储自定义的固定字段
+        if (item.getMonthCost() != null || item.getBonus() != null || item.getAllowance() != null || item.getInsuranceInjury() != null
+            || item.getInsuranceLosejob() != null || item.getInsuranceMedical() != null || item.getInsuranceOld() != null || item.getHouseFund() != null) {
+            item.setCompanyId(companyId);
+            financeFixedcolnameService.saveOrUpdate(item);
+        }
+
+        FinanceCalculate calculate = item.toCalculateObj();
+        //存储自定义的固定字段
+        if (calculate.getMonthCostCalculate() != null || calculate.getBonusCalculate() != null || calculate.getAllowanceCalculate() != null || calculate.getInsuranceInjuryCalculate() != null
+                || calculate.getInsuranceLosejobCalculate() != null || calculate.getInsuranceMedicalCalculate() != null || calculate.getInsuranceOldCalculate() != null || calculate.getHouseFundCalculate() != null) {
+            calculate.setCompanyId(companyId);
+            financeCalculateService.saveOrUpdate(calculate);
+        }
+
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/delete")
+    public HttpRespMsg delete(Integer id) {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        int companyId = userMapper.selectById(token).getCompanyId();
+        FinanceTblcuscol financeTblcuscol = financeTblcuscolMapper.selectById(id);
+        if (financeTblcuscol.getCompanyId() == companyId) {
+            financeTblcuscolMapper.deleteById(id);
+        } else {
+            //msg.setError("无权操作");
+            msg.setError(MessageUtils.message("access.operationError"));
+        }
+        return msg;
+    }
+}
+

+ 81 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FinancialAuditController.java

@@ -0,0 +1,81 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.management.platform.entity.FinancialAudit;
+import com.management.platform.entity.User;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.FinancialAuditService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.time.format.DateTimeFormatter;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2024-06-05
+ */
+@RestController
+@RequestMapping("/financial-audit")
+public class FinancialAuditController {
+    @Autowired
+    private FinancialAuditService financialAuditService;
+    @Resource
+    private UserMapper userMapper;
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(Integer pageIndex, Integer pageSize, String startDate, String endDate, Integer status, HttpServletRequest request) throws ParseException {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        LambdaQueryWrapper<FinancialAudit> financialAuditLambdaQueryWrapper = new LambdaQueryWrapper<>();
+        financialAuditLambdaQueryWrapper.eq(FinancialAudit::getCompanyId,companyId).between(FinancialAudit::getReportYrmnth,startDate,endDate).eq(status!=0,FinancialAudit::getReviewStatus,status);
+
+//            QueryWrapper<FinancialAudit> queryWrapper = new QueryWrapper<FinancialAudit>()
+//                    .eq("company_id", companyId)
+//                    .eq("review_status", status)
+//                    .ge("report_yrMnth", startDate)
+//                    .le("report_yrMnth", endDate);
+
+        IPage<FinancialAudit> auditIPage = financialAuditService.page(new Page<FinancialAudit>(pageIndex, pageSize), financialAuditLambdaQueryWrapper);
+        Map<String, Object> map = new HashMap<>();
+        map.put("records", auditIPage.getRecords());
+        map.put("total", auditIPage.getTotal());
+    
+        httpRespMsg.data = map;  
+        return httpRespMsg;
+    }
+
+    @RequestMapping("/audit")
+    public HttpRespMsg audit(Integer id, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        String token = request.getHeader("Token");
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+        User user = userMapper.selectById(token);
+//                financialAuditService.update().eq("id", id).set("review_status", 2).set("reviewer_id", user.getId()).set("reviewer_name", user.getName());
+        FinancialAudit item = new FinancialAudit();
+        item.setId(id);
+        item.setReviewStatus(2);
+        item.setReviewerId(user.getId());
+        item.setReviewerName(user.getName());
+        item.setReviewTime(sdf.format(new Date()));
+        financialAuditService.updateById(item);
+        return httpRespMsg;
+    }
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/FmwDetailController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-04-16
+ */
+@RestController
+@RequestMapping("/fmw-detail")
+public class FmwDetailController {
+
+}
+

+ 299 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/GroupBudgetReviewController.java

@@ -0,0 +1,299 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.*;
+import com.management.platform.mapper.*;
+import com.management.platform.service.ExcelExportService;
+import com.management.platform.service.GroupBudgetReviewService;
+import com.management.platform.service.TaskService;
+import com.management.platform.service.WxCorpInfoService;
+import com.management.platform.service.impl.WxCorpInfoServiceImpl;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2023-12-28
+ */
+@RestController
+@RequestMapping("/group-budget-review")
+public class GroupBudgetReviewController {
+
+    @Resource
+    private GroupBudgetReviewService groupBudgetReviewService;
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private TaskGroupMapper taskGroupMapper;
+    @Resource
+    private ProjectMapper projectMapper;
+    @Resource
+    private TaskService taskService;
+    @Value(value = "${upload.path}")
+    private String path;
+    @Resource
+    private WxCorpInfoMapper wxCorpInfoMapper;
+    @Resource
+    private ExcelExportService excelExportService;
+    @Resource
+    private WxCorpInfoService wxCorpInfoService;
+    @Resource
+    private TimeTypeMapper timeTypeMapper;
+    @Resource
+    private InformationMapper informationMapper;
+    @Resource
+    private CompanyDingdingMapper companyDingdingMapper;
+
+    @RequestMapping("/add")
+    public HttpRespMsg add(Integer groupId,Integer oldManDay,Integer changeManDay,Integer nowManDay,String remark){
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        if(changeManDay==null||changeManDay==0){
+            httpRespMsg.setError("预估工时未发生变更");
+            return httpRespMsg;
+        }
+        User user = userMapper.selectById(request.getHeader("token"));
+        GroupBudgetReview groupBudgetReview=new GroupBudgetReview();
+        TaskGroup taskGroup = taskGroupMapper.selectById(groupId);
+        Project project = projectMapper.selectById(taskGroup.getProjectId());
+        if(project.getCategory()!=null&&project.getCategory()==696){
+            List<Task> taskList = taskService.list(new LambdaQueryWrapper<Task>().select(Task::getPlanHours,Task::getGroupId).isNotNull(Task::getPlanHours).eq(Task::getGroupId, groupId));
+            int sum = taskList.stream().mapToInt(Task::getPlanHours).sum();
+            if(sum>((nowManDay==null?0:nowManDay)*8)){
+                httpRespMsg.setError("任务分组["+taskGroup.getName()+"]的预估工时需大于等于已分配任务的总计划工时["+sum+"]小时");
+                return httpRespMsg;
+            }
+        }
+        groupBudgetReview.setGroupId(groupId).setGroupName(taskGroup.getName())
+                .setOldManDay(oldManDay)
+                .setChangeManDay(changeManDay)
+                .setNowManDay(nowManDay)
+                .setCompanyId(user.getCompanyId())
+                .setProjectId(project.getId()).setProjectName(project.getProjectName())
+                .setCreatorId(user.getId())
+                .setCreator(user.getName())
+                .setRemark(remark);
+        if(!groupBudgetReviewService.save(groupBudgetReview)){
+            httpRespMsg.setError("验证失败");
+        }
+        return  httpRespMsg;
+    }
+
+    @RequestMapping("/check")
+    public HttpRespMsg check(Integer id,Integer checkType,String rejectReason){
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        GroupBudgetReview groupBudgetReview=groupBudgetReviewService.getById(id);
+        User checker = userMapper.selectById(request.getHeader("token"));
+        if(rejectReason!=null&&!StringUtils.isEmpty(rejectReason)){
+            groupBudgetReview.setRejectReason(rejectReason);
+        }
+        groupBudgetReview.setStatus(checkType);
+        groupBudgetReview.setCheckerId(checker.getId());
+        groupBudgetReview.setChecker(checker.getName());
+        if(!groupBudgetReviewService.updateById(groupBudgetReview)){
+            httpRespMsg.setError("验证失败");
+            return httpRespMsg;
+        }
+        Integer groupId = groupBudgetReview.getGroupId();
+        TaskGroup taskGroup = taskGroupMapper.selectById(groupId);
+        Project project = projectMapper.selectById(taskGroup.getProjectId());
+        if(checkType==1){
+            //审核通过计算到任务分组的项目人天
+            Double manDay = taskGroup.getManDay();
+            BigDecimal bigDecimal = new BigDecimal(manDay==null?0:manDay);
+            bigDecimal=bigDecimal.add(new BigDecimal(groupBudgetReview.getChangeManDay()==null?0:groupBudgetReview.getChangeManDay()));
+            taskGroup.setManDay(bigDecimal.doubleValue());
+            taskGroupMapper.updateById(taskGroup);
+            //项目人天按照分组工时增加
+            double day = project.getManDay();
+            day=day+(groupBudgetReview.getChangeManDay()==null?0:groupBudgetReview.getChangeManDay());
+            project.setManDay(day);
+            projectMapper.updateById(project);
+        }
+        if(checkType!=0){
+            User user = userMapper.selectById(groupBudgetReview.getCreatorId());
+            StringBuilder sb=new StringBuilder();
+            sb.append("$userName="+checker.getCorpwxUserid()+"$");
+            if(checkType==1){
+                sb.append("通过了");
+                sb.append("您项目["+project.getProjectName()+"]下分组["+taskGroup.getName()+"]的预估工时修改申请");
+            }else{
+                sb.append("驳回了");
+                sb.append("您项目["+project.getProjectName()+"]下分组["+taskGroup.getName()+"]的预估工时修改申请");
+                sb.append(",驳回理由:"+groupBudgetReview.getRejectReason());
+            }
+            String corpwxUserid = user.getCorpwxUserid();
+            if (corpwxUserid != null) {
+                WxCorpInfo info = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id",checker.getCompanyId()));
+                wxCorpInfoService.sendWXCorpMsg(info, corpwxUserid,sb.toString(), "projectInside/"+taskGroup.getProjectId()+"@adjustBudget-"+taskGroup.getId(), WxCorpInfoServiceImpl.TEXT_CARD_MSG_REPORT_DENY);
+            }
+            //系统消息
+            Information information=new Information();
+            information.setType(10);
+            information.setUserId(groupBudgetReview.getCreatorId());
+            information.setTime(LocalDateTime.now());
+            information.setContent(String.valueOf(groupBudgetReview.getProjectId())+"@adjustBudget-"+groupBudgetReview.getGroupId());
+            information.setMsg("您在项目["+project.getProjectName()+"]下分组["+taskGroup.getName()+"]的预估工时修改申请被"+(checkType==1?"通过了":("驳回了,驳回理由")+groupBudgetReview.getRejectReason()));
+            informationMapper.insert(information);
+        }
+        return  httpRespMsg;
+    }
+
+    @RequestMapping("/list")
+    public HttpRespMsg list(String startDate,String endDate,Integer projectId,Integer status,String checkUserId){
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        DateTimeFormatter df1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        LocalDateTime localDateTimesStart = LocalDate.parse(startDate, df).atTime(LocalTime.MIN);
+        LocalDateTime localDateTimesEnd = LocalDate.parse(endDate, df).atTime(LocalTime.MAX);
+        LambdaQueryWrapper<GroupBudgetReview> queryWrapper = new LambdaQueryWrapper<GroupBudgetReview>().eq(GroupBudgetReview::getCompanyId, companyId).orderByDesc(GroupBudgetReview::getCreateTime);
+        if(startDate!=null && endDate!=null){
+            queryWrapper.between(GroupBudgetReview::getCreateTime,localDateTimesStart.format(df1),localDateTimesEnd.format(df1));
+        }
+        if(projectId!=null){
+            queryWrapper.eq(GroupBudgetReview::getProjectId,projectId);
+        }
+        if(status!=null){
+            queryWrapper.eq(GroupBudgetReview::getStatus,status-1);
+        }
+        if(!StringUtils.isEmpty(checkUserId)){
+            queryWrapper.eq(GroupBudgetReview::getCheckerId,checkUserId);
+        }
+        List<GroupBudgetReview> list = groupBudgetReviewService.list(queryWrapper);
+        TimeType timeType = timeTypeMapper.selectById(companyId);
+        list.forEach(l->{
+            if(l.getOldManDay()!=null){
+                BigDecimal bigDecimal=new BigDecimal(l.getOldManDay());
+                bigDecimal=bigDecimal.multiply(new BigDecimal(timeType.getAllday()));
+                String format = String.format("%.1f", bigDecimal.doubleValue());
+                l.setOldEstimatedWorkTime(format);
+            }
+            if(l.getChangeManDay()!=null){
+                BigDecimal bigDecimal=new BigDecimal(l.getChangeManDay());
+                bigDecimal=bigDecimal.multiply(new BigDecimal(timeType.getAllday()));
+                String format = String.format("%.1f", bigDecimal.doubleValue());
+                l.setChangeEstimatedWorkTime(format);
+            }
+            if(l.getNowManDay()!=null){
+                BigDecimal bigDecimal=new BigDecimal(l.getNowManDay());
+                bigDecimal=bigDecimal.multiply(new BigDecimal(timeType.getAllday()));
+                String format = String.format("%.1f", bigDecimal.doubleValue());
+                l.setNowEstimatedWorkTime(format);
+            }
+        });
+        httpRespMsg.setData(list);
+        return httpRespMsg;
+    }
+
+    @RequestMapping("/export")
+    public HttpRespMsg export(String startDate,String endDate,Integer projectId,Integer status,String checkUserId){
+        HttpRespMsg httpRespMsg=new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        DateTimeFormatter df=DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        DateTimeFormatter df1=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        LocalDateTime localDateTimesStart = LocalDate.parse(startDate, df).atTime(LocalTime.MIN);
+        LocalDateTime localDateTimesEnd = LocalDate.parse(endDate, df).atTime(LocalTime.MAX);
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId, companyId));
+        CompanyDingding dingding = companyDingdingMapper.selectOne(new LambdaQueryWrapper<CompanyDingding>().eq(CompanyDingding::getCompanyId, companyId));
+        List<User> userList = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getCompanyId, companyId));
+        LambdaQueryWrapper<GroupBudgetReview> queryWrapper = new LambdaQueryWrapper<GroupBudgetReview>().eq(GroupBudgetReview::getCompanyId, companyId).orderByDesc(GroupBudgetReview::getCreateTime);
+        if(startDate!=null && endDate!=null){
+            queryWrapper.between(GroupBudgetReview::getCreateTime,localDateTimesStart.format(df1),localDateTimesEnd.format(df1));
+        }
+        if(projectId!=null){
+            queryWrapper.eq(GroupBudgetReview::getProjectId,projectId);
+        }
+        if(status!=null){
+            queryWrapper.eq(GroupBudgetReview::getStatus,status-1);
+        }
+        if(!StringUtils.isEmpty(checkUserId)){
+            queryWrapper.eq(GroupBudgetReview::getCreatorId,checkUserId);
+        }
+        List<GroupBudgetReview> list = groupBudgetReviewService.list(queryWrapper);
+        List<Integer> projectIdList=new ArrayList<>();
+        if (!list.isEmpty()) {
+            projectIdList = list.stream().map(GroupBudgetReview::getProjectId).distinct().collect(Collectors.toList());
+        }
+        List<Project> projectList = projectMapper.selectList(new LambdaQueryWrapper<Project>().in(Project::getId, projectIdList).eq(Project::getCompanyId, companyId));
+        List<List<String>> dataList=new ArrayList<>();
+        List<String> titleList=new ArrayList<>();
+        titleList.add("项目编号");
+        titleList.add("项目名称");
+        titleList.add("分组名称");
+        titleList.add("提交人");
+        titleList.add("提交时间");
+        titleList.add("变更前预估工时");
+        titleList.add("预估工时变更");
+        titleList.add("变更后预估工时");
+        titleList.add("变更理由");
+        titleList.add("驳回理由");
+        titleList.add("状态");
+        dataList.add(titleList);
+        for (GroupBudgetReview groupBudgetReview : list) {
+            List<String> item=new ArrayList<>();
+            if (!projectList.isEmpty()){
+                Optional<Project> optional = projectList.stream().filter(p -> p.getId().equals(groupBudgetReview.getProjectId())).findFirst();
+                if (optional.isPresent()){
+                    item.add(optional.get().getProjectCode());
+                }else {
+                    item.add("");
+                }
+            }else {
+                item.add("");
+            }
+            item.add(groupBudgetReview.getProjectName());
+            item.add(groupBudgetReview.getGroupName());
+            if((wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1)||(dingding!=null&&dingding.getContactNeedTranslate()==1)){
+                Optional<User> first = userList.stream().filter(u -> u.getId().equals(groupBudgetReview.getCreatorId())).findFirst();
+                if(first.isPresent()){
+                    item.add("$userName="+first.get().getName()+"$");
+                }else {
+                    item.add("");
+                }
+            }
+            item.add(df.format(groupBudgetReview.getCreateTime()));
+            item.add(String.valueOf(groupBudgetReview.getOldManDay()*8)+"h");
+            item.add(String.valueOf(groupBudgetReview.getChangeManDay()*8)+"h");
+            item.add(String.valueOf(groupBudgetReview.getNowManDay()*8)+"h");
+            item.add(String.valueOf(groupBudgetReview.getRemark()));
+            item.add(String.valueOf(groupBudgetReview.getRejectReason()==null?"":groupBudgetReview.getRejectReason()));
+            item.add(groupBudgetReview.getStatus()==0?"待审核":groupBudgetReview.getStatus()==1?"审核通过":"已驳回");
+            dataList.add(item);
+        }
+        String fileUrlSuffix = "预估工时审核表_" + System.currentTimeMillis();
+        try {
+            return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileUrlSuffix,dataList,path);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return httpRespMsg;
+    }
+
+
+
+}
+

+ 48 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/GroupParticipatorController.java

@@ -0,0 +1,48 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.GroupParticipator;
+import com.management.platform.service.GroupParticipatorService;
+import com.management.platform.util.HttpRespMsg;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2022-04-21
+ */
+@RestController
+@RequestMapping("/group-participator")
+public class GroupParticipatorController {
+    @Resource
+    private GroupParticipatorService groupParticipatorService;
+
+    @RequestMapping("/save")
+    public HttpRespMsg save(Integer groupId, String idsJson) {
+        return groupParticipatorService.save(groupId, idsJson);
+    }
+
+    @RequestMapping("/get")
+    public HttpRespMsg get(Integer groupId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        List<GroupParticipator> gpList = groupParticipatorService.list(new QueryWrapper<GroupParticipator>().eq("group_id", groupId));
+        msg.data = gpList.stream().map(GroupParticipator::getUserId).collect(Collectors.toList());
+        return msg;
+    }
+
+    @RequestMapping("/importData")
+    public HttpRespMsg importData(){
+        return null;
+    }
+}
+

+ 125 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/GroupTemplateController.java

@@ -0,0 +1,125 @@
+package com.management.platform.controller;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.entity.GroupTemplate;
+import com.management.platform.entity.GroupTmpstages;
+import com.management.platform.entity.OperationRecord;
+import com.management.platform.entity.User;
+import com.management.platform.service.GroupTemplateService;
+import com.management.platform.service.GroupTmpstagesService;
+import com.management.platform.service.OperationRecordService;
+import com.management.platform.service.UserService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-05-05
+ */
+@RestController
+@RequestMapping("/group-template")
+public class GroupTemplateController {
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private GroupTemplateService groupTemplateService;
+    @Resource
+    private GroupTmpstagesService groupTmpstagesService;
+    @Resource
+    private UserService userService;
+    @Resource
+    private OperationRecordService operationRecordService;
+
+    @RequestMapping("/initData")
+    public HttpRespMsg initData() {
+        if (groupTemplateService.count() == 0) {
+            //系统中没有数据,需要初始化
+            //String[] templateNames = {"工程设计","软硬件研发","客服工单处理"};
+            String[] templateNames = {MessageUtils.message("stages.engineering"),MessageUtils.message("stages.research"),MessageUtils.message("stages.service")};
+            /*String[][] stages = {{"信息收集","策划","原型图","效果图","审核中","修改调整","完成"},
+                                {"需求分析","设计中","研发中","测试中","修改BUG","已发布"},
+                                {"用户问题","解决中","已解决","反馈用户&问题解决"}
+                                };*/
+            String[][] stages = {{MessageUtils.message("stages.infoCollect"),MessageUtils.message("stages.plan"),MessageUtils.message("stages.proDrawing"),MessageUtils.message("stages.designSketch"),MessageUtils.message("stages.underReview"),MessageUtils.message("stages.modify"),MessageUtils.message("stages.complete")},
+                    {MessageUtils.message("stages.requirement"),MessageUtils.message("stages.design"),MessageUtils.message("stages.development"),MessageUtils.message("stages.test"),MessageUtils.message("stages.BUG"),MessageUtils.message("stages.release")},
+                    {MessageUtils.message("stages.userPro"),MessageUtils.message("stages.inSettlement"),MessageUtils.message("stages.resolved"),MessageUtils.message("stages.feedbackAndProblem")}
+            };
+            for (int i=0;i<templateNames.length;i++) {
+                String s = templateNames[i];
+                GroupTemplate template = new GroupTemplate();
+                template.setName(s);
+                template.setIsSystem(1);
+                groupTemplateService.save(template);
+                String[] curStages = stages[i];
+                int seq = 1;
+                for(String name:curStages) {
+                    GroupTmpstages sItem = new GroupTmpstages();
+                    sItem.setSequence(seq);
+                    sItem.setTemplateId(template.getId());
+                    sItem.setStagesName(name);
+                    groupTmpstagesService.save(sItem);
+                    seq++;
+                }
+            }
+        }
+        return new HttpRespMsg();
+    }
+
+    @RequestMapping("/getList")
+    public HttpRespMsg getList() {
+        if (groupTemplateService.count() == 0) {
+            initData();
+        }
+        String uid = request.getHeader("Token");
+        User user = userService.getById(uid);
+        QueryWrapper<GroupTemplate> templateQueryWrapper = new QueryWrapper<>();
+        templateQueryWrapper.eq("company_id", user.getCompanyId()).or().eq("is_system",1).orderByDesc("id");
+        List<GroupTemplate> list = groupTemplateService.list(templateQueryWrapper);
+        //查找任务列表名称
+        for (GroupTemplate template:list) {
+            List<GroupTmpstages> groupTmpstages = groupTmpstagesService.list(new QueryWrapper<GroupTmpstages>().eq("template_id", template.getId()));
+            template.setStagesList(groupTmpstages);
+
+            //TODO: 查找每个阶段模板任务/里程碑/风险
+
+        }
+        HttpRespMsg msg = new HttpRespMsg();
+        msg.data = list;
+        return msg;
+    }
+
+    @RequestMapping("/addTemplate")
+    public HttpRespMsg addTemplate(Integer groupId, String name, Boolean saveTask, Boolean saveMileStone, Boolean saveRisk,Boolean automatically) {
+        String uid = request.getHeader("Token");
+        return groupTemplateService.addTemplate(uid, groupId, name, saveTask, saveMileStone, saveRisk,automatically);
+    }
+
+    @RequestMapping("/deleteTemplate")
+    public HttpRespMsg deleteTemplate(Integer id) {
+        User user = userService.getById(request.getHeader("token"));
+        if(groupTemplateService.removeById(id)){
+            OperationRecord operationRecord=new OperationRecord();
+            operationRecord.setOperatorName(user.getName());
+            operationRecord.setModuleName("项目管理");
+            operationRecord.setCompanyId(user.getCompanyId());
+            operationRecord.setOperationTime(LocalDateTime.now());
+            operationRecord.setContent("删除了模板");
+            operationRecordService.save(operationRecord);
+        }
+        return new HttpRespMsg();
+    }
+}
+

+ 21 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/GroupTmpstagesController.java

@@ -0,0 +1,21 @@
+package com.management.platform.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author Seyason
+ * @since 2021-05-05
+ */
+@RestController
+@RequestMapping("/group-tmpstages")
+public class GroupTmpstagesController {
+
+}
+

+ 0 - 0
fhKeeper/formulahousekeeper/management-platform-mld/src/main/java/com/management/platform/controller/GtemplateTaskController.java


部分文件因为文件数量过多而无法显示