Commit 0e2e9b05 by 刘栋

剥离云服务,成为spring boot单体服务

parent dd81e4fb
Showing with 5479 additions and 335 deletions
No preview for this file type
No preview for this file type
......@@ -3,6 +3,14 @@
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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.6</version> <!-- 当前最新的Spring Boot 2.x稳定版本 -->
<relativePath/>
</parent>
<artifactId>saas-udi</artifactId>
<name>saas-udi</name>
<groupId>com.infynova</groupId>
......@@ -18,21 +26,15 @@
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<java.version>1.8</java.version>
<springboot.version>2.4.6</springboot.version>
<nacos.client.version>1.4.1</nacos.client.version>
<spring.cloud.version>2020.0.3</spring.cloud.version>
<alibaba.version>2021.1</alibaba.version>
<lombok.version>1.18.20</lombok.version>
<fastjson.version>1.2.57</fastjson.version>
<mybatisplus.version>3.5.6</mybatisplus.version>
<mybatisplus.dynamic.datasource.version>3.4.1</mybatisplus.dynamic.datasource.version>
<spring.version>5.3.7</spring.version>
<redis.version>2.4.2</redis.version>
<commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.3.1</commons.fileupload.version>
<commons.lang.version>3.9</commons.lang.version>
<commons.collections4.version>4.4</commons.collections4.version>
<mysql.connector.version>8.0.16</mysql.connector.version>
<knife4j.version>3.0.2</knife4j.version>
<swagger2.serion>3.0.0</swagger2.serion>
<swagger.ui.version>1.9.6</swagger.ui.version>
......@@ -49,120 +51,22 @@
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>${nacos.client.version}</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
</dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${redis.version}</version>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- MyBatis-Plus 集成 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
<version>3.5.3.2</version> <!-- 兼容 Spring Boot 2.x 的最新版 -->
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.connector.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
......@@ -251,6 +155,11 @@
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.7.0</version>
</dependency>
</dependencies>
</dependencyManagement>
......@@ -288,14 +197,6 @@
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springboot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
......
......@@ -15,6 +15,5 @@
</properties>
<dependencies>
</dependencies>
</project>
\ No newline at end of file
......@@ -12,84 +12,52 @@
<artifactId>saas-udi-service</artifactId>
<properties>
<jetcache.version>2.6.2</jetcache.version>
</properties>
<dependencies>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<exclusions>
<exclusion>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</exclusion>
</exclusions>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- MyBatis-Plus -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
</dependency>
<dependency>
<groupId>com.infynova</groupId>
<artifactId>saas-udi-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alicp.jetcache</groupId>
<artifactId>jetcache-starter-redis</artifactId>
<version>${jetcache.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
......@@ -99,7 +67,6 @@
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.7.0</version>
</dependency>
<dependency>
......@@ -119,6 +86,7 @@
<artifactId>swagger-bootstrap-ui</artifactId>
</dependency>
<!-- sqlite jdbc 驱动 -->
<dependency>
<groupId>org.xerial</groupId>
......@@ -199,12 +167,11 @@
</dependency>
<dependency>
<groupId>com.infynova</groupId>
<artifactId>saas-ucpm-api</artifactId>
<version>4.1.1</version>
<scope>system</scope>
<systemPath>${project.basedir}/../libs/saas-ucpm-api-1.0.0.jar</systemPath>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.2.0-jre</version>
</dependency>
<dependency>
<groupId>org.simmetrics</groupId>
<artifactId>simmetrics-core</artifactId>
......@@ -212,13 +179,7 @@
<scope>system</scope>
<systemPath>${project.basedir}/../libs/simmetrics-core-4.1.1.jar</systemPath>
</dependency>
<dependency>
<groupId>com.infynova</groupId>
<artifactId>saas-core</artifactId>
<version>1.0.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/../libs/saas-core-1.0.0.jar</systemPath>
</dependency>
</dependencies>
<build>
......
package com.infynova.udi;
import com.alicp.jetcache.anno.config.EnableMethodCache;
import com.infynova.udi.constant.UdiConstant;
import lombok.extern.slf4j.Slf4j;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@Slf4j
@EnableAsync
@EnableScheduling
@EnableConfigurationProperties
@EnableFeignClients(basePackages = {UdiConstant.INFYNOVA_PACKAGE_NAME})
@EnableDiscoveryClient
@MapperScan(UdiConstant.MAPPER_PACKAGE_NAME)
@EnableMethodCache(basePackages = {UdiConstant.UDI_PACKAGE_NAME})
@SpringBootApplication(scanBasePackages = {"com.infynova.udi","com.infynova.common"})
@SpringBootApplication
//@SpringBootApplication(scanBasePackages = {"com.infynova.udi","com.infynova.udi.common"})
public class UdiApplication {
public static void main(String[] args) {
SpringApplication.run(UdiApplication.class, args);
......
package com.infynova.udi.common.api;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @author zzw
* @date 2022/8/29
* @apiNote
*/
@Data
public abstract class BaseOpenData {
@ApiModelProperty(value = "企业ID/租户ID", required = true)
private Long tenantId;
}
package com.infynova.udi.common.api;
import lombok.Data;
import java.io.Serializable;
/**
* @author zoupx
* @date 2022/5/13 16:19
* @desc 返回通用前端显示对象
*/
@Data
public class BaseVo implements Serializable {
private static final long serialVersionUID = 1L;
}
package com.infynova.udi.common.api;
import lombok.Data;
import java.io.Serializable;
/**
* @Description 前端请求入参
* @anthor zoupx
* @date 2020/9/19 11:56
*/
@Data
public class RequestData implements Serializable {
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.api;
import cn.hutool.core.util.ObjectUtil;
import com.infynova.udi.common.context.HeaderCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.slf4j.MDC;
import java.io.Serializable;
/**
* @Description 响应结果对象
* @anthor zoupx
* @date 2020/9/19 11:56
*/
@Data
@ApiModel(value = "ResponseData", description = "统一返回对象")
public class ResponseData<T> implements Serializable {
public final static int SUCCESS = 200;
/**
* 响应码(默认200正常响应)
*/
@ApiModelProperty(value = "返回码")
private int code = SUCCESS;
/**
* 响应信息(默认OK)
*/
@ApiModelProperty(value = "响应信息")
private String msg = "SUCCESS";
/**
* 响应结果(默认成功)
*/
private boolean success = true;
/**
* 响应数据
*/
@ApiModelProperty(value = "响应数据")
private T data;
private Object detail;
private String traceId = MDC.get(HeaderCode.TRACE_ID);
public ResponseData() {
}
private ResponseData(T data) {
this.data = data;
}
public static <T> ResponseData<T> error(ServiceCode serviceCode) {
return error(serviceCode.getCode(), serviceCode.getMsg());
}
public static <T> ResponseData<T> error(ServiceCode serviceCode, T data) {
return error(serviceCode.getCode(), serviceCode.getMsg(), data);
}
public static <T> ResponseData<T> error(int code, String msg) {
return error(code, msg, null);
}
public static <T> ResponseData<T> error(int code, String msg, T data) {
ResponseData responseData = new ResponseData();
responseData.setCode(code);
responseData.setMsg(msg);
responseData.setData(data);
responseData.setSuccess(false);
return responseData;
}
/**
* 成功响应
*
* @param <T>
* @return
*/
public static <T> ResponseData<T> ok() {
return new ResponseData<>();
}
/**
* 成功响应:带data数据
*
* @param <T>
* @return
*/
public static <T> ResponseData<T> ok(T data) {
return new ResponseData<>(data);
}
public ResponseData(int code) {
this.code = code;
}
public ResponseData(String msg) {
this.msg = msg;
}
public ResponseData detail(Object detail) {
this.detail = detail;
return this;
}
public ResponseData detail(Throwable exception) {
this.detail = ObjectUtil.isNotEmpty(exception) ? exception.getMessage() : "";
return this;
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.api;
/**
* @author zoupx
* @email
* @date 2020/9/15 9:13 上午
* @description: 响应编码
*/
public interface ServiceCode {
/**
* 响应编码
* @return
*/
int getCode();
/**
* 响应描述
* @return
*/
String getMsg();
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.config;
import com.infynova.udi.common.context.SpringContextUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @Author: zoupx
* @Description: GlobalMvcConfigurer 类
* @Date: 2021/9/8
*/
@Configuration
public class GlobalMvcConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ThreadLocalInterceptor())
.addPathPatterns("/**")
.order(-100);
}
/**
* @Author: zoupx
* @Description: 处理异步线程请求头丢失问题
* @Date: 2021/9/8
*/
public static class ThreadLocalInterceptor implements HandlerInterceptor {
/**
* 拦截前处理
* @param request request
* @param response response
* @param handler handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){
if (!(handler instanceof HandlerMethod)) {
return true;
}
/*Map<String, String> headers = new HashMap<>();
headers.put(HeaderCode.CLIENT_CODE, request.getHeader(HeaderCode.CLIENT_CODE));
headers.put(HeaderCode.TENANT_CODE, request.getHeader(HeaderCode.TENANT_CODE));
headers.put(HeaderCode.IDENTITY_ID, request.getHeader(HeaderCode.IDENTITY_ID));
//headers.put(HeaderCode.IDENTITY_TYPE, request.getHeader(HeaderCode.IDENTITY_TYPE));
MDC.put(HeaderCode.TENANT_CODE, request.getHeader(HeaderCode.TENANT_CODE));
MDC.put(HeaderCode.IDENTITY_ID, request.getHeader(HeaderCode.IDENTITY_ID));
MDC.put(HeaderCode.TRACE_ID, request.getHeader(HeaderCode.TRACE_ID));
// 放到TransmittableThreadLocal中,避免异步线程丢失
SpringContextUtils.setLocalMap(headers);*/
return true;
}
/**
* DispatcherServlet完全处理完请求后,清除SpringContextUtils的LocalMap
* @param request request
* @param response response
* @param handler handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
SpringContextUtils.removeLocalMap();
}
}
}
package com.infynova.udi.config;
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.config;
import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.databind.DeserializationFeature;
......@@ -24,8 +40,7 @@ import java.time.format.DateTimeFormatter;
* @date 2020/9/15
* @return
*/
@Deprecated
//@Configuration
@Configuration
public class JsonSerializerManage {
@Bean
......
package com.infynova.udi.config;
package com.infynova.udi.common.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
......@@ -6,7 +6,7 @@ import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
@Deprecated
public class LongToStringSerializer extends StdSerializer<Long> {
protected LongToStringSerializer(Class<Long> t) {
super(t);
......
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.config;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
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.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* @author zoupx
* @email
* @date 2021/8/5 10:57 下午
* @description:
*/
@SuppressWarnings("all")
@Configuration
public class RedisConfig {
@Bean
public RedisSerializer<String> redisKeySerializer() {
return new StringRedisSerializer();
}
/**
*
* @description 使用FastJson
* @param
* @author zoupx
* @date 2021/8/5
* @return org.springframework.data.redis.serializer.RedisSerializer<java.lang.Object>
*/
@Bean
public RedisSerializer<Object> redisValueSerializer() {
return new GenericFastJsonRedisSerializer();
}
/**
*
* @description RedisTemplate配置
* @param factory
* @param redisKeySerializer
* @param redisValueSerializer
* @author zoupx
* @date 2021/8/5
* @return org.springframework.data.redis.core.RedisTemplate<java.lang.String,java.lang.Object>
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory, RedisSerializer<String> redisKeySerializer, RedisSerializer<Object> redisValueSerializer) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
//设置Key的序列化采用StringRedisSerializer
redisTemplate.setKeySerializer(redisKeySerializer);
redisTemplate.setHashKeySerializer(redisKeySerializer);
//设置值的序列化
redisTemplate.setValueSerializer(redisValueSerializer);
redisTemplate.setHashValueSerializer(redisValueSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
package com.infynova.udi.common.constant;
/**
* @author he-xing
* @description
* @date 2022-06-01
*/
public interface AuthConstant {
/**
* 平台角色ID
*/
Long PLATFORM_RULE = 1L;
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.constant;
/**
* @author zoupx
* @email
* @date 2021/6/29 11:05 下午
* @description: 认证服务redis key
*/
public interface AuthRedisKeyConstant {
String AUTH = "AUTH" + SpecialCharacterPool.DOUBLE_COLON;
// 用户菜单key [AUTH::MENU::clientCode::userId]
String USER_MENU_KEY = AUTH + "MENU" + SpecialCharacterPool.DOUBLE_COLON;
// 用户权限key [AUTH::INTERFACE::clientCode::userId]
String USER_INTERFACE_KEY = AUTH + "INTERFACE" + SpecialCharacterPool.DOUBLE_COLON;
String ALL_INTERFACE_KEY = AUTH + "ALL_INTERFACE_KEY";
// 用户信息key [AUTH::AUTH::clientCode::userId]
String USER_INFO_KEY = AUTH + "INFO" + SpecialCharacterPool.DOUBLE_COLON;
/**
* 验证码 key
*/
String USER_CAPTCHA_KEY = AUTH + "CAPTCHA" + SpecialCharacterPool.DOUBLE_COLON;
/**
* 登录验证码
*/
String USER_CAPTCHA_LOGIN_KEY = USER_CAPTCHA_KEY + "LOGIN" + SpecialCharacterPool.DOUBLE_COLON;
/**
* 失效JWT
*/
String USER_INVALID_JWT = AUTH + "INVALID" + SpecialCharacterPool.DOUBLE_COLON + "JWT" + SpecialCharacterPool.DOUBLE_COLON;
/**
* 登录次数
*/
String USER_LOGIN_COUNT_KEY = AUTH + "LOGIN" + SpecialCharacterPool.DOUBLE_COLON + "COUNT" + SpecialCharacterPool.DOUBLE_COLON;
/**
* 登录限制时长
*/
String USER_LOGIN_LOCK_TIME_KEY = AUTH + "LOGIN" + SpecialCharacterPool.DOUBLE_COLON + "LOCK" + SpecialCharacterPool.DOUBLE_COLON;
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.constant;
/**
* @author zoupx
* @email
* @date 2021/6/29 11:05 下午
* @description:
*/
public interface ConfigValueConstant {
String SPRING_APPLICATION_NAME = "spring.application.name";
String SPRING_PROFILES_ACTIVE = "spring.profiles.active";
// ------------gateway------------------
String GATEWAY_URI_FILTER = "saas.gateway.uri.filter";
// ------------thread------------------
String THREAD_POOL_CORE_SIZE = "saas.thread.pool.coreSize";
String THREAD_POOL_MAX_SIZE = "saas.thread.pool.maxSize";
String THREAD_POOL_KEEPALIVE = "saas.thread.pool.keepalive";
String THREAD_POOL_BLOCK_QUEUE_SIZE = "saas.thread.pool.blockQueueSize";
// ------------JWT------------------
String JWT_EXPIRE ="saas.jwt.expire";
String JWT_PC_EXPIRE ="saas.jwt.pc-expire";
String JWT_REFRESH_EXPIRE ="saas.jwt.refreshExpire";
String JWT_ALLOWABLE_ERROR_TIME ="saas.jwt.allowableErrorTime";
// ------------LOG------------------
String LOG_ENABLED ="saas.log.enabled";
String LOG_DB ="saas.log.db";
// ------------mybatis plus------------------
String MYBATIS_PLUS_IGNORE_TABLE ="saas.mybatisPlus.ignoreTable";
String MYBATIS_PLUS_OPEN_TENANT ="saas.mybatisPlus.openTenant";
// ------------security------------------
String SECURITY_ENABLED = "saas.security.enabled";
}
package com.infynova.udi.common.constant;
/**
* @author liaosj
* @date 2023/3/27 11:32
*/
public interface DateConstant {
String DATE_PATTERN = "yyyy-MM-dd";
String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
String DATETIME_PATTERN_MINUTE = "yyyy-MM-dd HH:mm";
}
package com.infynova.udi.common.constant;
/**
* @author zoupx
* @date 2022/6/24 11:43
* @desc
*/
public interface FileSaveConstant {
// 借货出库单
String SAAN_RECEIPTS_PDF = "saas.receipts.pdf";
// 借货出库单
String SAAN_RECEIPTS_BORROW_OUT_STOCK_MODE = "saas.receipts.borrow-out-stock";
}
package com.infynova.udi.common.constant;
/**
* @author he-xing
* @description
* @date 2022-05-28
*/
public interface GatewayConstant {
/**
* 基础架构
*/
String UCPM_PATH = "/ucpm";
String UCPM_SERVICE_NAME = "saas-ucpm";
String SAAS_UCPM_PACKAGE = "com.infynova.ucpm";
/**
* obs 智能仓
*/
String OBS_PATH = "/obs";
String OBS_SERVICE_NAME = "saas-obs";
String SAAS_OBS_PACKAGE = "com.infynova.obs";
/**
* oms 订单服务
*/
String OMS_PATH = "/oms";
String OMS_SERVICE_NAME = "saas-oms";
String SAAS_OMS_PACKAGE = "com.infynova.oms";
/**
* pms 商品服务
*/
String PMS_PATH = "/pms";
String PMS_SERVICE_NAME = "saas-pms";
String SAAS_PMS_PACKAGE = "com.infynova.pms";
/**
* 物流服务
*/
String LOGISTICS_PATH = "/logistics";
String LOGISTICS_SERVICE_NAME = "saas-logistics";
String SAAS_LOGISTICS_PACKAGE = "com.infynova.logistics";
/**
* report 报表服务
*/
String REPORT_PATH = "/report";
String REPORT_SERVICE_NAME = "saas-report";
String SAAS_REPORT_PACKAGE = "com.infynova.report";
/**
* 手机端路由前缀
*/
String CLIENT_TYPE_MOBILE_PRE = "/mob";
/**
* 无境操作台
*/
String CLIENT_TYPE_CONSOLE_PRE = "console/";
/**
* 无境之眼(IE)
*/
String CLIENT_TYPE_IE_PRE = "ie/";
/**
* 无境合格证扫描器(CS)
*/
String CLIENT_TYPE_CS_PRE = "cs/";
/**
* PDA
*/
String CLIENT_TYPE_PDA_PRE = "pda/";
/**
* 安卓 || 微信
*/
String CLIENT_TYPE_ANDROID_PRE = "android/";
/**
* openapi
*/
String CLIENT_TYPE_OPENAPI = "openapi/";
/**
* 价格服务
*/
String PRICE_PATH = "/price";
String PRICE_SERVICE_NAME = "saas-price";
String SAAS_PRICE_PACKAGE = "com.infynova.price";
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.constant;
/**
* @author zoupx
* @email
* @date 2021/6/29 11:05 下午
* @description:
*/
public interface GrantTypeConstant {
// 手机验证码登录
String MOBILE = "mobile";
// 用户名+密码+验证码
String PASSWORD = "password";
// 微信openId登录方式
String OPEN_ID = "openId";
/**
* 手机号登录 - 内部
*/
String MOBILE_INSIDE = "mobileInside";
/**
* 人脸识别
*/
String FACE = "face";
/**
* 工号 密码登录
*/
String WORK_NO = "workNo";
/**
* 内部工号 密码登录
*/
String INTERNAL_WORK_NO = "internalWorkNo";
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.constant;
/**
* @author zoupx
* @email
* @date 2021/6/29 11:05 下午
* @description:
*/
public interface JwtKeyConstant {
String USER_ID = "userId";
String ACCOUNT_ID = "accountId";
String TENANT_CODE = "tenantCode";
String DEPT_ID = "deptId";
String DEPT_CODE = "deptCode";
String DATA_SCOPE = "dataScope";
String USERNAME = "username";
String IDENTITY_TYPE = "identityType";
String TENANT_ID = "tenantId";
String USER_TYPE = "userType";
String CLIENT_CODE = "clientCode";
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.constant;
/**
* @author zoupx
* @email
* @date 2021/6/29 11:05 下午
* @description:
*/
public interface SaasConstant {
// common
String SAAS_COMMON_PACKAGE = "com.infynova.udi.common.*";
//jwt
String SAAS_JWT_PACKAGE = "com.infynova.udi.common.jwt";
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.constant;
import cn.hutool.core.text.StrPool;
/**
* @author zoupx
* @email
* @date 2021/8/2 9:28 下午
* @description: 特殊字符定义
*/
public interface SpecialCharacterPool extends StrPool {
// 双冒号
String DOUBLE_COLON = "::";
// 双冒号
String TRUE = "true";
// 默认密码
String DEF_PASSWORD = "123456";
// 空串
String EMPTY = "";
}
package com.infynova.udi.common.constant;
/**
* @author zoupx
* @date 2022/6/5 11:12
* @desc
*/
public interface SysConstant {
/**
*平台租户id
*/
Long PLAT_FORM_TENANT_ID = 1533028981736583171L;
/**
*平台管理员id
*/
Long PLAT_FORM_MAN_ACCOUNT_ID = 1422201971793182722l;
/**
*初始化企业服务包id
*/
Long INIT_COMPANY_SERVER_PACKAGE_ID = 1534354035304738818L;
}
package com.infynova.udi.common.constant;
/**
* @author liaosj
* @date 2022/9/7 18:52
*/
public interface Versions {
String V2_2 = "v2.2";
String V2_3 = "v2.3";
String V2_4 = "v2.4";
String V2_5 = "v2.5";
String V2_6 = "v2.6";
String V2_7 = "v2.7";
String V2_8 = "v2.8";
String V2_9 = "v2.9";
String V2_10 = "v2.10";
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.context;
/**
* @Description 请求头code常量
* @anthor zoupx
* @date 2019/9/22
*/
public interface HeaderCode {
/**
* 链路id
*/
String TRACE_ID = "Trace-Id";
/**
* token
*/
String TOKEN = "Access-Token";
/**
* 公司CODE
*/
String TENANT_CODE = "Tenant-Code";
/**
* 客户端code
*/
String CLIENT_CODE = "Client-Code";
/**
* 部门ID
*/
String DEPT_ID = "Dept-Id";
/**
* 部门code
*/
String DEPT_CODE = "Dept-Code";
/**
* 用户身份ID
*/
String IDENTITY_ID = "Identity-Id";
/**
* 账号
*/
String USER_NAME = "User-Name";
/**
* 账号类型
*/
String USER_TYPE = "User-Type";
/**
* 账号ID
*/
String ACCOUNT_ID = "Account-Id";
/**
* 身份来源
*/
// String IDENTITY_TYPE = "Identity-Type";
String DATA_SCOPE = "Saas-Data-Scope";
/**
* ip
*/
String IP = "Ip";
/**
* 浏览器信息
*/
String USER_AGENT = "User-Agent";
/**
* Feign 调用标识
*/
String FEIGN = "Feign";
/**
* 公司id
*/
String TENANT_ID = "Tenant-ID";
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.context;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.infynova.udi.common.constant.SpecialCharacterPool;
import com.infynova.udi.common.enums.UserTypeEnums;
import com.infynova.udi.common.jwt.AuthUtil;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author zoupx
* @email
* @date 2020-03-30
* @description: 请求上下文数据
*/
@Component
public class SpringContextUtils implements ApplicationContextAware {
private static AuthUtil authUtil;
@Autowired
private SpringContextUtils(AuthUtil authUtil) {
SpringContextUtils.authUtil = authUtil;
}
/**
* 多线程参数
*/
private static final ThreadLocal<Map<String, String>> THREAD_LOCAL = new TransmittableThreadLocal<Map<String, String>>() {
public Map<String, String> copy(Map<String, String> src) {
// 注意:子线程拷贝(继承)父线程上下文,并且保证后续父子线程上下文互相独立(各自修改,互不影响)——比如切换当前租户的场景
Map<String, String> dst = new ConcurrentHashMap<>(16);
dst.putAll(src);
return dst;
}
};
/**
* 上下文对象实例
*/
private static ApplicationContext applicationContext;
/**
* applicationContext
*
* @param applicationContext applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
/**
* 从applicationContext中获取Bean
*/
public static <T> T getBean(Class<T> requiredType) {
return applicationContext.getBean(requiredType);
}
/**
* 获取applicationContext
*
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取HttpServletRequest
*/
public static HttpServletRequest getHttpServletRequest() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return Objects.isNull(requestAttributes) ? null : requestAttributes.getRequest();
}
/**
* 获取
*
* @param key key
* @return value
*/
public static String get(String key) {
Map<String, String> map = THREAD_LOCAL.get();
if (ObjectUtil.isNotEmpty(map) && map.containsKey(key)) {
return Convert.toStr(map.get(key));
}
HttpServletRequest request = getHttpServletRequest();
if (request == null) {
return SpecialCharacterPool.EMPTY;
}
String value = request.getHeader(key);
if (ObjectUtil.isNotEmpty(value)) {
return value;
}
return SpecialCharacterPool.EMPTY;
}
/**
* 设置THREAD_LOCAL
*
* @param localMap TransmittableThreadLocal
*/
public static void setLocalMap(Map<String, String> localMap) {
THREAD_LOCAL.set(localMap);
}
/**
* 设置THREAD_LOCAL
*
* @param key key
* @param value value
*/
public static void set(String key, String value) {
Map<String, String> map = THREAD_LOCAL.get();
if (MapUtil.isEmpty(map)) {
map = new ConcurrentHashMap<>(16);
THREAD_LOCAL.set(map);
}
map.put(key, value == null ? SpecialCharacterPool.EMPTY : value);
}
/**
* 移除THREAD_LOCAL
*/
public static void removeLocalMap() {
THREAD_LOCAL.remove();
}
/**
* 获取当前用户ID
*
* @return ACCOUNT_ID
*/
public static Long getAccountId() {
String value = get(HeaderCode.ACCOUNT_ID);
return Optional.ofNullable(value).filter(ObjectUtil::isNotEmpty).map(Long::valueOf).orElse(null);
}
/**
* 获取当前用户的员工ID
*
* @return identityId
*/
public static Long getIdentityId() {
String value = get(HeaderCode.IDENTITY_ID);
return Optional.ofNullable(value).filter(ObjectUtil::isNotEmpty).map(Long::valueOf).orElse(null);
}
/**
* 获取当前用户的员工ID
*
* @return USERNAME
*/
public static String getUserName() {
return get(HeaderCode.USER_NAME);
}
/**
* 是否是平台超管用户
*
* @return true 是 ,false:否
*/
public static boolean isPlatformAdmin() {
return UserTypeEnums.PLATFORM_ADMIN == getUserTypeEnum();
}
/**
* 是否是企业管理员
*
* @return true 是 ,false:否
*/
public static boolean isCompanyAdmin() {
return UserTypeEnums.COMPANY_ADMIN == getUserTypeEnum();
}
/**
* 获取用户类型
*
* @return
*/
public static Integer getUserType() {
String value = get(HeaderCode.USER_TYPE);
return Optional.ofNullable(value)
.filter(ObjectUtil::isNotEmpty)
.map(userType -> Integer.parseInt(userType))
.orElse(null);
}
public static UserTypeEnums getUserTypeEnum() {
Integer userType = getUserType();
return ObjectUtil.isNotEmpty(userType) ? UserTypeEnums.getEnum(userType) : null;
}
/**
* 获取公司数据范围
*
* @return DATA_SCOPE
*/
public static Integer getDataScope() {
String value = get(HeaderCode.DATA_SCOPE);
return Optional.ofNullable(value).filter(ObjectUtil::isNotEmpty).map(Integer::parseInt).orElse(null);
}
/**
* 部门ID
*
* @return DEPT_ID
*/
public static Long getDeptId() {
String value = get(HeaderCode.DEPT_ID) ;
return Optional.ofNullable(value).filter(ObjectUtil::isNotEmpty).map(Long::valueOf).orElse(null);
}
/**
* 部门code
*
* @return DEPT_CODE
*/
public static String getDeptCode() {
return get(HeaderCode.DEPT_CODE);
}
/**
* 获取请求来源
*
* @return IDENTITY_TYPE
*/
/* public static Integer getIdentityType() {
HttpServletRequest httpServletRequest = getHttpServletRequest();
return Integer.valueOf(Objects.isNull(httpServletRequest) ? get(HeaderCode.IDENTITY_TYPE) : httpServletRequest.getHeader(HeaderCode.IDENTITY_TYPE));
}*/
/**
* 获取该用户的token
* @return TOKEN
*/
// public static String getToken(){
// HttpServletRequest httpServletRequest = getHttpServletRequest();
// return Objects.isNull(httpServletRequest) ? get(HeaderCode.TOKEN) : httpServletRequest.getHeader(HeaderCode.TOKEN);
// }
/**
* 获取该用户所在租户
*
* @return TENANT_Id
*/
public static Long getTenantId() {
String value = get(HeaderCode.TENANT_ID) ;
return Optional.ofNullable(value).filter(ObjectUtil::isNotEmpty).map(Long::valueOf).orElse(null);
}
/**
* 获取该用户客户端类型
*
* @return CLIENT_CODE
*/
public static String getClientCode() {
return get(HeaderCode.CLIENT_CODE);
}
/**
* ip
*
* @return IP
*/
public static String getIp() {
return get(HeaderCode.IP);
}
/**
* ip
*
* @return FEIGN
*/
public static String getFeign() {
return get(HeaderCode.FEIGN);
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.entity;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @Description 基础实体 (通用字段)
* @anthor zoupx
* @date 2019/9/26
*/
@Data
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键id
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
private Long createBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
/**
* 更新人
*/
@TableField(fill = FieldFill.UPDATE)
private Long updateBy;
/**
* 更新时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
/**
* 删除状态(0-正常,1-已删除)
*/
@TableLogic
@TableField(fill = FieldFill.INSERT)
private Integer delFlag;
}
package com.infynova.udi.common.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 基础实体-租户维度 (通用字段)
* @author rubin 2022年05月30日
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class BaseTenantEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 部门ID
*/
@ApiModelProperty(value = "所属部门")
@TableField(fill = FieldFill.INSERT)
private Long deptId;
/**
* 租户号
*/
@ApiModelProperty(value = "租户号")
@TableField(fill = FieldFill.INSERT)
private Long tenantId;
}
package com.infynova.udi.common.entity;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 基础实体-版本号
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class BaseVersionEntity extends BaseTenantEntity {
private static final long serialVersionUID = 1L;
/**
* 版本号
*/
@Version
@TableField(fill = FieldFill.INSERT_UPDATE, update="%s+1")
private Integer version;
}
package com.infynova.udi.common.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author he-xing
* @description
* @date 2022-08-17
*/
@Data
public abstract class OpenApiRequest implements Serializable {
@ApiModelProperty(value = "上游公司租户ID")
private Long parentTenant;
}
package com.infynova.udi.common.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @author he-xing
* @description
* @date 2022-05-31
*/
@Data
@ApiModel(value = "PageVo", description = "分页参数")
public class PageVo implements Serializable {
private static final long serialVersionUID = 1L;
@NotNull(message = "当前页 不能为空.")
@ApiModelProperty(value = "当前页")
private Integer pageNo = 1;
@NotNull(message = "每页显示条数 不能为空.")
@ApiModelProperty(value = "每页显示条数")
private Integer pageSize = 20;
}
package com.infynova.udi.common.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
/**
* @author he-xing
* @description
* @date 2022-05-19
*/
@Data
@ApiModel(value = "UploadResultVo", description = "上传模型返回")
public class UploadResultVo implements Serializable {
@ApiModelProperty(value = "文件地址")
private String filePath;
@ApiModelProperty(value = "文件名称")
private String fileName;
@ApiModelProperty(value = "文件id")
private Long id;
}
package com.infynova.udi.common.enums;
import lombok.Getter;
import lombok.Setter;
/**
* @author he-xing
* @description 权限CODE
* @date 2022-07-01
*/
public enum AuthPermsCodeEnum {
// 订单
ORDER_APPROVED("order:audit", "审核通过"),
ORDER_reject("order:reject", "驳回"),
;
@Getter
@Setter
private String code;
@Getter
@Setter
private String msg;
AuthPermsCodeEnum(String code, String msg) {
this.code = code;
this.msg = msg;
}
}
package com.infynova.udi.common.enums;
import lombok.Getter;
/**
* @author he-xing
* @description
* @date 2022-06-24
*/
public enum BaseClientTypeEnum {
PC(0, "pc"),
MOBILE(1, "android || wx"),
PDA(2, "PDA"),
CONSOLE(3, "CZT"),
;
BaseClientTypeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
@Getter
private final int code;
@Getter
private final String msg;
}
package com.infynova.udi.common.enums;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.infynova.udi.common.exception.SaasException;
import lombok.Getter;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
/**
* @author he-xing
* @description
* @date 2022-06-24
*/
public enum ClientTypeEnum {
PC(0, "pc", "PC"),
ANDROID(1, "android", "MOB"),
WX(2, "wechat", "MOB"),
PDA(10, "pda", "PDA"),
DB(11, "db", "DB"),
CS(12, "cs", "CS"),
IE(13, "ie", "IE"),
;
ClientTypeEnum(int code, String value, String desc) {
this.code = code;
this.value = value;
this.desc = desc;
}
@Getter
private final int code;
@Getter
private final String value;
@Getter
private final String desc;
private static final List<ClientTypeEnum> typeList = Arrays.asList(ClientTypeEnum.values());
public static Optional<ClientTypeEnum> find(Integer code) {
return typeList.stream()
.filter(type -> ObjectUtil.equal(code, type.getCode()))
.findFirst();
}
public static ClientTypeEnum findOrThrow(Integer code) {
return find(code).orElseThrow(() -> new SaasException("未找到类型=" + code));
}
public static boolean isPc(Integer code) {
ClientTypeEnum type = findOrThrow(code);
return type == PC;
}
public static boolean isMobile(Integer code) {
ClientTypeEnum type = findOrThrow(code);
return type == ANDROID || type == WX;
}
public static boolean isPda(Integer code) {
ClientTypeEnum type = findOrThrow(code);
return type == PDA;
}
public static boolean isDb(Integer code) {
ClientTypeEnum type = findOrThrow(code);
return type == DB;
}
public static boolean isCs(Integer code) {
ClientTypeEnum type = findOrThrow(code);
return type == CS;
}
public static boolean isIe(Integer code) {
ClientTypeEnum type = findOrThrow(code);
return type == IE;
}
public static Optional<ClientTypeEnum> find(String value) {
Optional<ClientTypeEnum> typeEnum = typeList.stream()
.filter(type -> ObjectUtil.equal(value, type.getValue()))
.findFirst();
if (typeEnum.isPresent()) {
return typeEnum;
}
if (StrUtil.equalsIgnoreCase(value, "pc-tenant")) {
return Optional.of(PC);
}
if (StrUtil.equalsIgnoreCase(value, "console")) {
return Optional.of(DB);
}
return Optional.empty();
}
public static ClientTypeEnum findOrThrow(String value) {
return find(value)
.orElseThrow(() -> new SaasException("未找到类型=" + value));
}
public static ClientTypeEnum findOrDefault(String value) {
return find(value)
.orElse(PC);
}
public static boolean isPc(String value) {
ClientTypeEnum type = findOrThrow(value);
return type == PC;
}
public static boolean isMobile(String value) {
ClientTypeEnum type = findOrThrow(value);
return type == ANDROID || type == WX;
}
public static boolean isPda(String value) {
ClientTypeEnum type = findOrThrow(value);
return type == PDA;
}
public static boolean isDb(String value) {
ClientTypeEnum type = findOrThrow(value);
return type == DB;
}
public static boolean isCs(String value) {
ClientTypeEnum type = findOrThrow(value);
return type == CS;
}
public static boolean isIe(String value) {
ClientTypeEnum type = findOrThrow(value);
return type == IE;
}
public static void main(String[] args) {
ClientTypeEnum pc = findOrDefault("pc");
System.out.println(pc.getCode());
System.out.println(pc.getValue().toLowerCase());
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.enums;
import lombok.Getter;
/**
* @Author: zoupx
* @Description: StatusEnum 类 数据启用状态
* @Date: 2022/5/30
*/
public enum DelFlagEnum {
NORMAL(0, "正常"),
DELETE(1, "已删除");
;
@Getter
private int code;
@Getter
private String msg;
DelFlagEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public static DelFlagEnum getEnumByCode(int code){
for (DelFlagEnum delFlagEnum: DelFlagEnum.values()) {
if(delFlagEnum.getCode() == code){
return delFlagEnum;
}
}
return null;
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.enums;
import lombok.Getter;
/**
* @Author: zoupx
* @Description: BaseExceptionCode 类
* @Date: 2021/7/7
*/
public enum IdentityEnum {
EMPLOYEE(10, "内部员工身份"),
DOMESTIC_CONSUMER(20, "普通用户身份");
;
@Getter
private int code;
@Getter
private String msg;
IdentityEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
/**
*
* @description 根据code返回对应枚举
* @param code
* @author zoupx
* @date 2021/9/7
* @return IdentityEnum
*/
public static IdentityEnum getEnumByCode(int code){
for (IdentityEnum identityEnum:IdentityEnum.values()) {
if(identityEnum.getCode() == code){
return identityEnum;
}
}
return null;
}
}
package com.infynova.udi.common.enums;
import com.infynova.udi.common.api.ServiceCode;
/**
* @author zoupx
* @date 2022/5/8 11:08
* @desc
*/
public enum ResultCodeEnum implements ServiceCode {
SUCCESS(200, "操作成功"),
FAILED(201, "操作失败"),
UNAUTHORIZED(50008, "账号在别处登录"),
VALIDATE_FAILED(4040, "参数检验失败"),
FORBIDDEN(40301, "接口未授权,请联系管理员"),
VALIDATE_SIGN(4100, "签名不通过"),
ACCESSFORBIDDEN(5010, "禁止访问");
private int code;
private String msg;
ResultCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
@Override
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.enums;
import lombok.Getter;
/**
* @Author: zoupx
* @Description: StatusEnum 类 数据启用状态
* @Date: 2022/5/30
*/
public enum StatusEnum {
ENABLE(1, "启用"),
DISABLE(0, "禁用");
;
@Getter
private int code;
@Getter
private String msg;
StatusEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public static StatusEnum getEnumByCode(int code){
for (StatusEnum statusEnum:StatusEnum.values()) {
if(statusEnum.getCode() == code){
return statusEnum;
}
}
return null;
}
}
package com.infynova.udi.common.enums;
import lombok.Getter;
/**
* @author he-xing
* @description
* @date 2022-06-27
*/
public enum UserTypeEnums {
COMPANY_ADMIN(0, "企业管理员"),
COMPANY_USER(1, "企业员工"),
PLATFORM_ADMIN(2, "平台管理员"),
APPLY_USER(3, "申请用户");
@Getter
private int code;
@Getter
private String msg;
UserTypeEnums(int code, String msg) {
this.code = code;
this.msg = msg;
}
public static UserTypeEnums getEnum(int code) {
for (UserTypeEnums enums : UserTypeEnums.values()) {
if (enums.getCode() == code) {
return enums;
}
}
return null;
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.exception;
import com.infynova.udi.common.api.ServiceCode;
/**
* @author zoupx
* @email
* @date 2020-03-30 17:33
* @description: WEB 异常码
*/
public enum CommonExceptionCode implements ServiceCode {
SYSTEM_500(500, "未知异常,请联系管理员"),
SYSTEM_501(500, "入参错误或入参不全"),
SYSTEM_502(502, "服务调用异常"),
SYSTEM_503(504, "服务调用超时"),
SYSTEM_400(400, "请求错误"),
SYSTEM_401(401, "token失效,请重新登录。"),
SYSTEM_403(403, "接口未授权,请联系管理员"),
SYSTEM_404(404, "路径不存在,请检查路径是否正确"),
SYSTEM_405(405, "请求方式错误"),
SYSTEM_406(406, "已存在下级组织,禁止删除"),
SYSTEM_409(409, "添加的数据已存在,禁止重复添加!"),
SYSTEM_412(412, "不满足条件,禁止添加!"),
SYSTEM_416(416, "已达到添加上限,禁止添加下一层级!"),
SYSTEM_417(417, "token为空,请重新登录!"),
SYSTEM_460(46012, "上传文件太大。"),
SYSTEM_480(48010, "数据重复。"),
SENTINEL_FLOW(429, "操作过于频繁稍后重试 [Sentinel]"),
SENTINEL_DEGRADE_FLOW(430, "服务降级,请稍后重试 [Sentinel]"),
SENTINEL_PARAM_FLOW(431, "参数访问过于频繁,请稍后重试 [Sentinel]"),
SENTINEL_SYSTEM_BLOCK(432, "系统异常,繁稍后重试 [Sentinel]"),
SENTINEL_AUTHORITY(433, "服务授权异常,稍后重试 [Sentinel]"),
JWT_TOKEN_EXPIRED(401031, "token已失效,请重新登录"),
JWT_SIGNATURE(401032, "token签名错误,请重新登录"),
JWT_ILLEGAL_ARGUMENT(401033, "token为空,请重新登录"),
JWT_PARSER_TOKEN_FAIL(401034, "token解析失败,请重新登录"),
TENANT_AUTH_NULL(701, "租户未开通此端权限"),
OPT_ERROR(702, "演示环境不可操作"),
NO_OPEN_PERMISSION(703, "该账户尚未开通任何权限"),
HTTP_REQUEST_ERROR(405011, "请求方式错误"),
;
private int code;
private String msg;
CommonExceptionCode(int code, String msg) {
this.code = code;
this.msg = msg;
}
@Override
public int getCode() {
return this.code;
}
@Override
public String getMsg() {
return this.msg;
}
public void setCode(int code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.exception;
import cn.hutool.core.util.ObjectUtil;
import com.infynova.udi.common.api.ServiceCode;
import lombok.Getter;
import lombok.Setter;
/**
* @Author: zoupx
* @Description: SaasException 类
* @Date: 2021/7/7
*/
@Getter
@Setter
public class SaasException extends RuntimeException {
private ServiceCode serviceCode;
public SaasException(ServiceCode serviceCode) {
super(serviceCode.getCode() + "," + serviceCode.getMsg());
this.serviceCode = serviceCode;
}
public SaasException(ServiceCode serviceCode, String detail) {
this(serviceCode, detail, null);
}
public SaasException(ServiceCode serviceCode, Throwable cause) {
this(serviceCode, "", cause);
}
public SaasException(ServiceCode serviceCode, String detail, Throwable cause) {
super(ObjectUtil.isEmpty(detail) ?
serviceCode.getCode() + "," + serviceCode.getMsg() :
serviceCode.getCode() + "," + serviceCode.getMsg() + ":" + detail,
cause);
this.serviceCode = new ServiceCode() {
@Override
public int getCode() {
return serviceCode.getCode();
}
@Override
public String getMsg() {
return serviceCode.getMsg() + "," + detail;
}
};
}
public SaasException(int code, String msg) {
super(code + "," + msg);
this.serviceCode = new ServiceCode() {
@Override
public int getCode() {
return code;
}
@Override
public String getMsg() {
return msg;
}
};
}
public SaasException(String msg) {
super(CommonExceptionCode.SYSTEM_400.getCode() + "," + msg);
this.serviceCode = new ServiceCode() {
@Override
public int getCode() {
return CommonExceptionCode.SYSTEM_400.getCode();
}
@Override
public String getMsg() {
return msg;
}
};
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.exception;
import cn.hutool.core.util.ObjectUtil;
import com.infynova.udi.common.api.ResponseData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author zoupx
* @email
* @date 2020-03-30 17:33
* @description: 统一异常处理
*/
@Slf4j
@RestControllerAdvice
public class SaasExceptionHandler {
/**
* 路径异常
*
* @param e
* @return
*/
@ExceptionHandler(NoHandlerFoundException.class)
public ResponseData handlerNoFoundException(Exception e, HttpServletResponse response) {
response.setStatus(CommonExceptionCode.SYSTEM_404.getCode());
return ResponseData.error(CommonExceptionCode.SYSTEM_404).detail(e);
}
/**
* 请求方式错误
*
* @param e
* @return
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ResponseData handlerHttpRequestMethodNotSupportedException(Exception e, HttpServletResponse response) {
log.error("Request error : {}", e.getMessage());
response.setStatus(CommonExceptionCode.SYSTEM_400.getCode());
return ResponseData.error(CommonExceptionCode.SYSTEM_405).detail(e);
}
/**
* 参数错误
*
* @param e
* @return
*/
@ExceptionHandler(MissingServletRequestParameterException.class)
public ResponseData handleException(MissingServletRequestParameterException e, HttpServletResponse response) {
log.error("Request params error: {}", e.getMessage(), e);
response.setStatus(CommonExceptionCode.SYSTEM_400.getCode());
return ResponseData.error(CommonExceptionCode.SYSTEM_400).detail(e);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseData handleException(MethodArgumentNotValidException e, HttpServletResponse response) {
response.setStatus(CommonExceptionCode.SYSTEM_501.getCode());
return ResponseData.error(CommonExceptionCode.SYSTEM_501.getCode(), e.getBindingResult().getFieldError().getDefaultMessage());
}
/**
* 系统异常
*
* @param e
* @return
*/
@ExceptionHandler(SaasException.class)
public ResponseData handleException(SaasException e, HttpServletResponse response) {
log.error("SaasException:{} -- {} -- {}", e.getServiceCode().getCode(), e.getServiceCode().getMsg(), e);
response.setStatus(CommonExceptionCode.SYSTEM_400.getCode());
return ResponseData.error(e.getServiceCode()).detail(e.getCause());
}
@ExceptionHandler(SaasUnauthorizedException.class)
public ResponseData handleException(SaasUnauthorizedException e, HttpServletResponse response) {
log.error("SaasUnauthorizedException:{} -- {} -- {}", e.getServiceCode().getCode(), e.getServiceCode().getMsg(), e);
response.setStatus(CommonExceptionCode.SYSTEM_403.getCode());
return ResponseData.error(e.getServiceCode());
}
@ExceptionHandler(SaasNotTokenException.class)
public ResponseData handleException(SaasNotTokenException e, HttpServletResponse response) {
log.error("SaasNotTokenException:{} -- {} -- {}", e.getServiceCode().getCode(), e.getServiceCode().getMsg(), e);
response.setStatus(CommonExceptionCode.SYSTEM_401.getCode());
return ResponseData.error(e.getServiceCode());
}
/**
* 未知异常
*
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
public ResponseData handleException(Exception e, HttpServletResponse response) {
log.error(e.getMessage(), e);
response.setStatus(CommonExceptionCode.SYSTEM_500.getCode());
Throwable cause = getFirstSignificantException(e);
if (ObjectUtil.isEmpty(cause)) {
cause = e;
}
return ResponseData.error(CommonExceptionCode.SYSTEM_500).detail(cause);
}
@ExceptionHandler(MultipartException.class)
public ResponseData handleException(MultipartException e, HttpServletResponse response) {
log.error(e.getMessage(), e);
response.setStatus(CommonExceptionCode.SYSTEM_460.getCode());
return ResponseData.error(CommonExceptionCode.SYSTEM_460).detail(e);
}
public static Throwable getFirstSignificantException(Throwable exception) {
if (ObjectUtil.isEmpty(exception)) {
return null;
}
Throwable cause = exception.getCause();
if (ObjectUtil.isEmpty(cause)) {
return null;
}
if (ObjectUtil.isNotEmpty(cause.getMessage())) {
return cause;
}
return getFirstSignificantException(cause);
}
}
\ No newline at end of file
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.exception;
import com.infynova.udi.common.api.ServiceCode;
import lombok.Getter;
import lombok.Setter;
/**
*
* @Author: zoupx
* @Description: SaasNotTokenException 类
* @Date: 2021/7/7
*/
@Getter
@Setter
public class SaasNotTokenException extends RuntimeException {
private ServiceCode serviceCode;
public SaasNotTokenException(ServiceCode serviceCode) {
this.serviceCode = serviceCode;
}
public SaasNotTokenException(int code, String msg) {
super(code + "," + msg);
this.serviceCode = new ServiceCode() {
@Override
public int getCode() {
return code;
}
@Override
public String getMsg() {
return msg;
}
};
}
public SaasNotTokenException(String msg) {
super( msg);
this.serviceCode = new ServiceCode() {
@Override
public int getCode() {
return CommonExceptionCode.SYSTEM_401.getCode();
}
@Override
public String getMsg() {
return msg;
}
};
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.exception;
import com.infynova.udi.common.api.ServiceCode;
import lombok.Getter;
import lombok.Setter;
/**
* @Author: zoupx
* @Description: SaasUnauthorizedException 类
* @Date: 2021/7/7
*/
@Getter
@Setter
public class SaasUnauthorizedException extends RuntimeException {
private ServiceCode serviceCode;
public SaasUnauthorizedException(ServiceCode serviceCode) {
this.serviceCode = serviceCode;
}
public SaasUnauthorizedException(int code, String msg) {
super(code + "," + msg);
this.serviceCode = new ServiceCode() {
@Override
public int getCode() {
return code;
}
@Override
public String getMsg() {
return msg;
}
};
}
public SaasUnauthorizedException(String msg) {
super(msg);
this.serviceCode = new ServiceCode() {
@Override
public int getCode() {
return CommonExceptionCode.SYSTEM_403.getCode();
}
@Override
public String getMsg() {
return msg;
}
};
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.jwt;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import com.infynova.udi.common.constant.ConfigValueConstant;
import com.infynova.udi.common.constant.JwtKeyConstant;
import com.infynova.udi.common.context.HeaderCode;
import com.infynova.udi.common.context.SpringContextUtils;
import com.infynova.udi.common.enums.BaseClientTypeEnum;
import com.infynova.udi.common.enums.ClientTypeEnum;
import com.infynova.udi.common.enums.UserTypeEnums;
import com.infynova.udi.common.exception.CommonExceptionCode;
import com.infynova.udi.common.exception.SaasNotTokenException;
import com.infynova.udi.common.jwt.model.AuthUserInfo;
import com.infynova.udi.common.jwt.model.JwtUserInfo;
import com.infynova.udi.common.jwt.model.TokenInfo;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
/**
* @Author: zoupx
* @Description: TokenUtil 类
* @Date: 2021/7/30
*/
@Service
@Slf4j
public class AuthUtil {
/**
* 过期时间 12h 单位:s
* 默认:12 * 60 * 60s = 43200
*/
@Value("${" + ConfigValueConstant.JWT_EXPIRE + ":43200}")
private Long expire;
@Value("${" + ConfigValueConstant.JWT_PC_EXPIRE + ":86400}")
private Long pcExpire;
/**
* 刷新token的过期时间12h 单位:s
* 默认:12 * 60 * 60s = 43200
*/
@Value("${" + ConfigValueConstant.JWT_REFRESH_EXPIRE + ":43200}")
private Long refreshExpire;
/**
* 设置解析token时,允许的误差 单位:s
* 默认:60s
*/
@Value("${" + ConfigValueConstant.JWT_ALLOWABLE_ERROR_TIME + ":60}")
private Long allowableErrorTime;
public static final String PWD_REGEX = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{8,20}$";
/**
* 创建 Token
*
* @param userInfo 用户信息
* @return token
*/
public AuthUserInfo createToken(JwtUserInfo userInfo) {
//设置jwt参数
Map<String, String> param = new HashMap<>(8);
param.put(JwtKeyConstant.USER_ID, Convert.toStr(userInfo.getIdentityId(), "0"));
param.put(JwtKeyConstant.ACCOUNT_ID, Convert.toStr(userInfo.getAccountId(), "0"));
param.put(JwtKeyConstant.DEPT_ID, Convert.toStr(userInfo.getDeptId(), "0"));
param.put(JwtKeyConstant.USERNAME, Convert.toStr(userInfo.getUserName()));
param.put(JwtKeyConstant.IDENTITY_TYPE, Convert.toStr(userInfo.getIdentityType()));
param.put(JwtKeyConstant.TENANT_ID, Convert.toStr(userInfo.getTenantId()));
//param.put(JwtKeyConstant.USER_TYPE, Convert.toStr(userInfo.getUserTypeEnums().getCode()));
param.put(JwtKeyConstant.CLIENT_CODE, Convert.toStr(userInfo.getClientCode()));
TokenInfo token = null;
if (Objects.nonNull(userInfo.getClientType()) && userInfo.getClientType().equals(ClientTypeEnum.PC)){
token = JwtUtil.generateJwt(param, pcExpire);
}else {
token = JwtUtil.generateJwt(param, expire);
}
AuthUserInfo authInfo = new AuthUserInfo();
authInfo.setIdentityId(userInfo.getIdentityId());
authInfo.setToken(token.getToken());
authInfo.setExpire(token.getExpire());
authInfo.setExpiration(DateUtil.format(token.getExpiration(), "yyyy-MM-dd HH:mm:ss"));
authInfo.setRefreshToken(createRefreshToken(userInfo).getToken());
authInfo.setAuditUser(Optional.ofNullable(userInfo.getIsAuditUser()).orElse(false));
return authInfo;
}
/**
* 创建 Refresh Token
*
* @param userInfo 用户信息
* @return Token
*/
private TokenInfo createRefreshToken(JwtUserInfo userInfo) {
Map<String, String> param = new HashMap<>(1);
param.put(JwtKeyConstant.USER_ID, Convert.toStr(userInfo.getIdentityId(), "0"));
return JwtUtil.generateJwt(param, refreshExpire);
}
/**
* 解析 Token
*
* @param token token
* @return JwtUserInfo
*/
public JwtUserInfo getAuthInfo(String token) {
if (StringUtils.isBlank(token)) {
throw new SaasNotTokenException(CommonExceptionCode.SYSTEM_417);
}
Claims claims = JwtUtil.parseJwt(token, allowableErrorTime);
Long userId = Convert.toLong(claims.get(JwtKeyConstant.USER_ID));
Long accountId = Convert.toLong(claims.get(JwtKeyConstant.ACCOUNT_ID));
Long deptId = Convert.toLong(claims.get(JwtKeyConstant.DEPT_ID));
String deptCode = Convert.toStr(claims.get(JwtKeyConstant.DEPT_CODE));
String tenantCode = Convert.toStr(claims.get(JwtKeyConstant.TENANT_CODE));
Integer dataScope = Convert.toInt(claims.get(JwtKeyConstant.DATA_SCOPE));
String username = Convert.toStr(claims.get(JwtKeyConstant.USERNAME));
Integer identityType = Convert.toInt(claims.get(JwtKeyConstant.IDENTITY_TYPE));
Long tenantId = Convert.toLong(claims.get(JwtKeyConstant.TENANT_ID));
Integer userType = Convert.toInt(claims.get(JwtKeyConstant.USER_TYPE));
String clientCode = Convert.toStr(claims.get(JwtKeyConstant.CLIENT_CODE));
JwtUserInfo jwtUserInfo = new JwtUserInfo();
jwtUserInfo.setAccountId(accountId);
jwtUserInfo.setIdentityType(identityType);
jwtUserInfo.setIdentityId(userId);
jwtUserInfo.setDeptCode(deptCode);
jwtUserInfo.setDeptId(deptId);
jwtUserInfo.setDataScope(dataScope);
jwtUserInfo.setTenantCode(tenantCode);
jwtUserInfo.setUserName(username);
jwtUserInfo.setUserType(userType);
jwtUserInfo.setTenantId(tenantId);
jwtUserInfo.setClientCode(clientCode);
return jwtUserInfo;
}
/**
* 解析刷新 Refresh Token
*
* @param token
* @return JwtUserInfo
*/
public JwtUserInfo parseRefreshToken(String token) {
Claims claims = JwtUtil.parseJwt(token, allowableErrorTime);
Long userId = Convert.toLong(claims.get(JwtKeyConstant.USER_ID));
JwtUserInfo jwtUserInfo = new JwtUserInfo();
jwtUserInfo.setIdentityId(userId);
return jwtUserInfo;
}
/**
* 获取当前用户相关信息
*
* @return 用户实体
*/
public JwtUserInfo getAuthInfo() {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (Objects.nonNull(requestAttributes)) {
Object userInfo = requestAttributes.getAttribute("JwtUserInfo", RequestAttributes.SCOPE_REQUEST);
if (Objects.nonNull(userInfo)) {
return (JwtUserInfo) userInfo;
}
}
HttpServletRequest httpServletRequest = SpringContextUtils.getHttpServletRequest();
JwtUserInfo userInfo = getAuthInfo(httpServletRequest.getHeader(HeaderCode.TOKEN));
if (Objects.nonNull(userInfo)) {
requestAttributes.setAttribute("JwtUserInfo", userInfo, RequestAttributes.SCOPE_REQUEST);
}
return userInfo;
}
/**
* 是否是平台超管用户
*
* @return true 是 ,false:否
*/
public boolean isPlatformAdmin() {
return UserTypeEnums.PLATFORM_ADMIN.equals(getType());
}
/**
* 是否是企业管理员
*
* @return true 是 ,false:否
*/
public boolean isCompanyAdmin() {
return UserTypeEnums.COMPANY_ADMIN.equals(getType());
}
/**
* 获取用户类型
*
* @return
*/
public UserTypeEnums getType() {
HttpServletRequest httpServletRequest = SpringContextUtils.getHttpServletRequest();
JwtUserInfo authInfo = getAuthInfo(httpServletRequest.getHeader(HeaderCode.TOKEN));
return getType(authInfo);
}
/**
* 获取用户类型
*
* @return
*/
public UserTypeEnums getType(JwtUserInfo authInfo) {
return authInfo.getUserTypeEnums();
}
/**
* 获取客户端类型 - 菜单展示类型
*
* @param client
* @return
*/
public BaseClientTypeEnum getClientType(String client) {
if (StringUtils.isNotBlank(client) && (ClientTypeEnum.isMobile(client.toLowerCase()))) {
return BaseClientTypeEnum.MOBILE;
} else if (ClientTypeEnum.isPda(client.toLowerCase())) {
return BaseClientTypeEnum.PDA;
} else if (ClientTypeEnum.isDb(client.toLowerCase())) {
return BaseClientTypeEnum.CONSOLE;
} else {
return BaseClientTypeEnum.PC;
}
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.jwt;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.infynova.udi.common.exception.CommonExceptionCode;
import com.infynova.udi.common.exception.SaasNotTokenException;
import com.infynova.udi.common.jwt.model.TokenInfo;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: zoupx
* @Description: JwtUtil 类
* @Date: 2021/7/30
*/
@Slf4j
public class JwtUtil {
private static final String BASE64_SECURITY_KEY = Base64.getEncoder().encodeToString("libra-key".getBytes(StandardCharsets.UTF_8));
/**
* 创建令牌
*
* @param user user
* @param expire 过期时间(秒)
* @return jwt
*/
public static TokenInfo generateJwt(Map<String, String> user, long expire) {
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
// 当前时间
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//添加Token过期时间
long expMillis = nowMillis + expire * 1000;
Date exp = new Date(expMillis);
//生成签名密钥
byte[] apiKeySecretBytes = Base64.getDecoder().decode(BASE64_SECURITY_KEY);
Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
//添加构成JWT的类
JwtBuilder builder = Jwts.builder().signWith(signatureAlgorithm, signingKey);
//设置JWT参数
user.forEach(builder::claim);
String token = builder
// 发布时间
.setIssuedAt(now)
// token从时间什么开始生效
.setNotBefore(now)
// token从什么时间截止生效
.setExpiration(exp)
// 执行
.compact();
// 组装Token信息
TokenInfo tokenInfo = new TokenInfo();
tokenInfo.setToken(token);
tokenInfo.setExpire(expire);
tokenInfo.setExpiration(LocalDateTimeUtil.of(exp));
return tokenInfo;
}
public static void main(String[] args) {
Map<String, String> user = new HashMap<>();
user.put("accountId","1559821662818672642");
user.put("identityType",null);
user.put("deptId","0");
user.put("tenantId","1559821662793506818");
user.put("userType","0");
user.put("userId","1559821662827061249");
user.put("username","15995200590");
TokenInfo tokenInfo = generateJwt(user, 1);
Claims claims = parseJwt(tokenInfo.getToken(), 1L);
System.out.println(claims);
}
/**
* 解析jwt
*
* @param jsonWebToken 待解析token
* @param allowedClockSkewSeconds 允许的时间差
* @return Claims
*/
public static Claims parseJwt(String jsonWebToken, long allowedClockSkewSeconds) {
try {
return Jwts.parser().setSigningKey(Base64.getDecoder().decode(BASE64_SECURITY_KEY)).setAllowedClockSkewSeconds(allowedClockSkewSeconds).parseClaimsJws(jsonWebToken).getBody();
} catch (ExpiredJwtException ex) {
log.error("token=[{}], 过期", jsonWebToken, ex);
//过期
throw new SaasNotTokenException(CommonExceptionCode.SYSTEM_401);
} catch (IllegalArgumentException ex) {
log.error("token=[{}] 为空", jsonWebToken, ex);
//token 为空
throw new SaasNotTokenException(CommonExceptionCode.SYSTEM_417);
} catch (Exception e) {
log.error("token=[{}] errCode:{}, message:{}", jsonWebToken, CommonExceptionCode.JWT_PARSER_TOKEN_FAIL, e.getMessage(), e);
throw new SaasNotTokenException(CommonExceptionCode.JWT_PARSER_TOKEN_FAIL);
}
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.jwt.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Author: zoupx
* @Description: 认证成功返回用户相关信息
* @Date: 2021/7/29
*/
@Data
@NoArgsConstructor
public class AuthUserInfo implements Serializable {
private static final long serialVersionUID = -1L;
// 对应登录身份的id
@ApiModelProperty(value = "用户iD")
private Long identityId;
// 令牌
@ApiModelProperty(value = "token")
private String token;
// 刷新令牌
@ApiModelProperty(value = "刷新令牌")
private String refreshToken;
// 过期时间(秒)
@ApiModelProperty(value = "过期时间(秒)")
private Long expire;
// 到期时间
@ApiModelProperty(value = "到期时间")
private String expiration;
@ApiModelProperty(value = "是否是审核用户, false:否, true:是")
private boolean isAuditUser;
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.jwt.model;
import com.infynova.udi.common.enums.ClientTypeEnum;
import com.infynova.udi.common.enums.UserTypeEnums;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @Author: zoupx
* @Description: jwt需要放对应的数据
* @Date: 2021/7/29
*/
@Data
@NoArgsConstructor
public class JwtUserInfo implements Serializable {
private static final long serialVersionUID = -1L;
/**
* 全局用户id
*/
private Long identityId;
/**
* 租户id
*/
private Long tenantId;
/**
* 部门id
*/
private Long deptId;
/**
* 用户名称
*/
private String userName;
/**
* 角色id
*/
private Long role;
/**
* 是否是审核用户
*/
private Boolean isAuditUser;
/**
* 用户类型 0企业管理员 1 企业用户 2 平台管理员
*/
private UserTypeEnums userTypeEnums;
private Integer userType;
public UserTypeEnums getUserTypeEnums() {
if (userType != null) {
return UserTypeEnums.getEnum(userType);
}
return userTypeEnums;
}
private Long accountId;
private String tenantCode;
private String deptCode;
private Integer dataScope;
private Integer identityType;
private ClientTypeEnum clientType;
private String clientCode;
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.jwt.model;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @Author: zoupx
* @Description: JwtUtil工具生成token返回实体
* @Date: 2021/7/29
*/
@Data
@NoArgsConstructor
public class TokenInfo implements Serializable {
private static final long serialVersionUID = -1L;
/**
* token
*/
private String token;
/**
* 有效时间:单位:秒
*/
private Long expire;
/**
* 到期时间
*/
private LocalDateTime expiration;
}
package com.infynova.udi.common.utils;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class ApiUtil {
/**
* 按参数名升续拼接参数
*/
public static String concatSignString(HttpServletRequest request) {
Map<String, String> paramMap = new HashMap<>();
request.getParameterMap().forEach((key, value) -> paramMap.put(key, value[0]));
// 按照key升续排序,然后拼接参数
Set<String> keySet = paramMap.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
// 或略掉的字段
if (k.equals("sign")) {
continue;
}
if (paramMap.get(k).trim().length() > 0) {
// 参数值为空,则不参与签名
sb.append(k).append("=").append(paramMap.get(k).trim()).append("&");
}
}
return sb.toString();
}
public static String concatSignString(Map<String, String> map) {
Map<String, String> paramMap = new HashMap<>();
map.forEach((key, value) -> paramMap.put(key, value));
// 按照key升续排序,然后拼接参数
Set<String> keySet = paramMap.keySet();
String[] keyArray = keySet.toArray(new String[keySet.size()]);
Arrays.sort(keyArray);
StringBuilder sb = new StringBuilder();
for (String k : keyArray) {
if (paramMap.get(k).trim().length() > 0) {
// 参数值为空,则不参与签名
sb.append(k).append("=").append(paramMap.get(k).trim()).append("&");
}
}
return sb.toString();
}
}
package com.infynova.udi.common.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
/**
* 随机产生唯一的app_key和app_secret
*/
public class AppUtils {
private final static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
"t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z"};
/**
* @Description: <p>
* 短8位UUID思想其实借鉴微博短域名的生成方式,但是其重复概率过高,而且每次生成4个,需要随即选取一个。
* 本算法利用62个可打印字符,通过随机生成32位UUID,由于UUID都为十六进制,
* 所以将UUID分成8组,每4个为一组,然后通过模62操作,结果作为索引取出字符,
* 这样重复率大大降低。
* 经测试,在生成一千万个数据也没有出现重复,完全满足大部分需求。
* </p>
*/
public static String getAppId() {
StringBuffer shortBuffer = new StringBuffer();
String uuid = UUID.randomUUID().toString().replace("-", "");
for (int i = 0; i < 8; i++) {
String str = uuid.substring(i * 4, i * 4 + 4);
int x = Integer.parseInt(str, 16);
shortBuffer.append(chars[x % 0x3E]);
}
return shortBuffer.toString();
}
/**
* 算法: sha1(appid+uuid) 生成AppSecret
*/
public static String getAppSecret(String appId) {
try {
StringBuffer sb = new StringBuffer();
String uuid = UUID.randomUUID().toString();
sb.append(appId).append(uuid);
String str = sb.toString();
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return appId;
}
public static void main(String[] args) {
String appId = getAppId();
String appSecret = getAppSecret(appId);
System.out.println("appId: "+appId);
System.out.println("appSecret: "+appSecret);
}
}
\ No newline at end of file
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.utils;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.infynova.udi.common.api.ServiceCode;
import com.infynova.udi.common.exception.SaasException;
import java.util.Collection;
import java.util.Objects;
/**
* @author zoupx
* @email
* @date 2021/9/25 12:41 上午
* @description: Util class for checking arguments.
*/
public class AssertUtil {
private AssertUtil(){}
public static void notBlank(String string, ServiceCode serviceCode) {
if (StrUtil.isEmpty(string)) {
throw new SaasException(serviceCode);
}
}
public static void notEmpty(Collection<?> collection, ServiceCode serviceCode) {
if (CollectionUtil.isEmpty(collection)) {
throw new SaasException(serviceCode);
}
}
public static void notNull(Object object, ServiceCode serviceCode) {
if (Objects.isNull(object)) {
throw new SaasException(serviceCode);
}
}
public static void isTrue(boolean value, ServiceCode serviceCode) {
if (!value) {
throw new SaasException(serviceCode);
}
}
}
package com.infynova.udi.common.utils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import java.util.Objects;
/**
* @Description
* @author zoupx
* @Date 2021-02-22
*/
public class ClientIp {
public static String getIp(ServerHttpRequest request) {
HttpHeaders headers = request.getHeaders();
String ip = headers.getFirst("x-forwarded-for");
if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
// 多次反向代理后会有多个ip值,第一个ip才是真实ip
if (ip.contains(",")) {
ip = ip.split(",")[0];
}
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = headers.getFirst("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = Objects.requireNonNull(request.getRemoteAddress()).getAddress().getHostAddress();
}
return ip;
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.utils;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.StringUtils;
/**
* @Author: zoupx
* @Description: DeptCodeUtil 类
* @Date: 2021/7/7
*/
public class DeptCodeUtil {
// 数字位数(默认生成3位的数字)
private static final int numLength = 3;
/**
* 根据前一个code,获取同级下一个code
* 例如:当前最大code为D001A001,下一个code为:D001A002
*
* @param code
* @return
*/
public static synchronized String genCode(String code) {
String newcode = "";
if (StrUtil.isBlank(code)) {
String zimu = "A";
String num = getStrNum(1);
newcode = zimu + num;
} else {
code = StringUtils.leftPad(code, numLength + 1, "0");
String before_code = code.substring(0, code.length() - 1- numLength);
String after_code = code.substring(code.length() - 1 - numLength);
char after_code_zimu = after_code.substring(0, 1).charAt(0);
int after_code_num = Integer.parseInt(after_code.substring(1));
String nextNum = "";
char nextZimu = 'A';
// 先判断数字等于999*,则计数从1重新开始,递增
if (after_code_num == getMaxNumByLength(numLength)) {
nextNum = getNextStrNum(0);
} else {
nextNum = getNextStrNum(after_code_num);
}
// 先判断数字等于999*,则字母从A重新开始,递增
if(after_code_num == getMaxNumByLength(numLength)) {
nextZimu = getNextZiMu(after_code_zimu);
}else{
nextZimu = after_code_zimu;
}
// 例如Z99,下一个code就是Z99A01
if ('Z' == after_code_zimu && getMaxNumByLength(numLength) == after_code_num) {
newcode = code + (nextZimu + nextNum);
} else {
newcode = before_code + (nextZimu + nextNum);
}
}
return newcode;
}
/**
* 根据父亲code,获取下级的下一个code
*
* 例如:父亲CODE:A001
* 当前CODE:A001B001
* 获取的code:A001B002
*
* @param parentCode 上级code
* @param localCode 同级code
* @return
*/
public static synchronized String genSubCode(String parentCode,String localCode) {
if(StrUtil.isNotBlank(localCode)){
return genCode(localCode);
}else{
parentCode = parentCode + "A"+ getNextStrNum(0);
}
return parentCode;
}
/**
* 将数字前面位数补零
*
* @param num
* @return
*/
private static String getNextStrNum(int num) {
return getStrNum(getNextNum(num));
}
/**
* 将数字前面位数补零
*
* @param num
* @return
*/
private static String getStrNum(int num) {
return String.format("%0" + numLength + "d", num);
}
/**
* 递增获取下个数字
*
* @param num
* @return
*/
private static int getNextNum(int num) {
num++;
return num;
}
/**
* 递增获取下个字母
*
* @param zimu
* @return
*/
private static char getNextZiMu(char zimu) {
if (zimu == 'Z') {
return 'A';
}
zimu++;
return zimu;
}
/**
* 根据数字位数获取最大值
* @param length
* @return
*/
private static int getMaxNumByLength(int length){
if(length==0){
return 0;
}
StringBuilder max_num = new StringBuilder();
for (int i=0;i<length;i++){
max_num.append("9");
}
return Integer.parseInt(max_num.toString());
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.EnumUtils;
import java.lang.reflect.Method;
import java.util.List;
/**
* @author zoupx
* @email
* @date 2021/8/8 3:20 下午
* @description:
*/
@Slf4j
public class EnumUtil {
/**
* 判断某个枚举是否包某个code值
* @param enumClass 枚举
* @param code code
* @return 存在返回true,否则返回false
*/
public static boolean isInclude(Class enumClass, int code){
List enumList = EnumUtils.getEnumList(enumClass);
for (int i = 0;i<enumList.size(); i++){
Object en = enumList.get(i);
Class<?> enClass = en.getClass();
try {
Method method = enClass.getMethod("getCode"); // 需要与枚举类方法对应
Object invoke = method.invoke(en, null);
if(Integer.parseInt(invoke.toString()) == code) {
return true;
}
}catch (Exception e){
e.printStackTrace();
log.error("枚举执行getCode方法失败..." , e);
}
}
return false;
}
}
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.utils;
import com.infynova.udi.common.api.ResponseData;
import com.infynova.udi.common.exception.CommonExceptionCode;
import com.infynova.udi.common.exception.SaasException;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
/**
* @Author: zoupx
* @Description: 远程调用返回处理
* @Date: 2021/7/30
*/
@Slf4j
public class FeignResponseUtil {
/**
* 如果返回异常则此处默认处理返回为空
* @param responseData
* @param <T>
* @return
*/
public static <T> T get(ResponseData<T> responseData) {
if(Objects.isNull(responseData)){
return null;
}
if (responseData.isSuccess()) {
return responseData.getData();
}
log.error("FeignResponse error, info:{}", responseData.getData());
return null;
}
/**
* 如果返回为异常则抛出具体异常
* @param responseData
* @param <T>
* @return
*/
public static <T> T getThrow(ResponseData<T> responseData) {
if(Objects.isNull(responseData)){
throw new SaasException(CommonExceptionCode.SYSTEM_502);
}
if (responseData.isSuccess()) {
return responseData.getData();
}else {
throw new SaasException(responseData.getCode(), responseData.getMsg());
}
}
}
package com.infynova.udi.common.utils;
import java.security.MessageDigest;
/**
* MD5工具类
*/
public class MD5Util {
/**
* 全局数组
*/
private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
/**
* 将字节数组转换成为16进制的字符串
*/
private static String byteArrayToHexString(byte b[]) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++)
resultSb.append(byteToHexString(b[i]));
return resultSb.toString();
}
/**
* 返回形式为数字和字符串
*/
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n += 256;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
/**
* 获取MD5的值
*/
public static String getMD5(String origin) {
return encode(origin, "UTF-8");
}
public static String encode(String origin, String charsetname) {
String resultString = null;
try {
resultString = new String(origin);
MessageDigest md = MessageDigest.getInstance("MD5");
if (charsetname == null || "".equals(charsetname))
resultString = byteArrayToHexString(md.digest(resultString
.getBytes()));
else
resultString = byteArrayToHexString(md.digest(resultString
.getBytes(charsetname)));
} catch (Exception exception) {
}
return resultString;
}
public static void main(String[] args) {
Long l = System.currentTimeMillis();
System.out.println(l);
String signString = l.toString() + "j6ZACIDd" + "9aae7756510d70fd7e420f5391950f01b7a744ed";
String signature = MD5Util.getMD5(signString);
System.out.println(signature);
// token + timestamp + nonce
// String data= "12345678954556"+"8882872e-cc12-4e51-8f6a-591bbf423feb" + "1658909039296" +"112";
// String datas = MD5Util.getMD5(data);
// System.out.println(datas);
}
}
\ No newline at end of file
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.common.utils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
* @author zoupx
* @email
* @date 2021/8/5
* @description: V1 redis 操作工具,后续需优化V2:1、加锁解决缓存击穿,2、缓存空值解决缓存穿透
*/
@Slf4j
@Component
public class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// start ***************************公共操作*******************************
/**
* [公共]指定缓存失效时间
*
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [公共]根据key 获取过期时间
*
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* [公共]判断key是否存在
*
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
log.error("redis -- hasKey,key:"+key,e);
return false;
}
}
/**
* [公共]删除缓存
*
* @param key 可以传一个值 或多个
*/
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(Arrays.asList(key));
}
}
}
// end ***************************公共操作*******************************
// start ***************************String***************************
/**
* [String]获取
*
* @param key 键
* @return 值
*/
public Object strGet(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
public Boolean lock(String key,Long second){
Boolean aBoolean = null;
try {
aBoolean = redisTemplate.opsForValue().setIfAbsent(key, "1", Duration.ofSeconds(second));
} catch (Exception e) {
log.error("redis -- lock,key:"+key,e);
}
return aBoolean;
}
public Boolean lock(String key,Integer value, Long second){
Boolean aBoolean = null;
try {
aBoolean = redisTemplate.opsForValue().setIfAbsent(key, value, Duration.ofSeconds(second));
} catch (Exception e) {
log.error("redis -- lock,key:"+key,e);
}
return aBoolean;
}
// public Boolean lock(String key,Integer value, Long second){
// return redisTemplate.opsForValue().setIfAbsent(key, value, Duration.ofSeconds(second));
// }
/**
* [String]添加
*
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean strSet(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [String]普通缓存放入并设置时间(如果不存在时)
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean strSetIfAbsent(String key, Object value, long time) {
try {
if (time > 0) {
return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS));
} else {
return strSetIfAbsent(key, value);
}
} catch (Exception e) {
log.error("redis error, key:{}", key, e);
return false;
}
}
/**
* [String]普通缓存放入并设置时间(如果不存在时)
*
* @param key 键
* @param value 值
* @return true成功 false 失败
*/
public boolean strSetIfAbsent(String key, Object value) {
try {
return Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(key, value));
} catch (Exception e) {
log.error("redis error, key:{}", key, e);
return false;
}
}
/**
* [String]普通缓存放入并设置时间
*
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean strSet(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
strSet(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [String]递增
*
* @param key 键
* @param delta 要增加几(大于0)
* @return
*/
public long strIncr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
Long increment = null;
try {
increment = redisTemplate.opsForValue().increment(key, delta);
} catch (Exception e) {
log.error("redis -- strIncr,key:"+key+",deta:"+delta,e);
}
return increment;
}
/**
* [String]递减
*
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public long strDecr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// end ***************************String***************************
// start ***************************Map***************************
/**
* [Map] 向一张hash表中放入数据,如果key则会自动创建key
*
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean mapSet(String key, String item, Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [Map] 向一张hash表中放入数据,如果key则会自动创建key
*
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean mapSet(String key, String item, Object value, long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [Map]获取map所以key值
*
* @param key 键
* @return 对应的多个键值
*/
public Map<Object, Object> mapGet(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* [Map]获取map对应key值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public Object mapGet(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* [Map] 添加HashSet
*
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean mapSetMap(String key, Map<String, Object> map) {
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [Map] 添加HashSet 并设置时间
*
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean mapSet(String key, Map<String, Object> map, long time) {
try {
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [Map]删除hash表中的值
*
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void mapDel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
}
/**
* [Map]判断hash表中是否有该项的值
*
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean mapHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* [Map] 不存在key会自动创建,并递增
*
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public double mapIncr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* [Map] 递减
*
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public double mapDecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
}
// end ***************************Map***************************
// start ***************************set***************************
/**
* [Set]根据key获取Set中的所有值
*
* @param key 键
* @return
*/
public Set<Object> setGet(String key) {
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* [Set]根据value从一个set中查询,是否存在
*
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public boolean setHasKey(String key, Object value) {
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [Set]将数据放入set缓存
*
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long setSet(String key, Object... values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* [Set]将set数据放入缓存
*
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long setSet(String key, long time, Object... values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if (time > 0) {
expire(key, time);
}
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* [Set]获取set缓存的长度
*
* @param key 键
* @return
*/
public long setGetSetSize(String key) {
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* [Set]移除值为value的
*
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object... values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// end ***************************set***************************
// start ***************************list***************************
/**
* [List]将list放入缓存
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean listSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [List]将list放入缓存
*
* @param key 键
* @param value 值
* @return
*/
public boolean listSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [List]将list放入缓存,并设置过期时间
*
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean listSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) {
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [List]获取list
*
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List<Object> listGet(String key, long start, long end) {
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* [List]获取list长度
*
* @param key 键
* @return
*/
public long listGetListSize(String key) {
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* [List]通过索引获取list中的值
*
* @param key 键
* @param index 索引 index>=0时,0->第一个元素,1->第二个元素,依次类推;index<0时,-1->倒数第一个元素,-2->倒数第二个元素,依次类推
* @return
*/
public Object listGetIndex(String key, long index) {
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* [List]将list放入缓存
*
* @param key 键
* @param value 值
* @return
*/
public boolean listSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* [List]根据索引修改list中的某条数据
*
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean listUpdateIndex(String key, long index, Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public void listSetMembers(String key, List values) {
//开启管道
redisTemplate.executePipelined((RedisCallback<List<Object>>) connection -> {
for (Object value: values) {
//添加执行命令
connection.lPush(key.getBytes(), JSON.toJSONBytes(value));
}
return null;
});
}
/**
* 将list从左边放入缓存
*
* @param key 键
* @param value 值
*/
public void listLeftPushAll(String key, List value) {
try {
redisTemplate.opsForList().leftPushAll(key, value);
} catch (Exception e) {
e.printStackTrace();
}
}
public void listLeftPush(String key, Object value) {
try {
redisTemplate.opsForList().leftPush(key, value);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 从list右边弹出一条数据
*
* @param key 键
* @return 队列中的值
*/
public Object listRightPop(String key) {
ListOperations<String, Object> listOperations = redisTemplate.opsForList();
return listOperations.rightPop(key);
}
/**
* [list]移除n个值为value
*
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long listRemove(String key, long count, Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
// end ***************************list***************************
// start ***************************批量操作key***************************
/**
* [数据量多时候,不推荐使用]查询指定前缀的key
* 生产环境上是不允许使用的,很多云redis都会屏蔽此操作,因为会影响redis性能,导致其它操作无法使用
*
* @param keyPrefix key前缀
* @return
*/
private Set<String> keys(String keyPrefix) {
String realKey = keyPrefix + "*";
try {
return redisTemplate.execute((RedisCallback<Set<String>>) connection -> {
Set<String> binaryKeys = new HashSet<>();
Cursor<byte[]> cursor = connection.scan(new ScanOptions.ScanOptionsBuilder().match(realKey).count(Integer.MAX_VALUE).build());
while (cursor.hasNext()) {
binaryKeys.add(new String(cursor.next()));
}
return binaryKeys;
});
} catch (Throwable e) {
e.printStackTrace();
}
return null;
}
/**
* [数据量多时候,不推荐使用]删除指定前缀的一系列key
* 生产环境上是不允许使用的,很多云redis都会屏蔽此操作,因为会影响redis性能,导致其它操作无法使用
*
* @param keyPrefix key前缀
*/
public void removeAll(String keyPrefix) {
try {
Set<String> keys = keys(keyPrefix);
redisTemplate.delete(keys);
} catch (Throwable e) {
e.printStackTrace();
}
}
// end ***************************批量操作key***************************
/**
* IP限制暴力访问方法
* @param ip 请求IP
* @param uri 请求接口地址
* @param limitTimes 访问次数最大限制
* @param ipLockTime 封锁IP时间,单位秒
* @param scopeTime 判断的时间范围 单位秒 如限制 60秒5次 此参数为60
* @param keyLockPrefix 封锁IP的KEY前缀
* @param keyUriPrefix URI的KEY前缀
* @return 是否超出限制
*/
public Boolean ipReqFilter(String ip, String uri,Long limitTimes,Long ipLockTime,
Long scopeTime,String keyLockPrefix,String keyUriPrefix){
if (hasKey(keyLockPrefix+ip)){
return true;
}
String key = keyUriPrefix + ip + uri;
if (hasKey(key)){
// 如果key存在,次数+1
long time = strIncr(key, (long) 1);
if (time >= limitTimes) {
// 如果超过限制次数,则设置ip被禁用
lock(keyLockPrefix + ip, ipLockTime);
return true;
}
}else {
// ip+uri请求次数为1
lock(key, 1, scopeTime);
}
return false;
}
}
\ No newline at end of file
......@@ -31,7 +31,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
* @description:
*/
@SuppressWarnings("all")
@Configuration
//@Configuration
public class RedisConfig {
@Bean
public RedisSerializer<String> redisKeySerializer() {
......
......@@ -7,18 +7,12 @@ package com.infynova.udi.config.mybatis;
*/
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.infynova.common.core.context.SpringContextUtils;
import com.infynova.udi.common.context.SpringContextUtils;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@Component
public class CustomTenantHandler implements TenantLineHandler {
......@@ -41,6 +35,9 @@ public class CustomTenantHandler implements TenantLineHandler {
if(StringUtils.equals("product",tableName)){
return true;
}
if(StringUtils.equals("udi_user",tableName)){
return true;
}
return false;
}
......
......@@ -16,10 +16,9 @@
package com.infynova.udi.config.mybatis;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.infynova.common.core.context.HeaderCode;
import com.infynova.common.core.context.SpringContextUtils;
import com.infynova.udi.common.context.HeaderCode;
import com.infynova.udi.common.context.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
......
......@@ -41,16 +41,16 @@ public class MybatisPlusConfig {
return interceptor;
}
@Bean
public ISqlInjector sqlInjector() {
return new DefaultSqlInjector() {
@Override
public List<AbstractMethod> getMethodList(org.apache.ibatis.session.Configuration configuration, Class<?> mapperClass, TableInfo tableInfo) {
List<AbstractMethod> methodList = super.getMethodList(configuration,mapperClass,tableInfo);
methodList.add(new InsertBatchSomeColumn());
methodList.add(new AlwaysUpdateSomeColumnById());
return methodList;
}
};
}
// @Bean
// public ISqlInjector sqlInjector() {
// return new DefaultSqlInjector() {
// @Override
// public List<AbstractMethod> getMethodList(org.apache.ibatis.session.Configuration configuration, Class<?> mapperClass, TableInfo tableInfo) {
// List<AbstractMethod> methodList = super.getMethodList(configuration,mapperClass,tableInfo);
// methodList.add(new InsertBatchSomeColumn());
// methodList.add(new AlwaysUpdateSomeColumnById());
// return methodList;
// }
// };
// }
}
......@@ -2,7 +2,7 @@ package com.infynova.udi.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.common.core.api.ResponseData;
import com.infynova.udi.common.api.ResponseData;
import com.infynova.udi.enums.match.MatchStatusEnum;
import com.infynova.udi.enums.match.MatchUpdateStatusEnum;
import com.infynova.udi.enums.task.TaskMatchStatusEnum;
......
......@@ -4,9 +4,7 @@ import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.common.core.api.ResponseData;
import com.infynova.common.core.context.HeaderCode;
import com.infynova.common.core.context.SpringContextUtils;
import com.infynova.udi.common.api.ResponseData;
import com.infynova.udi.dto.UdiListQry;
import com.infynova.udi.service.helper.UdiEasyExcelHelper;
import com.infynova.udi.service.UdiService;
......
......@@ -3,7 +3,7 @@ package com.infynova.udi.controller;
import com.alibaba.fastjson.JSON;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.common.core.api.ResponseData;
import com.infynova.udi.common.api.ResponseData;
import com.infynova.udi.dto.*;
import com.infynova.udi.service.helper.MatchHelper;
import com.infynova.udi.service.helper.TaskHelper;
......
......@@ -4,8 +4,8 @@ import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.common.core.api.ResponseData;
import com.infynova.common.core.context.SpringContextUtils;
import com.infynova.udi.common.api.ResponseData;
import com.infynova.udi.common.context.SpringContextUtils;
import com.infynova.udi.dto.*;
import com.infynova.udi.entity.MatchData;
import com.infynova.udi.entity.MatchTemp;
......
......@@ -4,8 +4,8 @@ import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.common.core.api.ResponseData;
import com.infynova.common.core.context.SpringContextUtils;
import com.infynova.udi.common.api.ResponseData;
import com.infynova.udi.common.context.SpringContextUtils;
import com.infynova.udi.dto.*;
import com.infynova.udi.service.helper.UdiEasyExcelHelper;
import com.infynova.udi.service.TaskImportService;
......
package com.infynova.udi.controller;
import cn.hutool.core.util.ObjectUtil;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.infynova.udi.common.api.ResponseData;
import com.infynova.udi.common.constant.AuthRedisKeyConstant;
import com.infynova.udi.common.constant.SpecialCharacterPool;
import com.infynova.udi.common.context.SpringContextUtils;
import com.infynova.udi.common.exception.CommonExceptionCode;
import com.infynova.udi.common.jwt.AuthUtil;
import com.infynova.udi.common.jwt.model.AuthUserInfo;
import com.infynova.udi.common.jwt.model.JwtUserInfo;
import com.infynova.udi.common.utils.RedisUtil;
import com.infynova.udi.entity.LoginParams;
import com.infynova.udi.entity.UdiUser;
import com.infynova.udi.service.UdiUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@Api(tags = "对码平台-公共接口")
@ApiSupport(order = 10)
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private AuthUtil authUtil;
@Autowired
private RedisUtil redisUtil;
@Autowired
private UdiUserService udiUserService;
@PostMapping("/token")
@ApiOperation(value = "登录接口", notes = "登录接口支持用户名密码和手机号登录")
public ResponseData<AuthUserInfo> login(@RequestBody LoginParams loginParams) {
UdiUser user = udiUserService.lambdaQuery().eq(UdiUser::getUsername, loginParams.getUsername()).one();
if (user == null) {
return ResponseData.error(CommonExceptionCode.SYSTEM_401);
}
if(!ObjectUtil.equals(loginParams.getPassword(), user.getPassword())){
return ResponseData.error(CommonExceptionCode.SYSTEM_401.getCode(),"密码错误");
}
return ResponseData.ok(createToken(user));
}
/**
* @return AuthUserInfo
* @description 根据账号信息、身份信息创建token
* @author zoupx
* @date 2021/9/30
*/
protected AuthUserInfo createToken(UdiUser user) {
// 5、生成token
JwtUserInfo jwtUserInfo = new JwtUserInfo();
jwtUserInfo.setIdentityId(user.getId());
jwtUserInfo.setDeptCode("");
jwtUserInfo.setDeptId(0L);
jwtUserInfo.setDataScope(1);
jwtUserInfo.setTenantCode("code");
jwtUserInfo.setAccountId(0L);
jwtUserInfo.setUserName(user.getUsername());
jwtUserInfo.setTenantId(user.getTenantId());
AuthUserInfo authUserInfo = authUtil.createToken(jwtUserInfo);
// key + client + identityId
Long EXPIRE = 3600L;
redisUtil.strSet(AuthRedisKeyConstant.USER_INFO_KEY + SpringContextUtils.getClientCode() + SpecialCharacterPool.DOUBLE_COLON + user.getId(), user, EXPIRE);
return authUserInfo;
}
}
package com.infynova.udi.dto;
import com.infynova.common.core.entity.PageVo;
import com.infynova.udi.common.entity.PageVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......
package com.infynova.udi.dto;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.common.api.BaseVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......
package com.infynova.udi.dto;
import com.infynova.common.core.entity.PageVo;
import com.infynova.udi.common.entity.PageVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......
package com.infynova.udi.dto;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.common.api.BaseVo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
......
package com.infynova.udi.dto;
import com.infynova.common.core.entity.UploadResultVo;
import com.infynova.udi.common.entity.UploadResultVo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
......
package com.infynova.udi.dto;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.common.api.BaseVo;
import com.infynova.udi.exception.validator.FixedValueValidator;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......
package com.infynova.udi.dto;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.common.api.BaseVo;
import com.infynova.udi.exception.validator.FixedValueValidator;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......
package com.infynova.udi.dto;
import com.infynova.common.core.entity.PageVo;
import com.infynova.udi.common.entity.PageVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......
package com.infynova.udi.dto;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.common.api.BaseVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......
package com.infynova.udi.dto;
import com.infynova.common.core.entity.PageVo;
import com.infynova.udi.common.entity.PageVo;
import com.infynova.udi.enums.match.MatchStatusEnum;
import com.infynova.udi.enums.match.MatchUpdateStatusEnum;
import com.infynova.udi.exception.validator.FixedValueValidator;
......
package com.infynova.udi.dto;
import com.infynova.common.core.entity.PageVo;
import com.infynova.udi.common.entity.PageVo;
import com.infynova.udi.exception.validator.FixedValueValidator;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......
package com.infynova.udi.dto.file;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* @author he-xing
* @description
* @date 2022-06-11
*/
@Data
@ApiModel(value = "FileGetUrlById")
public class FileGetUrlByIdReqVo implements Serializable {
@NotNull(message = "id不能为空,")
@ApiModelProperty(value = "文件id")
private Long id;
}
package com.infynova.udi.dto.file;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* @author he-xing
* @description
* @date 2022-06-21
*/
@Data
@ApiModel(value = "OSSBatchIdReqVo")
public class OSSBatchIdReqVo implements Serializable {
@ApiModelProperty(value = "id")
@NotNull(message = "id 不能为空。")
private List<Long> ids;
}
package com.infynova.udi.dto.file;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "StoragePolicyVo")
public class StoragePolicyVo implements Serializable {
@ApiModelProperty(value ="文件ID")
private Long fileId;
@ApiModelProperty(value ="用户发送上传请求的域名。")
private String host;
@ApiModelProperty(value ="文件请求地址")
private String url;
@ApiModelProperty(value ="存储平台")
private String platform;
/**
* OSS
*/
@ApiModelProperty(value = "OSS:key表示上传到Bucket内的Object的完整路径,例如exampledir/exampleobject.txtObject,完整路径中不能包含Bucket名称。")
private String key;
@ApiModelProperty(value ="OSS:对Policy签名后的字符串")
private String signature;
@ApiModelProperty(value ="OSS:accessid")
private String OSSAccessKeyId;
@ApiModelProperty(value ="OSS:policyBase64")
private String policy;
@ApiModelProperty(value ="OSS:设置服务端返回状态码为200,不设置则默认返回状态码204。")
private String success_action_status;
@ApiModelProperty(value ="OSS:过期时间戳,单位毫秒")
private Long expire;
}
package com.infynova.udi.entity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @Author: zoupx
* @Description: LoginParams 类
* @Date: 2021/6/10 12:34
*/
@Data
@ApiModel(value = "登录模块")
public class LoginParams {
private Long id;
@ApiModelProperty(value = "密码 | 手机验证码")
private String password;
@ApiModelProperty(value = "用户名")
private String username;
@ApiModelProperty(value = "工号")
private String workNo;
@ApiModelProperty(value = "租户ID")
private Long tenantId;
}
package com.infynova.udi.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.infynova.udi.common.entity.BaseEntity;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 文件表(sys_file)实体类
*
* @author hex
* @description 由 Mybatisplus Code Generator 创建
* @since 2022-06-01 16:15:43
*/
@Data
@NoArgsConstructor
@Accessors(chain = true)
@TableName("sys_file")
public class SysFile extends BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 三方id
*/
private String apiId;
/**
* 文件名称
*/
private String fileName;
/**
* 三方eTag
*/
private String eTag;
/**
* 文件名称
*/
private String originalFileName;
/**
* 源文件类型
*/
private String originalFileType;
/**
* bucketName
*/
private String bucketName;
/**
* 存储平台类型
*/
private String platform;
}
\ No newline at end of file
package com.infynova.udi.entity;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName(value = "udi_user")
public class UdiUser {
/** 主键ID,自增 */
@TableId(type = IdType.AUTO)
private Long id;
private String username;
private String password;
private String salt;
private String email;
private String phone;
private String mobile;
/** 租户=创建人数据隔离 */
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "租户=创建人数据隔离")
private Long tenantId;
/** 创建时间 */
@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "创建时间")
private LocalDateTime createTime;
/** 修改时间 */
@TableField(fill = FieldFill.INSERT_UPDATE)
@ApiModelProperty(value = "修改时间")
private LocalDateTime updateTime;
/** 删除标识 */
@ApiModelProperty(value = "删除标识")
private Boolean delFlag;
/** 版本号,默认为1 */
@ApiModelProperty(value = "版本号")
@Version
@TableField(fill = FieldFill.INSERT_UPDATE, update="%s+1")
private Integer version;
}
......@@ -17,7 +17,7 @@
package com.infynova.udi.exception;
import com.infynova.common.core.api.ServiceCode;
import com.infynova.udi.common.api.ServiceCode;
/**
* @author zoupx
......
package com.infynova.udi.exception;
import com.infynova.common.core.api.ServiceCode;
import com.infynova.udi.common.api.ServiceCode;
import java.util.Arrays;
......
package com.infynova.udi.exception;
import com.infynova.common.core.api.ServiceCode;
import com.infynova.udi.common.api.ServiceCode;
/**
* @author liudong
......
package com.infynova.udi.exception;
import com.infynova.common.core.api.ResponseData;
import com.infynova.udi.common.api.ResponseData;
import com.infynova.udi.common.exception.SaasException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.validation.BindException;
......
/*
* Copyright [2021] [SaasPlatform ]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.infynova.udi.filter;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.infynova.udi.common.jwt.AuthUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @Author: zoupx
* @Description: BaseFilter 类
* @Date: 2021/6/28
*/
@Slf4j
@Component
public abstract class BaseFilter implements Ordered {
@Autowired
protected AuthUtil authUtil;
protected final PathMatcher pathMatcher = new AntPathMatcher();
protected void setHeader(ServerWebExchange exchange, Map<String, String> headers) {
exchange.getRequest().mutate().headers(httpHeaders -> {
for (String key : headers.keySet()) {
String value = headers.get(key);
if (value != null) {
httpHeaders.add(key, value);
}
}
});
}
protected boolean checkPath(String requestPath, Set<String> configPathList) {
if (CollectionUtils.isEmpty(configPathList)) {
return false;
}
log.error(requestPath + "===============configPathList:" + JSONObject.toJSONString(configPathList));
for (String configPath : configPathList) {
if (pathMatcher.match(configPath.toLowerCase(), requestPath.toLowerCase())) {
return true;
}
}
return false;
}
protected boolean checkPath(String requestPath, List<String> pathList, boolean like) {
if (CollectionUtils.isEmpty(pathList)) {
return false;
}
requestPath = requestPath.toLowerCase();
for (String path : pathList) {
path = path.toLowerCase();
if (like) {
path = formatFirstAndLastStr(path, "/") + "/**";
}
if (pathMatcher.match((requestPath), path)) {
return true;
} else if (pathMatcher.match(path, requestPath)) {
return true;
}
}
return false;
}
public String formatFirstAndLastStr(String target, String str) {
target = StrUtil.removePrefix(target, str);
if (target.substring(target.length() - 1).equals(str)) {
target = target.substring(0, target.length() - 1);
}
return target;
}
public static void main(String[] args) {
PathMatcher pathMatcher = new AntPathMatcher();
List<String> preAuthorizeUrl = new ArrayList<>();
preAuthorizeUrl.add("/api/me/{pa}/query_get");
preAuthorizeUrl.add("/api/me/{pa}/update_put");
preAuthorizeUrl.add("api/me_*");
preAuthorizeUrl.add("companycustomer/**");
String reqUrl = "/companycustomer/{weqwe}/";
preAuthorizeUrl.forEach(url -> {
if (pathMatcher.match(reqUrl, url)) {
System.out.println("1用户权限列表:" + url);
} else if (pathMatcher.match(url, reqUrl)) {
System.out.println("2用户权限列表:" + url);
} else {
System.out.println("没有 用户权限列表:" + url);
}
});
}
protected String getPath(ServerWebExchange exchange) {
return String.valueOf(exchange.getRequest().getPath());
}
protected String getUri(ServerWebExchange exchange) {
return exchange.getRequest().getURI().toString();
}
}
......@@ -2,19 +2,26 @@ package com.infynova.udi.filter;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.infynova.common.core.constant.AuthRedisKeyConstant;
import com.infynova.common.core.context.HeaderCode;
import com.infynova.common.core.context.SpringContextUtils;
import com.infynova.common.core.exception.SaasException;
import com.infynova.common.core.exception.SaasNotTokenException;
import com.infynova.common.core.jwt.AuthUtil;
import com.infynova.common.core.jwt.model.JwtUserInfo;
import com.alibaba.fastjson.JSONObject;
import com.infynova.udi.common.constant.AuthRedisKeyConstant;
import com.infynova.udi.common.context.HeaderCode;
import com.infynova.udi.common.context.SpringContextUtils;
import com.infynova.udi.common.exception.SaasException;
import com.infynova.udi.common.exception.SaasNotTokenException;
import com.infynova.udi.common.jwt.AuthUtil;
import com.infynova.udi.common.jwt.model.JwtUserInfo;
import com.infynova.udi.common.utils.ClientIp;
import com.infynova.udi.exception.CommonExceptionCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.server.ServerWebExchange;
import javax.annotation.Resource;
import javax.servlet.*;
......@@ -22,9 +29,7 @@ import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.*;
/**
* @author liudong
......@@ -53,29 +58,34 @@ public class IdentityFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 进行身份验证逻辑,例如检查用户是否已登录,或者检查请求中的认证信息等
// 如果验证成功,则调用chain.doFilter(request, response)来继续执行请求,否则可以返回未经授权的错误信息
// 客户端
// 获取请求头的值
String clientCode = httpRequest.getHeader(HeaderCode.CLIENT_CODE);
// token
String token = httpRequest.getHeader(HeaderCode.TOKEN);
//log.info("请求路径:{}", httpRequest.getPathInfo());
//log.info("请求客户端:{}", clientCode);
log.info("请求路径:{}", httpRequest.getPathInfo());
// log.info("请求租户:{}", tenantCode);
log.info("请求客户端:{}", clientCode);
// log.info("请求token:{}", token);
// log.info("请求身份类型:{}", identityType);
//设置请求头
Map<String, String> headers = new HashMap<>();
Set<String> configPathList = new HashSet<>();
configPathList.add("/udi/user/token");
if (!checkPath(httpRequest.getRequestURI(), configPathList)) {
if (StrUtil.isBlank(token)) {
throw new SaasException(CommonExceptionCode.SYSTEM_401);
throw new SaasException(CommonExceptionCode.JWT_ILLEGAL_ARGUMENT);
}
JwtUserInfo authInfo = authUtil.getAuthInfo(token);
Optional.ofNullable(authInfo).orElseThrow(() -> new SaasNotTokenException(CommonExceptionCode.SYSTEM_401));
Optional.ofNullable(authInfo).orElseThrow(() -> new SaasNotTokenException(CommonExceptionCode.JWT_TOKEN_EXPIRED));
String identityId = String.valueOf(authInfo.getIdentityId());
Long identityInvalid = (Long) redisTemplate.opsForValue().get(AuthRedisKeyConstant.USER_INVALID_JWT + identityId);
if (ObjectUtil.isNotNull(identityInvalid)) {
log.error("TOKEN失效-用户禁用 {}", token);
throw new SaasNotTokenException(CommonExceptionCode.SYSTEM_401);
throw new SaasNotTokenException(CommonExceptionCode.JWT_TOKEN_EXPIRED);
}
SpringContextUtils.set(HeaderCode.IDENTITY_ID,identityId);
SpringContextUtils.set(HeaderCode.USER_NAME, authInfo.getUserName());
SpringContextUtils.set(HeaderCode.ACCOUNT_ID, String.valueOf(authInfo.getAccountId()));
......@@ -84,10 +94,73 @@ public class IdentityFilter implements Filter {
SpringContextUtils.set(HeaderCode.USER_TYPE, String.valueOf(authInfo.getUserType()));
SpringContextUtils.set(HeaderCode.DATA_SCOPE, String.valueOf(authInfo.getDeptCode()));
SpringContextUtils.set(HeaderCode.TENANT_ID, String.valueOf(authInfo.getTenantId()));
}
chain.doFilter(request, response);
}
protected final PathMatcher pathMatcher = new AntPathMatcher();
protected void setHeader(ServerWebExchange exchange, Map<String, String> headers) {
exchange.getRequest().mutate().headers(httpHeaders -> {
for (String key : headers.keySet()) {
String value = headers.get(key);
if (value != null) {
httpHeaders.add(key, value);
}
}
});
}
protected boolean checkPath(String requestPath, Set<String> configPathList) {
if (CollectionUtils.isEmpty(configPathList)) {
return false;
}
log.error(requestPath + "===============configPathList:" + JSONObject.toJSONString(configPathList));
for (String configPath : configPathList) {
if (pathMatcher.match(configPath.toLowerCase(), requestPath.toLowerCase())) {
return true;
}
}
return false;
}
protected boolean checkPath(String requestPath, List<String> pathList, boolean like) {
if (CollectionUtils.isEmpty(pathList)) {
return false;
}
requestPath = requestPath.toLowerCase();
for (String path : pathList) {
path = path.toLowerCase();
if (like) {
path = formatFirstAndLastStr(path, "/") + "/**";
}
if (pathMatcher.match((requestPath), path)) {
return true;
} else if (pathMatcher.match(path, requestPath)) {
return true;
}
}
return false;
}
public String formatFirstAndLastStr(String target, String str) {
target = StrUtil.removePrefix(target, str);
if (target.substring(target.length() - 1).equals(str)) {
target = target.substring(0, target.length() - 1);
}
return target;
}
protected String getPath(ServerWebExchange exchange) {
return String.valueOf(exchange.getRequest().getPath());
}
protected String getUri(ServerWebExchange exchange) {
return exchange.getRequest().getURI().toString();
}
@Override
public void destroy() {
log.info(LOG_PREFIX+"销毁~");
......
package com.infynova.udi.manager;
import com.infynova.udi.common.api.ResponseData;
import com.infynova.udi.common.entity.UploadResultVo;
import com.infynova.udi.dto.file.OSSBatchIdReqVo;
import com.infynova.udi.manager.storage.platform.LocalFileStorage;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.util.List;
@Service
public class OSSServiceClient {
@Resource
private LocalFileStorage localFileStorage;
public ResponseData<UploadResultVo> upload(MultipartFile file) {
// return success(ossService.uploadFile(file));
return ResponseData.ok(localFileStorage.save(file));
}
public ResponseData<String> getUrlById(Long id) {
return ResponseData.ok(localFileStorage.getUrl(id));
}
public ResponseData<List<UploadResultVo>> queryBatchById(OSSBatchIdReqVo ossBatchId) {
return ResponseData.ok(localFileStorage.getUrlById(ossBatchId.getIds()));
}
}
package com.infynova.udi.manager;
import com.infynova.common.core.api.ResponseData;
import com.infynova.common.core.entity.UploadResultVo;
import com.infynova.common.core.exception.SaasException;
import com.infynova.ucpm.client.OSSServiceClient;
import com.infynova.ucpm.vo.request.OSSBatchIdReqVo;
import com.infynova.udi.common.api.ResponseData;
import com.infynova.udi.common.entity.UploadResultVo;
import com.infynova.udi.common.exception.SaasException;
import com.infynova.udi.dto.UdiMatchTaskFileDto;
import com.infynova.udi.dto.file.OSSBatchIdReqVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Component;
......@@ -55,4 +54,7 @@ public class OssManager {
return null;
}
}
}
package com.infynova.udi.manager.storage.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
public class FileStorageProperties {
/**
* 前缀配置
*/
public static final String PREFIX = "infynova.file-storage";
/**
* 默认存储平台
*/
private String defaultPlatform = "aliyun-oss";
/**
* 本地存储
*/
private Local local = new Local();
/**
* minIO
*/
private MinIO minIO = new MinIO();
private Service service = new Service();
@Data
public static class Service {
private String platform = "minio";
private String url = "";
/**
* 下载接口地址
*/
private String downloadUrl = "";
/**
* 存储空间
*/
private String bucketName = "";
}
/**
* 本地存储
*/
@Data
public static class Local {
/**
* 本地存储路径
*/
private String basePath = "/data/infynova/file/";
/**
* 下载接口地址
*/
private String downloadUrl = "";
/**
* 存储空间
*/
private String bucketName = "";
/**
* 上传地址
*/
private String uploadUrl = "";
}
/**
* minIO
*/
@Data
public static class MinIO {
/**
* key
*/
private String accessKey = "";
/**
* 密钥
*/
private String secretKey = "";
/**
*地址
*/
private String endPoint = "";
/**
* bucketName
*/
private String bucketName = "";
}
}
package com.infynova.udi.manager.storage.finals;
public class StoragePlatformFinal {
/**
* 阿里云OSS
*/
public final static String ALIYUN_OSS = "aliyun-oss";
/**
* 本地存储
*/
public final static String LOCAL = "local";
/**
* minIO
*/
public final static String MINIO = "minio";
public final static String SERVICE = "service";
}
package com.infynova.udi.manager.storage.platform;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import com.infynova.udi.common.entity.UploadResultVo;
import com.infynova.udi.dto.file.FileGetUrlByIdReqVo;
import com.infynova.udi.dto.file.StoragePolicyVo;
import com.infynova.udi.entity.SysFile;
import com.infynova.udi.manager.storage.config.FileStorageProperties;
import com.infynova.udi.manager.storage.service.SysFileService;
import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
@Data
@Component
@Slf4j
public class LocalFileStorage{
@Resource
private FileStorageProperties fileStorageProperties;
@Resource
private SysFileService sysFileService;
@SneakyThrows
public UploadResultVo save(MultipartFile multipartFile) {
//真实文件全名
String originalFilename = multipartFile.getOriginalFilename();
//文件后缀
String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));
//存储的文件名,存储映射文件名
String fileName = IdUtil.getSnowflake(1, 1).nextId() + fileType;
//存储文件地址
String filePath = fileStorageProperties.getLocal().getBasePath() + fileStorageProperties.getLocal().getBucketName() + fileName;
try {
FileUtil.writeFromStream(multipartFile.getInputStream(),new File(filePath));
} catch (IOException e) {
FileUtil.del(filePath);
throw e;
}
SysFile sysFile = new SysFile();
sysFile.setFileName(fileName);
sysFile.setOriginalFileName(originalFilename);
sysFile.setOriginalFileType(fileType);
sysFile.setPlatform("local");
sysFileService.save(sysFile);
UploadResultVo uploadResultVo = new UploadResultVo();
uploadResultVo.setFilePath(getUrl(sysFile.getId()));
uploadResultVo.setFileName(originalFilename);
uploadResultVo.setId(sysFile.getId());
return uploadResultVo;
}
@SneakyThrows
public void serviceSave(String fileName,MultipartFile multipartFile) {
//存储文件地址
String filePath = fileStorageProperties.getLocal().getBasePath() + fileStorageProperties.getLocal().getBucketName() + fileName;
try {
FileUtil.writeFromStream(multipartFile.getInputStream(),new File(filePath));
} catch (IOException e) {
FileUtil.del(filePath);
throw e;
}
}
public String getUrl(Long fileId) {
SysFile sysFile = sysFileService.getById(fileId);
if (Objects.isNull(sysFile)){
return null;
}
return fileStorageProperties.getLocal().getDownloadUrl() +"?fileId="+ sysFile.getId();
}
public void download(String fileName, String url) {
//存储文件地址
String filePath = fileStorageProperties.getLocal().getBasePath() + fileStorageProperties.getLocal().getBucketName() + fileName;
FileUtil.copy(new File(filePath),new File(url),true);
}
@SneakyThrows
public void download(Long fileId, HttpServletResponse response) {
SysFile sysFile = sysFileService.getById(fileId);
String filePath = fileStorageProperties.getLocal().getBasePath()+fileStorageProperties.getLocal().getBucketName() + sysFile.getFileName();
// response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf8");
response.setHeader("Content-disposition", "attachment;filename="+sysFile.getOriginalFileName());
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
BufferedInputStream inputStream = FileUtil.getInputStream(filePath);
IoUtil.copy(inputStream,response.getOutputStream());
}
public StoragePolicyVo getPolicy(String name) {
//文件后缀
String fileType = name.substring(name.lastIndexOf("."));
//存储的文件名,存储映射文件名
String fileName = IdUtil.getSnowflake(1, 2).nextId() + fileType;
SysFile sysFile = new SysFile();
sysFile.setFileName(fileName);
sysFile.setOriginalFileName(name);
sysFile.setOriginalFileType(fileType);
sysFile.setPlatform("local");
sysFile.setBucketName(fileStorageProperties.getLocal().getBucketName());
sysFileService.save(sysFile);
StoragePolicyVo storagePolicyVo = new StoragePolicyVo();
storagePolicyVo.setHost(fileStorageProperties.getLocal().getUploadUrl());
storagePolicyVo.setFileId(sysFile.getId());
storagePolicyVo.setPlatform("local");
storagePolicyVo.setUrl(getUrl(sysFile.getId()));
return storagePolicyVo;
}
public Map<Long, String> getUrlBatch(List<Long> idList) {
return idList.parallelStream()
.collect(Collectors.toMap(
Function.identity(),
id -> Optional.ofNullable(getUrl(id)).orElse("")
));
}
public UploadResultVo getUrlById(FileGetUrlByIdReqVo fileGetUrlByIdReqVo) {
String url = getUrl(fileGetUrlByIdReqVo.getId());
SysFile sysFile = sysFileService.getById(fileGetUrlByIdReqVo.getId());
if (sysFile != null) {
UploadResultVo uploadResultVo = new UploadResultVo();
uploadResultVo.setId(sysFile.getId());
uploadResultVo.setFileName(sysFile.getFileName());
uploadResultVo.setFilePath(url);
return uploadResultVo;
}
return null;
}
public UploadResultVo getUrlById(Long id) {
FileGetUrlByIdReqVo fileGetUrlByIdReqVo = new FileGetUrlByIdReqVo();
fileGetUrlByIdReqVo.setId(id);
return getUrlById(fileGetUrlByIdReqVo);
}
public List<UploadResultVo> getUrlById(List<Long> ids) {
if (ids != null && ids.size() > 100) {
return new ArrayList<>();
}
return ids.stream().map(id -> getUrlById(id)).collect(Collectors.toList());
}
}
package com.infynova.udi.manager.storage.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.infynova.udi.entity.SysFile;
/**
* 文件表服务接口
*
* @author hex
* @description 由 Mybatisplus Code Generator 创建
* @since 2022-06-01 16:15:43
*/
public interface SysFileService extends IService<SysFile> {
}
package com.infynova.udi.manager.storage.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.infynova.udi.entity.SysFile;
import com.infynova.udi.manager.storage.service.SysFileService;
import com.infynova.udi.mapper.SysFileMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* 文件表服务接口实现
*
* @author hex
* @description 由 Mybatisplus Code Generator 创建
* @since 2022-06-01 16:15:43
*/
@Slf4j
@Service
public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {
}
package com.infynova.udi.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.infynova.udi.entity.SysFile;
import org.apache.ibatis.annotations.Mapper;
/**
* 文件表(sys_file)数据Mapper
*
* @author hex
* @description 由 Mybatisplus Code Generator 创建
* @since 2022-06-01 16:15:43
*/
@Mapper
public interface SysFileMapper extends BaseMapper<SysFile> {
}
package com.infynova.udi.mapper;
import com.infynova.udi.entity.UdiUser;
import com.infynova.udi.mapper.base.SuperMapper;
/**
* @author liudong
* 2024/2/29 16:41
* @version 1.0
*/
public interface UdiUserMapper extends SuperMapper<UdiUser> {
}
package com.infynova.udi.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.infynova.udi.entity.UdiUser;
import com.infynova.udi.mapper.UdiUserMapper;
import org.springframework.stereotype.Service;
@Service
public class UdiUserService extends ServiceImpl<UdiUserMapper, UdiUser> {
}
......@@ -2,7 +2,7 @@ package com.infynova.udi.service.base;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.common.core.entity.PageVo;
import com.infynova.udi.common.entity.PageVo;
/**
* @author liudong
......
......@@ -2,8 +2,8 @@ package com.infynova.udi.service.helper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.common.core.context.HeaderCode;
import com.infynova.common.core.context.SpringContextUtils;
import com.infynova.udi.common.context.HeaderCode;
import com.infynova.udi.common.context.SpringContextUtils;
import com.infynova.udi.entity.MatchData;
import com.infynova.udi.entity.MatchTemp;
import com.infynova.udi.enums.match.MatchStatusEnum;
......
......@@ -5,8 +5,8 @@ import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.infynova.common.core.context.HeaderCode;
import com.infynova.common.core.context.SpringContextUtils;
import com.infynova.udi.common.context.HeaderCode;
import com.infynova.udi.common.context.SpringContextUtils;
import com.infynova.udi.entity.MatchData;
import com.infynova.udi.entity.Task;
import com.infynova.udi.enums.match.MatchStatusEnum;
......
......@@ -3,7 +3,7 @@ package com.infynova.udi.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.infynova.common.core.context.SpringContextUtils;
import com.infynova.udi.common.context.SpringContextUtils;
import com.infynova.udi.dto.UdiAllMatchQry;
import com.infynova.udi.dto.UdiBatchMatchQry;
import com.infynova.udi.dto.UdiMatchConfirmationDto;
......
......@@ -5,7 +5,7 @@ import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.infynova.common.core.entity.UploadResultVo;
import com.infynova.udi.common.entity.UploadResultVo;
import com.infynova.udi.dto.ImportItemCount;
import com.infynova.udi.dto.ImportItemResp;
import com.infynova.udi.exception.CommonExceptionCode;
......
......@@ -2,7 +2,6 @@ package com.infynova.udi.service.properties;
import lombok.Getter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
/**
......@@ -12,7 +11,6 @@ import org.springframework.stereotype.Component;
*/
@Getter
@Component
@RefreshScope
public class UdiProperties {
/**
......
package com.infynova.udi.vo;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.common.api.BaseVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Builder;
......
......@@ -3,7 +3,7 @@ package com.infynova.udi.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.common.api.BaseVo;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......
......@@ -4,7 +4,7 @@ import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.infynova.common.core.api.BaseVo;
import com.infynova.udi.common.api.BaseVo;
import com.infynova.udi.enums.match.MatchStatusEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
......
server:
port: 7801
servlet:
context-path: /udi
spring:
application:
name: saas-udi
# main:
# allow-bean-definition-overriding: true
datasource:
url: jdbc:mysql://rm-wz92456b388ahxujbuo.mysql.rds.aliyuncs.com:3306/saas_base_test?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
#url: jdbc:p6spy:mysql://rm-wz92456b388ahxujbuo.mysql.rds.aliyuncs.com:3306/saas_base_test?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai
username: saas_test
password: qjCEgXg2z9U5mjL7
driver-class-name: com.mysql.cj.jdbc.Driver
#driver-class-name: com.p6spy.engine.spy.P6SpyDriver
type: com.zaxxer.hikari.HikariDataSource
hikari:
connection-timeout: 30000
minimum-idle: 10
maximum-pool-size: 40
idle-timeout: 300000
max-lifetime: 1800000
auto-commit: true
# Redis 配置(Spring Boot 2.x 格式)
redis:
#host: 172.18.91.89
host: 39.108.112.41
port: 6379
password: O5VefwieTul9h0uw
lettuce:
pool:
max-active: 20 # 连接池最大连接数
max-idle: 5 # 最大空闲连接
mybatis-plus:
mapper-locations: classpath*:/mapper/*.xml
typeAliasesPackage: com.infynova.*.entity
global-config:
banner: false
#原生配置
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
call-setters-on-nulls: true
jdbc-type-for-null: 'null'
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#jetcache 集成使用
#jetcache:
# statIntervalMinutes: 15 #每隔多久统计信息的时长配置
# areaInCacheName: false #是否配置前缀
# local:
# default:
# type: caffeine #本地缓存类型
# keyConvertor: fastjson #key的序列化转化的协议
# limit: 10000 #本地缓存最大个数
# defaultExpireInMillis: 10000 #缓存的时间全局 默认值
# remote:
# default:
# type: redis #缓存数据库类型
# keyConvertor: fastjson
# defaultExpireInMillis: 20000 #全局缓存失效时间
# host: 172.18.91.89
# port: 6379
# password: b9~}#EwAJAx*AvF^_zKe
# poolConfig:
# minIdle: 5
# maxIdle: 20
# maxTotal: 50
logging:
level:
console: debug
knife4j:
enable: true
# 上传转换任务开关
udi-upload-flag: true
# 对码转换任务开关
udi-match-flag: true
spring:
profiles:
active: dong-test
application:
name: saas-udi
main:
allow-bean-definition-overriding: true
cloud:
nacos:
config:
namespace: ${spring.cloud.nacos.namespace}
file-extension: yml
group: DEFAULT_GROUP
shared-configs:
- dataId: common.yml
group: COMMON
- dataId: sentinel.yml
group: COMMON
- dataId: prometheus.yml
group: COMMON
- dataId: redis.yml
group: COMMON
discovery:
namespace: ${spring.cloud.nacos.namespace}
knife4j:
enable: true
# #######################################
# 标准版
# #######################################
---
# saas-dev(标准版开发环境)
spring:
profiles: dong-test
cloud:
nacos:
server-addr: 120.79.249.213:8848
namespace: dong-test
---
# saas-test(标准版测试环境)
spring:
profiles: saas_test
cloud:
nacos:
server-addr: 127.0.0.1:8848
namespace: saas_test
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment