Explorar o código

创建凯悦南通模块

wzy hai 1 ano
pai
achega
1b5e0e82fb

+ 29 - 0
mjava-kaiyue_nt/pom.xml

@@ -0,0 +1,29 @@
+<?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>
+    <parent>
+        <groupId>com.malk</groupId>
+        <artifactId>java-mcli</artifactId>
+        <version>1.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>com.malk.kaiyue_nt</groupId>
+    <artifactId>mjava-kaiyue_nt</artifactId>
+
+    <properties>
+        <maven.compiler.source>8</maven.compiler.source>
+        <maven.compiler.target>8</maven.compiler.target>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.malk</groupId>
+            <artifactId>mjava</artifactId>
+            <version>0.0.3</version>
+            <scope>compile</scope>
+        </dependency>
+    </dependencies>
+
+</project>

+ 32 - 0
mjava-kaiyue_nt/src/main/java/com/malk/kaiyue_nt/Boot.java

@@ -0,0 +1,32 @@
+package com.malk.kaiyue_nt;
+
+import com.querydsl.jpa.impl.JPAQueryFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+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"})
+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);
+    }
+}

+ 113 - 0
mjava-kaiyue_nt/src/main/java/com/malk/kaiyue_nt/controller/KYNTController.java

@@ -0,0 +1,113 @@
+package com.malk.kaiyue_nt.controller;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.malk.controller.DDCallbackController;
+import com.malk.kaiyue_nt.service.KYNTService;
+import com.malk.server.dingtalk.DDConf;
+import com.malk.server.dingtalk.crypto.DingCallbackCrypto;
+import lombok.SneakyThrows;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import com.malk.server.common.McR;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@RestController
+@RequestMapping
+public class KYNTController extends DDCallbackController {
+    @Autowired
+    private KYNTService kyntService;
+
+    @Autowired
+    private DDConf ddConf;
+
+    @GetMapping("/test")
+    public McR test() {
+        log.info("11111111");
+        return McR.success();
+    }
+
+    //保存10s内已处理的回调事件
+    private Map<String, Long> eventList = new HashMap<>();
+
+    //钉钉事件回调
+    @SneakyThrows
+    public synchronized Map<String, String> invokeCallback(@RequestParam(value = "signature", required = false) String signature,
+                                                           @RequestParam(value = "timestamp", required = false) String timestamp,
+                                                           @RequestParam(value = "nonce", required = false) String nonce,
+                                                           @RequestBody(required = false) JSONObject json) {
+        DingCallbackCrypto callbackCrypto = new DingCallbackCrypto(ddConf.getToken(), ddConf.getAesKey(), ddConf.getAppKey());
+        // 处理回调消息,得到回调事件decryptMsg...
+        final String decryptMsg = callbackCrypto.getDecryptMsg(signature, timestamp, nonce, json.getString("encrypt"));
+        JSONObject eventJson = JSON.parseObject(decryptMsg);
+        Map success = callbackCrypto.getEncryptedMap(DDConf.CALLBACK_RESPONSE, System.currentTimeMillis(), DingCallbackCrypto.Utils.getRandomStr(8));
+
+        // 检查回调事件是否已经处理过,如果是,则忽略该回调
+        if (isCallbackProcessed(decryptMsg)) {
+            log.info("----- [DD]该回调事件已处理过 忽略该回调 -----");
+            return success;
+        }
+
+        // 业务处理代码...
+        String eventType = eventJson.getString("EventType");
+        if (DDConf.CALLBACK_CHECK.equals(eventType)) {
+            log.info("----- [DD]验证注册 -----");
+            return success;
+        }
+        // [回调任务执行逻辑: 异步] 钉钉超时3s未返回会被记录为失败, 可通过失败接口获取记录
+        if (Arrays.asList(DDConf.HRM_USER_RECORD_CHANGE).contains(eventType)) {
+            log.info("[DD]人事档案变动回调, eventType:{}, eventJson:{}",eventType, eventJson);
+            //获取员工userId
+            String userId = "";
+            if (Objects.nonNull(eventJson.get("staffId"))){
+                //人事档案返回的userId
+                userId = eventJson.get("staffId").toString();
+            }else if (Objects.nonNull(eventJson.get("userid"))){
+                //通讯录事件返回的userId
+                userId = eventJson.get("userid").toString();
+            }else {
+                log.error("[DD]人事档案变动回调, 未获取到userId");
+                return success;
+            }
+
+            log.info("员工userId:"+userId);
+            Map<String, Object> map = new HashMap();
+            map.put("userid_list", userId);
+            //更新员工年假余额
+            log.info("----- [DD]更新员工年假余额 -----");
+
+
+            // 将回调事件和当前时间戳添加到已处理集合中
+            long currentTime = System.currentTimeMillis();
+            eventList.put(decryptMsg, currentTime);
+
+            return success;
+        }
+        log.info("----- [DD]已注册, 未处理的其它回调 -----, eventType:{}, eventJson:{}",eventType, eventJson);
+        return success;
+    }
+
+    /**
+     * 检查该回调事件在10s内是否处理过,应对钉钉瞬间重复回调
+     *
+     * @param decryptMsg 回调事件
+     * @return 是否处理过
+     */
+    private boolean isCallbackProcessed(String decryptMsg) {
+        // 清理超过十分钟的回调事件
+        long currentTime = System.currentTimeMillis();
+        long expirationTime = currentTime - TimeUnit.MINUTES.toMillis(10);
+        eventList.entrySet().removeIf(entry -> entry.getValue() < expirationTime);
+
+        return eventList.containsKey(decryptMsg);
+    }
+
+
+}

