Ver código fonte

黑龙江江达项目后端代码初始化

fyz 2 semanas atrás
commit
3ac3583d11

+ 61 - 0
mjava-jiangda/pom.xml

@@ -0,0 +1,61 @@
+<?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>java-mcli</artifactId>
+        <groupId>com.malk</groupId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>mjava-jiangda</artifactId>
+    <description>江达系统</description>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+    </properties>
+
+    <dependencies>
+        <!-- 核心模块-->
+        <dependency>
+            <groupId>com.malk</groupId>
+            <artifactId>mjava</artifactId>
+            <version>${mjava.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.xerial</groupId>
+            <artifactId>sqlite-jdbc</artifactId>
+            <version>3.41.2.1</version>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.1.1.RELEASE</version>
+                <configuration>
+                    <includeSystemScope>true</includeSystemScope>
+                    <!-- 如果没有该配置,devtools不会生效: 打包时关闭 -->
+                    <fork>false</fork>
+                    <!-- 避免中文乱码 -->
+                    <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
+                </configuration>
+                <!-- 允许生成可运行jar -->
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+        <finalName>${project.artifactId}</finalName>
+    </build>
+</project>

+ 33 - 0
mjava-jiangda/src/main/java/com/malk/heyin/Boot.java

@@ -0,0 +1,33 @@
+package com.malk.heyin;
+
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
+
+import javax.persistence.EntityManager;
+
+/**
+ * corp项目: 扫描公共模块
+ * -
+ * 若是无需数据库模块, 配置无效地址也可启动, 引入mjava不支持直接 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class) 配置
+ * 需要配置 jpa.hibernate.ddl-auto 为 none. 标识对表没有任何操作. 若不设置为 none, flyway.enabled 配置会无效, 在没有数库连接情况下程序无法启动
+ */
+@EnableJpaAuditing
+@SpringBootApplication(scanBasePackages = {"com.malk"},exclude={DataSourceAutoConfiguration.class})
+public class Boot {
+
+    public static void main(String... args) {
+        SpringApplication.run(Boot.class, args);
+    }
+
+    /**
+     * 让Spring管理JPAQueryFactory [不使用Qualifier详见mjava-Boot]
+     */
+    @Bean
+    public JPAQueryFactory jpaQueryFactory(EntityManager entityManager) {
+        return new JPAQueryFactory(entityManager);
+    }
+}

+ 22 - 0
mjava-jiangda/src/main/java/com/malk/heyin/controller/DDController.java

@@ -0,0 +1,22 @@
+package com.malk.heyin.controller;
+
+import com.malk.controller.DDCallbackController;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 钉钉事件回调 3_1
+ * -
+ * [子项目直接继承即可有调用, 无需实现]
+ * -
+ * 注解 @RequestMapping 路径不能重复 [主子项目属同一个项目];
+ * 获取项目回调请求地址, https://mc.cloudpure.cn/frp/xxx/dd/callback [调试代理: frp + nginx]
+ */
+@Slf4j
+@RestController
+@RequestMapping("/dd")
+public class DDController extends DDCallbackController {
+
+
+}

+ 45 - 0
mjava-jiangda/src/main/java/com/malk/heyin/controller/DLController.java

@@ -0,0 +1,45 @@
+package com.malk.heyin.controller;
+
+/**
+ * 错误抛出与拦截详见 CatchException
+ */
+
+import com.malk.heyin.service.TimeService;
+import com.malk.server.common.McR;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.aliwork.YDService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
+
+@Slf4j
+@RestController
+@RequestMapping
+public class DLController {
+
+    @Autowired
+    private YDService ydService;
+    @Autowired
+    private YDClient ydClient;
+
+    @Autowired
+    private TimeService timeService;
+
+    @PostMapping(value = "generateDailyInspections")
+    McR generateDailyInspections(@RequestBody Map data) {
+        timeService.generateDailyInspections(data);
+        return McR.success();
+    }
+
+    @PostMapping(value = "testPost")
+    McR testPost(@RequestBody Map data) {
+        return McR.success();
+    }
+
+    @GetMapping(value = "testGet")
+    McR testGet() {
+        return McR.success();
+    }
+}

+ 62 - 0
mjava-jiangda/src/main/java/com/malk/heyin/delegate/DDDelegate.java

@@ -0,0 +1,62 @@
+package com.malk.heyin.delegate;
+
+import com.malk.heyin.service.TimeService;
+import com.malk.delegate.DDEvent;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Primary;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+/**
+ * OA审批事件 [主项目也有实现, 添加 @Primary 优先注入主项目实现]
+ * -
+ * 取消方案: 撤销和拒绝流程不继续执行连接器, 因此不使用连接器与轮询审批记录方案 [低效而且占用较高钉钉api调次数];
+ * 优化方案: 通过事件订阅实现实时同步所有审批状态, 定时查询钉钉回调失败记录 [配置钉钉事件Delegate, 添加定时任务]
+ */
+@Slf4j
+@Service
+@Primary
+public class DDDelegate implements DDEvent {
+
+    @Autowired
+    TimeService payService;
+    // 审批任务回调执行业务逻辑
+    @Async
+    @Override
+    public void executeEvent_Task_Finish(String processInstanceId, String processCode, boolean isAgree, String remark) {
+        log.info("executeEvent_Task_Finish");
+    }
+
+    @Async
+    @Override
+    public void executeEvent_Task_Start(String processInstanceId, String processCode) {
+        log.info("executeEvent_Task_Start");
+    }
+
+    @Async
+    @Override
+    public void executeEvent_Task_Redirect(String processInstanceId, String processCode) {
+        log.info("executeEvent_Task_Redirect");
+    }
+
+    @Async
+    @Override
+    public void executeEvent_Instance_Start(String processInstanceId, String processCode) {
+        log.info("executeEvent_Instance_Start");
+    }
+
+
+    // 审批实例回调执行业务逻辑
+    @Async
+    @Override
+    public void executeEvent_Instance_Finish(String processInstanceId, String processCode, boolean isAgree, boolean isTerminate, String staffId) {
+        log.info("executeEvent_Instance_Finish");
+        String approveResult = isAgree ? "agree" : "refuse";
+//        if (isTerminate) approveResult = "terminated";
+        if  (isAgree){
+            log.info("开始执行回调:{}",processInstanceId);
+        }
+        log.info("审批实例回调执行业务逻辑, {}", approveResult);
+    }
+}

+ 28 - 0
mjava-jiangda/src/main/java/com/malk/heyin/schedule/ScheduleTask.java

@@ -0,0 +1,28 @@
+package com.malk.heyin.schedule;
+
+import com.malk.heyin.service.TimeService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+
+@Slf4j
+@Configuration
+@EnableScheduling
+@ConditionalOnProperty(name = {"spel.scheduling"})
+public class ScheduleTask {
+    @Autowired
+    TimeService timeService;
+
+    /**
+     * 每日凌晨1点自动发起巡检任务
+     */
+    @Scheduled(cron = "0 0 1 * * ?")
+    void customStatusSchedule() {
+        log.info("开始更新客户信息状态");
+        timeService.generateDailyInspections();
+    }
+
+}

+ 200 - 0
mjava-jiangda/src/main/java/com/malk/heyin/service/Impl/TimeServiceImpl.java

@@ -0,0 +1,200 @@
+package com.malk.heyin.service.Impl;
+
+import cn.hutool.core.date.LocalDateTimeUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.heyin.service.TimeService;
+import com.malk.server.aliwork.YDConf;
+import com.malk.server.aliwork.YDParam;
+import com.malk.server.dingtalk.DDConf;
+import com.malk.service.aliwork.YDClient;
+import com.malk.service.aliwork.YDService;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.service.dingtalk.DDClient_Notice;
+import com.malk.utils.UtilMap;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.time.*;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+
+@Service
+@Slf4j
+public class TimeServiceImpl implements TimeService {
+
+    @Autowired
+    private YDService ydService;
+    @Autowired
+    private YDClient ydClient;
+    @Value("${aliwork.appType}")
+    private String appType;
+    @Value("${aliwork.systemToken}")
+    private String systemToken;
+    @Autowired
+    private DDClient_Notice ddClientNotice;
+    @Autowired
+    private DDClient ddClient;
+    @Autowired
+    private DDConf ddConf;
+    @Override
+    public void generateDailyInspections() {
+        // 获取当天的日期
+        LocalDate today = LocalDate.now();
+        LocalDate tomorrow = today.plusDays(1);
+        // 将当天的日期转换为当天 00:00 的时间,并指定时区(比如系统默认时区)
+        ZoneId zoneId = ZoneId.systemDefault();
+        ZonedDateTime nowOfDay = today.atStartOfDay(zoneId);
+        ZonedDateTime tomorrowOfDay = tomorrow.atStartOfDay(zoneId);
+        // 获取 13 位时间戳(毫秒级)用作过滤查询排班明细
+        long nowTimestamp = nowOfDay.toInstant().toEpochMilli();
+        long tomorrowTimestamp = tomorrowOfDay.toInstant().toEpochMilli();
+        List<String> dateList = new ArrayList<>();
+        dateList.add(String.valueOf(nowTimestamp));
+        dateList.add(String.valueOf(tomorrowTimestamp));
+        //查询排版明细数据
+        List<Map> dataList = ydService.queryFormData_all(YDParam.builder().formUuid("FORM-E106F7ADC547404EBF6FF608B90AFA0A9RL9")
+                .searchFieldJson(JSON.toJSONString(UtilMap.map("dateField_mca5qhty",dateList))).build());
+        if (ObjectUtil.isNotNull(dataList) && dataList.size()>0){
+            dataList.forEach(e->{
+                log.info("获取排班明细:{}",e);
+                String workType = e.get("selectField_mc8v6f7a").toString();
+                List workerInfo = UtilMap.getList(e, "employeeField_mcip6gu5_id");
+                //根据排班明细中的工种获取
+                List<Map> taskList = ydService.queryFormData_all(YDParam.builder().formUuid("FORM-564B023D3ADE468984BBB99E3D7AF3F2RSOD")
+                        .searchFieldJson(JSON.toJSONString(UtilMap.map("selectField_mc8v6f7a",workType))).build());
+                taskList.forEach(t->{
+                    List place = UtilMap.getList(t, "multiSelectField_mc8v6f7i");
+                    //排班巡检开始时间
+                    long startTime = UtilMap.getLong(t, "dateField_mc8wxp8c");
+                    //排班巡检结束时间
+                    long endTime = UtilMap.getLong(t, "dateField_mc8wxp8d");
+                    //间隔时长(若间隔为0则默认为1,只生成一次)
+                    int interval = UtilMap.getInt(t, "numberField_mc8wxp8g_value") == 0 ? 1 : UtilMap.getInt(t, "numberField_mc8wxp8g_value");
+                    // 提取开始时间的小时和分钟
+                    Instant instant = Instant.ofEpochMilli(startTime);
+                    LocalTime localTime = instant.atZone(zoneId).toLocalTime();
+                    int startHour = localTime.getHour();
+                    int startMinute = localTime.getMinute();
+                    // 提取结束时间的小时和分钟
+                    instant = Instant.ofEpochMilli(endTime);
+                    localTime = instant.atZone(zoneId).toLocalTime();
+                    int endHour = localTime.getHour();
+                    int endMinute = localTime.getMinute();
+                    //拼接今日日期与开始结束排班时分
+                    LocalDateTime startLocalDateTime = today.atStartOfDay().plusHours(startHour).plusMinutes(startMinute);
+                    startTime = startLocalDateTime.atZone(zoneId).toInstant().toEpochMilli();
+                    LocalDateTime endLocalDateTime = today.atStartOfDay().plusHours(endHour).plusMinutes(endMinute);
+                    endTime = endLocalDateTime.atZone(zoneId).toInstant().toEpochMilli();
+                    //如果结束时间小于开始时间则是晚班跨日,往后推24小时
+                    if (endTime < startTime){
+                        endTime = endLocalDateTime.plusHours(24).atZone(zoneId).toInstant().toEpochMilli();
+                        //重置localDateTime供while循环使用
+                        startLocalDateTime = today.atStartOfDay().plusHours(startHour).plusMinutes(startMinute);
+                    }
+                    while (startTime <= endTime){
+                        log.info("巡检开始时间:{}",startTime);
+                        List<Map> sonList = ydService.queryDetails(YDParam.builder()
+                                .formInstanceId(t.get("formInstanceId").toString())
+                                .formUuid("FORM-564B023D3ADE468984BBB99E3D7AF3F2RSOD")
+                                .tableFieldId("tableField_mc8v6f7j")
+                                .build());
+
+                        ydClient.operateData(YDParam.builder().userId(workerInfo.get(0).toString())
+                                .formUuid("FORM-B8328BD3B949447DBC9CCD8F2711D301E0M6")
+                                .formDataJson(JSON.toJSONString(UtilMap.map("tableField_mc8v6f7j, employeeField_mc8vbzw3, textField_mcjvgswh, dateField_mc8vbzw5, multiSelectField_mc8v6f7i"
+                                        ,sonList,workerInfo,workType,startTime,place)))
+                                .build(), YDConf.FORM_OPERATION.start);
+                        startLocalDateTime = startLocalDateTime.plusHours(interval);
+                        startTime = startLocalDateTime.atZone(zoneId).toInstant().toEpochMilli();
+                    }
+                });
+            });
+        }
+    }
+
+    @Override
+    public void generateDailyInspections(Map data) {
+        String formInstanceId = data.get("formInstanceId").toString();
+        // 获取当天的日期
+        LocalDate today = LocalDate.now();
+        LocalDate tomorrow = today.plusDays(1);
+        // 将当天的日期转换为当天 00:00 的时间,并指定时区(比如系统默认时区)
+        ZoneId zoneId = ZoneId.systemDefault();
+        ZonedDateTime nowOfDay = today.atStartOfDay(zoneId);
+        ZonedDateTime tomorrowOfDay = tomorrow.atStartOfDay(zoneId);
+        // 获取 13 位时间戳(毫秒级)用作过滤查询排班明细
+        long nowTimestamp = nowOfDay.toInstant().toEpochMilli();
+        long tomorrowTimestamp = tomorrowOfDay.toInstant().toEpochMilli();
+        List<String> dateList = new ArrayList<>();
+        dateList.add(String.valueOf(nowTimestamp));
+        dateList.add(String.valueOf(tomorrowTimestamp));
+        //查询排版明细数据
+        Map formData = ydClient.queryData(YDParam.builder()
+                        .formInstanceId(formInstanceId)
+                        .build(), YDConf.FORM_QUERY.retrieve_id).getFormData();
+        if (ObjectUtil.isNotNull(formData) && formData.size()>0){
+                log.info("获取排班明细:{}",formData);
+                String workType = formData.get("selectField_mc8v6f7a").toString();
+                List workerInfo = UtilMap.getList(formData, "employeeField_mcip6gu5_id");
+                //根据排班明细中的工种获取
+                List<Map> taskList = ydService.queryFormData_all(YDParam.builder().formUuid("FORM-564B023D3ADE468984BBB99E3D7AF3F2RSOD")
+                        .searchFieldJson(JSON.toJSONString(UtilMap.map("selectField_mc8v6f7a",workType))).build());
+                taskList.forEach(t->{
+                    List place = UtilMap.getList(t, "multiSelectField_mc8v6f7i");
+                    //排班巡检开始时间
+                    long startTime = UtilMap.getLong(t, "dateField_mc8wxp8c");
+                    //排班巡检结束时间
+                    long endTime = UtilMap.getLong(t, "dateField_mc8wxp8d");
+                    //间隔时长
+                    int interval = UtilMap.getInt(t, "numberField_mc8wxp8g_value");
+                    // 提取开始时间的小时和分钟
+                    Instant instant = Instant.ofEpochMilli(startTime);
+                    LocalTime localTime = instant.atZone(zoneId).toLocalTime();
+                    int startHour = localTime.getHour();
+                    int startMinute = localTime.getMinute();
+                    // 提取结束时间的小时和分钟
+                    instant = Instant.ofEpochMilli(endTime);
+                    localTime = instant.atZone(zoneId).toLocalTime();
+                    int endHour = localTime.getHour();
+                    int endMinute = localTime.getMinute();
+                    //拼接今日日期与开始结束排班时分
+                    LocalDateTime startLocalDateTime = today.atStartOfDay().plusHours(startHour).plusMinutes(startMinute);
+                    startTime = startLocalDateTime.atZone(zoneId).toInstant().toEpochMilli();
+                    LocalDateTime endLocalDateTime = today.atStartOfDay().plusHours(endHour).plusMinutes(endMinute);
+                    endTime = endLocalDateTime.atZone(zoneId).toInstant().toEpochMilli();
+                    //如果结束时间小于开始时间则是晚班跨日,往后推24小时
+                    if (endTime < startTime){
+                        endTime = endLocalDateTime.plusHours(24).atZone(zoneId).toInstant().toEpochMilli();
+                        //重置localDateTime供while循环使用
+                        startLocalDateTime = today.atStartOfDay().plusHours(startHour).plusMinutes(startMinute);
+                    }
+                    while (startTime <= endTime){
+                        log.info("巡检开始时间:{}",startTime);
+                        List<Map> sonList = ydService.queryDetails(YDParam.builder()
+                                .formInstanceId(t.get("formInstanceId").toString())
+                                .formUuid("FORM-564B023D3ADE468984BBB99E3D7AF3F2RSOD")
+                                .tableFieldId("tableField_mc8v6f7j")
+                                .build());
+
+                        ydClient.operateData(YDParam.builder().userId(workerInfo.get(0).toString())
+                                .formUuid("FORM-B8328BD3B949447DBC9CCD8F2711D301E0M6")
+                                .formDataJson(JSON.toJSONString(UtilMap.map("tableField_mc8v6f7j, employeeField_mc8vbzw3, textField_mcjvgswh, dateField_mc8vbzw5, multiSelectField_mc8v6f7i"
+                                        ,sonList,workerInfo,workType,startTime,place)))
+                                .build(), YDConf.FORM_OPERATION.start);
+                        startLocalDateTime = startLocalDateTime.plusHours(interval);
+                        startTime = startLocalDateTime.atZone(zoneId).toInstant().toEpochMilli();
+                    }
+                });
+        }
+    }
+}

+ 12 - 0
mjava-jiangda/src/main/java/com/malk/heyin/service/TimeService.java

@@ -0,0 +1,12 @@
+package com.malk.heyin.service;
+
+import java.util.Map;
+
+public interface TimeService {
+    /**
+     * 生成每日巡检任务
+     */
+    void generateDailyInspections();
+    void generateDailyInspections(Map data);
+
+}

+ 55 - 0
mjava-jiangda/src/main/resources/application-dev.yml

@@ -0,0 +1,55 @@
+# 环境配置
+server:
+  port: 9002
+  servlet:
+    context-path: /api/jiangda
+
+# condition
+spel:
+  scheduling: false        # 定时任务是否执行
+  multiSource: false       # 是否多数据源配置
+
+spring:
+  # database
+  datasource:
+    hikari:
+      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    username: test
+    password: test123
+    url: jdbc:mysql://47.97.181.40:3306?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  jpa:
+    hibernate:
+      ddl-auto: none      # JPA对表没有任何操作
+    show-sql: true
+    database: MYSQL
+    database-platform: org.hibernate.dialect.MySQL57Dialect
+
+# filepath
+#file:
+#  path:
+#    file: /Users/malk/server/_Tool/var/mjava/tmp/file/
+#    image: /Users/malk/server/_Tool/var/mjava/tmp/image/
+#    tmp: /Users/malk/server/_Tool/var/mjava/tmp/
+#  source:
+#    fonts: /Users/malk/server/_Tool/fonts/simsun.ttc
+#logging:
+#  file:
+#    path: /Users/malk/server/_Tool/var/mjava/log
+
+# dingtalk
+dingtalk:
+  agentId: 3927858641
+  appKey: dinggydmdyzpaq6cagdt
+  appSecret: nA1ewfOZqimC1IQDDSBzaBYk4a4Efquf5Cj96rVjJOwawNI7dVwl-tIHn4qSqO8L
+  corpId:
+  aesKey:
+  token:
+  operator: ""   # OA管理员账号
+
+# aliwork
+aliwork:
+  appType: APP_I2NHNR57RLW8IKKSJCX2
+  systemToken: JB966E9191HWECEA8JIYK8YTXGC92WF6EE8CMC26
+
+

+ 39 - 0
mjava-jiangda/src/main/resources/application-prod.yml

@@ -0,0 +1,39 @@
+# 环境配置
+server:
+  port: 9002
+  servlet:
+    context-path: /api/jiangda
+
+# condition
+spel:
+  scheduling: true        # 定时任务是否执行
+  multiSource: false       # 是否多数据源配置
+
+spring:
+  # database
+  datasource:
+    hikari:
+      connection-init-sql: SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci           # SqlServer, Oracle 无需设置类型
+    driver-class-name: com.mysql.cj.jdbc.Driver
+    username: test
+    password: test123
+    url: jdbc:mysql://47.97.181.40:3306?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  jpa:
+    hibernate:
+      ddl-auto: none      # JPA对表没有任何操作
+    show-sql: true
+    database: MYSQL
+    database-platform: org.hibernate.dialect.MySQL57Dialect
+
+dingtalk:
+  agentId: 3927858641
+  appKey: dinggydmdyzpaq6cagdt
+  appSecret: nA1ewfOZqimC1IQDDSBzaBYk4a4Efquf5Cj96rVjJOwawNI7dVwl-tIHn4qSqO8L
+  corpId:
+  aesKey:
+  token:
+  operator: ""   # OA管理员账号
+
+aliwork:
+  appType: APP_I2NHNR57RLW8IKKSJCX2
+  systemToken: JB966E9191HWECEA8JIYK8YTXGC92WF6EE8CMC26

+ 33 - 0
mjava-jiangda/src/test/java/test.java

@@ -0,0 +1,33 @@
+import com.malk.heyin.Boot;
+import com.malk.heyin.service.Impl.TimeServiceImpl;
+import com.malk.server.dingtalk.DDConf;
+import com.malk.server.dingtalk.crypto.DingCallbackCrypto;
+import com.malk.service.dingtalk.DDClient;
+import com.malk.service.dingtalk.DDClient_Event;
+
+import lombok.extern.slf4j.Slf4j;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@Slf4j
+@RunWith(SpringRunner.class)
+@SpringBootTest(classes = Boot.class)
+public class test {
+
+    @Autowired
+    private DDConf ddConf;
+    @Autowired
+    private DDClient_Event ddClient_event;
+    @Autowired
+    private DDClient ddClient;
+    @Autowired
+    private TimeServiceImpl timeService;
+    @Test
+    public void sonUpdateTest() throws DingCallbackCrypto.DingTalkEncryptException {
+//        timeService.followRemindSchedule();
+        timeService.generateDailyInspections();
+    }
+}

+ 39 - 0
mjava-jiangda/src/test/resource/server.sh

@@ -0,0 +1,39 @@
+#!/bin/bash
+
+appname='mjava-dongfangxinhua'
+
+if [ "$1" == "dev" ]; then
+  java -Xms256m -Xmx256m -jar $appname.jar --spring.profiles.active=dev
+else
+  if [ "$1" == "start" ]; then
+    nohup java -Xms256m -Xmx256m -jar $appname.jar &
+    echo "server prod is starting"
+    tail -f log/info.log
+  else
+    if [ "$1" == "test" ]; then
+      nohup java -Xms256m -Xmx256m -jar $appname.jar --spring.profiles.active=test &
+      echo "server test is starting"
+      tail -f log/info.log
+    else
+      if [ "$1" == "stop" ]; then
+        PID=$(ps -ef | grep $appname.jar | grep -v grep | awk '{ print $2 }')
+        if [ -z "$PID" ]; then
+          echo "server is already stopped"
+        else
+          echo kill $PID
+          kill $PID
+        fi
+      else
+        if [ "$1" == "status" ]; then
+          PID=$(ps -ef | grep $appname.jar | grep -v grep | awk '{ print $2 }')
+          if [ -z "$PID" ]; then
+            echo "server is stopped"
+          else
+            echo "server is running"
+            echo $PID
+          fi
+        fi
+      fi
+    fi
+  fi
+fi

+ 448 - 0
pom.xml

@@ -0,0 +1,448 @@
+<?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">
+    <modelVersion>4.0.0</modelVersion>
+
+    <groupId>com.malk</groupId>
+    <artifactId>java-mcli</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <modules>
+        <module>mjava-jiangda</module>
+    </modules>
+    <packaging>pom</packaging>
+
+    <name>java-mcli</name>
+    <description>mjava framework</description>
+
+    <!-- 版本管理 Management -->
+    <properties>
+        <!-- mjava版本: 修改mjava pom配置 -->
+        <mjava.version>0.0.3</mjava.version>
+        <!-- 全局配置 -->
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+        <java.version>1.8</java.version>
+        <!-- 公共依赖 -->
+        <spring-boot-dependencies.version>2.2.13.RELEASE</spring-boot-dependencies.version>
+        <junit.verson>4.12</junit.verson>
+        <lombok.version>1.18.8</lombok.version>
+        <validation-api.version>2.0.1.Final</validation-api.version>
+        <fastjson.version>1.2.83</fastjson.version>
+        <commons-lang3.version>3.10</commons-lang3.version>
+        <guava.version>30.1.1-jre</guava.version>
+        <hutool-all.version>5.6.0</hutool-all.version>
+        <spring-boot-starter-data-jpa.version>2.1.3.RELEASE</spring-boot-starter-data-jpa.version>
+        <querydsl-apt.version>4.2.1</querydsl-apt.version>
+        <querydsl-jpa.version>4.2.1</querydsl-jpa.version>
+        <spring-boot-starter-jdbc.version>2.2.13.RELEASE</spring-boot-starter-jdbc.version>
+        <easyexcel.version>2.2.7</easyexcel.version>
+        <!-- 数据库连接 [仅mysql为全局依赖] -->
+        <mysql-connector-java.version>8.0.22</mysql-connector-java.version>
+        <mssql-jdbc.version>6.4.0.jre8</mssql-jdbc.version>
+        <ojdbc6.version>11.2.0.4</ojdbc6.version>
+        <mongo-java-driver.version>3.12.7</mongo-java-driver.version>
+        <spring-boot-starter-data-mongodb.version>2.2.13.RELEASE</spring-boot-starter-data-mongodb.version>
+        <!-- jsp [非全局依赖] -->
+        <tomcat-embed-jasper.version>9.0.41</tomcat-embed-jasper.version>
+        <jstl.version>1.2</jstl.version>
+        <javax.servlet-api.version>4.0.1</javax.servlet-api.version>
+        <javax.servlet.jsp-api.version>2.3.1</javax.servlet.jsp-api.version>
+        <!-- jwt [非全局依赖] -->
+        <java-jwt.version>3.4.0</java-jwt.version>
+        <!-- swagger3: todo -->
+        <springfox-boot-starter.version>3.0.0</springfox-boot-starter.version>
+        <!-- 网页转pdf [非全局依赖] -->
+        <flying-saucer-pdf-itext5.version>9.0.3</flying-saucer-pdf-itext5.version>
+        <!-- 腾讯云[发票识别] [非全局依赖] -->
+        <tencentcloud-sdk-java.version>3.1.778</tencentcloud-sdk-java.version>
+        <!-- 不执行单元测试,也不编译测试类 -->
+        <skipTests>true</skipTests>
+        <!-- 不执行单元测试,但会编译测试类,并在target/test-classes目录下生成相应的class -->
+        <maven.test.skip>true</maven.test.skip>
+        <mybatis-plus.version>3.5.1</mybatis-plus.version>
+        <durid.version>1.1.18</durid.version>
+    </properties>
+
+    <!-- 依赖声明 & 版本 -->
+    <dependencyManagement>
+        <dependencies>
+            <!-- SpringBoot 依赖 -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-dependencies</artifactId>
+                <version>${spring-boot-dependencies.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <!-- 单元测试 -->
+            <dependency>
+                <groupId>junit</groupId>
+                <artifactId>junit</artifactId>
+                <version>${junit.verson}</version>
+                <scope>test</scope>
+            </dependency>
+
+            <!-- lombok -->
+            <dependency>
+                <groupId>org.projectlombok</groupId>
+                <artifactId>lombok</artifactId>
+                <version>${lombok.version}</version>
+                <scope>provided</scope>
+            </dependency>
+
+            <!-- validation 参数校验 -->
+            <dependency>
+                <groupId>javax.validation</groupId>
+                <artifactId>validation-api</artifactId>
+                <version>${validation-api.version}</version>
+            </dependency>
+
+            <!-- 阿里巴巴 json -->
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>fastjson</artifactId>
+                <version>${fastjson.version}</version>
+            </dependency>
+
+            <!-- 通用的工具类集 -->
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-lang3</artifactId>
+                <version>${commons-lang3.version}</version>
+            </dependency>
+            <!-- ppExt: 23.10.26 钉钉新方式以Steam接入, HTTP形式commonsc-codec在升级之后,其内部做了一个validateCharacter校验. 使用 guava 替代-->
+            <dependency>
+                <groupId>com.google.guava</groupId>
+                <artifactId>guava</artifactId>
+                <version>${guava.version}</version>
+            </dependency>
+            <!-- 国产工具集 -->
+            <dependency>
+                <groupId>cn.hutool</groupId>
+                <artifactId>hutool-all</artifactId>
+                <version>${hutool-all.version}</version>
+            </dependency>
+
+            <!-- data-jpa 数据库操作 -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-data-jpa</artifactId>
+                <version>${spring-boot-starter-data-jpa.version}</version>
+            </dependency>
+
+            <!-- QueryDSL 4.x 支持-->
+            <dependency>
+                <groupId>com.querydsl</groupId>
+                <artifactId>querydsl-apt</artifactId>
+                <scope>provided</scope>
+                <version>${querydsl-apt.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>com.querydsl</groupId>
+                <artifactId>querydsl-jpa</artifactId>
+                <version>${querydsl-jpa.version}</version>
+            </dependency>
+
+            <!-- AOP多数据源切换 -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-jdbc</artifactId>
+                <version>${spring-boot-starter-jdbc.version}</version>
+            </dependency>
+
+            <!-- easyExcel 优化 poi [不影响单独引入poi, 会冲突] -->
+            <dependency>
+                <groupId>com.alibaba</groupId>
+                <artifactId>easyexcel</artifactId>
+                <version>${easyexcel.version}</version>
+            </dependency>
+
+            <!-- mySql 驱动 -->
+            <dependency>
+                <groupId>mysql</groupId>
+                <artifactId>mysql-connector-java</artifactId>
+                <version>${mysql-connector-java.version}</version>
+            </dependency>
+
+            <!-- sqlserver依赖 -->
+            <dependency>
+                <groupId>com.microsoft.sqlserver</groupId>
+                <artifactId>mssql-jdbc</artifactId>
+                <scope>runtime</scope>
+                <version>${mssql-jdbc.version}</version>
+            </dependency>
+
+            <!-- Oracle 依赖 -->
+            <dependency>
+                <groupId>com.oracle.database.jdbc</groupId>
+                <artifactId>ojdbc6</artifactId>
+                <version>${ojdbc6.version}</version>
+            </dependency>
+
+            <!-- MongoDB 驱动 -->
+            <dependency>
+                <groupId>org.mongodb</groupId>
+                <artifactId>mongo-java-driver</artifactId>
+                <version>${mongo-java-driver.version}</version>
+            </dependency>
+            <!-- MongoDB jpa 操作 -->
+            <dependency>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-starter-data-mongodb</artifactId>
+                <version>${spring-boot-starter-data-mongodb.version}</version>
+            </dependency>
+
+            <!-- url转pdf -->
+            <dependency>
+                <groupId>org.xhtmlrenderer</groupId>
+                <artifactId>flying-saucer-pdf-itext5</artifactId>
+                <version>${flying-saucer-pdf-itext5.version}</version>
+            </dependency>
+
+            <!-- jsp: tomcat-embed-jasper 需要添加到子项目内 -->
+            <dependency>
+                <groupId>org.apache.tomcat.embed</groupId>
+                <artifactId>tomcat-embed-jasper</artifactId>
+                <version>${tomcat-embed-jasper.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>jstl</artifactId>
+                <version>${jstl.version}</version>
+            </dependency>
+            <!-- servlet -->
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>javax.servlet-api</artifactId>
+                <version>${javax.servlet-api.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.servlet.jsp</groupId>
+                <artifactId>javax.servlet.jsp-api</artifactId>
+                <version>${javax.servlet.jsp-api.version}</version>
+            </dependency>
+
+            <!-- jwt -->
+            <dependency>
+                <groupId>com.auth0</groupId>
+                <artifactId>java-jwt</artifactId>
+                <version>${java-jwt.version}</version>
+            </dependency>
+
+            <!-- 腾讯云 -->
+            <dependency>
+                <groupId>com.tencentcloudapi</groupId>
+                <artifactId>tencentcloud-sdk-java</artifactId>
+                <version>${tencentcloud-sdk-java.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <!-- 子项目需要与 mjava 相同的依赖, 否则调试可运行, 打包后会运行报错. 为了避免重复引入 pom, 将 mjava 依赖直接在全局 pom 引入 -->
+    <dependencies>
+        <!-- spring boot -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-tomcat</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-configuration-processor</artifactId>
+            <optional>true</optional>
+        </dependency>
+        <!-- spring-boot-devtools [热部署] -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-devtools</artifactId>
+            <optional>true</optional> <!-- 表示依赖不会传递 -->
+        </dependency>
+        <!-- 单元测试 -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <!-- lombok -->
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <!-- validation 参数校验 -->
+        <dependency>
+            <groupId>javax.validation</groupId>
+            <artifactId>validation-api</artifactId>
+        </dependency>
+
+        <!-- 阿里巴巴 json -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+
+        <!-- 通用的工具类集 -->
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <!-- 国产工具集 -->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+
+        <!-- data-jpa 数据库操作 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+
+        <!-- QueryDSL 4.x 支持-->
+        <dependency>
+            <groupId>com.querydsl</groupId>
+            <artifactId>querydsl-apt</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>com.querydsl</groupId>
+            <artifactId>querydsl-jpa</artifactId>
+        </dependency>
+
+        <!-- AOP多数据源切换 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-jdbc</artifactId>
+        </dependency>
+
+        <!-- easyExcel 优化 poi [不影响单独引入poi, 会冲突] -->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>easyexcel</artifactId>
+        </dependency>
+
+        <!-- mySql 驱动 -->
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+        <!--        引入mybatisPlus 包含了 jdbc -->
+<!--        <dependency>-->
+<!--            <groupId>com.baomidou</groupId>-->
+<!--            <artifactId>mybatis-plus-boot-starter</artifactId>-->
+<!--            <version>${mybatis-plus.version}</version>-->
+<!--        </dependency>-->
+
+        <!--        引入durid數據源-->
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>${durid.version}</version>
+        </dependency>
+
+        <!-- Oracle 依赖 -->
+<!--                <dependency>-->
+<!--                    <groupId>com.oracle.database.jdbc</groupId>-->
+<!--                    <artifactId>ojdbc6</artifactId>-->
+<!--                </dependency>-->
+
+<!--         sqlserver 依赖 -->
+<!--                <dependency>-->
+<!--                    <groupId>com.microsoft.sqlserver</groupId>-->
+<!--                    <artifactId>mssql-jdbc</artifactId>-->
+<!--                    <scope>runtime</scope>-->
+<!--                </dependency>-->
+
+
+<!--         MongoDB 驱动 -->
+<!--                <dependency>-->
+<!--                    <groupId>org.mongodb</groupId>-->
+<!--                    <artifactId>mongo-java-driver</artifactId>-->
+<!--                </dependency>-->
+<!--         MongoDB jpa 操作 -->
+<!--                <dependency>-->
+<!--                    <groupId>org.springframework.boot</groupId>-->
+<!--                    <artifactId>spring-boot-starter-data-mongodb</artifactId>-->
+<!--                    <version>${spring-boot-starter-data-mongodb.version}</version>-->
+<!--                </dependency>-->
+
+<!--         url转pdf -->
+<!--                <dependency>-->
+<!--                    <groupId>org.xhtmlrenderer</groupId>-->
+<!--                    <artifactId>flying-saucer-pdf-itext5</artifactId>-->
+<!--                </dependency>-->
+
+<!--         jsp: tomcat-embed-jasper 需要在子项目内引用才有效 -->
+<!--                <dependency>-->
+<!--                    <groupId>javax.servlet</groupId>-->
+<!--                    <artifactId>jstl</artifactId>-->
+<!--                </dependency>-->
+<!--         servlet -->
+                <dependency>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>javax.servlet-api</artifactId>
+                </dependency>
+                <dependency>
+                    <groupId>javax.servlet.jsp</groupId>
+                    <artifactId>javax.servlet.jsp-api</artifactId>
+                </dependency>
+
+<!--         jwt -->
+                <dependency>
+                    <groupId>com.auth0</groupId>
+                    <artifactId>java-jwt</artifactId>
+                </dependency>
+
+<!--         腾讯云 [go to https://search.maven.org/search?q=tencentcloud-sdk-java and get the latest version.] -->
+<!--                <dependency>-->
+<!--                    <groupId>com.tencentcloudapi</groupId>-->
+<!--                    <artifactId>tencentcloud-sdk-java</artifactId>-->
+<!--                </dependency>-->
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>3.8.1</version>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                    <encoding>${project.build.sourceEncoding}</encoding>
+                    <!-- jva使用了未经检查或不安全的操作,编译会有打印,通过插件显示具体报错警告位置, 如 T, Map, List 也会报警告 -->
+                    <compilerArgument>-Xlint:unchecked</compilerArgument>
+                </configuration>
+            </plugin>
+            <!-- QueryDSL 插件: 因为QueryDsl是类型安全的,所以还需要加上Maven APT plugin,使用 APT 自动生成Q类 -->
+            <plugin>
+                <groupId>com.mysema.maven</groupId>
+                <artifactId>apt-maven-plugin</artifactId>
+                <version>1.1.3</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>process</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>target/generated-sources/java</outputDirectory>
+                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>