diff --git a/assembly/assembly.xml b/assembly/assembly.xml
new file mode 100644
index 0000000..4a86351
--- /dev/null
+++ b/assembly/assembly.xml
@@ -0,0 +1,108 @@
+
+
+
+ bin
+
+
+
+ zip
+
+
+
+ false
+
+
+
+
+
+
+ false
+ true
+ lib
+ provided
+
+
+ false
+ true
+ lib
+ system
+
+
+ false
+ true
+ lib
+ runtime
+
+
+
+
+
+ true
+
+ integration-platform-access:cdaxxt-bootstrap
+ integration-platform-access:cdaxxt-business
+ integration-platform-access:cdaxxt-common
+ integration-platform-access:cdaxxt-core
+
+
+
+
+
+
+
+
+ ${project.basedir}
+
+
+ README*
+ LICENSE*
+ NOTICE*
+
+
+
+
+
+ ../cdaxxt-bootstrap/src/main/resources
+ config
+
+ *.yml
+
+
+
+
+
+ ../cdaxxt-bootstrap/src/main/resources/bin
+
+
+ 777
+
+ 777
+
+
+
+
+ ../cdaxxt-bootstrap/target
+
+
+ *.jar
+
+
+
+
+
\ No newline at end of file
diff --git a/assembly/pom.xml b/assembly/pom.xml
new file mode 100644
index 0000000..8b4c042
--- /dev/null
+++ b/assembly/pom.xml
@@ -0,0 +1,63 @@
+
+
+
+ integration-platform-access
+ com.tobacco.mp
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ assembly
+
+
+
+ com.tobacco.mp
+ cdaxxt-bootstrap
+ 1.0-SNAPSHOT
+
+
+ com.tobacco.mp
+ cdaxxt-business
+ 1.0-SNAPSHOT
+
+
+ com.tobacco.mp
+ cdaxxt-common
+ 1.0-SNAPSHOT
+
+
+ com.tobacco.mp
+ cdaxxt-core
+ 1.0-SNAPSHOT
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 2.4.1
+
+
+ make-assembly
+ package
+
+ single
+
+
+ assembly-package
+
+ assembly.xml
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cdaxxt-bootstrap/pom.xml b/cdaxxt-bootstrap/pom.xml
new file mode 100644
index 0000000..e11082c
--- /dev/null
+++ b/cdaxxt-bootstrap/pom.xml
@@ -0,0 +1,72 @@
+
+
+
+ integration-platform-access
+ com.tobacco.mp
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ cdaxxt-bootstrap
+
+
+
+ com.tobacco.mp
+ cdaxxt-common
+ 1.0-SNAPSHOT
+
+
+ com.tobacco.mp
+ cdaxxt-business
+ 1.0-SNAPSHOT
+
+
+ com.tobacco.mp
+ cdaxxt-core
+ 1.0-SNAPSHOT
+
+
+
+
+
+
+ src/main/java
+
+ **/*.xml
+
+
+
+ src/main/resources
+
+ **/*.*
+ static/**
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ false
+
+
+ true
+
+ lib/
+
+ com.tobacco.mp.BasisApplication
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/BasisApplication.java b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/BasisApplication.java
new file mode 100644
index 0000000..6125367
--- /dev/null
+++ b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/BasisApplication.java
@@ -0,0 +1,19 @@
+package com.tobacco.mp;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@EnableScheduling
+@EnableFeignClients(basePackages = {"com.tobacco.mp.uc.client.api","com.tobacco.mp.auth.businessdomain.auth.client.api","com.tobacco.mp.mcext.client.api","com.tobacco.mp.ttc.client.api"})
+@EnableAsync
+@SpringBootApplication(scanBasePackages = {"com.tobacco.mp"})
+public class BasisApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(BasisApplication.class, args);
+ }
+
+}
diff --git a/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/BizworksApiGatewayConfiguration.java b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/BizworksApiGatewayConfiguration.java
new file mode 100644
index 0000000..e0cecd4
--- /dev/null
+++ b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/BizworksApiGatewayConfiguration.java
@@ -0,0 +1,24 @@
+package com.tobacco.mp.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 阿里云网关包扫描配置
+ */
+@Slf4j
+@Configuration
+@ConditionalOnExpression("'ali'.equals('${bizworks-api-gateway.type}') and 'true'.equals('${bizworks-api-gateway.enable}') ")
+@ComponentScan("com.bizworks.ubcp.apiclient.feign")
+public class BizworksApiGatewayConfiguration {
+
+ @Bean
+ public String init(){
+ log.info("开启阿里网关模式");
+ return null;
+ }
+
+}
diff --git a/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/CorsFilter.java b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/CorsFilter.java
new file mode 100644
index 0000000..352a116
--- /dev/null
+++ b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/CorsFilter.java
@@ -0,0 +1,52 @@
+package com.tobacco.mp.config;
+
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+/**
+ * 跨域处理机制
+ */
+@Component
+public class CorsFilter implements Filter {
+
+ @Override
+ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
+ throws IOException, ServletException {
+ HttpServletResponse response = (HttpServletResponse) res;
+ HttpServletRequest request = (HttpServletRequest) req;
+ String origin = request.getHeader("Origin");
+ String allowHeaders = request.getHeader("Access-Control-Request-Headers");
+ if (!StringUtils.isEmpty(origin)) {
+ response.setHeader("Access-Control-Allow-Origin", origin);
+ } else {
+ response.setHeader("Access-Control-Allow-Origin", "*");
+ }
+ if (!StringUtils.isEmpty(allowHeaders)) {
+ response.setHeader("Access-Control-Allow-Headers", allowHeaders);
+ } else {
+ response.setHeader("Access-Control-Allow-Headers", "*");
+ }
+ response.setHeader("Access-Control-Allow-Credentials", "true");
+ response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT");
+ response.setHeader("Access-Control-Max-Age", "3600");
+ if ("OPTIONS".equals(request.getMethod())) {
+ response.setStatus(HttpServletResponse.SC_OK);
+ } else {
+ chain.doFilter(req, res);
+ }
+ }
+
+ @Override
+ public void init(FilterConfig filterConfig) {
+ }
+
+ @Override
+ public void destroy() {
+ }
+
+}
diff --git a/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/RedisConfig.java b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/RedisConfig.java
new file mode 100644
index 0000000..49ca6a7
--- /dev/null
+++ b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/RedisConfig.java
@@ -0,0 +1,107 @@
+package com.tobacco.mp.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.cache.annotation.CachingConfigurerSupport;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.*;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * redis配置
+ */
+@Configuration
+@EnableCaching
+public class RedisConfig extends CachingConfigurerSupport {
+
+ /**
+ * retemplate相关配置
+ * @param factory
+ * @return
+ */
+ @Bean
+ public RedisTemplate redisTemplate(RedisConnectionFactory factory) {
+
+ RedisTemplate template = new RedisTemplate<>();
+ // 配置连接工厂
+ template.setConnectionFactory(factory);
+
+ //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值(默认使用JDK的序列化方式)
+ Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
+
+ ObjectMapper om = new ObjectMapper();
+ // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
+ om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+ // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
+ om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+ jacksonSeial.setObjectMapper(om);
+
+ // 值采用json序列化
+ template.setValueSerializer(jacksonSeial);
+ //使用StringRedisSerializer来序列化和反序列化redis的key值
+ template.setKeySerializer(new StringRedisSerializer());
+
+ // 设置hash key 和value序列化模式
+ template.setHashKeySerializer(new StringRedisSerializer());
+ template.setHashValueSerializer(jacksonSeial);
+ template.afterPropertiesSet();
+
+ return template;
+ }
+
+ /**
+ * 对hash类型的数据操作
+ * @param redisTemplate
+ * @return
+ */
+ @Bean
+ public HashOperations hashOperations(RedisTemplate redisTemplate) {
+ return redisTemplate.opsForHash();
+ }
+
+ /**
+ * 对redis字符串类型数据操作
+ * @param redisTemplate
+ * @return
+ */
+ @Bean
+ public ValueOperations valueOperations(RedisTemplate redisTemplate) {
+ return redisTemplate.opsForValue();
+ }
+
+ /**
+ * 对链表类型的数据操作
+ * @param redisTemplate
+ * @return
+ */
+ @Bean
+ public ListOperations listOperations(RedisTemplate redisTemplate) {
+ return redisTemplate.opsForList();
+ }
+
+ /**
+ * 对无序集合类型的数据操作
+ * @param redisTemplate
+ * @return
+ */
+ @Bean
+ public SetOperations setOperations(RedisTemplate redisTemplate) {
+ return redisTemplate.opsForSet();
+ }
+
+ /**
+ * 对有序集合类型的数据操作
+ * @param redisTemplate
+ * @return
+ */
+ @Bean
+ public ZSetOperations zSetOperations(RedisTemplate redisTemplate) {
+ return redisTemplate.opsForZSet();
+ }
+
+}
diff --git a/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/RequestInterceptor.java b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/RequestInterceptor.java
new file mode 100644
index 0000000..45fc787
--- /dev/null
+++ b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/RequestInterceptor.java
@@ -0,0 +1,19 @@
+package com.tobacco.mp.config;
+
+import org.springframework.web.servlet.HandlerInterceptor;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 请求拦截器处理
+ */
+public class RequestInterceptor implements HandlerInterceptor {
+
+ @Override
+ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+ // 请求拦截处理
+ return true;
+ }
+
+}
diff --git a/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/ServerRunner.java b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/ServerRunner.java
new file mode 100644
index 0000000..4bd30ad
--- /dev/null
+++ b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/ServerRunner.java
@@ -0,0 +1,20 @@
+package com.tobacco.mp.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.CommandLineRunner;
+import org.springframework.stereotype.Component;
+
+
+@Slf4j
+@Component
+public class ServerRunner implements CommandLineRunner {
+
+
+ @Override
+ public void run(String... args) throws Exception {
+ // 服务器成功启动加载其他
+
+ }
+
+
+}
diff --git a/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/WebMvcConfig.java b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/WebMvcConfig.java
new file mode 100644
index 0000000..dc94773
--- /dev/null
+++ b/cdaxxt-bootstrap/src/main/java/com/tobacco/mp/config/WebMvcConfig.java
@@ -0,0 +1,43 @@
+package com.tobacco.mp.config;
+
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * @Author XiongLiJian
+ * @Date 2021/12/28 15:36
+ * @Description 资源管理配置
+ * @Version 1.0
+ **/
+@Configuration
+public class WebMvcConfig implements WebMvcConfigurer {
+
+ /**
+ * 声明需要放行的swagger资源路径
+ */
+ private String[] newPassPath = new String[]{"/login", "/swagger-ui.html/**", "/v2/**","/files/**", "/webjars/**", "/swagger-resources/**",
+ "/**.js", "/static/**", "/images/**", "/index.html", "/css/**", "/js/**", "/file/**"};
+
+
+ /**
+ * 添加资源站点
+ * @param registry
+ */
+ @Override
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
+
+ }
+
+ /**
+ * 注册拦截器
+ * @param registry
+ */
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ // 注册拦截器
+ registry.addInterceptor(new RequestInterceptor()).addPathPatterns("/**").excludePathPatterns(newPassPath);
+ }
+
+}
diff --git a/cdaxxt-bootstrap/src/main/resources/application.yml b/cdaxxt-bootstrap/src/main/resources/application.yml
new file mode 100644
index 0000000..aec6e39
--- /dev/null
+++ b/cdaxxt-bootstrap/src/main/resources/application.yml
@@ -0,0 +1,106 @@
+server:
+ host: 0.0.0.0
+ port: 8049
+ compression:
+ enabled: true
+ servlet:
+ context-path: /mosty-platform
+
+spring:
+ aop:
+ auto: true
+ application:
+ name: integration-platform-access
+ jackson:
+ date-format: yyyy-MM-dd HH:mm:ss
+ resources:
+ static-locations: classpath:/META-INF/resources/, classpath:/resources/, classpath:/static/, classpath:/public/, classpath:/templates/
+ servlet:
+ multipart:
+ max-file-size: 20MB
+ max-request-size: 20MB
+ datasource:
+ type: com.alibaba.druid.pool.DruidDataSource
+ driver-class-name: com.mysql.jdbc.Driver
+ url: jdbc:mysql://47.108.232.77:4407/mosty_jcgl_gs?autoReconnect=true&failOverReadOnly=false&useUnicode=true&characterEncoding=utf8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true&serverTimezone=Asia/Shanghai
+ username: root
+ password: Mosty@888
+ druid: # 以下参数针对每个库可以重新设置druid参数
+ # 使用druid数据源
+ filters: stat
+ maxActive: 20
+ initialSize: 1
+ maxWait: 60000
+ minIdle: 1
+ timeBetweenEvictionRunsMillis: 60000
+ minEvictableIdleTimeMillis: 300000
+ validationQuery: select 'x'
+ testWhileIdle: true
+ testOnBorrow: false
+ testOnReturn: false
+ poolPreparedStatements: true
+ maxOpenPreparedStatements: 20
+ redis:
+ host: 47.108.232.77
+ port: 6379
+ password: sczy@2022
+ timeout: 10000
+ max-active: 100
+ min-idle: 0
+ max-idle: 20
+ max-wait: 30000
+ sxExpire: 1800
+ database: 12
+ thymeleaf:
+ prefix: classpath:/templates/
+ mode: HTML5
+ suffix: .html
+ encoding: UTF-8
+ cache: false
+ servlet:
+ content-type: text/html
+ enabled: true
+
+# mybatis
+mybatis-plus:
+ configuration:
+ log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl
+ map-underscore-to-camel-case: true
+ cache-enabled: false
+ global-config:
+ db-config:
+ logic-delete-field: actived
+ logic-delete-value: 0
+ logic-not-delete-value: 1
+ table-underline: true
+ update-strategy: ignored
+ banner: false
+
+logging:
+ file:
+ name: ${user.dir}/logs/${spring.application.name}/${spring.application.name}.log
+ level:
+ org.springframework.cloud.openfeign: DEBUG
+ feign: DEBUG
+
+#feign:
+# client:
+# config:
+# default:
+# contract: org.springframework.cloud.openfeign.support.SpringMvcContract
+
+bizworks:
+ clientId: 6f938da0e22911f0bc71bc16950a55fb
+
+bizworks-api-gateway:
+ enable: true
+ type: ali
+ disSignService:
+ signature:
+ - host: api.gansu-ywzt.zgs.yun
+ appKey: 1762305806807768
+ appSecret: 5e1385488c054e9980bf0bf8e68c10a5
+ bizId:
+ service: tobacco-mp-uc-client
+
+
diff --git a/cdaxxt-bootstrap/src/main/resources/templates/word.html b/cdaxxt-bootstrap/src/main/resources/templates/word.html
new file mode 100644
index 0000000..892688a
--- /dev/null
+++ b/cdaxxt-bootstrap/src/main/resources/templates/word.html
@@ -0,0 +1,212 @@
+
+
+
+
+ toWord
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+ | 接口描述 |
+ |
+
+
+ | URL |
+ |
+
+
+ | 请求方式 |
+ |
+
+
+ | 请求类型 |
+ |
+
+
+ | 返回类型 |
+ |
+
+
+
+ | 参数名 |
+ 数据类型 |
+ 参数类型 |
+ 是否必填 |
+ 说明 |
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+
+
+ | 状态码 |
+ 描述 |
+ 说明 |
+
+
+
+ |
+ |
+ |
+
+
+
+ | 返回属性名 |
+ 类型 |
+ 说明 |
+
+
+
+
+
+
+ | 示例 |
+
+
+ | 请求参数 |
+ |
+
+
+ | 返回值 |
+ |
+
+
+
+
+
+
+
+
+
+
+ |
+ |
+ |
+ |
+ |
+ |
+
+
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+
diff --git a/cdaxxt-business/pom.xml b/cdaxxt-business/pom.xml
new file mode 100644
index 0000000..d97de3f
--- /dev/null
+++ b/cdaxxt-business/pom.xml
@@ -0,0 +1,45 @@
+
+
+
+ integration-platform-access
+ com.tobacco.mp
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ cdaxxt-business
+
+
+
+ com.tobacco.mp
+ cdaxxt-common
+ 1.0-SNAPSHOT
+
+
+ com.tobacco.mp
+ cdaxxt-core
+ 1.0-SNAPSHOT
+
+
+
+
+
+
+ src/main/java
+
+ **/*.xml
+
+
+
+ src/main/resources
+
+ **/*
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/controller/PlatformController.java b/cdaxxt-business/src/main/java/com/tobacco/mp/controller/PlatformController.java
new file mode 100644
index 0000000..7f9022f
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/controller/PlatformController.java
@@ -0,0 +1,75 @@
+package com.tobacco.mp.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.tobacco.mp.dto.PlatformMessageDTO;
+import com.tobacco.mp.dto.PlatformNoticeDTO;
+import com.tobacco.mp.dto.PlatformTaskDTO;
+import com.tobacco.mp.dto.PlatformTaskHandleDTO;
+import com.tobacco.mp.service.PlatformMessageService;
+import com.tobacco.mp.service.PlatformUserService;
+import com.tobacco.mp.model.ResponseResult;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+
+// 一体化平台对接
+@RestController
+@AllArgsConstructor
+@RequestMapping("/platform")
+public class PlatformController {
+
+ @Resource
+ PlatformUserService userService;
+
+ @Resource
+ PlatformMessageService messageService;
+
+ // 查询一体化平台的用户列表
+ @GetMapping(value = "/getUserList")
+ public ResponseResult getUserList() {
+ userService.getUserList();
+ return ResponseResult.success();
+ }
+
+ // 查询一体化平台的用户ID
+ @GetMapping(value = "/getUserIdByAccount")
+ public ResponseResult getUserIdByAccount(@RequestParam String loginName) {
+ return ResponseResult.success(userService.getUserIdByAccount(loginName));
+ }
+
+ // 一体化平台身份令牌认证
+ @GetMapping(value = "/tokenAccess")
+ public ResponseResult tokenAccess(@RequestParam String token) {
+ return ResponseResult.success(userService.tokenAccess(token));
+ }
+
+ // 向一体化平台发送消息
+ @PostMapping(value = "/sendMessage")
+ public ResponseResult sendMessage(@RequestBody PlatformMessageDTO dataDTO) {
+ messageService.sendMessage(dataDTO);
+ return ResponseResult.success();
+ }
+
+ // 向一体化平台发送通知/公告
+ @PostMapping(value = "/sendNotice")
+ public ResponseResult sendNotice(@RequestBody PlatformNoticeDTO dataDTO) {
+ messageService.sendNotice(dataDTO);
+ return ResponseResult.success();
+ }
+
+ // 向一体化平台发送待办
+ @PostMapping(value = "/sendToDo")
+ public ResponseResult sendToDo(@RequestBody PlatformTaskDTO taskDTO) {
+ messageService.sendToDo(taskDTO);
+ return ResponseResult.success();
+ }
+
+ // 向一体化平台发送待办处置信息
+ @PostMapping(value = "/sendHandleToDo")
+ public ResponseResult sendHandleToDo(@RequestBody PlatformTaskHandleDTO handleDTO) {
+ messageService.sendHandleToDo(handleDTO);
+ return ResponseResult.success();
+ }
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformMessageDTO.java b/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformMessageDTO.java
new file mode 100644
index 0000000..ee781d7
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformMessageDTO.java
@@ -0,0 +1,47 @@
+package com.tobacco.mp.dto;
+
+import com.tobacco.mp.model.PlatformReceiverInfo;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class PlatformMessageDTO {
+
+ // 事件编码
+ private String eventCode;
+
+ // 消息类型,值范围: 10-系统消息 20-流程通知 30-赋能通知
+ private String msgType;
+
+ // 消息标题
+ private String msgTitle;
+
+ // 消息内容
+ private String msgContent;
+
+ // 消息链接
+ private String msgLink;
+
+ // 发送者名称
+ private String senderName;
+
+ // 发送者ID
+ private String senderId;
+
+ // 来源应用ID
+ private String fromAppId;
+
+ // 来源应用名称
+ private String fromAppName;
+
+ // 来源业务id
+ private String fromBusiId;
+
+ // 消息重要程度:URGENT-紧急 IMPORTANT-重要 NORMAL-普通
+ private String msgPriority = "NORMAL";
+
+ // 消息接收人列表
+ private List msgUserList;
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformNoticeDTO.java b/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformNoticeDTO.java
new file mode 100644
index 0000000..028527f
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformNoticeDTO.java
@@ -0,0 +1,55 @@
+package com.tobacco.mp.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class PlatformNoticeDTO {
+
+ // 公告标题*
+ private String title;
+
+ // 通知公告类型*
+ private String type;
+
+ // 公告来源* (PORTAL-门户维护,API-系统接入)
+ private String source;
+
+ // 内容类型* (TEXT-文字内容,LINK-跳转链接)
+ private String contentType;
+
+ // 公告内容*
+ private String content;
+
+ // 跳转链接url*
+ private String linkUrl;
+
+ // 发布方式* (IMMEDIATE:立即发布;SCHEDULE:定时发布)
+ private String publishType;
+
+ // 定时发布时间*
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date scheduleTime;
+
+ // 有效期类型* (PERMANENT-永久有效,TEMPORARY-非永久有效)
+ private String expiryType;
+
+ // 有效期截止时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
+ private Date expiryDate;
+
+ // 可见范围类型* (ALL-全省可见,CITY:全市可见,DEPT-下级组织可见)
+ private String visibleType;
+
+ // 创建人名称*
+ private String creatorName;
+
+ // 创建人用户id*
+ private String creatorId;
+
+ // 应用id*
+ private String clientId;
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformTaskDTO.java b/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformTaskDTO.java
new file mode 100644
index 0000000..c0fc20c
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformTaskDTO.java
@@ -0,0 +1,92 @@
+package com.tobacco.mp.dto;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class PlatformTaskDTO {
+
+ // 任务名称*
+ private String taskName;
+
+ // 任务描述*
+ private String taskDesc;
+
+ // 业务主键*
+ private String businessId;
+
+ // 需要关联的流程实例
+ private String processId;
+
+ // 需要关联的流程名称
+ private String processName;
+
+ // 会签分组标记,用于记录任务所属的会签分组,也可用于其他分组(按需维护)
+ private String taskCollaborateId;
+
+ // 需要关联的流程任务实例
+ private String processTaskId;
+
+ // 待办类型 (字典TTC_TODO_TYPE)
+ private String todoType;
+
+ // 业务类型
+ private String bizType;
+
+ // 紧急程度* (1高2中3低)
+ private int todoPriority = 2;
+
+ // 中台消息中心的模板编码,发通知消息时,未指定模板则使用该默认模板
+ private String eventCode;
+
+ // 上级任务ID,有撤回场景时需要维护
+ private String preTaskId;
+
+ // 创建人账号ID*
+ private String createUserId;
+
+ // 是否开始节点
+ private Boolean isStart;
+
+ // 是否结束节点
+ private Boolean isEnd;
+
+ // 相关附件
+ private List attachmentPath;
+
+ // 系统需要在业务中台AppId* (用户中心完成应用系统注册,得到appId)
+ private String createAppId;
+
+ //系统需要在业务中台AppId* (用户中心完成应用系统注册,得到appId)
+ private String handleAppId;
+
+ // 任务处理地址*
+ private String optAddress;
+
+ // 移动任务处理地址,模糊查询*
+ private String optAddressMobile;
+
+ // 拓展属性配置
+ private String extraConfig;
+
+ // 处理截止时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date deadline;
+
+ // 移交前任务ID
+ private String translateOriginId;
+
+ // 创建时间
+ @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+ private Date gmtCreate;
+
+ // 操作人ID*
+ private String optUserId;
+
+ // 操作人名称
+ private String optUserName;
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformTaskHandleDTO.java b/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformTaskHandleDTO.java
new file mode 100644
index 0000000..b26f6d8
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/dto/PlatformTaskHandleDTO.java
@@ -0,0 +1,50 @@
+package com.tobacco.mp.dto;
+
+import lombok.Data;
+
+import java.util.List;
+import java.util.Map;
+
+@Data
+public class PlatformTaskHandleDTO {
+
+ // 待办任务ID*
+ private String todoTaskId;
+
+ // 实际处理人ID*
+ private String handleUserId;
+
+ // 相关附件
+ private List attachmentPath;
+
+ // 处理结果,字典TTC_TASK_OPT_RESULT
+ private String optResult;
+
+ // 处理意见
+ private String optComment;
+
+ // 操作人ID*
+ private String optUserId;
+
+ // 操作人名称
+ private String optUserName;
+
+ // 是否发送待办通知 (false或null则根据任务自动通知配置情况发送消息)
+ private Boolean sendNotification;
+
+ // 中台消息模板,发送通知时有效,不传值则使用任务设置的默认模板
+ private String eventCode;
+
+ // 消息接收人
+ private String receiverId;
+
+ // 消息额外参数,不同消息类型的个性化参数与模板的动态参数
+ private Map extraProps;
+
+ // 任务处理地址
+ private String optAddress;
+
+ // 移动任务处理地址,模糊查询
+ private String optAddressMobile;
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/entity/SysUser.java b/cdaxxt-business/src/main/java/com/tobacco/mp/entity/SysUser.java
new file mode 100644
index 0000000..f327686
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/entity/SysUser.java
@@ -0,0 +1,202 @@
+package com.tobacco.mp.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+@Accessors(chain = true)
+@TableName(value = "sys_user")
+public class SysUser implements Serializable {
+
+ @TableField(exist = false)
+ private static final long serialVersionUID = 1L;
+
+ @TableId(value = "id", type = IdType.INPUT)
+ @ApiModelProperty(value = "用户ID")
+ private String id;
+
+ @TableField(value = "position_type")
+ @ApiModelProperty(value = "岗位类型")
+ private String positionType;
+
+ @TableField(value = "position_id")
+ @ApiModelProperty(value = "岗位ID")
+ private String positionId;
+
+ @TableField(value = "position_name")
+ @ApiModelProperty(value = "岗位名称")
+ private String positionName;
+
+ @TableField(value = "is_virtual_user")
+ @ApiModelProperty(value = "是否虚拟用户:1、是 2、不是")
+ private String isVirtualUser;
+
+ @TableField(value = "login_name")
+ @ApiModelProperty(value = "登录账号")
+ private String loginName;
+
+ @TableField(value = "password")
+ @ApiModelProperty(value = "密码")
+ private String password;
+
+ @TableField(value = "user_name")
+ @ApiModelProperty(value = "用户昵称")
+ private String userName;
+
+ @TableField(value = "user_type")
+ @ApiModelProperty(value = "用户类型(00系统用户 01注册用户)")
+ private String userType;
+
+ @TableField(value = "email")
+ @ApiModelProperty(value = "用户邮箱")
+ private String email;
+
+ @TableField(value = "mobile", updateStrategy = FieldStrategy.IGNORED)
+ @ApiModelProperty(value = "移动电话")
+ private String mobile;
+
+ @TableField(value = "tele_phone", updateStrategy = FieldStrategy.IGNORED)
+ @ApiModelProperty(value = "电话号码")
+ private String telePhone;
+
+ @TableField(value = "id_entity_card")
+ @ApiModelProperty(value = "身份证号")
+ private String idEntityCard;
+
+ @TableField(value = "in_dust_rial_id")
+ @ApiModelProperty(value = "行业号码(如:警号)")
+ private String inDustRialId;
+
+ @TableField(value = "sex")
+ @ApiModelProperty(value = "用户性别(0男 1女 2未知)")
+ private String sex;
+
+ @TableField(value = "nation", updateStrategy = FieldStrategy.IGNORED)
+ @ApiModelProperty(value = "民族")
+ private String nation;
+
+ @TableField(value = "politic", updateStrategy = FieldStrategy.IGNORED)
+ @ApiModelProperty(value = "政治面貌")
+ private String politic;
+
+ @TableField(value = "marital")
+ @ApiModelProperty(value = "婚姻状态")
+ private String marital;
+
+ @TableField(value = "type")
+ @ApiModelProperty(value = "人员类别")
+ private String type;
+
+ @TableField(value = "type_name")
+ @ApiModelProperty(value = "人员类别中文")
+ private String typeName;
+
+ @TableField(value = "whcd", updateStrategy = FieldStrategy.IGNORED)
+ @ApiModelProperty(value = "文化程度")
+ private String whcd;
+
+ @TableField(value = "user_no", updateStrategy = FieldStrategy.IGNORED)
+ @ApiModelProperty(value = "排序")
+ private Integer userNo;
+
+ @TableField(value = "bz", updateStrategy = FieldStrategy.IGNORED)
+ @ApiModelProperty(value = "备注")
+ private String bz;
+
+ @TableField(value = "birthday")
+ @ApiModelProperty(value = "出生日期")
+ private String birthday;
+
+ @TableField(value = "begin_time")
+ @ApiModelProperty(value = " 用户有效开始时间,默认为当前日期(用户可改)")
+ private Date beginTime;
+
+ @TableField(value = "end_time")
+ @ApiModelProperty(value = " 用户有效结束时间,默认空")
+ private Date endTime;
+
+ @TableField(value = "salt")
+ @ApiModelProperty(value = "盐加密")
+ private String salt;
+
+ @TableField("duty_code")
+ @ApiModelProperty("职务code")
+ private String dutyCode;
+
+ @TableField("duty_name")
+ @ApiModelProperty("职务名称")
+ private String dutyName;
+
+ @TableField("outsourcing_level")
+ @ApiModelProperty("D_BZ_ZYWHRYLB-聘用人员类别 1.在岗在册 2.劳务派遣 3.业务外包")
+ private String outsourcingLevel;
+
+ @TableField("long_term_sick_leave")
+ @ApiModelProperty(" 是否长期病假人员")
+ private String longTermSickLeave;
+
+ @TableField("platform_user_id")
+ @ApiModelProperty(" 业务中台用户ID")
+ private String platformUserId;
+
+ @TableField(value = "xzcs")
+ @ApiModelProperty(value = "选择次数")
+ private Integer xzcs;
+
+ @TableField(value = "xt_zxbz")
+ private Integer xtZxbz;
+
+ @TableField(value = "xt_zxyz")
+ private String xtZxyz;
+
+ @TableField(value = "xt_cjsj")
+ private Date xtCjsj;
+
+ @TableField(value = "xt_lrsj")
+ private Date xtLrsj;
+
+ @TableField(value = "xt_lrrxm")
+ private String xtLrrxm;
+
+ @TableField(value = "xt_lrrid")
+ private String xtLrrid;
+
+ @TableField(value = "xt_lrrbm")
+ private String xtLrrbm;
+
+ @TableField(value = "xt_lrrbmid")
+ private String xtLrrbmid;
+
+ @TableField(value = "xt_lrip")
+ private String xtLrip;
+
+ @TableField(value = "xt_zhxgsj")
+ private Date xtZhxgsj;
+
+ @TableField(value = "xt_zhxgrxm")
+ private String xtZhxgrxm;
+
+ @TableField(value = "xt_zhxgid")
+ private String xtZhxgid;
+
+ @TableField(value = "xt_zhxgrbm")
+ private String xtZhxgrbm;
+
+ @TableField(value = "xt_zhxgrbmid")
+ private String xtZhxgrbmid;
+
+ @TableField(value = "xt_zhxgrip")
+ private String xtZhxgrip;
+
+ @TableField(value = "xt_city_code")
+ private String xtCityCode;
+
+ @TableField(value = "xt_city_name")
+ private String xtCityName;
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/mapper/SysUserMapper.java b/cdaxxt-business/src/main/java/com/tobacco/mp/mapper/SysUserMapper.java
new file mode 100644
index 0000000..e7808f3
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/mapper/SysUserMapper.java
@@ -0,0 +1,22 @@
+package com.tobacco.mp.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.tobacco.mp.entity.SysUser;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface SysUserMapper extends BaseMapper {
+
+ // 获取业务中台用户ID为空的用户账号列表
+ List getNullPlatformUserId();
+
+ // 给用户绑定业务中台的用户ID
+ void setPlatformUserId(@Param("userName") String userName, @Param("platformUserId") String platformUserId);
+
+ // 更新任务的一体化平台ID
+ void updateRwPlatformId(@Param("rwId") String rwId, @Param("platformId") String platformId);
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/mapper/SysUserMapper.xml b/cdaxxt-business/src/main/java/com/tobacco/mp/mapper/SysUserMapper.xml
new file mode 100644
index 0000000..6cf8c56
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/mapper/SysUserMapper.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+ UPDATE mosty_base_gs.sys_user SET platform_user_id = #{platformUserId} WHERE user_name = #{userName}
+
+
+
+
+ UPDATE mosty_jcgl_gs.tb_rw SET platform_id = #{platformId} WHERE id = #{rwId}
+
+
+
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/model/PlatformReceiverInfo.java b/cdaxxt-business/src/main/java/com/tobacco/mp/model/PlatformReceiverInfo.java
new file mode 100644
index 0000000..07ab332
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/model/PlatformReceiverInfo.java
@@ -0,0 +1,14 @@
+package com.tobacco.mp.model;
+
+import lombok.Data;
+
+@Data
+public class PlatformReceiverInfo {
+
+ // 接收者名称
+ private String receiverName;
+
+ // 接收者ID
+ private String receiverId;
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/model/PlatformResponseCode.java b/cdaxxt-business/src/main/java/com/tobacco/mp/model/PlatformResponseCode.java
new file mode 100644
index 0000000..60facec
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/model/PlatformResponseCode.java
@@ -0,0 +1,23 @@
+package com.tobacco.mp.model;
+
+/**
+ * 一体化平台响应状态码
+ */
+public class PlatformResponseCode {
+
+ // 成功
+ public static final String SUCCESS = "200";
+
+ // 未授权
+ public static final String UNAUTHORIZED = "401";
+
+ // 禁止访问
+ public static final String ACCESS_DENIED = "403";
+
+ // 资源不存在
+ public static final String NOT_EXIST = "404";
+
+ // 服务异常
+ public static final String SERVICE_EXCEPTION = "500";
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/service/PlatformMessageService.java b/cdaxxt-business/src/main/java/com/tobacco/mp/service/PlatformMessageService.java
new file mode 100644
index 0000000..2fcf293
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/service/PlatformMessageService.java
@@ -0,0 +1,136 @@
+package com.tobacco.mp.service;
+
+import com.alibaba.bizworks.core.runtime.common.SingleResponse;
+import com.tobacco.mp.dto.PlatformMessageDTO;
+import com.tobacco.mp.dto.PlatformNoticeDTO;
+import com.tobacco.mp.dto.PlatformTaskDTO;
+import com.tobacco.mp.dto.PlatformTaskHandleDTO;
+import com.tobacco.mp.mcext.client.api.McExtNoticeServiceAPI;
+import com.tobacco.mp.mcext.client.api.MessageSendExtServiceAPI;
+import com.tobacco.mp.mcext.client.api.message.dto.SendMessageDTO;
+import com.tobacco.mp.mcext.client.api.message.req.SendInternalMessageRequest;
+import com.tobacco.mp.mcext.client.api.notice.dto.CreateNoticeResponse;
+import com.tobacco.mp.mcext.client.api.notice.req.CreateNoticeRequest;
+import com.tobacco.mp.model.PlatformResponseCode;
+import com.tobacco.mp.ttc.client.api.TodoTaskApi;
+import com.tobacco.mp.ttc.client.api.enums.TaskHandleTargetTypeEnum;
+import com.tobacco.mp.ttc.client.api.task.dto.TodoTaskDTO;
+import com.tobacco.mp.ttc.client.api.task.req.CreateTaskRequest;
+import com.tobacco.mp.ttc.client.api.task.req.SubmitTaskRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+@Service
+public class PlatformMessageService {
+
+ @Resource
+ private MessageSendExtServiceAPI messageSendExtServiceAPI;
+
+ @Resource
+ private McExtNoticeServiceAPI mcExtNoticeServiceAPI;
+
+ @Resource
+ private TodoTaskApi todoTaskApi;
+
+ @Resource
+ private SysUserService sysUserService;
+
+ @Value("${bizworks.clientId}")
+ private String clientId;
+
+
+ /**
+ * 发送消息
+ * @param messageDTO
+ */
+ public void sendMessage(PlatformMessageDTO messageDTO) {
+ // 构建消息请求参数
+ SendInternalMessageRequest request = new SendInternalMessageRequest();
+ BeanUtils.copyProperties(messageDTO, request, "msgUserList");
+ request.setFromAppId(clientId);
+ request.setFromAppName("安管平台应用");
+ List msgUserList = new ArrayList<>();
+ BeanUtils.copyProperties(messageDTO.getMsgUserList(), msgUserList);
+ request.setMsgUserList(msgUserList);
+ // 发送消息请求
+ SingleResponse response = messageSendExtServiceAPI.sendInternalMessage(request);
+ if (response.getCode().equals(PlatformResponseCode.SUCCESS)) {
+ log.info("消息【{}】请求处理成功", messageDTO.getMsgTitle());
+ } else {
+ log.error("消息【{}】请求处理失败。失败原因:{}", messageDTO.getMsgTitle(), response.getMessage());
+ }
+ }
+
+ /**
+ * 发送通知/公告
+ * @param noticeDTO
+ */
+ public void sendNotice(PlatformNoticeDTO noticeDTO) {
+ // 构建通知/公告请求参数
+ CreateNoticeRequest request = new CreateNoticeRequest();
+ BeanUtils.copyProperties(noticeDTO, request);
+ request.setSource("API");
+ request.setClientId(clientId);
+ // 发送通知/公告请求
+ SingleResponse response = mcExtNoticeServiceAPI.createNotice(request);
+ if (response.getCode().equals(PlatformResponseCode.SUCCESS)) {
+ log.info("通知【{}】请求处理成功", noticeDTO.getTitle());
+ } else {
+ log.error("通知【{}】请求处理失败。失败原因:{}", noticeDTO.getTitle(), response.getMessage());
+ }
+ }
+
+ /**
+ * 创建待办任务
+ * @param taskDTO
+ */
+ public void sendToDo(PlatformTaskDTO taskDTO) {
+ // 构建待办任务请求参数
+ CreateTaskRequest request = new CreateTaskRequest();
+ BeanUtils.copyProperties(taskDTO, request);
+ request.setHandleTargetId(taskDTO.getOptUserId());
+ request.setHandleTargetType(TaskHandleTargetTypeEnum.USER);
+ request.setCreateAppId(clientId);
+ request.setHandleAppId(clientId);
+ // 发送待办任务请求
+ SingleResponse response = todoTaskApi.createTask(request);
+ if (response.getCode().equals(PlatformResponseCode.SUCCESS)) {
+ TodoTaskDTO todoTaskDTO = response.getData();
+ if (todoTaskDTO != null && StringUtils.isNotEmpty(todoTaskDTO.getId())) {
+ sysUserService.updateRwPlatformId(taskDTO.getBusinessId(), todoTaskDTO.getId());
+ }
+ log.info("待办【{}】请求处理成功", taskDTO.getTaskName());
+ } else {
+ log.error("待办【{}】请求处理失败。失败原因:{}", taskDTO.getTaskName(), response.getMessage());
+ }
+ }
+
+ /**
+ * 处置待办
+ * @param handleDTO
+ */
+ public void sendHandleToDo(PlatformTaskHandleDTO handleDTO) {
+ // 处置待办参数校验
+ if (StringUtils.isEmpty(handleDTO.getTodoTaskId())) {
+ return;
+ }
+ // 构建处置待办请求参数
+ SubmitTaskRequest request = new SubmitTaskRequest();
+ BeanUtils.copyProperties(handleDTO, request);
+ // 发送处置待办请求
+ SingleResponse response = todoTaskApi.submitTask(request);
+ if (response.getCode().equals(PlatformResponseCode.SUCCESS)) {
+ log.info("待办处理【{}】请求处理成功", handleDTO.getTodoTaskId());
+ } else {
+ log.error("待办处理【{}】请求处理失败。失败原因:{}", handleDTO.getTodoTaskId(), response.getMessage());
+ }
+ }
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/service/PlatformUserService.java b/cdaxxt-business/src/main/java/com/tobacco/mp/service/PlatformUserService.java
new file mode 100644
index 0000000..2a206cf
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/service/PlatformUserService.java
@@ -0,0 +1,127 @@
+package com.tobacco.mp.service;
+
+import com.alibaba.bizworks.core.runtime.common.MultiDataDTO;
+import com.alibaba.bizworks.core.runtime.common.MultiResponse;
+import com.alibaba.bizworks.core.runtime.common.SingleResponse;
+import com.alibaba.fastjson.JSONObject;
+import com.tobacco.mp.auth.businessdomain.auth.client.api.SsoAuthI;
+import com.tobacco.mp.auth.businessdomain.auth.client.api.auth.dto.TokenCheckResultDTO;
+import com.tobacco.mp.auth.businessdomain.auth.client.api.auth.req.CheckTokenRequest;
+import com.tobacco.mp.constant.Constant;
+import com.tobacco.mp.model.PlatformResponseCode;
+import com.tobacco.mp.uc.client.api.UserServiceAPI;
+import com.tobacco.mp.uc.client.api.user.dto.GetUserByUserCodeDTO;
+import com.tobacco.mp.uc.client.api.user.dto.UserDTO;
+import com.tobacco.mp.uc.client.api.user.req.GetUserByUserCodeRequest;
+import com.tobacco.mp.uc.client.api.user.req.PageQueryUserRequest;
+import com.tobacco.mp.utils.JWTUtil;
+import com.tobacco.mp.utils.RandomUtil;
+import com.tobacco.mp.utils.RedisUtils;
+import io.jsonwebtoken.Claims;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.Resource;
+
+@Slf4j
+@Service
+public class PlatformUserService {
+
+ @Resource
+ private UserServiceAPI userServiceAPI;
+
+ @Resource
+ private SsoAuthI ssoAuthI;
+
+ @Resource
+ private RedisUtils redisUtils;
+
+ @Value("${bizworks.clientId}")
+ private String clientId;
+
+ /**
+ * 查询一体化平台的用户ID
+ * @param loginName
+ * @return
+ */
+ public String getUserIdByAccount(String loginName) {
+ // 构建查询平台用户请求参数
+ GetUserByUserCodeRequest request = new GetUserByUserCodeRequest();
+ request.setUserCode(loginName);
+ // 发送查询平台用户请求
+ SingleResponse response = userServiceAPI.getUserByUserCode(request);
+ if (response.getCode().equals(PlatformResponseCode.SUCCESS)) {
+ GetUserByUserCodeDTO userDTO = response.getData();
+ if (userDTO != null && StringUtils.isNotEmpty(userDTO.getUserId())) {
+ return userDTO.getUserId();
+ }
+ } else {
+ log.error("获取中台用户[{}]请求处理失败。失败原因:{}", loginName, response.getMessage());
+ }
+ return null;
+ }
+
+ /**
+ * 查询一体化平台的用户列表
+ */
+ public void getUserList() {
+ // 构建查询平台用户列表请求参数
+ PageQueryUserRequest request = new PageQueryUserRequest();
+ request.setPageNumber(1);
+ request.setPageSize(10);
+ request.setManageUnitId("12");
+ // 发送查询平台用户列表请求
+ MultiResponse response = userServiceAPI.pageQueryUser(request);
+ if (response.getCode().equals(PlatformResponseCode.SUCCESS)) {
+ MultiDataDTO userDTO = response.getData();
+ if (userDTO != null && !CollectionUtils.isEmpty(userDTO.getItems())) {
+ for (UserDTO user : userDTO.getItems()) {
+ System.out.println("userId:" + user.getUserId() + ", userName:" + user.getLoginName());
+ }
+ }
+ } else {
+ log.error("分页获取中台用户请求处理失败。失败原因:{}", response.getMessage());
+ }
+ }
+
+ /**
+ * 校验本系统登录页面的token(一体化平台的token)信息
+ * @param token
+ * @return
+ */
+ public JSONObject tokenAccess(String token) {
+ // 声明响应数据(用户名和系统登录校验码)
+ JSONObject jsonObject = new JSONObject();
+ String account = "";
+
+ // 给一体化平台发送解析请求以验证令牌获取用户名
+ SingleResponse singleResponse = ssoAuthI.checkToken(new CheckTokenRequest(token, clientId));
+ if (singleResponse.getCode().equals(PlatformResponseCode.SUCCESS)) {
+ TokenCheckResultDTO data = singleResponse.getData();
+ if (data != null && StringUtils.isNotEmpty(data.getUserInfo())) {
+ Claims claims = JWTUtil.verifyJWTToken(data.getUserInfo(), JWTUtil.PUBLIC_KEY_STR);
+ account = claims.get("account", String.class);
+ } else {
+ log.error("请求一体化平台响应数据:{}", JSONObject.toJSONString(data));
+ return jsonObject;
+ }
+ } else {
+ log.error("鉴权请求处理失败。失败原因:{}", singleResponse.getMessage());
+ return jsonObject;
+ }
+
+ // 验证通过后,给页面返回用户名和本系统登录校验码
+ if (StringUtils.isNotEmpty(account)) {
+ String verifyCode = RandomUtil.generateLowerString(16);
+ redisUtils.set(Constant.LOGIN_VERIFY_CODE + account, verifyCode, 30);
+ jsonObject.put("userName", account);
+ jsonObject.put("verifyCode", verifyCode);
+ log.info("--------一体化平台成功鉴权!----------");
+ }
+
+ return jsonObject;
+ }
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/service/SchedulerService.java b/cdaxxt-business/src/main/java/com/tobacco/mp/service/SchedulerService.java
new file mode 100644
index 0000000..4cb33de
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/service/SchedulerService.java
@@ -0,0 +1,30 @@
+package com.tobacco.mp.service;
+
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+@Service
+public class SchedulerService {
+
+ @Resource
+ SysUserService sysUserService;
+
+ @Resource
+ PlatformUserService platformUserService;
+
+ /**
+ * 刷新用户业务中台的ID
+ */
+ // @Scheduled(cron = "0 0 3 * * ?")
+ public void refreshUserPlatformId() {
+ List userNames = sysUserService.getNullPlatformUserId();
+ for (String userName : userNames) {
+ String platformUserId = platformUserService.getUserIdByAccount(userName);
+ sysUserService.setPlatformUserId(userName, platformUserId);
+ }
+ }
+
+}
diff --git a/cdaxxt-business/src/main/java/com/tobacco/mp/service/SysUserService.java b/cdaxxt-business/src/main/java/com/tobacco/mp/service/SysUserService.java
new file mode 100644
index 0000000..18fb4eb
--- /dev/null
+++ b/cdaxxt-business/src/main/java/com/tobacco/mp/service/SysUserService.java
@@ -0,0 +1,39 @@
+package com.tobacco.mp.service;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.tobacco.mp.entity.SysUser;
+import com.tobacco.mp.mapper.SysUserMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+@Service
+public class SysUserService extends ServiceImpl {
+
+ /**
+ * 获取业务中台用户ID为空的用户账号列表
+ * @return
+ */
+ public List getNullPlatformUserId() {
+ return this.baseMapper.getNullPlatformUserId();
+ }
+
+ /**
+ * 给用户绑定业务中台的用户ID
+ * @param userName
+ * @param platformUserId
+ */
+ public void setPlatformUserId(String userName, String platformUserId) {
+ this.baseMapper.setPlatformUserId(userName, platformUserId);
+ }
+
+ /**
+ * 更新任务的一体化平台ID
+ * @param rwId
+ * @param platformId
+ */
+ public void updateRwPlatformId(String rwId, String platformId) {
+ this.baseMapper.updateRwPlatformId(rwId, platformId);
+ }
+
+}
diff --git a/cdaxxt-common/pom.xml b/cdaxxt-common/pom.xml
new file mode 100644
index 0000000..79df900
--- /dev/null
+++ b/cdaxxt-common/pom.xml
@@ -0,0 +1,32 @@
+
+
+
+ integration-platform-access
+ com.tobacco.mp
+ 1.0-SNAPSHOT
+
+ 4.0.0
+
+ cdaxxt-common
+
+
+
+
+ src/main/java
+
+ **/*.xml
+
+
+
+ src/main/resources
+
+ **/*
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/AuthOperation.java b/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/AuthOperation.java
new file mode 100644
index 0000000..ba1c817
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/AuthOperation.java
@@ -0,0 +1,14 @@
+package com.tobacco.mp.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 【允许已登录的社会用户访问的接口】使用该注解(无效)
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface AuthOperation {
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/LogOperation.java b/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/LogOperation.java
new file mode 100644
index 0000000..0d8fd8b
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/LogOperation.java
@@ -0,0 +1,14 @@
+package com.tobacco.mp.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 【需要记录操作日志】使用该注解
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LogOperation {
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/OpenOperation.java b/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/OpenOperation.java
new file mode 100644
index 0000000..a2096ab
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/OpenOperation.java
@@ -0,0 +1,14 @@
+package com.tobacco.mp.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 【需要开放第三方对接的接口】使用该注解
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface OpenOperation {
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/PassOperation.java b/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/PassOperation.java
new file mode 100644
index 0000000..4ed2106
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/annotation/PassOperation.java
@@ -0,0 +1,14 @@
+package com.tobacco.mp.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 【不需要登录就能访问的接口】使用该注解
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PassOperation {
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/constant/Constant.java b/cdaxxt-common/src/main/java/com/tobacco/mp/constant/Constant.java
new file mode 100644
index 0000000..733dad8
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/constant/Constant.java
@@ -0,0 +1,24 @@
+package com.tobacco.mp.constant;
+
+/**
+ * 基础常量信息
+ */
+public class Constant {
+
+
+ /********************************************缓存key***********************************************/
+ public static final String LOGIN_VERIFY_CODE = "LoginVerifyCode:";
+ public static final String JWT_USER = "JwtUser:";
+
+ /*************************************************************************************************/
+
+
+ public static final String DEFAULT_IP = "0.0.0.0";
+
+ /** 开放的API */
+ public static final String OPEN_API = "OPENAPI";
+
+ /** 开放的应用 */
+ public static final String OPEN_APP = "OPENAPP";
+
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/constant/Symbol.java b/cdaxxt-common/src/main/java/com/tobacco/mp/constant/Symbol.java
new file mode 100644
index 0000000..3105155
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/constant/Symbol.java
@@ -0,0 +1,35 @@
+package com.tobacco.mp.constant;
+
+/**
+ * @Author XiongLiJian
+ * @Date 2021/6/4 9:31
+ * @Description 符号工具类
+ * @Version 1.0
+ **/
+public class Symbol {
+
+ /** 符号:[-] */
+ public static final String ACROSS = "-";
+
+ /** 符号:[_] */
+ public static final String LOW_ACROSS = "_";
+
+ /** 符号[.] */
+ public static final String POINT = ".";
+
+ /** 符号[:] */
+ public static final String COLON = ":";
+
+ /** 逗号[,] */
+ public static final String COMMA = ",";
+
+ /** 斜杠 */
+ public static final String SLASH = "/";
+
+ /** 逗号[@] */
+ public static final String A2 = "@";
+
+ /** 符号[;] */
+ public static final String SEMICOLON = ";";
+
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/enums/ResponseCodeEnum.java b/cdaxxt-common/src/main/java/com/tobacco/mp/enums/ResponseCodeEnum.java
new file mode 100644
index 0000000..0abac37
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/enums/ResponseCodeEnum.java
@@ -0,0 +1,48 @@
+package com.tobacco.mp.enums;
+
+/**
+ * 响应码管理
+ * @Author: XiongLiJian
+ * @Date: 2020/12/29 09:14
+ */
+public enum ResponseCodeEnum {
+
+ NORMAL(200, "ok"),
+ REQUEST_PARAM_ERROR(400, "请求参数错误!"),
+ SYSTEM_NO_LOGIN(401, "系统未登录!"),
+ USER_ALREADY_DISABLED(402, "该用户已被禁用!"),
+ NO_ACCESS_PERMISSION(403, "没有访问权限!"),
+ REQUEST_RESOURCE_NO_EXIST(404, "请求的资源不存在!"),
+ REQUEST_METHOD_ERROR(405, "请求方式错误"),
+ SYSTEM_ERROR(500, "系统错误"),
+ SYSTEM_TIP(501, "系统提示"),
+
+ ;
+
+ /** 响应码 */
+ private Integer code;
+ /** 响应信息 */
+ private String msg;
+
+ ResponseCodeEnum(Integer code, String msg) {
+ this.code = code;
+ this.msg = msg;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/enums/TipEnum.java b/cdaxxt-common/src/main/java/com/tobacco/mp/enums/TipEnum.java
new file mode 100644
index 0000000..d3b57de
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/enums/TipEnum.java
@@ -0,0 +1,41 @@
+package com.tobacco.mp.enums;
+
+/**
+ * @Author XiongLiJian
+ * @Date 2021/12/29 9:25
+ * @Description 消息提示
+ * @Version 1.0
+ **/
+public enum TipEnum {
+
+ BATCH_DELETE_DATA_ERROR("批量删除解析错误!"),
+ FILE_NOT_SURE("请指定一个文件进行操作!"),
+ SYSTEM_ERROR("系统出现错误!"),
+ USERNAME_NOT_EXIST("用户名不存在!"),
+ PLEASE_WAIT_REPEAT_LOGIN("该账号今天重复多次密码错误,请30分钟后重新登录!"),
+ ACCOUNT_PASSWORD_ERROR("账号或密码错误!"),
+ ACCESS_FILE_ERROR("权限模板文件解析异常!"),
+ ACCESS_API_ERROR("权限映射解析异常!"),
+ ROLE_PERSON_NUM_EXSIT("角色下存在人员无法删除!"),
+ DATA_SHEET_IMPORT_ERROR("数据导入解析错误!"),
+ USERNAME_IS_REPEAT("该用户名已存在!"),
+ NOT_MODIFY_SYSTEM_ROLE("不能操作系统超级管理员!"),
+ CHECK_CODE_REPEAT("请不要频繁生成校验码!"),
+
+ ;
+
+ private String msg;
+
+ TipEnum(String msg) {
+ this.msg = msg;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/exception/ServiceException.java b/cdaxxt-common/src/main/java/com/tobacco/mp/exception/ServiceException.java
new file mode 100644
index 0000000..45dc56c
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/exception/ServiceException.java
@@ -0,0 +1,32 @@
+package com.tobacco.mp.exception;
+
+import com.tobacco.mp.enums.ResponseCodeEnum;
+import com.tobacco.mp.enums.TipEnum;
+import lombok.Data;
+
+/**
+ * @Author XiongLiJian
+ * @Date 2021/6/3 17:53
+ * @Description 服务器异常
+ * @Version 1.0
+ **/
+@Data
+public class ServiceException extends RuntimeException {
+
+ private static final long serialVersionUID = 6165589759025169495L;
+
+ private Integer code = ResponseCodeEnum.SYSTEM_TIP.getCode();
+
+ private String message;
+
+ public ServiceException(TipEnum tipEnum) {
+ super(tipEnum.getMsg());
+ this.message = tipEnum.getMsg();
+ }
+
+ public ServiceException(String message) {
+ super(message);
+ this.message = message;
+ }
+
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/model/Json.java b/cdaxxt-common/src/main/java/com/tobacco/mp/model/Json.java
new file mode 100644
index 0000000..233bcfc
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/model/Json.java
@@ -0,0 +1,54 @@
+package com.tobacco.mp.model;
+
+import com.tobacco.mp.enums.ResponseCodeEnum;
+import lombok.Data;
+
+@Data
+public class Json {
+
+ private boolean success;
+
+ private Integer code;
+
+ private String message;
+
+ private T data;
+
+ public static Json success() {
+ return success(null);
+ }
+
+ public static Json success(Object data) {
+ Json json = new Json();
+ json.setSuccess(true);
+ json.setCode(ResponseCodeEnum.NORMAL.getCode());
+ json.setMessage(ResponseCodeEnum.NORMAL.getMsg());
+ json.setData(data);
+ return json;
+ }
+
+ public static Json fail(ResponseCodeEnum responseCodeEnum) {
+ Json json = new Json();
+ json.setSuccess(false);
+ json.setCode(responseCodeEnum.getCode());
+ json.setMessage(responseCodeEnum.getMsg());
+ return json;
+ }
+
+ public static Json fail(Integer code, String message) {
+ Json json = new Json();
+ json.setCode(code);
+ json.setMessage(message);
+ json.setSuccess(false);
+ return json;
+ }
+
+ public static Json fail(String message) {
+ Json json = new Json();
+ json.setCode(ResponseCodeEnum.SYSTEM_TIP.getCode());
+ json.setMessage(message);
+ json.setSuccess(false);
+ return json;
+ }
+
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/model/ResponseResult.java b/cdaxxt-common/src/main/java/com/tobacco/mp/model/ResponseResult.java
new file mode 100644
index 0000000..f5a9b1c
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/model/ResponseResult.java
@@ -0,0 +1,93 @@
+package com.tobacco.mp.model;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Objects;
+
+@Data
+@SuppressWarnings("unused")
+public class ResponseResult implements Serializable {
+
+ /** 调用成功编码 */
+ private static final int SUCCESS_CODE = 10000;
+
+ /** 调用失败编码 */
+ private static final int FAIL_CODE = -1;
+
+ /** 编号 */
+ private int code = SUCCESS_CODE;
+
+ /** 消息 */
+ private String message;
+
+ /** 数据 */
+ private T data;
+
+ public ResponseResult() {
+ }
+
+ public ResponseResult(T data) {
+ this.message = "OK";
+ this.data = data;
+ }
+
+ public ResponseResult(int code, String msg) {
+ this.code = code;
+ this.message = msg;
+ this.data = null;
+ }
+
+ public ResponseResult(int code, String msg, T data) {
+ this.code = code;
+ this.message = msg;
+ this.data = data;
+ }
+
+ public static ResponseResult success() {
+ return new ResponseResult(SUCCESS_CODE, "OK", null);
+ }
+
+ public static ResponseResult success(int code, String message, T data) {
+ return new ResponseResult(code, message, data);
+ }
+
+ public static ResponseResult success(String message, T data) {
+ return new ResponseResult(SUCCESS_CODE, message, data);
+ }
+
+ public static ResponseResult success(T data) {
+ return new ResponseResult(SUCCESS_CODE, "OK", data);
+ }
+
+ public static ResponseResult fail(String message) {
+ return new ResponseResult(FAIL_CODE, message, (Object)null);
+ }
+
+ public static ResponseResult fail(int code, String message) {
+ return new ResponseResult(code, message, (Object)null);
+ }
+
+ public static ResponseResult fail(int code, String message, T t) {
+ return new ResponseResult(code, message, t);
+ }
+
+ public boolean isSuccess() {
+ return SUCCESS_CODE == code;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ ResponseResult> that = (ResponseResult>) o;
+ return Objects.equals(code, that.code) && Objects.equals(message, that.message) && Objects.equals(data, that.data);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(code, message, data);
+ }
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/utils/AnnotationUtil.java b/cdaxxt-common/src/main/java/com/tobacco/mp/utils/AnnotationUtil.java
new file mode 100644
index 0000000..77268bd
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/utils/AnnotationUtil.java
@@ -0,0 +1,172 @@
+package com.tobacco.mp.utils;
+
+import com.tobacco.mp.annotation.AuthOperation;
+import com.tobacco.mp.annotation.OpenOperation;
+import com.tobacco.mp.annotation.PassOperation;
+import com.tobacco.mp.constant.Constant;
+import com.tobacco.mp.constant.Symbol;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
+import org.springframework.core.io.support.ResourcePatternResolver;
+import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
+import org.springframework.core.type.classreading.MetadataReader;
+import org.springframework.core.type.classreading.MetadataReaderFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.*;
+
+import java.lang.reflect.Method;
+import java.util.*;
+
+@Slf4j
+@Component
+public class AnnotationUtil {
+
+ @Autowired
+ RedisUtils redisUtils;
+
+ private final String RESOURCE_PATTERN = "com/tobacco/mp/**/controller/*.class";
+
+ public static List PASS_API;
+
+ public static List AUTH_API;
+
+ /**
+ * 加载自定义注解
+ */
+ public void loadCustomAnnotation() {
+ Map> mapApis = getAccessAnnotations(RESOURCE_PATTERN);
+ // 获取开放给第三方的接口数据
+ if (mapApis.get(OpenOperation.class.getName()) != null) {
+ redisUtils.set(Constant.OPEN_API, StringUtils.toString(mapApis.get(OpenOperation.class.getName())));
+ }
+ // 不需要登录就能访问的接口
+ PASS_API = mapApis.get(PassOperation.class.getName());
+ if (PASS_API == null) {
+ PASS_API = new ArrayList<>();
+ }
+ // 允许已登录的社会用户访问的接口
+ AUTH_API = mapApis.get(AuthOperation.class.getName());
+ if (AUTH_API == null) {
+ AUTH_API = new ArrayList<>();
+ }
+ }
+
+ /**
+ * 获取指定路径下OpenOperation注解下的uri接口
+ * @return
+ */
+ private Map> getAccessAnnotations(String resourcePattern) {
+
+ ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
+ Map> map = new HashMap<>();
+
+ try {
+ String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resourcePattern;
+ Resource[] resources = resourcePatternResolver.getResources(pattern);
+ MetadataReaderFactory readerfactory = new CachingMetadataReaderFactory(resourcePatternResolver);
+ for (Resource resource : resources) {
+ // 读取类信息
+ MetadataReader reader = readerfactory.getMetadataReader(resource);
+ // 扫描到的class
+ String classname = reader.getClassMetadata().getClassName();
+ Class> clazz = Class.forName(classname);
+ Method[] methods = clazz.getMethods();
+ for (Method method: methods) {
+ OpenOperation openAnno = method.getAnnotation(OpenOperation.class);
+ // 判断是否有指定主解
+ if (openAnno != null) {
+ // 获取注解的方法与接口请求注解
+ String api = getApi(clazz, method);
+ List openApi = map.get(OpenOperation.class.getName());
+ if (CollectionUtils.isEmpty(openApi)) {
+ openApi = new ArrayList<>();
+ map.put(OpenOperation.class.getName(), openApi);
+ }
+ openApi.add(api);
+ }
+ AuthOperation authAnno = method.getAnnotation(AuthOperation.class);
+ // 判断是否有指定主解
+ if (authAnno != null) {
+ // 获取注解的方法与接口请求注解
+ String api = getApi(clazz, method);
+ List authApi = map.get(AuthOperation.class.getName());
+ if (CollectionUtils.isEmpty(authApi)) {
+ authApi = new ArrayList<>();
+ map.put(AuthOperation.class.getName(), authApi);
+ }
+ authApi.add(api);
+ }
+ PassOperation passAnno = method.getAnnotation(PassOperation.class);
+ // 判断是否有指定主解
+ if (passAnno != null) {
+ // 获取注解的方法与接口请求注解
+ String api = getApi(clazz, method);
+ List passApi = map.get(PassOperation.class.getName());
+ if (CollectionUtils.isEmpty(passApi)) {
+ passApi = new ArrayList<>();
+ map.put(PassOperation.class.getName(), passApi);
+ }
+ passApi.add(api);
+ }
+ }
+ }
+ } catch (Exception e) {
+
+ }
+
+ return map;
+
+ }
+
+ /**
+ * 获取api接口
+ * @param
+ * @param
+ */
+ private String getApi(Class> clazz, Method method) {
+ RequestMapping request = clazz.getDeclaredAnnotation(RequestMapping.class);
+ if (request != null) {
+ String api = request.value().length > 0 ? request.value()[0] : "";
+ if (!api.contains(Symbol.SLASH)) {
+ api = Symbol.SLASH + api;
+ }
+ String name = "";
+ // 获取方法的接口路由
+ GetMapping getAnn = method.getAnnotation(GetMapping.class);
+ if (getAnn != null) {
+ name = getAnn.value().length > 0 ? getAnn.value()[0] : "";
+ if (!name.contains(Symbol.SLASH)) {
+ name = Symbol.SLASH + name;
+ }
+ }
+ PostMapping postAnn = method.getAnnotation(PostMapping.class);
+ if (postAnn != null) {
+ name = postAnn.value().length > 0 ? postAnn.value()[0] : "";
+ if (!name.contains(Symbol.SLASH)) {
+ name = Symbol.SLASH + name;
+ }
+ }
+ DeleteMapping deleteAnn = method.getAnnotation(DeleteMapping.class);
+ if (deleteAnn != null) {
+ name = deleteAnn.value().length > 0 ? deleteAnn.value()[0] : "";
+ if (!name.contains(Symbol.SLASH)) {
+ name = Symbol.SLASH + name;
+ }
+ }
+ PutMapping putAnn = method.getAnnotation(PutMapping.class);
+ if (putAnn != null) {
+ name = putAnn.value().length > 0 ? putAnn.value()[0] : "";
+ if (!name.contains(Symbol.SLASH)) {
+ name = Symbol.SLASH + name;
+ }
+ }
+ api += name;
+ return api;
+ }
+ return UUID.randomUUID().toString();
+ }
+
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/utils/JWTUtil.java b/cdaxxt-common/src/main/java/com/tobacco/mp/utils/JWTUtil.java
new file mode 100644
index 0000000..9cb44d9
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/utils/JWTUtil.java
@@ -0,0 +1,108 @@
+package com.tobacco.mp.utils;
+
+import io.jsonwebtoken.Claims;
+import io.jsonwebtoken.Jwts;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+
+public class JWTUtil {
+
+ // 公钥
+ public static String PUBLIC_KEY_STR = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwHOi7T3dx95MADXlRPkLeFS+08f7dGg6RxbG5gug+yQLnw1ARNDYx6zK0gtHU+qmUlBCVqHS5vqAt73ydDKUGY9IgdMcxWtbPj456wF7W86xDv6EfiV/G9ZRVvPWmgNUxw1RXtQa91sIuyCxp4xIFd43wROxWUbmN+Omiv2ZYqYBquSdmzslL1dDypPCZ53ZCs1aY6TodbhndySp8E7YAhw8o+F2uGPW9p1Xz1w4hIZBo10b49rOpR5h0t2U4OloBbAC8Too6Smb5ZdYseUZLLD+PW1O0l7uMBlmJuqjPXRUxuTwXUO+EA4Z/ymBXalE4Zi3uEomISqWajSDPOG4pwIDAQAB";
+
+ /**
+ * 从Base64编码的字符串加载公钥
+ * @param publicKeyStr Base64编码的公钥字符串
+ * @return PublicKey对象
+ */
+ public static PublicKey loadPublicKey(String publicKeyStr) throws Exception {
+ // 移除PEM格式的标记
+ String publicKeyPEM = publicKeyStr
+ .replace("-----BEGIN PUBLIC KEY-----", "")
+ .replace("-----END PUBLIC KEY-----", "")
+ .replaceAll("\\s", "");
+ // Base64解码
+ byte[] encoded = Base64.getDecoder().decode(publicKeyPEM);
+ // 创建公钥规范
+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
+ // 根据算法获取KeyFactory
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ return keyFactory.generatePublic(keySpec);
+ }
+
+ /**
+ * 验证JWT令牌
+ * @param token JWT令牌字符串
+ * @param publicKey 公钥
+ * @return Claims 声明信息
+ */
+ public static Claims verifyJWT(String token, PublicKey publicKey) {
+ return Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token).getBody();
+ }
+
+ /**
+ * 验证令牌签名信息
+ * @param token 令牌
+ * @param publicKeyStr 公钥字符串
+ * @return
+ */
+ public static Claims verifyJWTToken(String token, String publicKeyStr) {
+ try {
+ // 加载公钥
+ PublicKey publicKey = loadPublicKey(publicKeyStr);
+ // 验证JWT
+ return Jwts.parserBuilder().setSigningKey(publicKey).build().parseClaimsJws(token).getBody();
+ } catch (io.jsonwebtoken.security.SignatureException e) {
+ throw new RuntimeException("无效的签名", e);
+ } catch (io.jsonwebtoken.ExpiredJwtException e) {
+ throw new RuntimeException("令牌已过期", e);
+ } catch (io.jsonwebtoken.MalformedJwtException e) {
+ throw new RuntimeException("无效的令牌格式", e);
+ } catch (Exception e) {
+ throw new RuntimeException("令牌验证失败", e);
+ }
+ }
+
+ /**
+ * 读取txt文件的内容
+ * @param file 想要读取的文件对象
+ * @return 返回文件内容
+ */
+ public static String readTxt(File file) {
+ StringBuilder result = new StringBuilder();
+ try {
+ // 构造一个BufferedReader类来读取文件
+ BufferedReader br = new BufferedReader(new FileReader(file));
+ String s = null;
+ // 使用readLine方法,一次读一行
+ while ((s = br.readLine()) != null) {
+ result.append(System.lineSeparator()+s);
+ }
+ br.close();
+ } catch(Exception e) {
+ e.printStackTrace();
+ }
+ return result.toString();
+ }
+
+ public static void main(String[] args) {
+ String publicKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwHOi7T3dx95MADXlRPkLeFS+08f7dGg6RxbG5gug+yQLnw1ARNDYx6zK0gtHU+qmUlBCVqHS5vqAt73ydDKUGY9IgdMcxWtbPj456wF7W86xDv6EfiV/G9ZRVvPWmgNUxw1RXtQa91sIuyCxp4xIFd43wROxWUbmN+Omiv2ZYqYBquSdmzslL1dDypPCZ53ZCs1aY6TodbhndySp8E7YAhw8o+F2uGPW9p1Xz1w4hIZBo10b49rOpR5h0t2U4OloBbAC8Too6Smb5ZdYseUZLLD+PW1O0l7uMBlmJuqjPXRUxuTwXUO+EA4Z/ymBXalE4Zi3uEomISqWajSDPOG4pwIDAQAB";
+ String jwtToken = "eyJhbGciOiJSUzI1NiJ9.eyJlbXBsb3llZUpvYklkIjoiNjIxMzI1MDMwNzAwMDAwMDAwMSIsIm1hbmFnZVVuaXRJZCI6IjAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDExNjIwNTAxIiwib3JpZ2luQXBwIjoiYzQ1Y2I1YzMwZDQzNGMyNDlkZWYyZGNiMzM2ODg4NGQiLCJ0YXJnZXRDbGllbnRzIjoiNmY5MzhkYTBlMjI5MTFmMGJjNzFiYzE2OTUwYTU1ZmIiLCJlbXBsb3llZUlkIjoiMDAwMDAwMDAwMDAwMDAwMDEwNjIwNTAxMDAwMDA0MjIiLCJ1c2VyVHlwZSI6IjAwMDAwMSIsInVzZXJOYW1lIjoi5p2c5YevIiwib3JnVW5pdElkIjoiMDAwMDAwMDAwMDAwMDAwMDAwMDAxMTYyMDUwMTAxMDciLCJnbXRDcmVhdGUiOiIyMDI1LTEyLTI2IDA4OjAxOjA5IiwidXNlcklkIjoiNjIxMzIzMDIyMzAwMDAwMDAzNDAwMDAiLCJhY2NvdW50IjoiRFVLQUkifQ.LzvpEPcGBeOnfV0tcO9yl11PeWuGQR0lzrRAmdUAcSGhvL-J_UF57P4_Q64qfMrzotoSEiVKiCErs4XcgexDFg4WIpx-wbZWdaQ7zIaFMWY-4eVe3R8Th72ABohwuQ7YRFJuWuNE21m3olfqbnbQ1DztDlsWrjd0l6LohrycK9A0teCAlP4Hhjl9kjT2UrRnMFVep1t5dTz8oPSE4KXNjseG8aTBGYbg304JYFQSfkdn3rB6ucp9FG0b9HGrpw1kCdq16m2VXGmKlqGizrOFw30SEZ9z9dABWiNMZjt3AqhY1ByNFtx0bNY-51DOdfVHeWTUDqItuwOak86r-ZVH_w";
+ try {
+ Claims claims = verifyJWTToken(jwtToken, publicKeyStr);
+ String account = claims.get("account", String.class);
+ System.out.println("验证成功!");
+ System.out.println("account: " + account);
+ System.out.println("过期时间: " + claims.getExpiration());
+ } catch (Exception e) {
+ System.err.println("验证失败: " + e.getMessage());
+ }
+ }
+
+}
diff --git a/cdaxxt-common/src/main/java/com/tobacco/mp/utils/Maps.java b/cdaxxt-common/src/main/java/com/tobacco/mp/utils/Maps.java
new file mode 100644
index 0000000..7ba7079
--- /dev/null
+++ b/cdaxxt-common/src/main/java/com/tobacco/mp/utils/Maps.java
@@ -0,0 +1,80 @@
+package com.tobacco.mp.utils;
+
+import com.alibaba.fastjson.JSON;
+
+import java.util.*;
+
+public class Maps {
+
+ /**
+ * json去除key-value处理
+ * @param json
+ * @return
+ */
+ public static String jsonRemoveKey(String json, String key) {
+ Map map = JSON.parseObject(json);
+ Iterator> iter = map.entrySet().iterator();
+ while (iter.hasNext()) {
+ Map.Entry entry = iter.next();
+ if (entry.getKey() != null && entry.getKey().equals(key)) {
+ map.remove(key);
+ break;
+ }
+ }
+ return JSON.toJSONString(map);
+ }
+
+ /**
+ * 默认采用HashMap
+ * @param args
+ * @return
+ */
+ public static Map