+ 4 - 0
mjava-kaiyue_nt/src/main/java/com/malk/kaiyue_nt/service/KYNTService.java

@@ -0,0 +1,4 @@
+package com.malk.kaiyue_nt.service;
+
+public interface KYNTService {
+}

+ 8 - 0
mjava-kaiyue_nt/src/main/java/com/malk/kaiyue_nt/service/impl/KYNTServiceImpl.java

@@ -0,0 +1,8 @@
+package com.malk.kaiyue_nt.service.impl;
+
+import com.malk.kaiyue_nt.service.KYNTService;
+import org.springframework.stereotype.Service;
+
+@Service
+public class KYNTServiceImpl implements KYNTService {
+}

+ 80 - 0
mjava-kaiyue_nt/src/main/resources/application-dev.yml

@@ -0,0 +1,80 @@
+# 环境配置
+server:
+  port: 9001
+  servlet:
+    context-path: /api/kaiyue_nt
+
+# 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: root
+    password: mu123
+    url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+    # 主库
+    primary:
+      username: root
+      password: mu123
+      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+    # 从库
+    slave:
+      username: root
+      password: mu123
+      jdbc-url: jdbc:mysql://127.0.0.1:3306/mjava_slave?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: 3103808497
+  appKey: dingrqlcenh5w4ibo83n
+  appSecret: _gwZ64kLPq1E7_h9nlBQULR5DEC1Ol-kNRE4X8enUFjIHrR5K-l5aM8Ib3mEAq29
+  corpId: ding5bdfeeb522ace222bc961a6cb783455b
+  aesKey: Xj5W56OQx0HyRclconpklFg4Tgk3orTty9gIaxL8Vwr
+  token: UDcVvKtr8qB
+  operator: "344749020127590108"   # OA管理员账号 [0开头需要转一下字符串]
+
+  #高级假期
+  #agentId: 3047931226
+  #appKey: dingzwmsgsh53i0vntbu
+  #appSecret: E2ro4owsTwPxba_4ntLg01kYn4-W_Ti6IU3MaALj-f_xQkXhnSDccEE5Iad-fnuk
+  #corpId: dingc905d8a60b6a641b24f2f5cc6abecb85
+  #aesKey: hEWViCdQbFxRoRwPDi64tRegzAkuoIpp5Oq3JSngWXi
+  #token: wKJlvqvPrEkNd849
+  #operator: "344749020127590108"   # OA管理员账号 [0开头需要转一下字符串]
+
+
+# aliwork
+aliwork:
+  appType: APP_ZL5NE83JE84UUACZDD03
+  systemToken: 3J966U61PPNCA6ROEIX8L8TY6DF33EYW60BKLY
+
+# teambition
+teambition:
+  AppID: 65956b5dd0ac095d62d0e592
+  AppSecret: gjQUoqKa1PHjTiyQFFuachfqKPyNeacA
+  TenantId: 6034c885e71842e1e5bb5218        # 管理后台 - 企业xx - 企业ID
+  OperatorId: 5e698cca21f5ad70dfba7d2b      # 公共账号, 需要有操作权限 [牧语]

+ 46 - 0
mjava-kaiyue_nt/src/main/resources/application-prod.yml

@@ -0,0 +1,46 @@
+# 环境配置
+server:
+  port: 9013
+  servlet:
+    context-path: /api/kaiyue_nt
+
+# 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: root
+    password: mu123
+    url: jdbc:mysql://127.0.0.1:3306/mjava?serverTimezone=Asia/Shanghai&useUnicode=yes&characterEncoding=UTF-8&useSSL=true
+  jpa:
+    database: MYSQL
+    database-platform: org.hibernate.dialect.MySQL57Dialect
+
+# dingtalk
+dingtalk:
+  agentId: 3103808497
+  appKey: dingrqlcenh5w4ibo83n
+  appSecret: _gwZ64kLPq1E7_h9nlBQULR5DEC1Ol-kNRE4X8enUFjIHrR5K-l5aM8Ib3mEAq29
+  corpId: ding5bdfeeb522ace222bc961a6cb783455b
+  aesKey: Xj5W56OQx0HyRclconpklFg4Tgk3orTty9gIaxL8Vwr
+  token: UDcVvKtr8qB
+  operator: "344749020127590108"   # OA管理员账号 [0开头需要转一下字符串]
+
+# aliwork
+aliwork:
+  appType: APP_ZL5NE83JE84UUACZDD03
+  systemToken: 3J966U61PPNCA6ROEIX8L8TY6DF33EYW60BKLY
+
+# teambition
+teambition:
+  AppID: 659cf4922fefb4a7ec89137b
+  AppSecret: ploT7pyTcEVz91i5IIBZ8Pw7LbrOWPYD
+  TenantId: 655f1512ad7db5a6a70cf7b1                # 管理后台 - 企业xx - 企业ID
+  OperatorId: 65682c174655a82b4fa04dfe              # 公共账号, 需要有操作权限 [x]
+  ApiHost: https://tb.awinic.com:443/gateway        # 私有部署

+ 1 - 0
pom.xml

@@ -14,6 +14,7 @@
         <module>mjava-kaiyue_yt</module>
         <module>mjava-kaiyue_cd</module>
         <module>mjava-zhixingtongde</module>
+        <module>mjava-kaiyue_nt</module>
     </modules>
     <packaging>pom</packaging>