提交 0dbc5509 编写于 作者: ibizdev's avatar ibizdev

zhouweidong@lab.ibiz5.com 发布系统代码

上级 4f6069f5
*volumes
*target
.settings
*node_modules
*bin
*.project
*.classpath
*.factorypath
.history
.vscode
.idea
**.iml
*.jar
*.log
# 系统概览 iBiz4j Spring R7 dev
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ibzpay</artifactId>
<groupId>cn.ibizlab</groupId>
<version>1.0.0.0</version>
</parent>
<artifactId>ibzpay-app</artifactId>
<name>Ibzpay Application</name>
<description>Ibzpay Application</description>
<packaging>pom</packaging>
<modules>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
</dependencies>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ibzpay</artifactId>
<groupId>cn.ibizlab</groupId>
<version>1.0.0.0</version>
</parent>
<artifactId>ibzpay-boot</artifactId>
<name>Ibzpay Dev Monolithic Boot</name>
<description>Ibzpay Boot</description>
<dependencies>
<dependency>
<groupId>cn.ibizlab</groupId>
<artifactId>ibzpay-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.ibizlab</groupId>
<artifactId>ibzpay-provider-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<!--由于boot是通过dependency来关联所有子项目,页面和配置等信息都存在与子项目中,
所以您在对boot进行打包前,需要先将子项目install到maven仓库,以确保boot可以正常引用所有完整的子项目-->
<profiles>
<profile>
<id>boot</id>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>ibzpay</finalName>
<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
<mainClass>cn.ibizlab.DevBootApplication</mainClass>
<outputDirectory>../</outputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
version: "3.2"
services:
ibzpay-nacos:
image: nacos/nacos-server:latest
container_name: nacos-standalone
environment:
- PREFER_HOST_MODE=hostname
- MODE=standalone
ports:
- "8848:8848"
networks:
- agent_network
networks:
agent_network:
attachable: true
version: "3.2"
services:
ibzpay-redis:
image: redis
ports:
- 6379:6379
environment:
- TZ=Asia/Shanghai
logging:
driver: "json-file"
command: redis-server
networks:
- agent_network
networks:
agent_network:
attachable: true
package cn.ibizlab;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.List;
import cn.ibizlab.util.web.SearchContextHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
@Slf4j
@EnableDiscoveryClient
@Configuration
@EnableTransactionManagement
@EnableFeignClients(basePackages = {"cn.ibizlab" })
@SpringBootApplication(exclude = {
})
@ComponentScan(basePackages = {"cn.ibizlab"}
// ,excludeFilters={
// @ComponentScan.Filter(type= org.springframework.context.annotation.FilterType.REGEX,pattern="cn.ibizlab.xxx.rest.xxx"),
// }
)
@Import({
org.springframework.cloud.openfeign.FeignClientsConfiguration.class
})
@EnableAsync
@EnableScheduling
public class DevBootApplication extends WebMvcConfigurerAdapter{
@Autowired
SearchContextHandlerMethodArgumentResolver resolver;
public static void main(String[] args) {
SpringApplication.run(DevBootApplication.class,args);
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(resolver);
}
}
package cn.ibizlab.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
public class DevBootAutoConfiguration {
}
package cn.ibizlab.config;
import cn.ibizlab.util.security.AuthenticationEntryPoint;
import cn.ibizlab.util.security.AuthorizationTokenFilter;
import cn.ibizlab.util.service.AuthenticationUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.core.GrantedAuthorityDefaults;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.beans.factory.annotation.Qualifier;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class DevBootSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationEntryPoint unauthorizedHandler;
@Autowired
private AuthenticationUserService userDetailsService;
/**
* 自定义基于JWT的安全过滤器
*/
@Autowired
AuthorizationTokenFilter authenticationTokenFilter;
@Value("${ibiz.auth.path:v7/login}")
private String loginPath;
@Value("${ibiz.auth.logoutpath:v7/logout}")
private String logoutPath;
@Value("${ibiz.file.uploadpath:ibizutil/upload}")
private String uploadpath;
@Value("${ibiz.file.downloadpath:ibizutil/download}")
private String downloadpath;
@Value("${ibiz.file.previewpath:ibizutil/preview}")
private String previewpath;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoderBean());
}
@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
// Remove the ROLE_ prefix
return new GrantedAuthorityDefaults("");
}
@Bean
public PasswordEncoder passwordEncoderBean() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// 禁用 CSRF
.csrf().disable()
// 授权异常
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// 不创建会话
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 过滤请求
.authorizeRequests()
.antMatchers(
HttpMethod.GET,
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/**/*.ico",
"/**/assets/**",
"/**/css/**",
"/**/fonts/**",
"/**/js/**",
"/**/img/**",
"/",
"webjars/**",
"/swagger-resources/**",
"/v2/**"
).permitAll()
//放行登录请求
.antMatchers( HttpMethod.POST,"/"+loginPath).permitAll()
//放行注销请求
.antMatchers( HttpMethod.GET,"/"+logoutPath).permitAll()
// 文件操作
.antMatchers("/"+downloadpath+"/**").permitAll()
.antMatchers("/"+uploadpath).permitAll()
.antMatchers("/"+previewpath+"/**").permitAll()
.anyRequest().authenticated()
// 防止iframe 造成跨域
.and().headers().frameOptions().disable();
httpSecurity
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}
server:
port: 8080
#zuul网关路由设置
zuul:
routes:
loginv7:
path: /v7/login
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}
stripPrefix: false
changepwd:
path: /v7/changepwd
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}
stripPrefix: false
uaa:
path: /uaa/**
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}
stripPrefix: false
config:
path: /config/**
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}
stripPrefix: false
oucore:
path: /ibzorganizations/**
serviceId: ${ibiz.ref.service.ou:ibzou-api}
stripPrefix: false
oudict:
path: /dictionarys/**/Ibzou**
serviceId: ${ibiz.ref.service.ou:ibzou-api}
stripPrefix: false
uaadict:
path: /dictionarys/**/SysOperator
serviceId: ${ibiz.ref.service.uaa:ibzuaa-api}
stripPrefix: false
dict:
path: /dictionarys/**
serviceId: ${ibiz.ref.service.dict:ibzdict-api}
stripPrefix: false
disk:
path: /net-disk/**
serviceId: ${ibiz.ref.service.disk:ibzdisk-api}
stripPrefix: false
sensitive-headers:
- Cookie,Set-Cookie,Authorization
spring:
profiles:
include: sys ,nacos, api-dev, dev
application:
name: ibzpay
main:
allow-bean-definition-overriding: true
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<property name="LOG_PATH" value="logs" />
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %-40.40logger{39} : %msg%n" />
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="LOG_PATTERN2" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr([${LOG_LEVEL_PATTERN:-%5p}]) %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
<!-- 控制台输出 -->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_PATH}/ibzpay.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>100MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="Console" />
<appender-ref ref="file" />
</root>
</configuration>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ibzpay</artifactId>
<groupId>cn.ibizlab</groupId>
<version>1.0.0.0</version>
</parent>
<artifactId>ibzpay-core</artifactId>
<name>Ibzpay Core</name>
<description>Ibzpay Core</description>
<dependencies>
<dependency>
<groupId>cn.ibizlab</groupId>
<artifactId>ibzpay-util</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<!-- JBPM -->
<dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-flow-builder</artifactId>
</dependency>
<dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-bpmn2</artifactId>
</dependency>
<!-- Drools -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-spring</artifactId>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- MySQL数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Druid阿里连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!--MapStruct高性能属性映射工具-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
</dependency>
<!--MongoDB-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<!--Liquibase数据库版本更新工具-->
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
<!--baomidou-jobs定时服务 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>jobs-spring-boot-starter</artifactId>
</dependency>
</dependencies>
<properties>
<maven.build.timestamp.format>yyyyMMddHHmmss</maven.build.timestamp.format>
</properties>
<profiles>
<profile>
<id>diff</id>
<build>
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>${liquibase.version}</version>
<executions>
<execution>
<id>prepare-newdb</id>
<configuration>
<changeLogFile>${project.basedir}/src/main/resources/liquibase/h2_table.xml</changeLogFile>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:file:${project.build.directory}/db/new;MODE=mysql</url>
<username>root</username>
<dropFirst>true</dropFirst>
</configuration>
<phase>process-resources</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
<execution>
<id>prepare-olddb</id>
<configuration>
<changeLogFile>${project.basedir}/src/main/resources/liquibase/master_table.xml</changeLogFile>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:file:${project.build.directory}/db/last;MODE=mysql</url>
<username>root</username>
<dropFirst>true</dropFirst>
</configuration>
<phase>process-resources</phase>
<goals>
<goal>update</goal>
</goals>
</execution>
<execution>
<id>make-diff</id>
<configuration>
<changeLogFile>${project.basedir}/src/main/resources/liquibase/empty.xml</changeLogFile>
<diffChangeLogFile>${project.basedir}/src/main/resources/liquibase/changelog/${maven.build.timestamp}_changelog.xml</diffChangeLogFile>
<driver>org.h2.Driver</driver>
<url>jdbc:h2:file:${project.build.directory}/db/last;MODE=mysql</url>
<username>root</username>
<password></password>
<referenceUrl>jdbc:h2:file:${project.build.directory}/db/new;MODE=mysql</referenceUrl>
<referenceDriver>org.h2.Driver</referenceDriver>
<referenceUsername>root</referenceUsername>
<verbose>true</verbose>
<logging>debug</logging>
<contexts>!test</contexts>
<diffExcludeObjects>Index:.*,table:ibzfile,ibzuser,ibzdataaudit,ibzcfg,IBZFILE,IBZUSER,IBZDATAAUDIT,IBZCFG</diffExcludeObjects>
</configuration>
<phase>process-resources</phase>
<goals>
<goal>diff</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
package cn.ibizlab.core.pay.domain;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.math.BigInteger;
import java.util.HashMap;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.util.ObjectUtils;
import org.springframework.util.DigestUtils;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.enums.DEPredefinedFieldType;
import cn.ibizlab.util.enums.DEFieldDefaultValueType;
import java.io.Serializable;
import lombok.*;
import org.springframework.data.annotation.Transient;
import cn.ibizlab.util.annotation.Audit;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.baomidou.mybatisplus.annotation.*;
import cn.ibizlab.util.domain.EntityMP;
/**
* 实体[支付平台]
*/
@Getter
@Setter
@NoArgsConstructor
@JsonIgnoreProperties(value = "handler")
@TableName(value = "IBZOPENACCESS",resultMap = "PayOpenAccessResultMap")
public class PayOpenAccess extends EntityMP implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 开放平台接入标识
*/
@DEField(name = "accessid" , isKeyField=true)
@TableId(value= "accessid",type=IdType.ASSIGN_UUID)
@JSONField(name = "id")
@JsonProperty("id")
private String id;
/**
* 开放平台
*/
@DEField(name = "accessname")
@TableField(value = "accessname")
@JSONField(name = "name")
@JsonProperty("name")
private String name;
/**
* 开放平台类型
*/
@DEField(name = "open_type")
@TableField(value = "open_type")
@JSONField(name = "open_type")
@JsonProperty("open_type")
private String openType;
/**
* AccessKey(AppId)
*/
@DEField(name = "access_key")
@TableField(value = "access_key")
@JSONField(name = "access_key")
@JsonProperty("access_key")
private String accessKey;
/**
* SecretKey(AppSecret)
*/
@DEField(name = "secret_key")
@TableField(value = "secret_key")
@JSONField(name = "secret_key")
@JsonProperty("secret_key")
private String secretKey;
/**
* RegionId
*/
@DEField(name = "region_id")
@TableField(value = "region_id")
@JSONField(name = "region_id")
@JsonProperty("region_id")
private String regionId;
/**
* 管理账号token
*/
@DEField(name = "access_token")
@TableField(value = "access_token")
@JSONField(name = "access_token")
@JsonProperty("access_token")
private String accessToken;
/**
* 管理账号token过期时间
*/
@DEField(name = "expires_time")
@TableField(value = "expires_time")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", locale = "zh" , timezone="GMT+8")
@JSONField(name = "expires_time" , format="yyyy-MM-dd HH:mm:ss")
@JsonProperty("expires_time")
private Timestamp expiresTime;
/**
* 是否禁用
*/
@DEField(defaultValue = "0")
@TableField(value = "disabled")
@JSONField(name = "disabled")
@JsonProperty("disabled")
private Integer disabled;
/**
* RedirectURI
*/
@DEField(name = "redirect_uri")
@TableField(value = "redirect_uri")
@JSONField(name = "redirect_uri")
@JsonProperty("redirect_uri")
private String redirectUri;
/**
* 设置 [开放平台]
*/
public void setName(String name){
this.name = name ;
this.modify("accessname",name);
}
/**
* 设置 [开放平台类型]
*/
public void setOpenType(String openType){
this.openType = openType ;
this.modify("open_type",openType);
}
/**
* 设置 [AccessKey(AppId)]
*/
public void setAccessKey(String accessKey){
this.accessKey = accessKey ;
this.modify("access_key",accessKey);
}
/**
* 设置 [SecretKey(AppSecret)]
*/
public void setSecretKey(String secretKey){
this.secretKey = secretKey ;
this.modify("secret_key",secretKey);
}
/**
* 设置 [RegionId]
*/
public void setRegionId(String regionId){
this.regionId = regionId ;
this.modify("region_id",regionId);
}
/**
* 设置 [管理账号token]
*/
public void setAccessToken(String accessToken){
this.accessToken = accessToken ;
this.modify("access_token",accessToken);
}
/**
* 设置 [管理账号token过期时间]
*/
public void setExpiresTime(Timestamp expiresTime){
this.expiresTime = expiresTime ;
this.modify("expires_time",expiresTime);
}
/**
* 格式化日期 [管理账号token过期时间]
*/
public String formatExpiresTime(){
if (this.expiresTime == null) {
return null;
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
return sdf.format(expiresTime);
}
/**
* 设置 [是否禁用]
*/
public void setDisabled(Integer disabled){
this.disabled = disabled ;
this.modify("disabled",disabled);
}
/**
* 设置 [RedirectURI]
*/
public void setRedirectUri(String redirectUri){
this.redirectUri = redirectUri ;
this.modify("redirect_uri",redirectUri);
}
}
package cn.ibizlab.core.pay.domain;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.math.BigInteger;
import java.util.HashMap;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.util.ObjectUtils;
import org.springframework.util.DigestUtils;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.enums.DEPredefinedFieldType;
import cn.ibizlab.util.enums.DEFieldDefaultValueType;
import java.io.Serializable;
import lombok.*;
import org.springframework.data.annotation.Transient;
import cn.ibizlab.util.annotation.Audit;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.baomidou.mybatisplus.annotation.*;
import cn.ibizlab.util.domain.EntityMP;
/**
* 实体[支付交易]
*/
@Getter
@Setter
@NoArgsConstructor
@JsonIgnoreProperties(value = "handler")
@TableName(value = "IBZPAYTRADE",resultMap = "PayTradeResultMap")
public class PayTrade extends EntityMP implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 属性
*/
@DEField(isKeyField=true)
@TableId(value= "tradeid",type=IdType.ASSIGN_UUID)
@JSONField(name = "tradeid")
@JsonProperty("tradeid")
private String tradeid;
/**
* 属性2
*/
@TableField(value = "tradename")
@JSONField(name = "tradename")
@JsonProperty("tradename")
private String tradename;
/**
* 设置 [属性2]
*/
public void setTradename(String tradename){
this.tradename = tradename ;
this.modify("tradename",tradename);
}
}
package cn.ibizlab.core.pay.filter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.fastjson.annotation.JSONField;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import cn.ibizlab.util.filter.QueryWrapperContext;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.ibizlab.core.pay.domain.PayOpenAccess;
/**
* 关系型数据实体[PayOpenAccess] 查询条件对象
*/
@Slf4j
@Data
public class PayOpenAccessSearchContext extends QueryWrapperContext<PayOpenAccess> {
private String n_accessname_like;//[开放平台]
public void setN_accessname_like(String n_accessname_like) {
this.n_accessname_like = n_accessname_like;
if(!ObjectUtils.isEmpty(this.n_accessname_like)){
this.getSearchCond().like("accessname", n_accessname_like);
}
}
private String n_open_type_eq;//[开放平台类型]
public void setN_open_type_eq(String n_open_type_eq) {
this.n_open_type_eq = n_open_type_eq;
if(!ObjectUtils.isEmpty(this.n_open_type_eq)){
this.getSearchCond().eq("open_type", n_open_type_eq);
}
}
/**
* 启用快速搜索
*/
public void setQuery(String query)
{
this.query=query;
if(!StringUtils.isEmpty(query)){
this.getSearchCond().and( wrapper ->
wrapper.like("accessname", query)
);
}
}
}
package cn.ibizlab.core.pay.filter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.alibaba.fastjson.annotation.JSONField;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import cn.ibizlab.util.filter.QueryWrapperContext;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import cn.ibizlab.core.pay.domain.PayTrade;
/**
* 关系型数据实体[PayTrade] 查询条件对象
*/
@Slf4j
@Data
public class PayTradeSearchContext extends QueryWrapperContext<PayTrade> {
private String n_tradename_like;//[属性2]
public void setN_tradename_like(String n_tradename_like) {
this.n_tradename_like = n_tradename_like;
if(!ObjectUtils.isEmpty(this.n_tradename_like)){
this.getSearchCond().like("tradename", n_tradename_like);
}
}
/**
* 启用快速搜索
*/
public void setQuery(String query)
{
this.query=query;
if(!StringUtils.isEmpty(query)){
this.getSearchCond().and( wrapper ->
wrapper.like("tradename", query)
);
}
}
}
package cn.ibizlab.core.pay.mapper;
import java.util.List;
import org.apache.ibatis.annotations.*;
import java.util.Map;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import java.util.HashMap;
import org.apache.ibatis.annotations.Select;
import cn.ibizlab.core.pay.domain.PayOpenAccess;
import cn.ibizlab.core.pay.filter.PayOpenAccessSearchContext;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import java.io.Serializable;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.alibaba.fastjson.JSONObject;
public interface PayOpenAccessMapper extends BaseMapper<PayOpenAccess>{
Page<PayOpenAccess> searchDefault(IPage page, @Param("srf") PayOpenAccessSearchContext context, @Param("ew") Wrapper<PayOpenAccess> wrapper) ;
@Override
PayOpenAccess selectById(Serializable id);
@Override
int insert(PayOpenAccess entity);
@Override
int updateById(@Param(Constants.ENTITY) PayOpenAccess entity);
@Override
int update(@Param(Constants.ENTITY) PayOpenAccess entity, @Param("ew") Wrapper<PayOpenAccess> updateWrapper);
@Override
int deleteById(Serializable id);
/**
* 自定义查询SQL
* @param sql
* @return
*/
@Select("${sql}")
List<JSONObject> selectBySQL(@Param("sql") String sql, @Param("et")Map param);
/**
* 自定义更新SQL
* @param sql
* @return
*/
@Update("${sql}")
boolean updateBySQL(@Param("sql") String sql, @Param("et")Map param);
/**
* 自定义插入SQL
* @param sql
* @return
*/
@Insert("${sql}")
boolean insertBySQL(@Param("sql") String sql, @Param("et")Map param);
/**
* 自定义删除SQL
* @param sql
* @return
*/
@Delete("${sql}")
boolean deleteBySQL(@Param("sql") String sql, @Param("et")Map param);
}
package cn.ibizlab.core.pay.mapper;
import java.util.List;
import org.apache.ibatis.annotations.*;
import java.util.Map;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import java.util.HashMap;
import org.apache.ibatis.annotations.Select;
import cn.ibizlab.core.pay.domain.PayTrade;
import cn.ibizlab.core.pay.filter.PayTradeSearchContext;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import java.io.Serializable;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.alibaba.fastjson.JSONObject;
public interface PayTradeMapper extends BaseMapper<PayTrade>{
Page<PayTrade> searchDefault(IPage page, @Param("srf") PayTradeSearchContext context, @Param("ew") Wrapper<PayTrade> wrapper) ;
@Override
PayTrade selectById(Serializable id);
@Override
int insert(PayTrade entity);
@Override
int updateById(@Param(Constants.ENTITY) PayTrade entity);
@Override
int update(@Param(Constants.ENTITY) PayTrade entity, @Param("ew") Wrapper<PayTrade> updateWrapper);
@Override
int deleteById(Serializable id);
/**
* 自定义查询SQL
* @param sql
* @return
*/
@Select("${sql}")
List<JSONObject> selectBySQL(@Param("sql") String sql, @Param("et")Map param);
/**
* 自定义更新SQL
* @param sql
* @return
*/
@Update("${sql}")
boolean updateBySQL(@Param("sql") String sql, @Param("et")Map param);
/**
* 自定义插入SQL
* @param sql
* @return
*/
@Insert("${sql}")
boolean insertBySQL(@Param("sql") String sql, @Param("et")Map param);
/**
* 自定义删除SQL
* @param sql
* @return
*/
@Delete("${sql}")
boolean deleteBySQL(@Param("sql") String sql, @Param("et")Map param);
}
package cn.ibizlab.core.pay.service;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Collection;
import java.math.BigInteger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cache.annotation.CacheEvict;
import cn.ibizlab.core.pay.domain.PayOpenAccess;
import cn.ibizlab.core.pay.filter.PayOpenAccessSearchContext;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 实体[PayOpenAccess] 服务对象接口
*/
public interface IPayOpenAccessService extends IService<PayOpenAccess>{
boolean create(PayOpenAccess et) ;
void createBatch(List<PayOpenAccess> list) ;
boolean update(PayOpenAccess et) ;
void updateBatch(List<PayOpenAccess> list) ;
boolean remove(String key) ;
void removeBatch(Collection<String> idList) ;
PayOpenAccess get(String key) ;
PayOpenAccess getDraft(PayOpenAccess et) ;
boolean checkKey(PayOpenAccess et) ;
boolean save(PayOpenAccess et) ;
void saveBatch(List<PayOpenAccess> list) ;
Page<PayOpenAccess> searchDefault(PayOpenAccessSearchContext context) ;
/**
*自定义查询SQL
* @param sql select * from table where id =#{et.param}
* @param param 参数列表 param.put("param","1");
* @return select * from table where id = '1'
*/
List<JSONObject> select(String sql, Map param);
/**
*自定义SQL
* @param sql update table set name ='test' where id =#{et.param}
* @param param 参数列表 param.put("param","1");
* @return update table set name ='test' where id = '1'
*/
boolean execute(String sql, Map param);
}
package cn.ibizlab.core.pay.service;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Collection;
import java.math.BigInteger;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cache.annotation.CacheEvict;
import cn.ibizlab.core.pay.domain.PayTrade;
import cn.ibizlab.core.pay.filter.PayTradeSearchContext;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 实体[PayTrade] 服务对象接口
*/
public interface IPayTradeService extends IService<PayTrade>{
boolean create(PayTrade et) ;
void createBatch(List<PayTrade> list) ;
boolean update(PayTrade et) ;
void updateBatch(List<PayTrade> list) ;
boolean remove(String key) ;
void removeBatch(Collection<String> idList) ;
PayTrade get(String key) ;
PayTrade getDraft(PayTrade et) ;
boolean checkKey(PayTrade et) ;
boolean save(PayTrade et) ;
void saveBatch(List<PayTrade> list) ;
Page<PayTrade> searchDefault(PayTradeSearchContext context) ;
/**
*自定义查询SQL
* @param sql select * from table where id =#{et.param}
* @param param 参数列表 param.put("param","1");
* @return select * from table where id = '1'
*/
List<JSONObject> select(String sql, Map param);
/**
*自定义SQL
* @param sql update table set name ='test' where id =#{et.param}
* @param param 参数列表 param.put("param","1");
* @return update table set name ='test' where id = '1'
*/
boolean execute(String sql, Map param);
}
package cn.ibizlab.core.pay.service.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.math.BigInteger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.util.ObjectUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Lazy;
import cn.ibizlab.core.pay.domain.PayOpenAccess;
import cn.ibizlab.core.pay.filter.PayOpenAccessSearchContext;
import cn.ibizlab.core.pay.service.IPayOpenAccessService;
import cn.ibizlab.util.helper.CachedBeanCopier;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.ibizlab.core.pay.mapper.PayOpenAccessMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.StringUtils;
/**
* 实体[支付平台] 服务对象接口实现
*/
@Slf4j
@Service("PayOpenAccessServiceImpl")
public class PayOpenAccessServiceImpl extends ServiceImpl<PayOpenAccessMapper, PayOpenAccess> implements IPayOpenAccessService {
protected int batchSize = 500;
@Override
@Transactional
public boolean create(PayOpenAccess et) {
if(!this.retBool(this.baseMapper.insert(et)))
return false;
CachedBeanCopier.copy(get(et.getId()),et);
return true;
}
@Override
public void createBatch(List<PayOpenAccess> list) {
this.saveBatch(list,batchSize);
}
@Override
@Transactional
public boolean update(PayOpenAccess et) {
if(!update(et,(Wrapper) et.getUpdateWrapper(true).eq("accessid",et.getId())))
return false;
CachedBeanCopier.copy(get(et.getId()),et);
return true;
}
@Override
public void updateBatch(List<PayOpenAccess> list) {
updateBatchById(list,batchSize);
}
@Override
@Transactional
public boolean remove(String key) {
boolean result=removeById(key);
return result ;
}
@Override
public void removeBatch(Collection<String> idList) {
removeByIds(idList);
}
@Override
@Transactional
public PayOpenAccess get(String key) {
PayOpenAccess et = getById(key);
if(et==null){
et=new PayOpenAccess();
et.setId(key);
}
else{
}
return et;
}
@Override
public PayOpenAccess getDraft(PayOpenAccess et) {
return et;
}
@Override
public boolean checkKey(PayOpenAccess et) {
return (!ObjectUtils.isEmpty(et.getId()))&&(!Objects.isNull(this.getById(et.getId())));
}
@Override
@Transactional
public boolean save(PayOpenAccess et) {
if(!saveOrUpdate(et))
return false;
return true;
}
@Override
@Transactional
public boolean saveOrUpdate(PayOpenAccess et) {
if (null == et) {
return false;
} else {
return checkKey(et) ? this.update(et) : this.create(et);
}
}
@Override
public boolean saveBatch(Collection<PayOpenAccess> list) {
saveOrUpdateBatch(list,batchSize);
return true;
}
@Override
public void saveBatch(List<PayOpenAccess> list) {
saveOrUpdateBatch(list,batchSize);
}
/**
* 查询集合 数据集
*/
@Override
public Page<PayOpenAccess> searchDefault(PayOpenAccessSearchContext context) {
com.baomidou.mybatisplus.extension.plugins.pagination.Page<PayOpenAccess> pages=baseMapper.searchDefault(context.getPages(),context,context.getSelectCond());
return new PageImpl<PayOpenAccess>(pages.getRecords(), context.getPageable(), pages.getTotal());
}
@Override
public List<JSONObject> select(String sql, Map param){
return this.baseMapper.selectBySQL(sql,param);
}
@Override
@Transactional
public boolean execute(String sql , Map param){
if (sql == null || sql.isEmpty()) {
return false;
}
if (sql.toLowerCase().trim().startsWith("insert")) {
return this.baseMapper.insertBySQL(sql,param);
}
if (sql.toLowerCase().trim().startsWith("update")) {
return this.baseMapper.updateBySQL(sql,param);
}
if (sql.toLowerCase().trim().startsWith("delete")) {
return this.baseMapper.deleteBySQL(sql,param);
}
log.warn("暂未支持的SQL语法");
return true;
}
}
package cn.ibizlab.core.pay.service.impl;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.HashSet;
import java.util.HashMap;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.math.BigInteger;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.util.ObjectUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Lazy;
import cn.ibizlab.core.pay.domain.PayTrade;
import cn.ibizlab.core.pay.filter.PayTradeSearchContext;
import cn.ibizlab.core.pay.service.IPayTradeService;
import cn.ibizlab.util.helper.CachedBeanCopier;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.ibizlab.core.pay.mapper.PayTradeMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.StringUtils;
/**
* 实体[支付交易] 服务对象接口实现
*/
@Slf4j
@Service("PayTradeServiceImpl")
public class PayTradeServiceImpl extends ServiceImpl<PayTradeMapper, PayTrade> implements IPayTradeService {
protected int batchSize = 500;
@Override
@Transactional
public boolean create(PayTrade et) {
if(!this.retBool(this.baseMapper.insert(et)))
return false;
CachedBeanCopier.copy(get(et.getTradeid()),et);
return true;
}
@Override
public void createBatch(List<PayTrade> list) {
this.saveBatch(list,batchSize);
}
@Override
@Transactional
public boolean update(PayTrade et) {
if(!update(et,(Wrapper) et.getUpdateWrapper(true).eq("tradeid",et.getTradeid())))
return false;
CachedBeanCopier.copy(get(et.getTradeid()),et);
return true;
}
@Override
public void updateBatch(List<PayTrade> list) {
updateBatchById(list,batchSize);
}
@Override
@Transactional
public boolean remove(String key) {
boolean result=removeById(key);
return result ;
}
@Override
public void removeBatch(Collection<String> idList) {
removeByIds(idList);
}
@Override
@Transactional
public PayTrade get(String key) {
PayTrade et = getById(key);
if(et==null){
et=new PayTrade();
et.setTradeid(key);
}
else{
}
return et;
}
@Override
public PayTrade getDraft(PayTrade et) {
return et;
}
@Override
public boolean checkKey(PayTrade et) {
return (!ObjectUtils.isEmpty(et.getTradeid()))&&(!Objects.isNull(this.getById(et.getTradeid())));
}
@Override
@Transactional
public boolean save(PayTrade et) {
if(!saveOrUpdate(et))
return false;
return true;
}
@Override
@Transactional
public boolean saveOrUpdate(PayTrade et) {
if (null == et) {
return false;
} else {
return checkKey(et) ? this.update(et) : this.create(et);
}
}
@Override
public boolean saveBatch(Collection<PayTrade> list) {
saveOrUpdateBatch(list,batchSize);
return true;
}
@Override
public void saveBatch(List<PayTrade> list) {
saveOrUpdateBatch(list,batchSize);
}
/**
* 查询集合 数据集
*/
@Override
public Page<PayTrade> searchDefault(PayTradeSearchContext context) {
com.baomidou.mybatisplus.extension.plugins.pagination.Page<PayTrade> pages=baseMapper.searchDefault(context.getPages(),context,context.getSelectCond());
return new PageImpl<PayTrade>(pages.getRecords(), context.getPageable(), pages.getTotal());
}
@Override
public List<JSONObject> select(String sql, Map param){
return this.baseMapper.selectBySQL(sql,param);
}
@Override
@Transactional
public boolean execute(String sql , Map param){
if (sql == null || sql.isEmpty()) {
return false;
}
if (sql.toLowerCase().trim().startsWith("insert")) {
return this.baseMapper.insertBySQL(sql,param);
}
if (sql.toLowerCase().trim().startsWith("update")) {
return this.baseMapper.updateBySQL(sql,param);
}
if (sql.toLowerCase().trim().startsWith("delete")) {
return this.baseMapper.deleteBySQL(sql,param);
}
log.warn("暂未支持的SQL语法");
return true;
}
}
package cn.ibizlab.core.util.config;
import org.kie.api.KieBase;
import org.kie.api.KieServices;
import org.kie.api.builder.*;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.internal.io.ResourceFactory;
import org.kie.spring.KModuleBeanFactoryPostProcessor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.IOException;
import java.util.List;
@Configuration
public class DroolsAutoConfiguration {
private Log logger= LogFactory.getLog(DroolsAutoConfiguration.class);
private static final String RULES_PATH = "rules/";
@Bean
@ConditionalOnMissingBean(KieFileSystem.class)
public KieFileSystem kieFileSystem() throws IOException {
KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
for (Resource file : getRuleFiles()) {
kieFileSystem.write(ResourceFactory.newUrlResource(file.getURL()));
}
return kieFileSystem;
}
private Resource[] getRuleFiles() throws IOException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
return resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "**/*.*");
}
@Bean
@ConditionalOnMissingBean(KieContainer.class)
public KieContainer kieContainer() throws IOException {
final KieRepository kieRepository = getKieServices().getRepository();
kieRepository.addKieModule(new KieModule() {
public ReleaseId getReleaseId() {
return kieRepository.getDefaultReleaseId();
}
});
KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem());
kieBuilder.buildAll();
if(kieBuilder.getResults().hasMessages(new Message.Level[] { Message.Level.ERROR })){
List<Message> errors = kieBuilder.getResults().getMessages(new Message.Level[] { Message.Level.ERROR });
StringBuilder stringBuilder = new StringBuilder("Errors:");
for (Message msg : errors)
{
stringBuilder.append(new StringBuilder().append("\n ").append(prettyBuildMessage(msg)).toString());
}
logger.error(String.format("初始化处理逻辑发生异常,异常原因为[%s]",stringBuilder.toString()));
//忽略处理逻辑
getKieServices().newKieBuilder(getKieServices().newKieFileSystem()).buildAll();
}
return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());
}
private KieServices getKieServices() {
return KieServices.Factory.get();
}
@Bean
@ConditionalOnMissingBean(KieBase.class)
public KieBase kieBase() throws IOException {
return kieContainer().getKieBase();
}
@Bean
@ConditionalOnMissingBean(KieSession.class)
public KieSession kieSession() throws IOException {
return kieContainer().newKieSession();
}
@Bean
@ConditionalOnMissingBean(KModuleBeanFactoryPostProcessor.class)
public KModuleBeanFactoryPostProcessor kiePostProcessor() {
return new KModuleBeanFactoryPostProcessor();
}
/**
* 输出异常信息
* @param msg
* @return
*/
public static String prettyBuildMessage(Message msg)
{
return new StringBuilder().append("Message: {id=").append(msg.getId()).append(", level=").append(msg.getLevel()).append(", path=").append(msg.getPath()).append(", line=").append(msg.getLine())
.append(", column=").append(msg.getColumn()).append(", text=\"").append(msg.getText()).append("\"}").toString();
}
}
\ No newline at end of file
package cn.ibizlab.core.util.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import java.util.Properties;
import org.springframework.context.annotation.Primary;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.jdbc.DataSourceBuilder;
import cn.ibizlab.util.domain.LiquibaseProp;
import org.springframework.beans.factory.annotation.Autowired;
import liquibase.integration.spring.SpringLiquibase;
import org.springframework.util.StringUtils;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
@Configuration
public class LiquibaseConfiguration {
/**
* 主数据源版本管理
* @param
* @return
*/
@Bean
public SpringLiquibase masterliquibase(LiquibaseProp masterProperties) {
return LiquibaseInit(masterProperties);
}
/**
* liquibase初始化数据库
* @param properties
* @return
*/
private SpringLiquibase LiquibaseInit(LiquibaseProp properties){
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setUsername(properties.getUsername());
druidDataSource.setPassword(properties.getPassword());
druidDataSource.setUrl(properties.getUrl());
SpringLiquibase liquibase = new SpringLiquibase();
liquibase.setDataSource(druidDataSource);
liquibase.setChangeLog(getChangelog(properties.getIsSyncDBSchema(),properties.getConf()));
liquibase.setContexts("development,test,production");
liquibase.setShouldRun(true);
liquibase.setDefaultSchema(properties.getDefaultSchema());
return liquibase;
}
/**
* 获取数据库差异文件
* @param isSyncDBSchema 是否同步表结构
* @param conf //liquibase配置文件
* @return
*/
private String getChangelog(String isSyncDBSchema,String conf){
String defaultChangelog="classpath:liquibase/empty.xml";
if((!StringUtils.isEmpty(isSyncDBSchema))&&(!StringUtils.isEmpty(conf))){
if(isSyncDBSchema.toLowerCase().equals("true"))
defaultChangelog=conf;
}
return defaultChangelog;
}
}
\ No newline at end of file
package cn.ibizlab.core.util.config;
import cn.ibizlab.util.helper.JSR310DateConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.mongodb.core.convert.*;
import java.util.ArrayList;
import java.util.List;
@Configuration
public class MongoDBConfig {
@Bean
public MongoCustomConversions customConversions() {
List<Converter<?, ?>> converterList = new ArrayList<>();
converterList.add(JSR310DateConverters.DateToZonedDateTimeConverter.INSTANCE);
converterList.add(JSR310DateConverters.ZonedDateTimeToDateConverter.INSTANCE);
converterList.add(JSR310DateConverters.DurationToLongConverter.INSTANCE);
converterList.add(JSR310DateConverters.TimestampToDateConverter.INSTANCE);
converterList.add(JSR310DateConverters.DateToTimestampConverter.INSTANCE);
return new MongoCustomConversions(converterList);
}
}
\ No newline at end of file
package cn.ibizlab.core.util.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Configuration;
/**
* mybatis自动配置
*/
@Configuration
@ConditionalOnClass(MybatisConfiguration.class)
@ConditionalOnWebApplication
public class MybatisAutoConfiguration {
}
package cn.ibizlab.core.util.config;
import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties;
import cn.ibizlab.util.helper.UniqueNameGenerator;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.mybatis.spring.annotation.MapperScan;
import java.util.Properties;
/**
* mybatis全局配置类
*/
@Configuration
@MapperScan(value="cn.ibizlab.core.*.mapper",nameGenerator = UniqueNameGenerator.class)
public class MybatisConfiguration {
/**
* mybatis适配多数据库
* @return
*/
@Bean
public DatabaseIdProvider getDatabaseIdProvider() {
DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
Properties p = new Properties();
p.setProperty("Oracle", "oracle");
p.setProperty("MySQL", "mysql");
p.setProperty("PostgreSQL", "postgresql");
p.setProperty("DM", "oracle");//达梦数据库使用oracle模式
p.setProperty("H2", "mysql");//根据当前运行的数据库设置h2对应的databaseid
databaseIdProvider.setProperties(p);
return databaseIdProvider;
}
/**
* mybatis-plus分页
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
paginationInterceptor.setLimit(-1);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
\ No newline at end of file
package cn.ibizlab.core.util.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Configuration;
@ConditionalOnExpression("!'${jobs.admin-address:NA}'.equals('NA')")
@Configuration
public class XxlJobConfig {
}
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
<changeSet author="Think (generated)" id="1561433044682-1">
<createTable remarks="文件" tableName="IBZFILE">
<column name="FILEID" type="VARCHAR2(100 BYTE)">
<constraints primaryKey="true" primaryKeyName="SYS_C00168533"/>
</column>
<column name="FILENAME" type="VARCHAR2(200 BYTE)"/>
<column name="FILEPATH" type="VARCHAR2(500 BYTE)"/>
<column name="FOLDER" type="VARCHAR2(20 BYTE)"/>
<column name="CREATEMAN" type="VARCHAR2(60 BYTE)"/>
<column name="CREATEDATE" type="date"/>
<column name="UPDATEMAN" type="VARCHAR2(60 BYTE)"/>
<column name="UPDATEDATE" type="date"/>
<column name="FILEEXT" type="VARCHAR2(10 BYTE)"/>
<column name="FILESIZE" type="INTEGER"/>
<column name="DIGESTCODE" type="VARCHAR2(64 BYTE)"/>
<column name="OWNERTYPE" type="VARCHAR2(100 BYTE)"/>
<column name="OWNERID" type="VARCHAR2(100 BYTE)"/>
<column name="MEMO" type="VARCHAR2(500 BYTE)"/>
<column name="RESERVER" type="VARCHAR2(100 BYTE)"/>
</createTable>
</changeSet>
<changeSet author="Think (generated)" id="1561433044682-2">
<createTable remarks="用户" tableName="IBZUSER">
<column name="USERID" type="VARCHAR2(100 BYTE)">
<constraints primaryKey="true" primaryKeyName="SYS_C00168531"/>
</column>
<column name="PERSONNAME" type="VARCHAR2(200 BYTE)"/>
<column name="USERNAME" type="VARCHAR2(200 BYTE)"/>
<column name="USERCODE" type="VARCHAR2(100 BYTE)"/>
<column name="LOGINNAME" type="VARCHAR2(100 BYTE)"/>
<column name="PASSWORD" type="VARCHAR2(100 BYTE)"/>
<column name="DOMAINS" type="VARCHAR2(100 BYTE)"/>
<column name="MDEPTID" type="VARCHAR2(100 BYTE)"/>
<column name="MDEPTCODE" type="VARCHAR2(100 BYTE)"/>
<column name="MDEPTNAME" type="VARCHAR2(200 BYTE)"/>
<column name="BCODE" type="VARCHAR2(100 BYTE)"/>
<column name="POSTID" type="VARCHAR2(100 BYTE)"/>
<column name="POSTCODE" type="VARCHAR2(100 BYTE)"/>
<column name="POSTNAME" type="VARCHAR2(200 BYTE)"/>
<column name="ORGID" type="VARCHAR2(100 BYTE)"/>
<column name="ORGCODE" type="VARCHAR2(100 BYTE)"/>
<column name="ORGNAME" type="VARCHAR2(200 BYTE)"/>
<column name="NICKNAME" type="VARCHAR2(36 BYTE)"/>
<column name="EMAIL" type="VARCHAR2(100 BYTE)"/>
<column name="AVATAR" type="VARCHAR2(100 BYTE)"/>
<column name="PHONE" type="VARCHAR2(100 BYTE)"/>
<column name="RESERVER" type="VARCHAR2(100 BYTE)"/>
<column name="USERICON" type="VARCHAR2(100 BYTE)"/>
<column name="SEX" type="VARCHAR2(10 BYTE)"/>
<column name="BIRTHDAY" type="date"/>
<column name="CERTCODE" type="VARCHAR2(36 BYTE)"/>
<column name="ADDR" type="VARCHAR2(200 BYTE)"/>
<column name="THEME" type="VARCHAR2(100 BYTE)"/>
<column name="FONTSIZE" type="VARCHAR2(10 BYTE)"/>
<column name="LANG" type="VARCHAR2(100 BYTE)"/>
<column name="MEMO" type="VARCHAR2(500 BYTE)"/>
<column name="SUPERUSER" type="INTEGER"/>
</createTable>
</changeSet>
<changeSet author="Think (generated)" id="1561433044682-3">
<insert tableName="IBZUSER">
<column name="USERID" value="0100"/>
<column name="PERSONNAME" value="管理员"/>
<column name="USERNAME" value="系统管理员"/>
<column name="USERCODE" value="0100"/>
<column name="LOGINNAME" value="ibzadmin"/>
<column name="SUPERUSER" value="1"/>
<column name="PASSWORD" value="123456"/>
<column name="DOMAINS" value="100000"/>
<column name="MDEPTID"/>
<column name="MDEPTCODE"/>
<column name="MDEPTNAME"/>
<column name="BCODE"/>
<column name="POSTID"/>
<column name="POSTCODE"/>
<column name="POSTNAME"/>
<column name="ORGID"/>
<column name="ORGCODE"/>
<column name="ORGNAME"/>
<column name="NICKNAME"/>
<column name="EMAIL"/>
<column name="AVATAR"/>
<column name="PHONE"/>
<column name="RESERVER"/>
<column name="USERICON"/>
<column name="SEX"/>
<column name="BIRTHDAY"/>
<column name="CERTCODE"/>
<column name="ADDR"/>
<column name="THEME"/>
<column name="FONTSIZE"/>
<column name="LANG"/>
<column name="MEMO"/>
</insert>
</changeSet>
</databaseChangeLog>
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.9.xsd">
<changeSet author="Think (generated)" id="1591012776347-1">
<createTable remarks="配置" tableName="IBZCFG">
<column name="CFGID" remarks="配置标识" type="VARCHAR(100)">
<constraints primaryKey="true"/>
</column>
<column name="SYSTEMID" remarks="系统标识" type="VARCHAR(100)"/>
<column name="CFGTYPE" remarks="配置类型" type="VARCHAR(100)"/>
<column name="TARGETTYPE" remarks="引用对象" type="VARCHAR(100)"/>
<column name="USERID" remarks="用户标识" type="VARCHAR(100)"/>
<column name="CFG" remarks="配置" type="MEDIUMTEXT"/>
<column name="UPDATEDATE" remarks="更新时间" type="datetime"/>
</createTable>
</changeSet>
</databaseChangeLog>
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
<changeSet author="Think (generated)" id="1566027230162-1">
<preConditions onFail="MARK_RAN" >
<not>
<tableExists tableName="IBZDATAAUDIT" />
</not>
</preConditions>
<createTable remarks="数据审计" tableName="IBZDATAAUDIT">
<column name="DATAAUDITID" remarks="数据审计标识" type="VARCHAR2(100 BYTE)">
<constraints primaryKey="true" primaryKeyName="SYS_C00115093"/>
</column>
<column name="OPPERSONID" remarks="操作人标识" type="VARCHAR2(100 BYTE)"/>
<column name="OPPERSONNAME" remarks="操作人名称" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITTYPE" remarks="审计行为类型" type="VARCHAR2(60 BYTE)"/>
<column name="OPTIME" remarks="操作时间" type="date"/>
<column name="IPADDRESS" remarks="访问地址" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITOBJECTDATA" remarks="审计对象(表数据)" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITOBJECT" remarks="审计对象(表)" type="VARCHAR2(100 BYTE)"/>
<column name="AUDITINFO" remarks="审计明细" type="CLOB"/>
<column name="ISDATACHANGED" remarks="审计数据是否发生变化" type="INTEGER"/>
</createTable>
</changeSet>
</databaseChangeLog>
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<!--liquibase启动时需要指定chanlogxml,若无changelog,则使用此xml来初始化liquibase,使liquibase能正常启动 -->
</databaseChangeLog>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<include file="changelog/20190625112530_init_ibizsys.xml" relativeToChangelogFile="true"/>
<include file="h2_table.xml" relativeToChangelogFile="true"/>
<include file="view.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
\ No newline at end of file
!!!!模版产生代码错误:----
Tip: If the failing expression is known to be legally refer to something that's sometimes null or missing, either specify a default value like myOptionalVar!myDefault, or use <#if myOptionalVar??>when-present<#else>when-missing</#if>. (These only cover the last step of the expression; to cover the whole expression, use parenthesis: (myOptionalVar.foo)!myDefault, (myOptionalVar.foo)??
----
----
FTL stack trace ("~" means nesting-related):
- Failed at: ${dbinst.getUserName()} [in template "CODETEMPL_zh_CN" at line 28, column 24]
----
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<includeAll path="liquibase/changelog/"/>
<include file="view.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<includeAll path="liquibase/changelog/"/>
</databaseChangeLog>
\ No newline at end of file
此文件只用于让模板能发出[rollback]文件夹,无实际用途
\ No newline at end of file
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.6.xsd">
</databaseChangeLog>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.ibizlab.core.pay.mapper.PayOpenAccessMapper">
<!--该方法用于重写mybatis中selectById方法,以实现查询逻辑属性-->
<select id="selectById" resultMap="PayOpenAccessResultMap" databaseId="oracle">
<![CDATA[select t1.* from (SELECT t1.ACCESSID, t1.ACCESSNAME, t1.ACCESS_KEY, t1.ACCESS_TOKEN, t1.DISABLED, t1.EXPIRES_TIME, t1.OPEN_TYPE, t1.REDIRECT_URI, t1.REGION_ID, t1.SECRET_KEY FROM IBZOPENACCESS t1 ) t1 where accessid=#{id}]]>
</select>
<!--通过mybatis将查询结果注入到entity中,通过配置autoMapping="true"由mybatis自动处理映射关系 -->
<resultMap id="PayOpenAccessResultMap" type="cn.ibizlab.core.pay.domain.PayOpenAccess" autoMapping="true">
<id property="id" column="accessid" /><!--主键字段映射-->
<result property="name" column="accessname" />
<result property="openType" column="open_type" />
<result property="accessKey" column="access_key" />
<result property="secretKey" column="secret_key" />
<result property="regionId" column="region_id" />
<result property="accessToken" column="access_token" />
<result property="expiresTime" column="expires_time" />
<result property="redirectUri" column="redirect_uri" />
</resultMap>
<!--数据集合[Default]-->
<select id="searchDefault" parameterType="cn.ibizlab.core.pay.filter.PayOpenAccessSearchContext" resultMap="PayOpenAccessResultMap">
select t1.* from (
<include refid="Default" />
)t1
<where><if test="ew!=null and ew.sqlSegment!=null and !ew.emptyOfWhere">${ew.sqlSegment}</if></where>
<if test="ew!=null and ew.sqlSegment!=null and ew.emptyOfWhere">${ew.sqlSegment}</if>
</select>
<!--数据查询[Default]-->
<sql id="Default" databaseId="oracle">
<![CDATA[ SELECT t1.ACCESSID, t1.ACCESSNAME, t1.ACCESS_KEY, t1.ACCESS_TOKEN, t1.DISABLED, t1.EXPIRES_TIME, t1.OPEN_TYPE, t1.REDIRECT_URI, t1.REGION_ID, t1.SECRET_KEY FROM IBZOPENACCESS t1
]]>
</sql>
<!--数据查询[View]-->
<sql id="View" databaseId="oracle">
<![CDATA[ SELECT t1.ACCESSID, t1.ACCESSNAME, t1.ACCESS_KEY, t1.ACCESS_TOKEN, t1.DISABLED, t1.EXPIRES_TIME, t1.OPEN_TYPE, t1.REDIRECT_URI, t1.REGION_ID, t1.SECRET_KEY FROM IBZOPENACCESS t1
]]>
</sql>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.ibizlab.core.pay.mapper.PayTradeMapper">
<!--该方法用于重写mybatis中selectById方法,以实现查询逻辑属性-->
<select id="selectById" resultMap="PayTradeResultMap" databaseId="oracle">
<![CDATA[select t1.* from (SELECT t1.TRADEID, t1.TRADENAME FROM IBZPAYTRADE t1 ) t1 where tradeid=#{id}]]>
</select>
<!--通过mybatis将查询结果注入到entity中,通过配置autoMapping="true"由mybatis自动处理映射关系 -->
<resultMap id="PayTradeResultMap" type="cn.ibizlab.core.pay.domain.PayTrade" autoMapping="true">
<id property="tradeid" column="tradeid" /><!--主键字段映射-->
</resultMap>
<!--数据集合[Default]-->
<select id="searchDefault" parameterType="cn.ibizlab.core.pay.filter.PayTradeSearchContext" resultMap="PayTradeResultMap">
select t1.* from (
<include refid="Default" />
)t1
<where><if test="ew!=null and ew.sqlSegment!=null and !ew.emptyOfWhere">${ew.sqlSegment}</if></where>
<if test="ew!=null and ew.sqlSegment!=null and ew.emptyOfWhere">${ew.sqlSegment}</if>
</select>
<!--数据查询[Default]-->
<sql id="Default" databaseId="oracle">
<![CDATA[ SELECT t1.TRADEID, t1.TRADENAME FROM IBZPAYTRADE t1
]]>
</sql>
<!--数据查询[View]-->
<sql id="View" databaseId="oracle">
<![CDATA[ SELECT t1.TRADEID, t1.TRADENAME FROM IBZPAYTRADE t1
]]>
</sql>
</mapper>
{
"systemid":"ibzpay",
"unires":[
],
"entities":[
],
"appmenus":[
]
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>ibzpay-dependencies</artifactId>
<groupId>cn.ibizlab</groupId>
<version>1.0.0.0</version>
<name>Ibzpay Dependencies</name>
<packaging>pom</packaging>
<description>Ibzpay Dependencies</description>
<!-- Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
</parent>
<properties>
<!-- Spring Cloud Alibaba(2.2.x.RELEASE) & Spring Cloud(Spring Cloud Greenwich) & Spring Boot(2.2.x.RELEASE) compatibility -->
<spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
<spring-cloud-openfeign.version>2.2.1.RELEASE</spring-cloud-openfeign.version>
<!-- Alibaba Druid -->
<alibaba-druid.version>1.1.16</alibaba-druid.version>
<!-- Mybatis Plus -->
<mybatis-plus.version>3.3.1</mybatis-plus.version>
<mybatis-plus-dynamic-datasource.version>3.0.0</mybatis-plus-dynamic-datasource.version>
<!-- Liquibase -->
<liquibase.version>3.6.3</liquibase.version>
<!-- Swagger2 -->
<springfox-swagger.version>2.9.2</springfox-swagger.version>
<!-- JBPM+Drools -->
<drools-version>7.23.0.Final</drools-version>
<!-- Error -->
<zalando-problem-spring-web.version>0.23.0</zalando-problem-spring-web.version>
<!-- Security -->
<spring-cloud-security.version>2.1.1.RELEASE</spring-cloud-security.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<!--logstash-logback-encoder-->
<logstash.version>5.2</logstash.version>
<!--Zuul网关-->
<spring-cloud-starter-netflix-zuul.version>2.2.1.RELEASE</spring-cloud-starter-netflix-zuul.version>
<!--MapStruct高性能属性映射工具-->
<mapstruct.version>1.3.0.Final</mapstruct.version>
<!--Java Web Token-->
<jsonwebtoken-jjwt.version>0.9.1</jsonwebtoken-jjwt.version>
<!--Liquibase数据库版本更新工具-->
<liquibase.version>3.8.7</liquibase.version>
<!--H2内存数据库-->
<h2.version>1.4.200</h2.version>
<!--caffeine缓存-->
<caffeine-cache.version>2.6.0</caffeine-cache.version>
<!--反序列化工具-->
<kryo.version>4.0.2</kryo.version>
<!--httpClient -->
<openfeign-httpclient.version>11.0</openfeign-httpclient.version>
<!--baomidou-jobs定时服务 -->
<baomidou-jobs.version>1.0.3</baomidou-jobs.version>
<!-- eureka微服务注册中心 -->
<eureka-client.version>2.2.1.RELEASE</eureka-client.version>
<!-- 阿里sentinel熔断器 -->
<alibaba-sentinel.version>2.1.1.RELEASE</alibaba-sentinel.version>
<!-- 阿里seata分布式事务 -->
<alibaba-seata.version>1.3.0</alibaba-seata.version>
<oracle.version>11.2.0.3</oracle.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- Alibaba Cloud -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-dependencies</artifactId>
<version>${spring-cloud-openfeign.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Alibaba Druid -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${alibaba-druid.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${alibaba-druid.version}</version>
</dependency>
<!-- Mybatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${mybatis-plus-dynamic-datasource.version}</version>
</dependency>
<!-- Liquibase -->
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
<version>${liquibase.version}</version>
</dependency>
<!-- H2 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<!-- Swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<!-- JBPM -->
<dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-flow-builder</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.jbpm</groupId>
<artifactId>jbpm-bpmn2</artifactId>
<version>${drools-version}</version>
</dependency>
<!-- Drools -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-spring</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>${drools-version}</version>
</dependency>
<!-- Error -->
<!-- Security -->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>${spring-cloud-starter-netflix-zuul.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
<version>${spring-cloud-security.version}</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jsonwebtoken-jjwt.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${alibaba-druid.version}</version>
</dependency>
<dependency>
<groupId>org.zalando</groupId>
<artifactId>problem-spring-web</artifactId>
<version>${zalando-problem-spring-web.version}</version>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine-cache.version}</version>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo-shaded</artifactId>
<version>${kryo.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<version>${openfeign-httpclient.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>jobs-spring-boot-starter</artifactId>
<version>${baomidou-jobs.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>${alibaba-sentinel.version}</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- Httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<!-- 阿里Druid数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<!-- H2内存库 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<!-- eureka服务注册中心 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>${eureka-client.version}</version>
</dependency>
<!-- Oracle驱动包 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>${oracle.version}</version>
</dependency>
<!-- MySQL驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ibzpay-provider</artifactId>
<groupId>cn.ibizlab</groupId>
<version>1.0.0.0</version>
</parent>
<artifactId>ibzpay-provider-api</artifactId>
<name>Ibzpay Microservice api</name>
<description> microservice</description>
<dependencies>
<dependency>
<groupId>cn.ibizlab</groupId>
<artifactId>ibzpay-core</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>api</id>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<finalName>ibzpay-provider-api</finalName>
<jvmArguments>-Dfile.encoding=UTF-8</jvmArguments>
<mainClass>cn.ibizlab.api.ibzpayapiApplication</mainClass>
<outputDirectory>../../</outputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
FROM openjdk:8-jre-alpine
ENV TZ=Asia/Shanghai \
SPRING_OUTPUT_ANSI_ENABLED=ALWAYS \
IBIZ_SLEEP=0 \
JAVA_OPTS=""
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
CMD echo "The application will start in ${IBIZ_SLEEP}s..." && \
sleep ${IBIZ_SLEEP} && \
java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /ibzpay-provider-api.jar
EXPOSE 8081
ADD ibzpay-provider-api.jar /ibzpay-provider-api.jar
version: "3.2"
services:
ibzpay-provider-api:
image: registry.cn-shanghai.aliyuncs.com/ibizsys/ibzpay-provider-api:latest
ports:
- "8081:8081"
networks:
- agent_network
deploy:
resources:
limits:
memory: 4048M
reservations:
memory: 400M
mode: replicated
replicas: 1
volumes:
- "nfs:/app/file"
volumes:
nfs:
driver: local
driver_opts:
type: "nfs"
o: "addr=172.16.240.109,rw"
device: ":/nfs"
networks:
agent_network:
driver: overlay
attachable: true
package cn.ibizlab.api.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
import org.springframework.context.annotation.Import;
@Configuration
@ConditionalOnClass(apiRestConfiguration.class)
@ConditionalOnWebApplication
@EnableConfigurationProperties(apiServiceProperties.class)
public class apiAutoConfiguration implements ApplicationContextAware{
protected ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Bean("asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(2000);
executor.setKeepAliveSeconds(600);
executor.setThreadNamePrefix("asyncExecutor-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
// @Bean
// public ServletRegistrationBean apiServlet() {
// AnnotationConfigWebApplicationContext dispatcherServletConfiguration = new AnnotationConfigWebApplicationContext();
// dispatcherServletConfiguration.setParent(applicationContext);
// dispatcherServletConfiguration.register(apiRestConfiguration.class);
// DispatcherServlet servlet = new DispatcherServlet(dispatcherServletConfiguration);
// String path = "/api";
// String urlMapping = (path.endsWith("/") ? path + "*" : path + "/*");
// ServletRegistrationBean registrationBean = new ServletRegistrationBean(servlet, urlMapping);
// registrationBean.setName("api");
// return registrationBean;
// }
}
package cn.ibizlab.api.config;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan("cn.ibizlab.api")
public class apiRestConfiguration {
}
package cn.ibizlab.api.config;
import cn.ibizlab.util.security.AuthenticationEntryPoint;
import cn.ibizlab.util.security.AuthorizationTokenFilter;
import cn.ibizlab.util.service.AuthenticationUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.core.GrantedAuthorityDefaults;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.context.annotation.Profile;
import org.springframework.beans.factory.annotation.Qualifier;
@Profile("api-prod")
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class apiSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private AuthenticationEntryPoint unauthorizedHandler;
@Autowired
private AuthenticationUserService userDetailsService;
/**
* 自定义基于JWT的安全过滤器
*/
@Autowired
AuthorizationTokenFilter authenticationTokenFilter;
@Value("${ibiz.auth.path:v7/login}")
private String loginPath;
@Value("${ibiz.auth.logoutpath:v7/logout}")
private String logoutPath;
@Value("${ibiz.file.uploadpath:ibizutil/upload}")
private String uploadpath;
@Value("${ibiz.file.downloadpath:ibizutil/download}")
private String downloadpath;
@Value("${ibiz.file.previewpath:ibizutil/preview}")
private String previewpath;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoderBean());
}
@Bean
GrantedAuthorityDefaults grantedAuthorityDefaults() {
// Remove the ROLE_ prefix
return new GrantedAuthorityDefaults("");
}
@Bean
public PasswordEncoder passwordEncoderBean() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity
// 禁用 CSRF
.csrf().disable()
// 授权异常
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
// 不创建会话
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// 过滤请求
.authorizeRequests()
.antMatchers(
HttpMethod.GET,
"/*.html",
"/**/*.html",
"/**/*.css",
"/**/*.js",
"/**/*.ico",
"/**/assets/**",
"/**/css/**",
"/**/fonts/**",
"/**/js/**",
"/**/img/**",
"/",
"webjars/**",
"/swagger-resources/**",
"/v2/**"
).permitAll()
//放行登录请求
.antMatchers( HttpMethod.POST,"/"+loginPath).permitAll()
//放行注销请求
.antMatchers( HttpMethod.GET,"/"+logoutPath).permitAll()
// 文件操作
.antMatchers("/"+downloadpath+"/**").permitAll()
.antMatchers("/"+uploadpath).permitAll()
.antMatchers("/"+previewpath+"/**").permitAll()
// 所有请求都需要认证
.anyRequest().authenticated()
// 防止iframe 造成跨域
.and().headers().frameOptions().disable();
httpSecurity
.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}
package cn.ibizlab.api.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.Data;
@ConfigurationProperties(prefix = "service.api")
@Data
public class apiServiceProperties {
private boolean enabled;
private boolean auth;
}
\ No newline at end of file
package cn.ibizlab.api;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import cn.ibizlab.util.web.SearchContextHandlerMethodArgumentResolver;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@Slf4j
@EnableDiscoveryClient
@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages = {"cn.ibizlab"}
// ,excludeFilters={
// @ComponentScan.Filter(type= org.springframework.context.annotation.FilterType.REGEX,pattern="cn.ibizlab.api.rest.xxx"),
// }
)
@EnableMongoRepositories(basePackages = {"cn.ibizlab"})
@MapperScan("cn.ibizlab.*.mapper")
@SpringBootApplication(exclude = {
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.class,
})
@Import({
org.springframework.cloud.openfeign.FeignClientsConfiguration.class
})
@EnableFeignClients(basePackages = {"cn.ibizlab" })
@EnableAsync
@EnableScheduling
public class ibzpayapiApplication extends WebMvcConfigurerAdapter{
@Autowired
SearchContextHandlerMethodArgumentResolver resolver;
public static void main(String[] args) {
SpringApplication.run(ibzpayapiApplication.class, args);
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(resolver);
}
}
server:
port: 8081
#Log配置
logging:
level:
cn.ibizlab: info
\ No newline at end of file
spring:
profiles:
include: sys ,nacos, api-prod
application:
name: ibzpay-api
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<property name="LOG_PATH" value="logs" />
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] %-40.40logger{39} : %msg%n" />
<!-- 彩色日志 -->
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- 彩色日志格式 -->
<property name="LOG_PATTERN2" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr([${LOG_LEVEL_PATTERN:-%5p}]) %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
<!-- 控制台输出 -->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_PATH}/ibzpay-api.%d{yyyy-MM-dd}.log</FileNamePattern>
<!--日志文件保留天数-->
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
</encoder>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>100MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="INFO">
<appender-ref ref="Console" />
<appender-ref ref="file" />
</root>
</configuration>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ibzpay</artifactId>
<groupId>cn.ibizlab</groupId>
<version>1.0.0.0</version>
</parent>
<artifactId>ibzpay-provider</artifactId>
<name>Ibzpay Provider</name>
<packaging>pom</packaging>
<description>Ibzpay Provider</description>
<modules>
<module>ibzpay-provider-api</module>
</modules>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>ibzpay</artifactId>
<groupId>cn.ibizlab</groupId>
<version>1.0.0.0</version>
</parent>
<artifactId>ibzpay-util</artifactId>
<name>Ibzpay Util</name>
<description>Ibzpay Util</description>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
</dependency>
<dependency>
<groupId>org.zalando</groupId>
<artifactId>problem-spring-web</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo-shaded</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- Swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
</dependencies>
</project>
package cn.ibizlab.util.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD})
public @interface Audit
{
}
package cn.ibizlab.util.annotation;
import cn.ibizlab.util.enums.DEFieldDefaultValueType;
import cn.ibizlab.util.enums.DEPredefinedFieldType;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.FIELD})
public @interface DEField
{
/**
* 属性名称
* @return
*/
String name() default "";
/**
* 属性名称
* @return
*/
String value() default "";
/**
* 是否为数据主键
* @return
*/
boolean isKeyField() default false;
/**
* 默认值
* @return
*/
String defaultValue() default "";
/**
* 属性类型
* @return
*/
String fieldType() default"";
/**
* 默认值类型
* @return
*/
DEFieldDefaultValueType defaultValueType() default DEFieldDefaultValueType.NONE;
/**
* 预置属性类型
* @return
*/
DEPredefinedFieldType preType() default DEPredefinedFieldType.NONE;
/**
* 逻辑删除有效值
* @return
*/
String logicval() default "";
/**
* 逻辑删除无效值
* @return
*/
String logicdelval() default "";
/**
* 代码表
* @return
*/
String dict() default "";
/**
* 日期格式化
* @return
*/
String format() default "";
}
package cn.ibizlab.util.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD})
public @interface VersionCheck
{
String entity();
String versionfield();
}
package cn.ibizlab.util.aspect;
import lombok.SneakyThrows;
import cn.ibizlab.util.annotation.Audit;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import cn.ibizlab.util.service.IBZDataAuditService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
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.Map;
/**
* 实体数据审计切面类
*/
@Aspect
@Component
public class AuditAspect
{
private final ExpressionParser parser = new SpelExpressionParser();
@Autowired
IBZDataAuditService dataAuditService;
/**
* 实体数据建立切面,在成功创建数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* @param point
*/
@AfterReturning(value = "execution(* cn.ibizlab.core.*.service.*.create(..))")
@SneakyThrows
public void create(JoinPoint point){
HttpServletRequest request=null;
RequestAttributes requestAttributes= RequestContextHolder.getRequestAttributes();
if(requestAttributes!=null){
request=((ServletRequestAttributes)requestAttributes).getRequest();
}
Object [] args = point.getArgs();
if(ObjectUtils.isEmpty(args) || args.length==0)
return;
Object serviceParam =args[0];
EntityBase entity=(EntityBase)serviceParam;//创建数据
Map<String, Audit> auditFields= DEFieldCacheMap.getAuditFields(entity.getClass());
if(auditFields.size()==0)//是否有审计属性
return;
String idField=DEFieldCacheMap.getDEKeyField(entity.getClass());
Object idValue="";
if(!StringUtils.isEmpty(idField)){
idValue=entity.get(idField);
}
//记录审计日志
dataAuditService.createAudit(request,entity,idValue,auditFields);
return;
}
/**
* 实体数据更新切面,在成功更新数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* 使用环切【@Around】获取到更新前后的实体数据并进行差异比较,并将差异内容记入审计日志内
* @param point
*/
@Around("execution(* cn.ibizlab.core.*.service.*.update(..))")
public Object update(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request=null;
RequestAttributes requestAttributes= RequestContextHolder.getRequestAttributes();
if(requestAttributes!=null){
request=((ServletRequestAttributes)requestAttributes).getRequest();
}
Object serviceObj=point.getTarget();
Object args[]=point.getArgs();
if(ObjectUtils.isEmpty(args) || args.length==0)
return point.proceed();
Object arg=args[0];
EntityBase entity= (EntityBase) arg;
Map<String, Audit> auditFields= DEFieldCacheMap.getAuditFields(entity.getClass());
//是否有审计属性
if(auditFields.size()==0)
return point.proceed();
String idField=DEFieldCacheMap.getDEKeyField(entity.getClass());
Object idValue="";
if(!StringUtils.isEmpty(idField)){
idValue=entity.get(idField);
}
if(ObjectUtils.isEmpty(idValue))
return point.proceed();
//获取更新前实体
EntityBase beforeEntity=getEntity(serviceObj,idValue);
//执行更新操作
point.proceed();
//记录审计日志
dataAuditService.updateAudit(request,beforeEntity,serviceObj,idValue,auditFields);
return true;
}
/**
* 实体数据更新切面,在成功更新数据后将新增数据内容记录审计日志内(审计明细【AuditInfo】中只记录审计属性变化情况,审计属性在平台属性中配置)
* 使用环切【@Around】获取要删除的完整数据,并将审计属性相关信息记录到审计日志中
* @param point
* @return
* @throws Throwable
*/
@Around("execution(* cn.ibizlab.core.*.service.*.remove(..))")
public Object remove(ProceedingJoinPoint point) throws Throwable {
HttpServletRequest request=null;
RequestAttributes requestAttributes= RequestContextHolder.getRequestAttributes();
if(requestAttributes!=null){
request=((ServletRequestAttributes)requestAttributes).getRequest();
}
Object serviceObj=point.getTarget();
Object args[]=point.getArgs();
if(ObjectUtils.isEmpty(args) || args.length==0)
return point.proceed();
Object idValue=args[0];
EntityBase entity=getEntity(serviceObj,idValue);
Map<String, Audit> auditFields= DEFieldCacheMap.getAuditFields(entity.getClass());
if(auditFields.size()==0){
return point.proceed();
}
else{
//执行删除操作
point.proceed();
//记录审计日志
dataAuditService.removeAudit(request,entity,idValue,auditFields);
return true;
}
}
/**
* 获取实体
* @param service
* @param id
* @return
*/
@SneakyThrows
private EntityBase getEntity(Object service, Object id){
EntityBase entity=null;
if(!ObjectUtils.isEmpty(service)){
EvaluationContext oldContext = new StandardEvaluationContext();
oldContext.setVariable("service",service);
oldContext.setVariable("id",id);
Expression oldExp = parser.parseExpression("#service.get(#id)");
return oldExp.getValue(oldContext, EntityBase.class);
}
return entity;
}
}
\ No newline at end of file
package cn.ibizlab.util.aspect;
import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.enums.DEFieldDefaultValueType;
import cn.ibizlab.util.enums.DEPredefinedFieldType;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import cn.ibizlab.util.security.AuthenticationUser;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.AlternativeJdkIdGenerator;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
* 实体属性默认值切面,只有新建(Create)时才会填充默认值
*/
@Aspect
@Order(50)
@Component
public class DEFieldDefaultValueAspect
{
/**
* 新建数据切入点
* @param point
* @throws Exception
*/
@Before(value = "execution(* cn.ibizlab.core.*.service.*.create(..))")
public void BeforeCreate(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
@Before(value = "execution(* cn.ibizlab.core.*.service.*.createBatch(..))")
public void BeforeCreateBatch(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
/**
* 更新数据切入点
* @param point
* @throws Exception
*/
@Before(value = "execution(* cn.ibizlab.core.*.service.*.update(..))")
public void BeforeUpdate(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
@Before(value = "execution(* cn.ibizlab.core.*.service.*.updateBatch(..))")
public void BeforeUpdateBatch(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
/**
* 保存数据切入点
* @param point
* @throws Exception
*/
@Before(value = "execution(* cn.ibizlab.core.*.service.*.save(..))")
public void BeforeSave(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
@Before(value = "execution(* cn.ibizlab.core.*.service.*.saveBatch(..))")
public void BeforeSaveBatch(JoinPoint point) throws Exception {
fillDEFieldDefaultValue(point);
}
/**
* 填充属性默认值
* @param joinPoint
* @return
* @throws Exception
*/
public Object fillDEFieldDefaultValue(JoinPoint joinPoint) throws Exception {
Object[] args = joinPoint.getArgs();
if (args.length > 0) {
Object obj = args[0];
String actionName=joinPoint.getSignature().getName();
if(obj instanceof EntityBase) {
Map<String, DEField> deFields = DEFieldCacheMap.getDEFields(obj.getClass());
AuthenticationUser curUser = AuthenticationUser.getAuthenticationUser();
String keyField=DEFieldCacheMap.getDEKeyField(obj.getClass());
if(StringUtils.isEmpty(keyField))
return true;
fillDEField((EntityBase)obj, deFields,actionName,curUser,keyField);
}
else if (obj instanceof List) {
Map<String, DEField> deFields = null;
AuthenticationUser curUser = null;
String keyField = "";
for(Object item:(List)obj) {
if(item instanceof EntityBase) {
if(deFields==null) {
deFields = DEFieldCacheMap.getDEFields(item.getClass());
curUser = AuthenticationUser.getAuthenticationUser();
keyField=DEFieldCacheMap.getDEKeyField(item.getClass());
if(StringUtils.isEmpty(keyField))
return true;
}
fillDEField((EntityBase)item, deFields,actionName,curUser,keyField);
}
}
}
}
return true;
}
/**
* 填充系统预置属性
* @param et 当前实体对象
*/
private void fillDEField(EntityBase et, Map<String, DEField> deFields, String actionName,AuthenticationUser curUser,String keyField) throws Exception {
if(deFields.size()==0)
return ;
if(actionName.toLowerCase().startsWith("save")) {
if(ObjectUtils.isEmpty(et.get(keyField)))
actionName="create";
}
for (Map.Entry<String, DEField> entry : deFields.entrySet()) {
String fieldname=entry.getKey();
//获取注解
DEField fieldAnnotation=entry.getValue();
//获取默认值类型
DEFieldDefaultValueType deFieldType=fieldAnnotation.defaultValueType();
//获取属性默认值
String deFieldDefaultValue = fieldAnnotation.defaultValue();
//获取预置属性类型
DEPredefinedFieldType predefinedFieldType = fieldAnnotation.preType();
//填充系统默认值
if(actionName.toLowerCase().startsWith("create") && ( deFieldType!= DEFieldDefaultValueType.NONE || (!StringUtils.isEmpty(deFieldDefaultValue)) )){
fillFieldDefaultValue(fieldname, deFieldType, deFieldDefaultValue, et , curUser) ;
}
//填充系统预置属性
if(predefinedFieldType != DEPredefinedFieldType.NONE){
fillPreFieldValue( fieldname, predefinedFieldType , et ,actionName ,fieldAnnotation.logicval(),curUser);
}
}
}
/**
* 填充属性默认值
* @param fieldname 实体属性名
* @param deFieldType 默认值类型
* @param deFieldDefaultValue 默认值
* @param et 当前实体对象
* @throws Exception
*/
private void fillFieldDefaultValue(String fieldname , DEFieldDefaultValueType deFieldType,String deFieldDefaultValue,EntityBase et ,AuthenticationUser curUser) throws Exception {
Object fieldValue = et.get(fieldname);
if(org.springframework.util.ObjectUtils.isEmpty(fieldValue)){
//填充直接值及其余默认值类型
if( (deFieldType== DEFieldDefaultValueType.NONE && !StringUtils.isEmpty(deFieldDefaultValue)) || (deFieldType != DEFieldDefaultValueType.NONE) ){
switch(deFieldType){
case SESSION:
if(!StringUtils.isEmpty(deFieldDefaultValue)){
Object sessionFieldValue = curUser.getSessionParams().get(deFieldDefaultValue.toLowerCase());
if(!ObjectUtils.isEmpty(sessionFieldValue)){
et.set(fieldname,sessionFieldValue);
}
}
break;
case APPLICATION:
//暂未实现
break;
case UNIQUEID:
et.set(fieldname,(new AlternativeJdkIdGenerator()).generateId().toString().replace("-", ""));
break;
case CONTEXT:
if(!StringUtils.isEmpty(deFieldDefaultValue)){
Object paramFieldValue=et.get(deFieldDefaultValue);
if(!ObjectUtils.isEmpty(paramFieldValue)){
et.set(fieldname,paramFieldValue);
}
}
break;
case PARAM:
if(!StringUtils.isEmpty(deFieldDefaultValue)){
Object paramFieldValue=et.get(deFieldDefaultValue);
if(!ObjectUtils.isEmpty(paramFieldValue)){
et.set(fieldname,paramFieldValue);
}
}
break;
case OPERATOR:
et.set(fieldname,curUser.getUserid());
break;
case OPERATORNAME:
et.set(fieldname,curUser.getPersonname());
break;
case CURTIME:
et.set(fieldname,new Timestamp(new Date().getTime()));
break;
case APPDATA:
//暂未实现
break;
case NONE:
et.set(fieldname,deFieldDefaultValue);
break;
}
}
}
}
private void fillPreFieldValue(String fieldname , DEPredefinedFieldType preFieldType ,EntityBase et , String actionName,String logicValue ,AuthenticationUser curUser) throws Exception {
Object fieldValue = et.get(fieldname);
//为预置属性进行赋值
if( actionName.equalsIgnoreCase("create")||
preFieldType== DEPredefinedFieldType.UPDATEDATE|| preFieldType== DEPredefinedFieldType.UPDATEMAN||
preFieldType== DEPredefinedFieldType.UPDATEMANNAME){
switch(preFieldType){//根据注解给预置属性填充值
case CREATEMAN:
et.set(fieldname,curUser.getUserid());
break;
case CREATEMANNAME:
et.set(fieldname,curUser.getPersonname());
break;
case UPDATEMAN:
et.set(fieldname,curUser.getUserid());
break;
case UPDATEMANNAME:
et.set(fieldname,curUser.getPersonname());
break;
case CREATEDATE:
et.set(fieldname,new Timestamp(new Date().getTime()));
break;
case UPDATEDATE:
et.set(fieldname,new Timestamp(new Date().getTime()));
break;
case ORGID:
if(org.springframework.util.StringUtils.isEmpty(fieldValue))
et.set(fieldname,curUser.getOrgid());
break;
case ORGNAME:
if(org.springframework.util.StringUtils.isEmpty(fieldValue))
et.set(fieldname,curUser.getOrgname());
break;
case ORGSECTORID:
if(org.springframework.util.StringUtils.isEmpty(fieldValue))
et.set(fieldname,curUser.getMdeptid());
break;
case ORGSECTORNAME:
if(org.springframework.util.StringUtils.isEmpty(fieldValue))
et.set(fieldname,curUser.getMdeptname());
break;
case LOGICVALID:
if(StringUtils.isEmpty(logicValue)){
logicValue="1";
}
et.set(fieldname,logicValue);
break;
}
}
}
}
package cn.ibizlab.util.aspect;
import lombok.SneakyThrows;
import cn.ibizlab.util.annotation.VersionCheck;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.helper.RuleUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.util.Map;
/**
* 数据库版本检查
*/
@Aspect
@Order(50)
@Component
public class VersionCheckAspect
{
private final ExpressionParser parser = new SpelExpressionParser();
private final String IgnoreField="ignoreversioncheck";
@SneakyThrows
@Before("execution(* cn.ibizlab.*.rest.*.update(..)) && @annotation(versionCheck)")
public void BeforeUpdate(JoinPoint point, VersionCheck versionCheck){
Object[] args = point.getArgs();
Object id=args[0];
Object dto=args[1];
if(ObjectUtils.isEmpty(id) || ObjectUtils.isEmpty(dto))
return;
String versionField=versionCheck.versionfield();
if(StringUtils.isEmpty(versionField))
return;
versionCheck(versionCheck,point.getTarget(),dto,id);
}
@SneakyThrows
@Before("execution(* cn.ibizlab.*.rest.*.updateBy*(..)) && @annotation(versionCheck)")
public void BeforeUpdateBy(JoinPoint point, VersionCheck versionCheck){
Object[] args = point.getArgs();
if(args.length>=2){
Object id=args[args.length-2];
Object dto=args[args.length-1];
if(ObjectUtils.isEmpty(id) || ObjectUtils.isEmpty(dto))
return;
String versionField=versionCheck.versionfield();
if(StringUtils.isEmpty(versionField))
return;
versionCheck(versionCheck,point.getTarget(),dto,id);
}
}
private void versionCheck(VersionCheck versionCheck,Object resource,Object dto,Object id ){
EvaluationContext context = new StandardEvaluationContext();
context.setVariable("dto",dto);
//忽略版本检查
Expression dtoParamsExp = parser.parseExpression("#dto.extensionparams");
Map dtoParam=dtoParamsExp.getValue(context, Map.class);
if(!ObjectUtils.isEmpty(dtoParam) && !ObjectUtils.isEmpty(dtoParam.get(IgnoreField)) && dtoParam.get(IgnoreField).equals(1))
return;
Expression newExp = parser.parseExpression(String.format("#dto.%s",versionCheck.versionfield()));
Object newVersion=newExp.getValue(context);
if(ObjectUtils.isEmpty(newVersion))
return;
//进行版本检查
Object oldVersion =getDBVersion(versionCheck,getService(resource,versionCheck.entity()),id);
if(!ObjectUtils.isEmpty(oldVersion)){
if(RuleUtils.gt(newVersion,oldVersion))
throw new BadRequestAlertException("数据已变更,可能后台数据已被修改,请重新加载数据","VersionCheckAspect","versionCheck");
}
}
/**
* 获取实体服务对象
* @param resource
* @param entity
* @return
*/
@SneakyThrows
private Object getService(Object resource,String entity){
Object service = null;
Field[] fields= resource.getClass().getDeclaredFields();
for(Field field : fields){
if(field.getModifiers()==1 && field.getName().equalsIgnoreCase(String.format("%sService",entity))){
service=field.get(resource);
break;
}
}
return service;
}
/**
* 获取数据库版本
* @param versionCheck
* @param service
* @param id
* @return
*/
@SneakyThrows
private Object getDBVersion(VersionCheck versionCheck,Object service,Object id){
Object dbVersion=null;
String versionField=versionCheck.versionfield();
if(!ObjectUtils.isEmpty(service)){
EvaluationContext oldContext = new StandardEvaluationContext();
oldContext.setVariable("service",service);
oldContext.setVariable("id",id);
Expression oldExp = parser.parseExpression("#service.get(#id)");
EntityBase oldEntity =oldExp.getValue(oldContext, EntityBase.class);
return oldEntity.get(versionField);
}
return dbVersion;
}
}
package cn.ibizlab.util.cache;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.util.StringUtils;
import cn.ibizlab.util.cache.cacheManager.CaffeineCacheManager;
/**
* Caffeine缓存配置类
*/
@EnableCaching
@Configuration
@EnableConfigurationProperties(CacheProperties.class)
@ConditionalOnExpression("'${ibiz.cacheLevel:None}'.equals('L1')")
public class CaffeineCacheConfig {
/**
* Caffeine配置:设置过期时间
* @return
*/
@Bean
@Primary
public CacheManager cacheManager(CacheProperties cacheProperties) {
CaffeineCacheManager caffeineCacheManager=new CaffeineCacheManager();
String strCacheConfig = cacheProperties.getCaffeine().getSpec();
if (StringUtils.hasText(strCacheConfig)) {
caffeineCacheManager.setCaffeineCacheConfig(CaffeineSpec.parse(strCacheConfig));
}
return caffeineCacheManager;
}
}
\ No newline at end of file
package cn.ibizlab.util.cache;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.StringUtils;
import java.time.Duration;
import cn.ibizlab.util.cache.cacheManager.LayeringCacheManager;
import cn.ibizlab.util.cache.listener.RedisMessageListener;
import cn.ibizlab.util.cache.redis.CustomJacksonSerializer;
import cn.ibizlab.util.enums.RedisChannelTopic;
/**
* 缓存配置类
* 1级缓存为caffeine
* 2级缓存为redis
*/
@EnableCaching
@Configuration
@EnableConfigurationProperties(CacheProperties.class)
@ConditionalOnExpression("'${ibiz.cacheLevel:None}'.equals('L2')")
public class RedisCacheConfig {
@Value("${spring.cache.redis.time-to-live:3600}")
private long timeToLive;
/**
* 分层缓存管理器
* @param redisConnectionFactory
* @param cacheProperties
* @return
*/
@Bean
@Primary
public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory ,CacheProperties cacheProperties){
LayeringCacheManager layeringCacheManager=new LayeringCacheManager(redisCacheWriter(redisConnectionFactory),redisCacheConfiguration(),redisTemplate(redisConnectionFactory));
String strCacheConfig = cacheProperties.getCaffeine().getSpec();
if (StringUtils.hasText(strCacheConfig)) {
layeringCacheManager.setCaffeineCacheConfig(CaffeineSpec.parse(strCacheConfig));
}
return layeringCacheManager;
}
/**
* redis配置:设置过期时间及序列化方式
* @return
*/
@Bean
public RedisCacheConfiguration redisCacheConfiguration(){
CustomJacksonSerializer jackson2JsonRedisSerializer = new CustomJacksonSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(timeToLive))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
return configuration;
}
/**
* 创建redis缓存
* @param connectionFactory
* @return
*/
@Bean
public RedisCacheWriter redisCacheWriter(RedisConnectionFactory connectionFactory){
RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
return redisCacheWriter;
}
/**
* 发送redis广播
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
CustomJacksonSerializer jacksonSerial = new CustomJacksonSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
jacksonSerial.setObjectMapper(om);
template.setValueSerializer(jacksonSerial);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(jacksonSerial);
template.afterPropertiesSet();
return template;
}
/**
* 监听redis指定频道
* @param redisConnectionFactory
* @param cacheManager
* @param redisTemplate
* @return
*/
@Bean
RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory, CacheManager cacheManager , RedisTemplate redisTemplate) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
MessageListenerAdapter messageListener=new RedisMessageListener(cacheManager,redisTemplate);
container.setConnectionFactory(redisConnectionFactory);
container.addMessageListener(messageListener, RedisChannelTopic.REDIS_CACHE_DELETE_TOPIC.getChannelTopic());
container.addMessageListener(messageListener, RedisChannelTopic.REDIS_CACHE_CLEAR_TOPIC.getChannelTopic());
return container;
}
}
\ No newline at end of file
package cn.ibizlab.util.cache.cache;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
/**
* 自定义的redis缓存
*/
public class CusRedisCache extends RedisCache {
public CusRedisCache(String name, RedisCacheWriter redisCacheWriter, RedisCacheConfiguration configuration) {
super(name, redisCacheWriter, configuration);
}
}
package cn.ibizlab.util.cache.cache;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.AbstractValueAdaptingCache;
import org.springframework.cache.support.NullValue;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.core.RedisOperations;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import cn.ibizlab.util.cache.listener.RedisPublisher;
import cn.ibizlab.util.enums.RedisChannelTopic;
/**
* 缓存分层类
* 1级缓存为caffeine
* 2级缓存为redis
*/
@Slf4j
public class LayeringCache extends AbstractValueAdaptingCache {
/**
* 缓存的名称
*/
private String cacheName;
/**
* Caffeine缓存
*/
private CaffeineCache caffeineCache;
/**
* redis缓存
*/
private RedisCache redisCache;
/**
* redis消息发布
*/
RedisOperations<? extends Object, ? extends Object> redisOperations;
public LayeringCache(String cacheName , CaffeineCache caffeineCache, RedisCache redisCache, RedisOperations redisOperations) {
super(true);
this.cacheName = cacheName;
this.caffeineCache = caffeineCache;
this.redisCache = redisCache;
this.redisOperations=redisOperations;
}
@Override
public String getName() {
return this.cacheName;
}
@Override
public Object getNativeCache() {
return this;
}
@Override
public ValueWrapper get(Object key) {
ValueWrapper wrapper = caffeineCache.get(key);
log.debug("查询一级缓存 key:{},value:{}", key,wrapper);
if (wrapper == null) {
wrapper = redisCache.get(key);
caffeineCache.put(key, wrapper == null ? null : wrapper.get());
log.debug("查询二级缓存,并将数据放到一级缓存。 key:{}", key);
}
return wrapper;
}
@Override
public <T> T get(Object key, Class<T> type) {
T value = caffeineCache.get(key, type);
log.debug("查询一级缓存 key:{}", key);
if (value == null) {
value = redisCache.get(key, type);
caffeineCache.put(key, value);
log.debug("查询二级缓存,并将数据放到一级缓存。 key:{}", key);
}
return value;
}
@SuppressWarnings("unchecked")
@Override
public <T> T get(Object key, Callable<T> valueLoader) {
T value = (T) caffeineCache.getNativeCache().get(key, k -> getSecondCacheValue(k, valueLoader));
if(value==null) {
value = (T) getSecondCacheValue(key, valueLoader);
}
if (value instanceof NullValue) {
return null;
}
return value;
}
@Override
public void put(Object key, Object value) {
if(value!=null) {
caffeineCache.put(key, value);
redisCache.put(key, value);
}
}
@Override
public ValueWrapper putIfAbsent(Object key, Object value) {
caffeineCache.putIfAbsent(key, value);
return redisCache.putIfAbsent(key, value);
}
@Override
public void evict(Object key) {
redisCache.evict(key); //清除redis中的二级缓存
caffeineCache.evict(key);//清除本机一级缓存
Map<String, Object> message = new HashMap<>();
message.put("cacheName", cacheName);
message.put("key", key);
RedisPublisher redisPublisher = new RedisPublisher(redisOperations, RedisChannelTopic.REDIS_CACHE_DELETE_TOPIC.getChannelTopic());// 创建redis发布者
redisPublisher.publisher(message);//发布消息,清除其它集群机器中的一级缓存
log.debug(String.format("清除二级缓存数据[%s]", key));
}
@Override
public void clear() {
redisCache.clear(); //清除redis中的二级缓存
caffeineCache.clear();//清除本机一级缓存
Map<String, Object> message = new HashMap<>();
message.put("cacheName", cacheName);
RedisPublisher redisPublisher = new RedisPublisher(redisOperations, RedisChannelTopic.REDIS_CACHE_CLEAR_TOPIC.getChannelTopic());// 创建redis发布者
redisPublisher.publisher(message);//发布消息,清除其它集群机器中的一级缓存
}
@Override
protected Object lookup(Object key) {
Object value = caffeineCache.get(key);
log.debug("查询一级缓存 key:{}", key);
if (value == null) {
value = redisCache.get(key);
log.debug("查询二级缓存 key:{}", key);
}
return value;
}
/**
* 获取caffeine缓存
* @return
*/
public CaffeineCache getFirstCache() {
return this.caffeineCache;
}
/**
* 获取redis缓存
* @return
*/
public RedisCache getSecondCache() {
return this.redisCache;
}
/**
* 查询二级缓存
* @param key
* @param valueLoader
* @return
*/
private <T> Object getSecondCacheValue(Object key, Callable<T> valueLoader) {
T value = redisCache.get(key, valueLoader);
log.debug("查询二级缓存 key:{}", key);
return toStoreValue(value);
}
}
package cn.ibizlab.util.cache.cacheManager;
import lombok.Data;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
/**
* Caffeine本地缓存
*/
@Data
public class CaffeineCacheManager implements CacheManager {
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
private static final int default_expire_after_write = 1;
private static final int default_initial_capacity = 5;
private static final int default_maximum_size = 1_000;
private Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder()
.expireAfterAccess(default_expire_after_write, TimeUnit.HOURS)
.initialCapacity(default_initial_capacity)
.maximumSize(default_maximum_size);
/**
* 获取缓存对象
* @param cacheName
* @return
*/
@Override
public Cache getCache(String cacheName) {
Cache cache = this.cacheMap.get(cacheName);
if (cache == null) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(cacheName);
if (cache == null) {
cache = createCache(cacheName);
this.cacheMap.put(cacheName, cache);
}
}
}
return cache;
}
/**
* 创建缓存
* @param cacheName
* @return
*/
protected Cache createCache(String cacheName) {
return new CaffeineCache(cacheName, this.cacheBuilder.build(), true);
}
/**
* 获取缓存名
* @return
*/
@Override
public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(this.cacheMap.keySet());
}
/**
* 缓存配置[缓存容量大小、时长等]
* @param caffeineCacheConfig
*/
public void setCaffeineCacheConfig(CaffeineSpec caffeineCacheConfig) {
Caffeine<Object, Object> cacheBuilder = Caffeine.from(caffeineCacheConfig);
if (!ObjectUtils.nullSafeEquals(this.cacheBuilder, cacheBuilder)) {
this.cacheBuilder = cacheBuilder;
}
}
}
package cn.ibizlab.util.cache.cacheManager;
import lombok.Data;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.CaffeineSpec;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.ObjectUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import cn.ibizlab.util.cache.cache.CusRedisCache;
import cn.ibizlab.util.cache.cache.LayeringCache;
/**
* 缓存分层
* 1级缓存为caffeine
* 2级缓存为redis
*/
@Data
public class LayeringCacheManager implements CacheManager {
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
private static final int default_expire_after_write = 1;
private static final int default_initial_capacity = 5;
private static final int default_maximum_size = 1_000;
private Caffeine<Object, Object> cacheBuilder = Caffeine.newBuilder()
.expireAfterAccess(default_expire_after_write, TimeUnit.HOURS)
.initialCapacity(default_initial_capacity)
.maximumSize(default_maximum_size);
private RedisCacheWriter redisCacheWriter;
private RedisCacheConfiguration redisConfiguration;
private RedisTemplate<String, Object> redisTemplate;
public LayeringCacheManager(RedisCacheWriter redisCacheWriter , RedisCacheConfiguration redisConfiguration , RedisTemplate<String, Object> redisTemplate ){
this.redisCacheWriter=redisCacheWriter;
this.redisConfiguration=redisConfiguration;
this.redisTemplate= redisTemplate;
}
/**
* 获取缓存对象
* @param cacheName
* @return
*/
@Override
public Cache getCache(String cacheName) {
Cache cache = this.cacheMap.get(cacheName);
if (cache == null) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(cacheName);
if (cache == null) {
cache = createCache(cacheName);
this.cacheMap.put(cacheName, cache);
}
}
}
return cache;
}
/**
* 获取集合中的缓存
* @return
*/
@Override
public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(this.cacheMap.keySet());
}
/**
* 创建缓存
* @param cacheName
* @return
*/
protected Cache createCache(String cacheName) {
return new LayeringCache(cacheName,new CaffeineCache(cacheName, this.cacheBuilder.build(), true),new CusRedisCache(cacheName, redisCacheWriter, redisConfiguration),redisTemplate);
}
/**
* 缓存配置[缓存容量大小、时长等]
* @param caffeineCacheConfig
*/
public void setCaffeineCacheConfig(CaffeineSpec caffeineCacheConfig) {
Caffeine<Object, Object> cacheBuilder = Caffeine.from(caffeineCacheConfig);
if (!ObjectUtils.nullSafeEquals(this.cacheBuilder, cacheBuilder)) {
this.cacheBuilder = cacheBuilder;
}
}
}
package cn.ibizlab.util.cache.listener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.util.StringUtils;
import java.util.Map;
import cn.ibizlab.util.cache.cache.LayeringCache;
import cn.ibizlab.util.enums.RedisChannelTopic;
/**
* redis消息的订阅者
*/
@Slf4j
public class RedisMessageListener extends MessageListenerAdapter {
private CacheManager cacheManager;
private RedisTemplate redisTemplate;
public RedisMessageListener(CacheManager cacheManager, RedisTemplate redisTemplate){
this.cacheManager=cacheManager;
this.redisTemplate=redisTemplate;
}
@Override
public void onMessage(Message message, byte[] pattern) {
RedisChannelTopic channelTopic = RedisChannelTopic.getChannelTopicEnum(new String(message.getChannel()));
Map<String, Object> map = null;
RedisSerializer serializer=redisTemplate.getValueSerializer();
Object result=serializer.deserialize(message.getBody());
if(result instanceof Map){
map= (Map<String, Object>) result;
}
if(StringUtils.isEmpty(map)|| (!map.containsKey("cacheName"))|| (!map.containsKey("key"))){
log.debug("解析缓存数据失败,无法获取指定值!");
return ;
}
log.debug("redis消息订阅者接收到频道【{}】发布的消息。消息内容:{}", channelTopic.getChannelTopicStr(), result.toString());
String cacheName = (String) map.get("cacheName");
Object key = map.get("key");
Cache cache = cacheManager.getCache(cacheName);// 根据缓存名称获取多级缓存
if (cache != null && cache instanceof LayeringCache) { // 判断缓存是否是多级缓存
switch (channelTopic) {
case REDIS_CACHE_DELETE_TOPIC: // 获取一级缓存,并删除一级缓存数据
((LayeringCache) cache).getFirstCache().evict(key);
((LayeringCache) cache).getSecondCache().evict(key);
log.debug("同步删除缓存{}数据,key:{},", cacheName, key.toString());
break;
case REDIS_CACHE_CLEAR_TOPIC:// 获取一级缓存,并删除一级缓存数据
((LayeringCache) cache).getFirstCache().clear();
((LayeringCache) cache).getSecondCache().clear();
log.debug("同步清除缓存{}数据", cacheName);
break;
default:
log.debug("接收到没有定义的订阅消息频道数据");
break;
}
}
}
}
package cn.ibizlab.util.cache.listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.listener.ChannelTopic;
/**
* redis消息的发布者
*/
public class RedisPublisher {
private static final Logger logger = LoggerFactory.getLogger(RedisPublisher.class);
RedisOperations<? extends Object, ? extends Object> redisOperations;
/**
* 频道名称
*/
ChannelTopic channelTopic;
/**
* @param redisOperations Redis客户端
* @param channelTopic 频道名称
*/
public RedisPublisher(RedisOperations<? extends Object, ? extends Object> redisOperations, ChannelTopic channelTopic) {
this.channelTopic = channelTopic;
this.redisOperations = redisOperations;
}
/**
* 发布消息到频道(Channel)
*
* @param message 消息内容
*/
public void publisher(Object message) {
redisOperations.convertAndSend(channelTopic.toString(), message);
logger.debug("redis消息发布者向频道【{}】发布了【{}】消息", channelTopic.toString(), message.toString());
}
}
package cn.ibizlab.util.cache.redis;
import cn.ibizlab.util.security.AuthenticationUser;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CustomJacksonSerializer<T> extends Jackson2JsonRedisSerializer<T> {
public static final String DEFAULT_PACKAGE ="[\\w+\\.]+\\.AuthenticationUser";
public static final String CLASSNAME_EX="_$$_";
public static final String CLASSNAME_EX_PATTEN="(_\\$\\$_)(\\w+)";
public static final String USER_PACKAGE= AuthenticationUser.class.getName();
public CustomJacksonSerializer(Class type) {
super(type);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
String serializerContent = new String(bytes, DEFAULT_CHARSET);
Matcher matcher = Pattern.compile(DEFAULT_PACKAGE).matcher(serializerContent);
if(matcher.find()){
serializerContent=serializerContent.replaceAll(DEFAULT_PACKAGE,USER_PACKAGE);
}
if(serializerContent.contains(CLASSNAME_EX)){
serializerContent=serializerContent.replaceAll(CLASSNAME_EX_PATTEN,"");
}
return super.deserialize(serializerContent.getBytes());
}
}
package cn.ibizlab.util.client;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
@Component
public class IBZNotifyFallback implements IBZNotifyFeignClient {
@Override
public Boolean SendMsg(JSONObject msg) {
return null;
}
@Override
public Boolean createMsgTemplate(JSONObject template) {
return null;
}
}
package cn.ibizlab.util.client;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
@FeignClient(value = "${ibiz.ref.service.notify:ibznotify-api}",fallback = IBZNotifyFallback.class)
public interface IBZNotifyFeignClient
{
@RequestMapping(method = RequestMethod.POST,value = "/SendMsg")
Boolean SendMsg(@RequestBody JSONObject msg);
@RequestMapping(method = RequestMethod.POST,value = "/createMsgTemplate")
Boolean createMsgTemplate(@RequestBody JSONObject template);
}
package cn.ibizlab.util.client;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Set;
@Component
public class IBZOUFallback implements IBZOUFeignClient {
@Override
public Map<String, Set<String>> getOUMapsByUserId(String userId) {
return null;
}
}
package cn.ibizlab.util.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.Map;
import java.util.Set;
@FeignClient(value = "${ibiz.ref.service.ou:ibzou-api}",fallback = IBZOUFallback.class)
public interface IBZOUFeignClient
{
/**
* 从ou中获取当前上下级组织、部门信息
* @param userId
* @return
*/
@GetMapping("/ibzemployees/{userId}/oumaps")
Map<String, Set<String>> getOUMapsByUserId(@PathVariable("userId") String userId);
}
package cn.ibizlab.util.client;
import cn.ibizlab.util.security.AuthenticationUser;
import cn.ibizlab.util.security.AuthorizationLogin;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
@Component
public class IBZUAAFallback implements IBZUAAFeignClient {
@Override
public Boolean syncSysAuthority(JSONObject system) {
return null;
}
@Override
public AuthenticationUser login(AuthorizationLogin authorizationLogin) {
return null;
}
@Override
public AuthenticationUser loginByUsername(String username) {
return null;
}
@Override
public String getPublicKey() {
return null;
}
}
package cn.ibizlab.util.client;
import cn.ibizlab.util.security.AuthenticationUser;
import cn.ibizlab.util.security.AuthorizationLogin;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import com.alibaba.fastjson.JSONObject;
@FeignClient(value = "${ibiz.ref.service.uaa:ibzuaa-api}",fallback = IBZUAAFallback.class)
public interface IBZUAAFeignClient
{
/**
* 同步系统资源到uaa
* @param system 系统资源信息
* @return
*/
@PostMapping("/syspssystems/save")
Boolean syncSysAuthority(@RequestBody JSONObject system);
/**
* 用户登录
* @param authorizationLogin 登录信息
* @return
*/
@PostMapping(value = "/uaa/login")
AuthenticationUser login(@RequestBody AuthorizationLogin authorizationLogin);
@PostMapping(value = "/uaa/loginbyusername")
AuthenticationUser loginByUsername(@RequestBody String username);
@Cacheable(value="ibzuaa_publickey")
@GetMapping(value = "/uaa/publickey")
String getPublicKey();
}
package cn.ibizlab.util.client;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class IBZWFFallback implements IBZWFFeignClient {
@Override
public List<String> getbusinesskeys(String system, String appname, String entity, String processDefinitionKey, String taskDefinitionKey) {
return null;
}
@Override
public List<String> getbusinesskeysByUserId(String system, String userId, String entity, String processDefinitionKey, String taskDefinitionKey) {
return null;
}
@Override
public Boolean deployBpmnFile(List<Map<String, Object>> bpmnfiles) {
return null;
}
}
package cn.ibizlab.util.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@FeignClient(value = "${ibiz.ref.service.wf:ibzwf-api}",fallback = IBZWFFallback.class)
public interface IBZWFFeignClient
{
@RequestMapping(method = RequestMethod.GET, value = "/{system}-app-{appname}/{entity}/process-definitions/{processDefinitionKey}/usertasks/{taskDefinitionKey}/tasks")
List<String> getbusinesskeys(@PathVariable("system") String system, @PathVariable("appname") String appname,
@PathVariable("entity") String entity, @PathVariable("processDefinitionKey") String processDefinitionKey, @PathVariable("taskDefinitionKey") String taskDefinitionKey);
@RequestMapping(method = RequestMethod.POST, value = "/{system}-user-{userId}/{entity}/process-definitions/{processDefinitionKey}/usertasks/{taskDefinitionKey}/tasks")
List<String> getbusinesskeysByUserId(@PathVariable("system") String system,@PathVariable("userId") String userId,
@PathVariable("entity") String entity,@PathVariable("processDefinitionKey") String processDefinitionKey,@PathVariable("taskDefinitionKey") String taskDefinitionKey);
@RequestMapping(method = RequestMethod.POST, value = "/deploybpmn")
Boolean deployBpmnFile(@RequestBody List<Map<String,Object>> bpmnfiles);
}
package cn.ibizlab.util.domain;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.alibaba.fastjson.annotation.JSONField;
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import lombok.Data;
@Data
public class DTOBase implements Serializable {
@JsonIgnore
@JSONField(serialize = false)
private Set<String> focusNull;
public void modify(String field,Object val) {
if(val==null)
this.getFocusNull(true).add(field.toLowerCase());
else
this.getFocusNull(true).remove(field.toLowerCase());
}
public Set<String> getFocusNull() {
if(focusNull==null)
focusNull=new HashSet<>();
if(focusNull.size()>0 && extensionparams.containsKey("dirtyflagenable"))
{
Set<String> nocheck=new HashSet<>();
for(String key:focusNull)
{
if(!extensionparams.containsKey(key+"dirtyflag"))
nocheck.add(key);
}
for(String key:nocheck)
focusNull.remove(key);
}
return focusNull;
}
private Set<String> getFocusNull(boolean newflag) {
if(focusNull==null)
focusNull=new HashSet<>();
return focusNull;
}
@JsonIgnore
private Map<String,Object> extensionparams=new HashMap<String,Object>();
public Map<String, Object> getExtensionparams() {
return extensionparams;
}
public void setExtensionparams(Map<String, Object> extensionparams) {
this.extensionparams = extensionparams;
}
@JsonAnyGetter
public Map<String , Object> any() {
return extensionparams;
}
@JsonAnySetter
public void set(String name, Object value) {
extensionparams.put(name.toLowerCase(), value);
}
}
package cn.ibizlab.util.domain;
public class DTOClient extends DTOBase {
@Override
public void modify(String field,Object val) {
getExtensionparams().put("dirtyflagenable",true);
if(val==null){
this.getFocusNull().add(field.toLowerCase());
getExtensionparams().put(field.toLowerCase()+"dirtyflag",true);
}
else{
this.getFocusNull().remove(field.toLowerCase());
getExtensionparams().remove(field.toLowerCase()+"dirtyflag");
}
}
}
package cn.ibizlab.util.domain;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.data.annotation.Transient;
import org.springframework.util.AlternativeJdkIdGenerator;
import java.io.Serializable;
import org.springframework.util.StringUtils;
import java.util.*;
public class EntityBase implements Serializable {
@JsonIgnore
@JSONField(serialize = false)
@TableField(exist = false)
@Transient
private Set<String> focusNull;
public Set<String> getFocusNull() {
if(focusNull==null)
focusNull=new HashSet<>();
return focusNull;
}
public void setFocusNull(Set<String> focusNull) {
this.focusNull = focusNull;
}
public void modify(String field,Object val) {
}
public Serializable getDefaultKey(boolean gen) {
String Id=(new AlternativeJdkIdGenerator()).generateId().toString();
return gen?Id.replace("-", ""):Id;
}
@JsonIgnore
@JSONField(serialize = false)
@TableField(exist = false)
@Transient
private BeanMap map;
private BeanMap getMap()
{
if(map==null)
map=BeanMap.create(this);
return map;
}
@JsonIgnore
@TableField(exist = false)
@Transient
private Map<String,Object> extensionparams=new HashMap<String,Object>();
public Map<String, Object> getExtensionparams() {
return extensionparams;
}
public void setExtensionparams(Map<String, Object> extensionparams) {
this.extensionparams = extensionparams;
}
public Object get(String field) {
String fieldRealName=DEFieldCacheMap.getFieldRealName(this.getClass(),field);
if(!StringUtils.isEmpty(fieldRealName))
return getMap().get(fieldRealName);
else
return this.extensionparams.get(field.toLowerCase());
}
@JsonAnyGetter
public Map<String , Object> any() {
return extensionparams;
}
@JsonAnySetter
public void set(String field, Object value) {
field=field.toLowerCase();
String fieldRealName=DEFieldCacheMap.getFieldRealName(this.getClass(),field);
if(!StringUtils.isEmpty(fieldRealName)) {
if (value == null)
getMap().put(fieldRealName, null);
else
getMap().put(fieldRealName, DEFieldCacheMap.fieldValueOf(this.getClass(), fieldRealName, value));
}
else
this.extensionparams.put(field.toLowerCase(),value);
}
}
\ No newline at end of file
package cn.ibizlab.util.domain;
public class EntityClient extends EntityBase {
@Override
public void modify(String field,Object val) {
if(val==null){
this.getFocusNull().add(field.toLowerCase());
getExtensionparams().put("dirtyflagenable",true);
getExtensionparams().put(field.toLowerCase()+"dirtyflag",true);
}
else{
this.getFocusNull().remove(field.toLowerCase());
getExtensionparams().remove(field.toLowerCase()+"dirtyflag");
}
}
}
package cn.ibizlab.util.domain;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
public class EntityMP extends EntityBase {
public UpdateWrapper getUpdateWrapper(boolean clean) {
UpdateWrapper wrapper=new UpdateWrapper();
for(String nullField:getFocusNull()) {
wrapper.set(nullField,null);
}
if(clean)
getFocusNull().clear();
return wrapper;
}
@Override
public void modify(String field,Object val) {
if(val==null)
this.getFocusNull().add(field.toLowerCase());
else
this.getFocusNull().remove(field.toLowerCase());
}
}
package cn.ibizlab.util.domain;
public class EntityMongo extends EntityBase {
}
package cn.ibizlab.util.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@JsonInclude(Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@AllArgsConstructor
public class FileItem
{
private String id;
private String name;
private String fileid;
private String filename;
private long size;
private String ext;
}
package cn.ibizlab.util.domain;
import cn.ibizlab.util.helper.DataObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.*;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import java.sql.Timestamp;
@TableName(value = "IBZCFG")
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class IBZConfig {
/**
* 配置标识
* 系统+配置类型+引用对象+用户标识联合主键
*/
@TableId
private String cfgId;
/**
* 系统标识
*/
private String systemId;
/**
* 配置类型
* 门户配置/表格自定义配置/自定义查询...消费方自定义
*/
private String cfgType;
/**
* 引用对象
* 门户页标识/具体表格视图标识...消费方具体使用位置的标识
*/
private String targetType;
/**
* 用户标识
* 默认当前登录者
*/
private String userId;
/**
* 配置
* JSONObject
*/
private String cfg;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", locale = "zh" , timezone="GMT+8")
@JSONField(format="yyyy-MM-dd HH:mm:ss")
private Timestamp updateDate;
public String getCfgId()
{
if(StringUtils.isEmpty(cfgId)&&
(!(StringUtils.isEmpty(systemId)))&&
(!(StringUtils.isEmpty(cfgType)))&&
(!(StringUtils.isEmpty(targetType)))&&
(!(StringUtils.isEmpty(userId))))
{
cfgId= DigestUtils.md5DigestAsHex((systemId+"||"+cfgType+"||"+targetType+"||"+userId).getBytes());
}
return cfgId;
}
}
package cn.ibizlab.util.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Objects;
/**
* 实体[DataAudit] 数据对象
*/
@TableName(value = "IBZDATAAUDIT")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class IBZDataAudit implements Serializable{
@TableId(value= "dataauditid",type=IdType.UUID)//指定主键生成策略
private String dataauditid;
private String dataauditname;
private String oppersonid;
private String oppersonname;
private String audittype;
private Timestamp optime;
private String ipaddress;
private String auditinfo;
private Object auditobjectdata;
private String auditobject;
private int isdatachanged;
}
\ No newline at end of file
package cn.ibizlab.util.domain;
import java.sql.Timestamp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Data;
import javax.validation.constraints.Size;
import java.io.Serializable;
/**
* 实体[IBZUSER] 数据对象
*/
@TableName(value = "IBZUSER")
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
public class IBZUSER implements Serializable{
@Size(min = 0, max = 100, message = "[用户标识]长度必须在[100]以内!")
@TableId(value= "userid",type=IdType.INPUT)//指定主键生成策略
private String userid;
@Size(min = 0, max = 200, message = "[用户全局名]长度必须在[200]以内!")
private String username;
@Size(min = 0, max = 100, message = "[用户姓名]长度必须在[100]以内!")
private String personname;
@Size(min = 0, max = 100, message = "[用户代码]长度必须在[100]以内!")
private String usercode;
@Size(min = 0, max = 100, message = "[登录别名]长度必须在[100]以内!")
private String loginname;
@Size(min = 0, max = 100, message = "[登录密码]长度必须在[100]以内!")
private String password;
@Size(min = 0, max = 100, message = "[区属]长度必须在[100]以内!")
private String domains;
@Size(min = 0, max = 100, message = "[主部门id]长度必须在[100]以内!")
private String mdeptid;
@Size(min = 0, max = 100, message = "[主部门代码]长度必须在[100]以内!")
private String mdeptcode;
@Size(min = 0, max = 200, message = "[主部门名称]长度必须在[200]以内!")
private String mdeptname;
@Size(min = 0, max = 100, message = "[业务编码]长度必须在[100]以内!")
private String bcode;
@Size(min = 0, max = 100, message = "[岗位id]长度必须在[100]以内!")
private String postid;
@Size(min = 0, max = 100, message = "[岗位代码]长度必须在[100]以内!")
private String postcode;
@Size(min = 0, max = 200, message = "[岗位名称]长度必须在[200]以内!")
private String postname;
@Size(min = 0, max = 100, message = "[单位id]长度必须在[100]以内!")
private String orgid;
@Size(min = 0, max = 100, message = "[单位代码]长度必须在[100]以内!")
private String orgcode;
@Size(min = 0, max = 200, message = "[单位名称]长度必须在[200]以内!")
private String orgname;
@Size(min = 0, max = 36, message = "[昵称]长度必须在[36]以内!")
private String nickname;
@Size(min = 0, max = 100, message = "[邮箱]长度必须在[100]以内!")
private String email;
@Size(min = 0, max = 100, message = "[通信账号]长度必须在[100]以内!")
private String avatar;
@Size(min = 0, max = 100, message = "[联系电话]长度必须在[100]以内!")
private String phone;
@Size(min = 0, max = 100, message = "[保留字段]长度必须在[100]以内!")
private String reserver;
@Size(min = 0, max = 100, message = "[头像]长度必须在[100]以内!")
private String usericon;
@Size(min = 0, max = 10, message = "[性别]长度必须在[10]以内!")
private String sex;
private Timestamp birthday;
@Size(min = 0, max = 36, message = "[证件号码]长度必须在[36]以内!")
private String certcode;
@Size(min = 0, max = 200, message = "[地址]长度必须在[200]以内!")
private String addr;
@Size(min = 0, max = 100, message = "[主题]长度必须在[100]以内!")
private String theme;
@Size(min = 0, max = 100, message = "[语言]长度必须在[100]以内!")
private String lang;
@Size(min = 0, max = 10, message = "[字号]长度必须在[10]以内!")
private String fontsize;
@Size(min = 0, max = 500, message = "[备注]长度必须在[500]以内!")
private String memo;
private int superuser;
}
\ No newline at end of file
package cn.ibizlab.util.domain;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class LiquibaseProp{
private String url;
private String username;
private String password;
private String isSyncDBSchema;
private String defaultSchema;
private String conf;
}
\ No newline at end of file
package cn.ibizlab.util.domain;
import java.util.List;
/**
* 实体转换器基类
* @param <D> domainDTO
* @param <E> domain
*/
public interface MappingBase<D, E> {
/**
* dto转domain
* @param dto
* @return
*/
E toDomain(D dto);
/**
* domain转dto
* @param entity
* @return
*/
D toDto(E entity);
/**
* dto集合转domain集合
* @param dtoList
* @return
*/
List <E> toDomain(List<D> dtoList);
/**
* domain集合转dto集合
* @param entityList
* @return
*/
List <D> toDto(List<E> entityList);
}
package cn.ibizlab.util.enums;
/**
* 实体属性默认值类型
*/
public enum DEFieldDefaultValueType {
/**
* 用户全局对象
*/
SESSION,
/**
* 系统全局对象
*/
APPLICATION,
/**
* 唯一编码
*/
UNIQUEID,
/**
* 网页请求
*/
CONTEXT,
/**
* 数据对象属性
*/
PARAM,
/**
* 当前时间
*/
CURTIME,
/**
* 当前操作用户(编号)
*/
OPERATOR,
/**
* 当前操作用户(名称)
*/
OPERATORNAME,
/**
* 当前应用数据
*/
APPDATA,
/**
* 默认值
*/
NONE
}
package cn.ibizlab.util.enums;
/**
* 实体属性预定义类型
*/
public enum DEPredefinedFieldType {
/**
* 创建人标识
*/
CREATEMAN,
/**
* 创建人名称
*/
CREATEMANNAME,
/**
* 更新人标识
*/
UPDATEMAN,
/**
* 更新人名称
*/
UPDATEMANNAME,
/**
* 创建时间
*/
CREATEDATE,
/**
* 更新时间
*/
UPDATEDATE,
/**
* 组织机构标识
*/
ORGID,
/**
* 组织机构名称
*/
ORGNAME,
/**
* 部门标识
*/
ORGSECTORID,
/**
* 部门名称
*/
ORGSECTORNAME,
/**
* 逻辑有效
*/
LOGICVALID,
/**
* 排序
*/
ORDERVALUE,
/**
* 不处理
*/
NONE
}
package cn.ibizlab.util.enums;
import org.springframework.data.redis.listener.ChannelTopic;
/**
* redis频道
*/
public enum RedisChannelTopic {
REDIS_CACHE_DELETE_TOPIC("redis:cache:delete:topic1", "删除redis缓存消息频道"),
REDIS_CACHE_CLEAR_TOPIC("redis:cache:clear:topic2", "清空redis缓存消息频道");
String channelTopic;
String label;
RedisChannelTopic(String channelTopic, String label) {
this.channelTopic = channelTopic;
this.label = label;
}
public ChannelTopic getChannelTopic() {
return new ChannelTopic(channelTopic);
}
public static RedisChannelTopic getChannelTopicEnum(String channelTopic) {
for (RedisChannelTopic awardTypeEnum : RedisChannelTopic.values()) {
if (awardTypeEnum.getChannelTopicStr().equals(channelTopic)) {
return awardTypeEnum;
}
}
return null;
}
public String getChannelTopicStr() {
return channelTopic;
}
}
package cn.ibizlab.util.errors;
import org.zalando.problem.AbstractThrowableProblem;
import org.zalando.problem.Status;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
public class BadRequestAlertException extends AbstractThrowableProblem {
private final String entityName;
private final String errorKey;
public BadRequestAlertException(String defaultMessage, String entityName, String errorKey) {
this(ErrorConstants.DEFAULT_TYPE, defaultMessage, entityName, errorKey);
}
public BadRequestAlertException(URI type, String defaultMessage, String entityName, String errorKey) {
super(type, defaultMessage, Status.BAD_REQUEST, null, null, null, getAlertParameters(entityName, errorKey));
this.entityName = entityName;
this.errorKey = errorKey;
}
public String getEntityName() {
return entityName;
}
public String getErrorKey() {
return errorKey;
}
private static Map<String, Object> getAlertParameters(String entityName, String errorKey) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("message", "error." + errorKey);
parameters.put("params", entityName);
return parameters;
}
}
package cn.ibizlab.util.errors;
import org.zalando.problem.AbstractThrowableProblem;
import java.util.HashMap;
import java.util.Map;
import static org.zalando.problem.Status.BAD_REQUEST;
public class CustomParameterizedException extends AbstractThrowableProblem {
private static final long serialVersionUID = 1L;
private static final String PARAM = "param";
public CustomParameterizedException(String message, String... params) {
this(message, toParamMap(params));
}
public CustomParameterizedException(String message, Map<String, Object> paramMap) {
super(ErrorConstants.PARAMETERIZED_TYPE, "处理发生异常", BAD_REQUEST, null, null, null, toProblemParameters(message, paramMap));
}
public static Map<String, Object> toParamMap(String... params) {
Map<String, Object> paramMap = new HashMap<>();
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
paramMap.put(PARAM + i, params[i]);
}
}
return paramMap;
}
public static Map<String, Object> toProblemParameters(String message, Map<String, Object> paramMap) {
Map<String, Object> parameters = new HashMap<>();
parameters.put("message", message);
parameters.put("params", paramMap);
return parameters;
}
}
package cn.ibizlab.util.errors;
import java.net.URI;
public final class ErrorConstants {
public static final String ERR_CONCURRENCY_FAILURE = "处理请求发生错误";
public static final String ERR_VALIDATION = "数据校验发生错误";
public static final String PROBLEM_BASE_URL = "";
public static final URI DEFAULT_TYPE = URI.create(PROBLEM_BASE_URL + "/problem-with-message");
public static final URI CONSTRAINT_VIOLATION_TYPE = URI.create(PROBLEM_BASE_URL + "/constraint-violation");
public static final URI PARAMETERIZED_TYPE = URI.create(PROBLEM_BASE_URL + "/parameterized");
private ErrorConstants() {
}
}
package cn.ibizlab.util.errors;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.NativeWebRequest;
import org.zalando.problem.DefaultProblem;
import org.zalando.problem.Problem;
import org.zalando.problem.ProblemBuilder;
import org.zalando.problem.Status;
import org.zalando.problem.spring.web.advice.ProblemHandling;
import org.zalando.problem.spring.web.advice.validation.ConstraintViolationProblem;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;
@ControllerAdvice
public class ExceptionTranslator implements ProblemHandling {
@Override
public ResponseEntity<Problem> process(@Nullable ResponseEntity<Problem> entity, NativeWebRequest request) {
if (entity == null || entity.getBody() == null) {
return entity;
}
Problem problem = entity.getBody();
if (!(problem instanceof ConstraintViolationProblem || problem instanceof DefaultProblem)) {
return entity;
}
ProblemBuilder builder = Problem.builder()
.withType(Problem.DEFAULT_TYPE.equals(problem.getType()) ? ErrorConstants.DEFAULT_TYPE : problem.getType())
.withStatus(problem.getStatus())
.withTitle(problem.getTitle())
.with("path", request.getNativeRequest(HttpServletRequest.class).getRequestURI());
if (problem instanceof ConstraintViolationProblem) {
builder
.with("violations", ((ConstraintViolationProblem) problem).getViolations())
.with("message", ErrorConstants.ERR_VALIDATION);
return new ResponseEntity<>(builder.build(), entity.getHeaders(), entity.getStatusCode());
} else {
builder
.withCause(((DefaultProblem) problem).getCause())
.withDetail(problem.getDetail())
.withInstance(problem.getInstance());
problem.getParameters().forEach(builder::with);
if (!problem.getParameters().containsKey("message") && problem.getStatus() != null) {
builder.with("message", "error.http." + problem.getStatus().getStatusCode());
}
return new ResponseEntity<>(builder.build(), entity.getHeaders(), entity.getStatusCode());
}
}
@Override
public ResponseEntity<Problem> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, @Nonnull NativeWebRequest request) {
BindingResult result = ex.getBindingResult();
List<FieldErrorVM> fieldErrors = result.getFieldErrors().stream()
.map(f -> new FieldErrorVM(f.getObjectName(), f.getField(), f.getDefaultMessage()))
.collect(Collectors.toList());
Problem problem = Problem.builder()
.withType(ErrorConstants.CONSTRAINT_VIOLATION_TYPE)
.withTitle(ErrorConstants.ERR_VALIDATION)
.withStatus(defaultConstraintViolationStatus())
.with("message", ErrorConstants.ERR_VALIDATION )
.with("fieldErrors", fieldErrors)
.build();
return create(ex, problem, request);
}
@ExceptionHandler(BadRequestAlertException.class)
public ResponseEntity<Problem> handleBadRequestAlertException(BadRequestAlertException ex, NativeWebRequest request) {
return create(ex, request, createFailureAlert(ex.getEntityName(), ex.getErrorKey(), ex.getMessage()));
}
@ExceptionHandler(ConcurrencyFailureException.class)
public ResponseEntity<Problem> handleConcurrencyFailure(ConcurrencyFailureException ex, NativeWebRequest request) {
Problem problem = Problem.builder()
.withStatus(Status.CONFLICT)
.with("message", ErrorConstants.ERR_CONCURRENCY_FAILURE)
.build();
return create(ex, problem, request);
}
public static HttpHeaders createFailureAlert(String entityName, String errorKey, String defaultMessage) {
HttpHeaders headers = new HttpHeaders();
headers.add("X-ibz-error", "error." + errorKey);
headers.add("X-ibz-params", entityName);
return headers;
}
}
package cn.ibizlab.util.errors;
import java.io.Serializable;
public class FieldErrorVM implements Serializable {
private static final long serialVersionUID = 1L;
private final String objectName;
private final String field;
private final String message;
public FieldErrorVM(String dto, String field, String message) {
this.objectName = dto;
this.field = field;
this.message = message;
}
public String getObjectName() {
return objectName;
}
public String getField() {
return field;
}
public String getMessage() {
return message;
}
}
package cn.ibizlab.util.errors;
import org.zalando.problem.AbstractThrowableProblem;
import org.zalando.problem.Status;
public class InternalServerErrorException extends AbstractThrowableProblem {
public InternalServerErrorException(String message) {
super(ErrorConstants.DEFAULT_TYPE, message, Status.INTERNAL_SERVER_ERROR);
}
}
package cn.ibizlab.util.filter;
public interface ISearchContext {
}
package cn.ibizlab.util.filter;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.mongodb.QueryBuilder;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ObjectUtils;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
@Slf4j
@Data
public class QueryBuildContext extends SearchContextBase implements ISearchContext{
@JsonIgnore
@JSONField(serialize = false)
private QueryBuilder selectCond=new QueryBuilder();
public QueryBuilder getSearchCond(){
return this.selectCond;
}
/**
* 填充自定义查询条件
* @return
*/
public QueryBuilder getSelectCond() {
if(!ObjectUtils.isEmpty(filter)){
QueryBuilder queryBuilder=parseQueryFilter(filter);
if(!ObjectUtils.isEmpty(queryBuilder)){
selectCond.and(queryBuilder.get());
}
}
return selectCond;
}
/**
* 解析自定义查询条件
* @param queryFilter
* @return
*/
private QueryBuilder parseQueryFilter(QueryFilter queryFilter){
if( ObjectUtils.isEmpty(queryFilter.get$and()) && ObjectUtils.isEmpty(queryFilter.get$or()) && ObjectUtils.isEmpty(queryFilter.any()))
return null;
QueryBuilder rsBuilder=QueryBuilder.start();
QueryBuilder fieldBuilder=parseFieldMap(queryFilter.any());
QueryBuilder orBuilder=parseOrQueryFilter(queryFilter.get$or());
QueryBuilder andBuilder=parseAndQueryFilter(queryFilter.get$and());
if(!ObjectUtils.isEmpty(fieldBuilder)){
rsBuilder.and(fieldBuilder.get());
}
if(!ObjectUtils.isEmpty(orBuilder)){
rsBuilder.and(orBuilder.get());
}
if(!ObjectUtils.isEmpty(andBuilder)){
rsBuilder.and(andBuilder.get());
}
return rsBuilder;
}
/**
* 解析自定义条件[or]
* @param queryFilters
* @return
*/
private QueryBuilder parseOrQueryFilter(List<QueryFilter> queryFilters) {
QueryBuilder orBuilder =new QueryBuilder();
if(queryFilters==null || queryFilters.size()==0){
return null;
}
for(QueryFilter queryFilter: queryFilters){
QueryBuilder queryBuilder=parseQueryFilter(queryFilter);
if(!ObjectUtils.isEmpty(queryBuilder)){
orBuilder.or(queryBuilder.get());
}
}
return orBuilder;
}
/**
* 解析自定义条件[and]
* @param queryFilters
* @return
*/
private QueryBuilder parseAndQueryFilter(List<QueryFilter> queryFilters) {
QueryBuilder orBuilder =new QueryBuilder();
if(queryFilters==null || queryFilters.size()==0){
return null;
}
for(QueryFilter queryFilter: queryFilters){
QueryBuilder queryBuilder=parseQueryFilter(queryFilter);
if(!ObjectUtils.isEmpty(queryBuilder)){
orBuilder.and(queryBuilder.get());
}
}
return orBuilder;
}
/**
* 解析自定义条件[字段条件]
* @param fieldMap
* @return
*/
private QueryBuilder parseFieldMap(Map<String , QueryFilter.SegmentCond> fieldMap) {
if(fieldMap.size()==0)
return null;
QueryBuilder fieldBuilders=QueryBuilder.start();
for(Map.Entry<String, QueryFilter.SegmentCond> entry: fieldMap.entrySet()){
getSegmentCondSql(entry.getKey(),entry.getValue(),fieldBuilders);
}
return fieldBuilders;
}
/**
* 解析自定义条件[字段条件]
* @param fieldName
* @param segmentCond
* @param fieldBuilder
*/
private void getSegmentCondSql(String fieldName, QueryFilter.SegmentCond segmentCond,QueryBuilder fieldBuilder) {
Map<String , Object> segmentCondMap = segmentCond.any();
for(Map.Entry<String , Object> entry: segmentCondMap.entrySet()){
Object value=entry.getValue();
switch (entry.getKey()){
case "$eq":
fieldBuilder.and(QueryBuilder.start().and(fieldName).is(value).get());
break;
case "$ne":
fieldBuilder.and(QueryBuilder.start().not().and(fieldName).is(value).get());
break;
case "$gt":
fieldBuilder.and(QueryBuilder.start().and(fieldName).greaterThan(value).get());
break;
case "$gte":
fieldBuilder.and(QueryBuilder.start().and(fieldName).greaterThanEquals(value).get());
break;
case "$lt":
fieldBuilder.and(QueryBuilder.start().and(fieldName).lessThan(value).get());
break;
case "$lte":
fieldBuilder.and(QueryBuilder.start().and(fieldName).lessThanEquals(value).get());
break;
case "$null":
fieldBuilder.and(QueryBuilder.start().and(fieldName).exists(null).get());
break;
case "$notNull":
fieldBuilder.and(QueryBuilder.start().and(fieldName).exists(true).and(fieldName).notEquals("").and(fieldName).notEquals(null).get());
break;
case "$in":
fieldBuilder.and(QueryBuilder.start().and(fieldName).in(value).get());
break;
case "$notIn":
fieldBuilder.and(QueryBuilder.start().and(fieldName).not().in(value).get());
break;
case "$like":
Pattern likePattern = Pattern.compile("^.*" + value + ".*$", Pattern.CASE_INSENSITIVE);
fieldBuilder.and(QueryBuilder.start().and(fieldName).regex(likePattern).get());
break;
case "$startsWith":
Pattern startsWithPattern = Pattern.compile(value + ".*$", Pattern.CASE_INSENSITIVE);
fieldBuilder.and(QueryBuilder.start().and(fieldName).regex(startsWithPattern).get());
break;
case "$endsWith":
Pattern endsWithPattern = Pattern.compile("^.*" + value + "$", Pattern.CASE_INSENSITIVE);
fieldBuilder.and(QueryBuilder.start().and(fieldName).regex(endsWithPattern).get());
break;
case "$exists":
break;
case "$notExists":
break;
}
}
}
}
package cn.ibizlab.util.filter;
import com.fasterxml.jackson.annotation.*;
import org.springframework.data.annotation.Transient;
import java.util.*;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class QueryFilter {
public static QueryFilter createQuery()
{
QueryFilter queryFilter=new QueryFilter();
return queryFilter;
}
public QueryFilter eq(String column,Object value) {
return op(column,SegmentCond.eq(value));
}
public QueryFilter ne(String column,Object value) {
return op(column,SegmentCond.ne(value));
}
public QueryFilter gt(String column,Object value) {
return op(column,SegmentCond.gt(value));
}
public QueryFilter ge(String column,Object value) {
return op(column,SegmentCond.ge(value));
}
public QueryFilter lt(String column,Object value) {
return op(column,SegmentCond.lt(value));
}
public QueryFilter le(String column,Object value) {
return op(column,SegmentCond.le(value));
}
public QueryFilter isnull(String column) {
return op(column,SegmentCond.isnull());
}
public QueryFilter isnotnull(String column) {
return op(column,SegmentCond.isnotnull());
}
public QueryFilter in(String column,Collection value) {
return op(column,SegmentCond.in(value));
}
public QueryFilter notin(String column,Collection value) {
return op(column,SegmentCond.notin(value));
}
public QueryFilter like(String column,String value) {
return op(column,SegmentCond.like(value));
}
public QueryFilter startsWith(String column,String value) {
return op(column,SegmentCond.startsWith(value));
}
public QueryFilter endsWith(String column,String value) {
return op(column,SegmentCond.endsWith(value));
}
public QueryFilter between(String column,Object from,Object to) {
return op(column,SegmentCond.between(from,to));
}
@JsonIgnore
@Transient
private Map<String,SegmentCond> map;
private Map<String,SegmentCond> getMap()
{
if(map==null)
map=new LinkedHashMap<>();
return map;
}
@JsonAnyGetter
public Map<String , SegmentCond> any() {
return getMap();
}
@JsonAnySetter
public void set(String column, SegmentCond value) {
getMap().put(column,value);
}
@JsonProperty(index = 999)
private List<QueryFilter> $or;
public List<QueryFilter> get$or() {
return $or;
}
public void set$or(List<QueryFilter> $or) {
this.$or = $or;
}
public QueryFilter or(QueryFilter... ors)
{
if ($or == null) {
$or = new ArrayList();
}
Collections.addAll($or, ors);
return this;
}
@JsonProperty(index = 999)
private List<QueryFilter> $and;
public List<QueryFilter> get$and() {
return $and;
}
public void set$and(List<QueryFilter> $and) {
this.$and = $and;
}
public QueryFilter and(QueryFilter... ands)
{
if ($and == null) {
$and = new ArrayList();
}
Collections.addAll($and, ands);
return this;
}
@Override
public String toString() {
return "QueryFilter{" +
"map=" + map +
", $or=" + $or +
'}';
}
private QueryFilter op(String column, SegmentCond segmentCond) {
if(this.getMap().containsKey(column))
((SegmentCond)this.getMap().get(column)).getMap().putAll(segmentCond.getMap());
else
this.getMap().put(column,segmentCond);
return this;
}
public static class SegmentCond {
@JsonIgnore
@Transient
private Map<String,Object> map;
@Override
public String toString() {
return "SegmentCond{" +
"map=" + map +
'}';
}
private Map<String,Object> getMap()
{
if(map==null)
map=new LinkedHashMap<>();
return map;
}
@JsonAnyGetter
public Map<String , Object> any() {
return getMap();
}
@JsonAnySetter
public void set(String column, Object value) {
getMap().put(column,value);
}
public static SegmentCond eq(Object value) {
return op(Segment.EQ,value);
}
public static SegmentCond ne(Object value) {
return op(Segment.NE,value);
}
public static SegmentCond gt(Object value) {
return op(Segment.GT,value);
}
public static SegmentCond ge(Object value) {
return op(Segment.GE,value);
}
public static SegmentCond lt(Object value) {
return op(Segment.LT,value);
}
public static SegmentCond le(Object value) {
return op(Segment.LE,value);
}
public static SegmentCond isnull() {
return op(Segment.IS_NULL,true);
}
public static SegmentCond isnotnull() {
return op(Segment.IS_NOT_NULL,true);
}
public static SegmentCond in(Collection value) {
return op(Segment.IN,value);
}
public static SegmentCond notin(Collection value) {
return op(Segment.NOTIN,value);
}
public static SegmentCond like(String value) {
return op(Segment.LIKE,value);
}
public static SegmentCond startsWith(String value) {
return op(Segment.LEFTLIKE,value);
}
public static SegmentCond endsWith(String value) {
return op(Segment.RIGHTLIKE,value);
}
public static SegmentCond between(Object from,Object to) {
return op(Segment.GE,from).op(Segment.LT,to);
}
private static SegmentCond op(Segment segment,Object value) {
SegmentCond segmentCond=new SegmentCond();
segmentCond.getMap().put(segment.keyword,value);
return segmentCond;
}
}
public enum Segment {
AND("$and"),
OR("$or"),
EQ("$eq"),
NE("$ne"),
GT("$gt"),
GE("$gte"),
LT("$lt"),
LE("$lte"),
IS_NULL("$null"),
IS_NOT_NULL("$notNull"),
IN("$in"),
NOTIN("$notIn"),
LIKE("$like"),
LEFTLIKE("$startsWith"),
RIGHTLIKE("$endsWith"),
EXISTS("$exists"),
NOTEXISTS("$notExists");
private final String keyword;
Segment(final String keyword) {
this.keyword = keyword;
}
}
/*
SQL: (field1>1 and field2='3' and (field3 like "a" or (field4 is not null and field5 in ['11','12']) )
JAVA: QueryFilter filter=QueryFilter.createQuery()
.gt("field1",1)
.eq("field2",'3')
.or(QueryFilter.createQuery().like("field3","a")
,QueryFilter.createQuery().isnotnull("field4").in("field5",Arrays.asList("11","12")));
JSON: {
"$or":[
{
"field3":{"$like":"a"}
},
{
"field4":{ "$notNull":true},
"field5":{"$in":["11","12"]}
}],
"field1":{"$gt":1},
"field2":{"$eq":"3" }
}
*/
}
package cn.ibizlab.util.filter;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import com.alibaba.fastjson.annotation.JSONField;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.ParameterizedType;
import java.util.*;
import java.util.function.Consumer;
@Slf4j
@Data
public class QueryWrapperContext<T> extends SearchContextBase implements ISearchContext{
@JsonIgnore
@JSONField(serialize = false)
private QueryWrapper<T> selectCond=new QueryWrapper<T>();
/**
* 解析查询上下文中的参数,构建mybatis-plus分页对象
* @return
*/
@JsonIgnore
@JSONField(serialize = false)
public Page getPages(){
Page page;
List<String> asc_fieldList = new ArrayList<>();
List<String> desc_fieldList = new ArrayList<>();
int currentPage=getPageable().getPageNumber();
int pageSize=getPageable().getPageSize();
//构造mybatis-plus分页
if(StringUtils.isEmpty(currentPage) || StringUtils.isEmpty(pageSize))
page=new Page(1,Short.MAX_VALUE);
else
page=new Page(currentPage+1,pageSize);
//构造mybatis-plus排序
Sort sort = getPageable().getSort();
Iterator<Sort.Order> it_sort = sort.iterator();
if(ObjectUtils.isEmpty(it_sort))
return page;
ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass();
Class<T> type = (Class<T>)parameterizedType.getActualTypeArguments()[0];
while (it_sort.hasNext()) {
Sort.Order sort_order = it_sort.next();
if(sort_order.getDirection()== Sort.Direction.ASC){
asc_fieldList.add(DEFieldCacheMap.getFieldColumnName(type,sort_order.getProperty()));
}
else if(sort_order.getDirection()== Sort.Direction.DESC){
desc_fieldList.add(DEFieldCacheMap.getFieldColumnName(type,sort_order.getProperty()));
}
}
if(asc_fieldList.size()>0){
page.setAscs(asc_fieldList);
}
if(desc_fieldList.size()>0){
page.setDescs(desc_fieldList);
}
return page;
}
public QueryWrapper<T> getSearchCond(){
return this.selectCond;
}
/**
* 填充自定义查询条件
* @return
*/
public QueryWrapper<T> getSelectCond() {
if(!ObjectUtils.isEmpty(filter)){
Consumer queryWrapper = parseQueryFilter(filter);
if(!ObjectUtils.isEmpty(queryWrapper)){
selectCond.and(queryWrapper);
}
}
return selectCond;
}
/**
* 解析自定义查询条件
* @param queryFilter
* @return
*/
private Consumer<QueryWrapper<T>> parseQueryFilter(QueryFilter queryFilter){
if(queryFilter.any().size()==0 && queryFilter.get$or()==null && queryFilter.get$and()==null)
return null;
Consumer<QueryWrapper<T>> consumer = queryWrapper -> {
Consumer fieldConsumer=parseFieldMap(queryFilter.any());
Consumer orConsumer=parseOrQueryFilter(queryFilter.get$or());
Consumer andConsumer=parseAndQueryFilter(queryFilter.get$and());
if(!ObjectUtils.isEmpty(fieldConsumer)){
queryWrapper.and(fieldConsumer);
}
if(!ObjectUtils.isEmpty(orConsumer)){
queryWrapper.and(orConsumer);
}
if(!ObjectUtils.isEmpty(andConsumer)){
queryWrapper.and(andConsumer);
}
};
return consumer;
}
/**
* 解析自定义条件[or]
* @param queryFilters
* @return
*/
private Consumer<QueryWrapper<T>> parseOrQueryFilter(List<QueryFilter> queryFilters) {
if(queryFilters==null || queryFilters.size()==0)
return null;
Consumer<QueryWrapper<T>> consumer = queryWrapper -> {
for(QueryFilter queryFilter: queryFilters){
Consumer tempQueryWrapper=parseQueryFilter(queryFilter);
queryWrapper.or(tempQueryWrapper);
}
};
return consumer;
}
/**
* 解析自定义条件[and]
* @param queryFilters
* @return
*/
private Consumer<QueryWrapper<T>> parseAndQueryFilter(List<QueryFilter> queryFilters) {
if(queryFilters==null || queryFilters.size()==0)
return null;
Consumer<QueryWrapper<T>> consumer = queryWrapper -> {
for(QueryFilter queryFilter: queryFilters){
Consumer tempQueryWrapper=parseQueryFilter(queryFilter);
queryWrapper.and(tempQueryWrapper);
}
};
return consumer;
}
/**
* 解析自定义条件[字段条件]
* @param fieldMap
* @return
*/
private Consumer<QueryWrapper<T>> parseFieldMap(Map<String , QueryFilter.SegmentCond> fieldMap) {
if(fieldMap.size()==0)
return null;
Consumer<QueryWrapper<T>> consumer = queryWrapper -> {
for(Map.Entry<String, QueryFilter.SegmentCond> field: fieldMap.entrySet()){
String fieldName=field.getKey();
QueryFilter.SegmentCond segmentCond=field.getValue();
Map<String , Object> segmentCondMap = segmentCond.any();
for(Map.Entry<String , Object> fieldCond: segmentCondMap.entrySet()){
Object value=fieldCond.getValue();
switch (fieldCond.getKey()){
case "$eq":
queryWrapper.eq(fieldName,value);
break;
case "$ne":
queryWrapper.ne(fieldName,value);
break;
case "$gt":
queryWrapper.gt(fieldName,value);
break;
case "$gte":
queryWrapper.ge(fieldName,value);
break;
case "$lt":
queryWrapper.lt(fieldName,value);
break;
case "$lte":
queryWrapper.le(fieldName,value);
break;
case "$null":
queryWrapper.isNull(fieldName);
break;
case "$notNull":
queryWrapper.isNotNull(fieldName);
break;
case "$in":
queryWrapper.in(fieldName,(Collection)value);
break;
case "$notIn":
queryWrapper.notIn(fieldName,(Collection)value);
break;
case "$like":
queryWrapper.like(fieldName,value);
break;
case "$startsWith":
queryWrapper.likeRight(fieldName,value);
break;
case "$endsWith":
queryWrapper.likeLeft(fieldName,value);
break;
case "$exists":
break;
case "$notExists":
break;
}
}
}
};
return consumer;
}
}
package cn.ibizlab.util.filter;
import cn.ibizlab.util.security.AuthenticationUser;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.PageRequest;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.util.StringUtils;
import org.springframework.util.ObjectUtils;
import java.util.*;
@Slf4j
@Data
public class SearchContextBase implements ISearchContext{
/**
* 自定义查询条件
*/
@JsonProperty("customcond")
public String customCond;
/**
* 自定义查询参数
*/
@JsonProperty("customparams")
public String customParams;
/**
* 快速搜索
*/
@JsonProperty("query")
public String query;
/**
* 条件表达式
*/
@JsonProperty("filter")
public QueryFilter filter;
/**
* 数据查询
*/
public List dataQueryList;
/**
* 当前页数
*/
public int page=0;
/**
* 每页显示条数
*/
public int size=20;
/**
* 排序
*/
public String sort;
/**
* 排序对象
*/
@JsonIgnore
public Sort pageSort;
/**
* 工作流步骤标识
*/
public String userTaskId;
/**
* 工作流流程标识
*/
public String processDefinitionKey;
/**
* 获取工作流步骤标识
*/
public String getUserTaskId() {
if(StringUtils.isEmpty(userTaskId)){
Object taskId=params.get("usertaskid");
return StringUtils.isEmpty(taskId)?null:String.valueOf(taskId);
}else{
return userTaskId;
}
}
/**
* 获取工作流流程标识
* @return
*/
public String getProcessDefinitionKey() {
if(StringUtils.isEmpty(processDefinitionKey)){
Object processKey=params.get("processdefinitionkey");
return StringUtils.isEmpty(processKey)?null:String.valueOf(processKey);
}
else{
return processDefinitionKey;
}
}
/**
* 获取分页参数
* @return
*/
public Pageable getPageable() {
if(ObjectUtils.isEmpty(pageSort))
return PageRequest.of(page,size);
else
return PageRequest.of(page,size,pageSort);
}
/**
* 设置排序值
* @param strSort
*/
public void setSort(String strSort) {
this.sort=strSort;
if(!StringUtils.isEmpty(strSort)){
String sortArr[]=strSort.split(",");
String sortField=sortArr[0];
String sortDirection=sortArr[1];
if(sortDirection.equalsIgnoreCase("asc")){
this.pageSort=Sort.by(Sort.Direction.ASC,sortField);
}
else if(sortDirection.equalsIgnoreCase("desc")){
this.pageSort=Sort.by(Sort.Direction.DESC,sortField);
}
}
}
/**
* 上下文参数
*/
Map<String,Object> params = new HashMap<String,Object>() ;
/**
* 获取数据上下文
* @return
*/
public Map<String,Object> getDatacontext() {
return params;
}
/**
* 获取网页请求上下文
* @return
*/
public Map<String,Object> getWebcontext() {
return params;
}
/**
* 获取用户上下文
* @return
*/
public Map<String,Object> getSessioncontext() {
return AuthenticationUser.getAuthenticationUser().getSessionParams();
}
@JsonAnyGetter
public Map<String , Object> any() {
return params;
}
@JsonAnySetter
public void set(String name, Object value) {
params.put(name, value);
}
}
package cn.ibizlab.util.helper;
import org.springframework.cglib.beans.BeanCopier;
import java.util.HashMap;
import java.util.Map;
public class CachedBeanCopier {
//创建过的BeanCopier实例放到缓存中,下次可以直接获取,提升性能
static final Map<String, BeanCopier> BEAN_COPIERS = new HashMap<String, BeanCopier>();
public static void copy(Object srcObj, Object destObj) {
copy(srcObj,destObj,false);
}
public static void copy(Object srcObj, Object destObj,boolean useConverter) {
if(srcObj==null||destObj==null)
return;
getCopier(srcObj,destObj,useConverter).copy(srcObj, destObj, null);
}
public synchronized static BeanCopier getCopier(Object srcObj, Object destObj,boolean useConverter) {
String key = srcObj.getClass().getName()+destObj.getClass().getName()+useConverter;
BeanCopier copier;
if (!BEAN_COPIERS.containsKey(key)) {
copier = BeanCopier.create(srcObj.getClass(), destObj.getClass(), useConverter);
BEAN_COPIERS.put(key, copier);
} else {
copier = BEAN_COPIERS.get(key);
}
return copier;
}
}
package cn.ibizlab.util.helper;
import cn.ibizlab.util.annotation.Audit;
import cn.ibizlab.util.annotation.DEField;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
/**
* 实体对象属性缓存类
*/
public class DEFieldCacheMap {
private static Hashtable<String, Hashtable<String,Field>> cacheMap = new Hashtable<>();
private static Hashtable<String, List<Field>> cacheList = new Hashtable<>();
private static Hashtable<String, Hashtable<String,String>> cacheKey = new Hashtable<>();
private static Hashtable<String, Hashtable<String,DEField>> cacheDEField = new Hashtable<>();
private static Hashtable<String, Hashtable<String,Audit>> cacheAuditField = new Hashtable<>();
private static Hashtable<String, String> cacheDEKeyField = new Hashtable<>();
private static Object objLock1=new Object();
/**
* 将实体对象中的属性存入缓存中
* @param
* @return
*/
public static <T> Hashtable<String,Field> getFieldMap(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheMap.containsKey(className))
return cacheMap.get(className);
synchronized (objLock1) {
if(cacheMap.containsKey(className))
return cacheMap.get(className);
Hashtable<String,Field> result = new Hashtable<String,Field>();
List<Field> list=new ArrayList<Field>();
Hashtable<String,String> keys=new Hashtable<String,String>();
Hashtable<String,DEField> defields=new Hashtable<>();
Hashtable<String, Audit> auditfields=new Hashtable<>();
Hashtable<String,String> dekeyfields=new Hashtable<>();
Field[] fields=clazz.getDeclaredFields();
for(Field field:fields){
result.put(field.getName(),field);
list.add(field);
keys.put(field.getName().toLowerCase(),field.getName());
DEField deField=field.getAnnotation(DEField.class);
Audit auditField=field.getAnnotation(Audit.class);
if(!ObjectUtils.isEmpty(deField)) {
defields.put(field.getName(),deField);
if(deField.isKeyField())
cacheDEKeyField.put(className,field.getName());
}
if(!ObjectUtils.isEmpty(auditField)) {
auditfields.put(field.getName(),auditField);
}
}
cacheMap.put(className, result);
cacheList.put(className,list);
cacheKey.put(className,keys);
cacheDEField.put(className,defields);
cacheAuditField.put(className,auditfields);
return result;
}
}
public static Hashtable<String,Field> getFieldMap(String className) {
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheMap.containsKey(className))
return cacheMap.get(className);
Class clazz = null;
try {
clazz = Class.forName(className);
return getFieldMap(clazz);
}
catch (Exception ex) {
cacheMap.put(className, new Hashtable<String,Field>());
return cacheMap.get(className);
}
}
/**
* 从缓存中查询实体对象属性集合
* @param
* @return
*/
public static <T> Hashtable<String,DEField> getDEFields(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheDEField.containsKey(className))
return cacheDEField.get(className);
else{
DEFieldCacheMap.getFieldMap(className);
return cacheDEField.get(className);
}
}
/**
* 从缓存中查询审计属性集合
* @param
* @return
*/
public static <T> Hashtable<String,Audit> getAuditFields(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheAuditField.containsKey(className))
return cacheAuditField.get(className);
else{
DEFieldCacheMap.getFieldMap(className);
return cacheAuditField.get(className);
}
}
/**
* 从缓存中查询实体对象主键
* @param
* @return
*/
public static <T> String getDEKeyField(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheDEKeyField.containsKey(className))
return cacheDEKeyField.get(className);
else{
DEFieldCacheMap.getFieldMap(className);
return cacheDEKeyField.get(className);
}
}
/**
* 从缓存中查询实体对象属性列表
* @param
* @return
*/
public static <T> List<Field> getFields(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheList.containsKey(className))
return cacheList.get(className);
else{
DEFieldCacheMap.getFieldMap(className);
return cacheList.get(className);
}
}
public static List<Field> getFields(String className) {
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheList.containsKey(className))
return cacheList.get(className);
else{
DEFieldCacheMap.getFieldMap(className);
return cacheList.get(className);
}
}
/**
* 从缓存中查询实体对象属性列表
* @param
* @return
*/
public static <T> Hashtable<String,String> getFieldKeys(Class<T> clazz) {
String className=clazz.getName();
if(className.indexOf("_$")>0)
className=className.substring(0, className.lastIndexOf("_$"));
if(cacheKey.containsKey(className))
return cacheKey.get(className);
else{
DEFieldCacheMap.getFieldMap(className);
return cacheKey.get(className);
}
}
public static <T> String getFieldRealName(Class<T> clazz,String fieldname) {
fieldname=fieldname.toLowerCase();
Hashtable<String,String> keys=DEFieldCacheMap.getFieldKeys(clazz);
if(keys.containsKey(fieldname))
return keys.get(fieldname);
else if(keys.containsKey(fieldname.replace("_","")))
return keys.get(fieldname.replace("_",""));
else
return "";
}
public static <T> Field getField(Class<T> clazz,String fieldname) {
String fieldRealName=DEFieldCacheMap.getFieldRealName(clazz,fieldname);
if(!StringUtils.isEmpty(fieldRealName))
return DEFieldCacheMap.getFieldMap(clazz).get(fieldRealName);
else
return null;
}
public static <T> String getFieldColumnName(Class<T> clazz,String fieldname) {
Field field = DEFieldCacheMap.getField(clazz,fieldname);
if(field!=null) {
DEField deField=field.getAnnotation(DEField.class);
if(deField!=null&& !StringUtils.isEmpty(deField.name()))
return deField.name();
}
return fieldname;
}
public static <T> Object fieldValueOf(Class<T> clazz,String fieldname,Object fieldValue) {
if(fieldValue==null)
return null;
Object resultValue=fieldValue;
Field field = DEFieldCacheMap.getField(clazz,fieldname);
if(field!=null) {
Class<?> type=field.getType();
resultValue = DataObject.objectValueOf(type,fieldValue);
}
return resultValue;
}
}
\ No newline at end of file
package cn.ibizlab.util.helper;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.StringUtils;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class DataObject {
final static public DateFormat datetimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
final static public DateFormat datetimeFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm");
final static public DateFormat dayFormat = new SimpleDateFormat("yyyy-MM-dd");
final static public String getStringValue(Object objValue, String strDefault) {
if (objValue == null) return strDefault;
if (objValue instanceof String) return (String) objValue;
if (objValue instanceof java.sql.Timestamp||objValue instanceof java.sql.Date||objValue instanceof java.util.Date) {
String rt=datetimeFormat.format(objValue);
if(rt.endsWith(" 00:00:00"))
rt=dayFormat.format(objValue);
else if(rt.endsWith(":00"))
rt=datetimeFormat2.format(objValue);
return rt;
}
return objValue.toString();
}
public static <T> Object objectValueOf(Class<T> type,Object fieldValue) {
if(fieldValue==null)
return null;
Object resultValue=fieldValue;
String targetType=type.getSimpleName();
if(targetType.equalsIgnoreCase(fieldValue.getClass().getSimpleName()))
return resultValue;
if(targetType.equals("Boolean")){
resultValue=getBooleanValue(fieldValue,false);
}
else if(targetType.equals("Character")){
resultValue=getCharacterValue(fieldValue,null);
}
else if(targetType.equals("Byte")){
resultValue=getBinaryValue(fieldValue,null);
}
else if(targetType.equals("Short")){
resultValue=Short.valueOf(fieldValue.toString());
}
else if(targetType.equals("Integer")){
resultValue= getIntegerValue(fieldValue,null);
}
else if(targetType.equals("Long")){
resultValue=getLongValue(fieldValue,null);
}
else if(targetType.equals("Float")){
resultValue= getFloatValue(fieldValue,null);
}
else if(targetType.equals("Double")){
resultValue= getDoubleValue(fieldValue,null);
}
else if(targetType.equals("BigDecimal")){
resultValue= getBigDecimalValue(fieldValue,null);
}
else if(targetType.equals("BigInteger")){
resultValue= getBigIntegerValue(fieldValue,null);
}
else if(targetType.equals("Timestamp")){
resultValue= getTimestampValue(fieldValue,null);
}
else if(targetType.equals("String")) {
resultValue= getStringValue(fieldValue,null);
}
if(resultValue==null)
return null;
return resultValue;
}
public static <T> T valueOf(Class<T> type,Object fieldValue) {
return (T)objectValueOf(type,fieldValue);
}
final static public JSONObject getJSONObjectValue(Object objValue, JSONObject jDefault) {
if (objValue == null) {
return jDefault;
}
if(objValue instanceof JSONObject)
return (JSONObject)objValue;
String strValue = objValue.toString();
try {
return JSONObject.parseObject(strValue);
}
catch (Exception ex)
{
return jDefault;
}
}
final static public JSONArray getJSONArrayValue(Object objValue, JSONArray jDefault) {
if (objValue == null) {
return jDefault;
}
if(objValue instanceof JSONArray)
return (JSONArray)objValue;
String strValue = objValue.toString();
try {
return JSONArray.parseArray(strValue);
}
catch (Exception ex)
{
return jDefault;
}
}
final static public List<String> getListValue(Object objValue) {
if (objValue == null) {
return new ArrayList<String>();
}
JSONArray arr=(getJSONArrayValue(objValue,null));
if(arr!=null)
{
List<String> chk1=new ArrayList<>();
for(int i=0;i<arr.size();i++)
{
if(arr.get(i) instanceof String)
chk1.add(arr.getString(i));
}
return chk1;
}
else
{
return new ArrayList<String>();
}
}
final static public Boolean getBooleanValue(Object objValue,Boolean bDefault) {
if (objValue == null) return bDefault;
if (objValue instanceof Boolean) {
return (Boolean) objValue;
}
return objValue.toString().equalsIgnoreCase("true")||objValue.toString().equals("1")||objValue.toString().equals("y");
}
final static public char[] getCharacterValue(Object objValue,char[] cDefault) {
if (objValue == null) return cDefault;
return objValue.toString().toCharArray();
}
final static public Double getDoubleValue(Object objValue,Double dDefault) {
if (objValue == null) return dDefault;
if (objValue instanceof Double) {
return (Double) objValue;
}
String strValue = objValue.toString();
if (StringUtils.isEmpty(strValue)) return null;
strValue = strValue.replace(",", "");
return Double.parseDouble(strValue);
}
final static public int getIntegerValue( Object objValue, Integer nDefault) {
if (objValue == null) {
return nDefault;
}
if(objValue instanceof Integer)
return (Integer)objValue;
if (objValue instanceof Double) {
return ((Double) objValue).intValue();
}
if (objValue instanceof BigDecimal) {
return ((BigDecimal) objValue).intValue();
}
String strValue = objValue.toString();
if(StringUtils.isEmpty(strValue))
return nDefault;
strValue = strValue.replace(",", "");
return Integer.parseInt(strValue);
}
final static public Float getFloatValue( Object objValue, Float fDefault) {
if (objValue == null) {
return fDefault;
}
try {
if(objValue instanceof Float)
return (Float)objValue;
String strValue = objValue.toString();
if(StringUtils.isEmpty(strValue))
return fDefault;
strValue = strValue.replace(",", "");
return Float.parseFloat(strValue);
} catch (Exception ex) {
return fDefault;
}
}
final static public BigDecimal getBigDecimalValue( Object objValue, BigDecimal fDefault) {
if (objValue == null) {
return fDefault;
}
try {
if(objValue instanceof BigDecimal){
return (BigDecimal)(objValue);
}
if(objValue instanceof Double){
return BigDecimal.valueOf((Double)objValue);
}
if(objValue instanceof Long){
return BigDecimal.valueOf((Long)objValue);
}
String strValue = objValue.toString();
if(StringUtils.isEmpty(strValue))
return fDefault;
strValue = strValue.replace(",", "");
return BigDecimal.valueOf(Double.parseDouble(strValue));
} catch (Exception ex) {
return fDefault;
}
}
final static public BigInteger getBigIntegerValue( Object objValue, BigInteger fDefault) {
if (objValue == null) {
return fDefault;
}
try {
if(objValue instanceof BigInteger){
return (BigInteger)(objValue);
}
else {
Long l=getLongValue(objValue,null);
if(l!=null)
return BigInteger.valueOf(l);
}
} catch (Exception ex) {
}
return fDefault;
}
final static public Long getLongValue( Object objValue, Long nDefault) {
if (objValue == null) {
return nDefault;
}
try {
if (objValue instanceof Long) return (Long) objValue;
if (objValue instanceof Integer) {
return ((Integer) objValue).longValue();
}
if (objValue instanceof Double) {
return ((Double) objValue).longValue();
}
if (objValue instanceof BigDecimal) {
return ((BigDecimal) objValue).longValue();
}
String strValue = objValue.toString();
if(StringUtils.isEmpty(strValue))
return nDefault;
strValue = strValue.replace(",", "");
return Long.parseLong(strValue);
} catch (Exception ex) {
return nDefault;
}
}
final static public byte[] getBinaryValue(Object objValue, byte[] def) {
if (objValue == null) return def;
if(objValue instanceof byte[]){
return (byte[])objValue;
}
if (objValue instanceof String){
return Base64.getDecoder().decode((String) objValue);
}
return def;
}
/**
* 转换对象值到时间值
*
* @param objValue
* @return
* @
*/
final static public java.sql.Timestamp getTimestampValue(Object objValue,java.sql.Timestamp tDefault) {
if (objValue == null) return tDefault;
if (objValue instanceof java.sql.Timestamp) {
java.sql.Timestamp ti = (java.sql.Timestamp) objValue;
return ti;
}
if (objValue instanceof java.sql.Date) {
java.sql.Date date = (java.sql.Date) objValue;
return new java.sql.Timestamp(date.getTime());
}
if (objValue instanceof java.util.Date) {
java.util.Date date = (java.util.Date) objValue;
return new java.sql.Timestamp(date.getTime());
}
if (objValue instanceof String) {
String strValue = (String) objValue;
strValue = strValue.trim();
if (StringUtils.isEmpty(strValue)) return null;
try {
java.util.Date date = parse((String) objValue);
return new java.sql.Timestamp(date.getTime());
}
catch (Exception ex)
{
return tDefault;
}
}
if(objValue instanceof Long)
{
Long lValue = (Long)objValue;
return new java.sql.Timestamp(lValue);
}
if(objValue instanceof Integer)
{
int lValue = (int)objValue;
return new java.sql.Timestamp(lValue);
}
return tDefault;
}
public static Object testDateTime(String strInput) throws Exception{
return testDateTime(strInput, null);
}
/**
* 转换文本值到日期时间
*
* @param strInput
* @param timeZone
* @return
* @
*/
public static Object testDateTime(String strInput, TimeZone timeZone) throws Exception{
if (StringUtils.isEmpty(strInput)) return null;
Date dtDate = parse(strInput, timeZone);
java.sql.Timestamp retDate = new java.sql.Timestamp(dtDate.getTime());
return retDate;
}
/**
* 转换字符串到时间对象
*
* @param strTimeString
* @return
* @throws ParseException
* @
*/
public static Date parse(String strTimeString) throws ParseException, Exception {
return parse(strTimeString, null);
}
/**
* 分析时间串
*
* @param strTimeString MM/dd/yy yy-MM-dd HH:mm:ss 格式
* @param timeZone
* @return
* @throws ParseException
* @
*/
public static Date parse(String strTimeString, TimeZone timeZone) throws ParseException, Exception {
strTimeString = strTimeString.trim();
if(StringUtils.isEmpty(strTimeString)){
throw new Exception("unknown date(time) string");
}
if(strTimeString.indexOf("Z")!=-1){
//有时区
String[] parts = strTimeString.split("[Z]");
if(parts.length>=1){
strTimeString = parts[0];
}
if(parts.length>=2){
if(timeZone == null){
if(!StringUtils.isEmpty(parts[1])){
timeZone = TimeZone.getTimeZone(parts[1]);
}
}
}
}
// 判断是长数据还是短数据
String strPart[] = null;
if(strTimeString.indexOf("T")!=-1){
strPart = strTimeString.split("[T]");
}
else
strPart = strTimeString.split(" ");
if (strPart.length == 2) {
// 两个部分
String strDate = "";
String strTime = "";
if (strPart[0].indexOf(":") != -1) {
strTime = strPart[0];
strDate = strPart[1];
} else {
strTime = strPart[1];
strDate = strPart[0];
}
strDate = strDate.trim();
strTime = strTime.trim();
strDate = getFormatDateString(strDate);
strTime = getFormatTimeString(strTime);
DateFormat dtFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if (timeZone != null) {
dtFormat.setTimeZone(timeZone);
}
return dtFormat.parse(strDate + " " + strTime);
} else {
// 一个部分
if (strTimeString.indexOf(":") != -1) {
// 时间
strTimeString = getFormatTimeString(strTimeString);
DateFormat dtFormat = new SimpleDateFormat("HH:mm:ss");
if (timeZone != null) {
dtFormat.setTimeZone(timeZone);
}
return dtFormat.parse(strTimeString);
} else {
// 作为日期处理
strTimeString = getFormatDateString(strTimeString);
DateFormat dtFormat = new SimpleDateFormat("yyyy-MM-dd");
if (timeZone != null) {
dtFormat.setTimeZone(timeZone);
}
return dtFormat.parse(strTimeString);
}
}
}
/**
* 获取时间格式化串
*
* @param strOrigin
* @return
*/
private static String getFormatTimeString(String strOrigin) {
int nDotPos = strOrigin.indexOf(".");
if (nDotPos != -1) {
strOrigin = strOrigin.substring(0, nDotPos);
}
Object Time[] = new Object[3];
Time[0] = 0;
Time[1] = 0;
Time[2] = 0;
String timepart[] = strOrigin.split(":");
int nTimePartLength = timepart.length;
if (nTimePartLength > 3) {
nTimePartLength = 3;
}
for (int i = 0; i < nTimePartLength; i++) {
Time[i] = Integer.parseInt(timepart[i]);
}
return String.format("%1$02d:%2$02d:%3$02d", Time);
}
/**
* 获取时日期格式化串
*
* @param strOrigin
* @return
* @
*/
private static String getFormatDateString(String strOrigin) throws Exception{
return getFormatDateString(strOrigin, true);
}
/**
* 获取时日期格式化串
*
* @param strOrigin
* @param bAdv
* @return
* @
*/
private static String getFormatDateString(String strOrigin, boolean bAdv) throws Exception{
Object Date[] = new Object[3];
Date[0] = 1970;
Date[1] = 1;
Date[2] = 1;
if (strOrigin.indexOf("-") != -1) {
String datePart[] = strOrigin.split("-");
if (datePart.length >= 1) {
Date[0] = Integer.parseInt(datePart[0]);
}
if (datePart.length >= 2) {
Date[1] = Integer.parseInt(datePart[1]);
}
if (datePart.length >= 3) {
Date[2] = Integer.parseInt(datePart[2]);
}
}
else if (strOrigin.indexOf("/") != -1) {
String datePart[] = strOrigin.split("/");
if (datePart.length >= 1) {
Date[1] = Integer.parseInt(datePart[0]);
}
if (datePart.length >= 2) {
Date[2] = Integer.parseInt(datePart[1]);
}
if (datePart.length >= 3) {
Date[0] = Integer.parseInt(datePart[2]);
}
} else {
if (bAdv) {
strOrigin = strOrigin.replace(".", "-");
strOrigin = strOrigin.replace("日", "");
strOrigin = strOrigin.replace("天", "");
strOrigin = strOrigin.replace("年", "-");
strOrigin = strOrigin.replace("月", "-");
return getFormatDateString(strOrigin, false);
} else
throw new Exception("无法识别的时间字符串,"+strOrigin);
}
return String.format("%1$04d-%2$02d-%3$02d", Date);
}
public static Timestamp getBeginDate()
{
Calendar cl=Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
cl.set(1900,1,1);
return new Timestamp(cl.getTime().getTime());
}
public static Timestamp getEndDate()
{
Calendar cl=Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
cl.set(2100,12,31,23,59,59);
return new Timestamp(cl.getTime().getTime());
}
public static Timestamp getNow()
{
Calendar cl=Calendar.getInstance(TimeZone.getTimeZone("GMT+8"));
return new Timestamp(cl.getTime().getTime());
}
}
package cn.ibizlab.util.helper;
import org.springframework.core.convert.converter.Converter;
import java.sql.Timestamp;
import java.time.*;
import java.util.Date;
/**
* <p>JSR310DateConverters class.</p>
*/
public final class JSR310DateConverters {
private JSR310DateConverters() {
}
public static class TimestampToDateConverter implements Converter<Timestamp, Date> {
public static final TimestampToDateConverter INSTANCE = new TimestampToDateConverter();
private TimestampToDateConverter() {
}
@Override
public Date convert(Timestamp source) {
return source == null ? null : new Date(source.getTime());
}
}
public static class DateToTimestampConverter implements Converter<Date, Timestamp> {
public static final DateToTimestampConverter INSTANCE = new DateToTimestampConverter();
private DateToTimestampConverter() {
}
@Override
public Timestamp convert(Date source) {
return source == null ? null : new Timestamp(source.getTime());
}
}
public static class LocalDateToDateConverter implements Converter<LocalDate, Date> {
public static final LocalDateToDateConverter INSTANCE = new LocalDateToDateConverter();
private LocalDateToDateConverter() {
}
@Override
public Date convert(LocalDate source) {
return source == null ? null : Date.from(source.atStartOfDay(ZoneId.systemDefault()).toInstant());
}
}
public static class DateToLocalDateConverter implements Converter<Date, LocalDate> {
public static final DateToLocalDateConverter INSTANCE = new DateToLocalDateConverter();
private DateToLocalDateConverter() {
}
@Override
public LocalDate convert(Date source) {
return source == null ? null : ZonedDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault())
.toLocalDate();
}
}
public static class ZonedDateTimeToDateConverter implements Converter<ZonedDateTime, Date> {
public static final ZonedDateTimeToDateConverter INSTANCE = new ZonedDateTimeToDateConverter();
private ZonedDateTimeToDateConverter() {
}
@Override
public Date convert(ZonedDateTime source) {
return source == null ? null : Date.from(source.toInstant());
}
}
public static class DateToZonedDateTimeConverter implements Converter<Date, ZonedDateTime> {
public static final DateToZonedDateTimeConverter INSTANCE = new DateToZonedDateTimeConverter();
private DateToZonedDateTimeConverter() {
}
@Override
public ZonedDateTime convert(Date source) {
return source == null ? null : ZonedDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
}
}
public static class LocalDateTimeToDateConverter implements Converter<LocalDateTime, Date> {
public static final LocalDateTimeToDateConverter INSTANCE = new LocalDateTimeToDateConverter();
private LocalDateTimeToDateConverter() {
}
@Override
public Date convert(LocalDateTime source) {
return source == null ? null : Date.from(source.atZone(ZoneId.systemDefault()).toInstant());
}
}
public static class DateToLocalDateTimeConverter implements Converter<Date, LocalDateTime> {
public static final DateToLocalDateTimeConverter INSTANCE = new DateToLocalDateTimeConverter();
private DateToLocalDateTimeConverter() {
}
@Override
public LocalDateTime convert(Date source) {
return source == null ? null : LocalDateTime.ofInstant(source.toInstant(), ZoneId.systemDefault());
}
}
public static class DurationToLongConverter implements Converter<Duration, Long> {
public static final DurationToLongConverter INSTANCE = new DurationToLongConverter();
private DurationToLongConverter() {
}
@Override
public Long convert(Duration source) {
return source == null ? null : source.toNanos();
}
}
public static class LongToDurationConverter implements Converter<Long, Duration> {
public static final LongToDurationConverter INSTANCE = new LongToDurationConverter();
private LongToDurationConverter() {
}
@Override
public Duration convert(Long source) {
return source == null ? null : Duration.ofNanos(source);
}
}
}
\ No newline at end of file
package cn.ibizlab.util.helper;
import cn.ibizlab.util.domain.EntityBase;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
import com.alibaba.fastjson.JSONObject;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
public class RuleUtils
{
public static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
public static Object getObj(Object object, String members)
{
if(object==null)
return null;
Object currentObj = object;
String[] arrayOfString = members.split("\\.");
int i = arrayOfString.length;
for (int j = 0; j < i; ++j)
{
String methodName = arrayOfString[j];
try
{
if(currentObj instanceof EntityBase)
{
currentObj=((EntityBase) currentObj).get(methodName);
if (currentObj == null)
return null;
}
else if(currentObj instanceof JSONObject)
{
currentObj=((JSONObject) currentObj).get(methodName);
if (currentObj == null)
return null;
}
else if(currentObj instanceof Map)
{
currentObj=((Map) currentObj).get(methodName);
if (currentObj == null)
return null;
}
else
{
Class clazz = currentObj.getClass();
Method method = null;
try
{
method=clazz.getMethod("get" , new Class[0]);
}
catch (Exception e2)
{
method=clazz.getDeclaredMethod("get" , new Class[0]);
}
currentObj = method.invoke(currentObj, methodName);
if (currentObj == null)
return null;
}
}
catch (Exception e)
{
return null;
}
}
return currentObj;
}
public static boolean test(Object finalObject,String option,Object exp)
{
if(option.equalsIgnoreCase("eq")||option.equalsIgnoreCase("equal")||option.equalsIgnoreCase("="))
return equal(exp,finalObject);
else if (option.equalsIgnoreCase("noteq")||option.equalsIgnoreCase("notequal")||option.equalsIgnoreCase("<>")||option.equalsIgnoreCase("!="))
return !equal(exp,finalObject);
else if (option.equalsIgnoreCase("gt")||option.equalsIgnoreCase(">"))
return gt(exp,finalObject);
else if (option.equalsIgnoreCase("lt")||option.equalsIgnoreCase("<"))
return lt(exp,finalObject);
else if (option.equalsIgnoreCase("gtandeq")||option.equalsIgnoreCase("ge")||option.equalsIgnoreCase(">="))
return ge(exp,finalObject);
else if (option.equalsIgnoreCase("ltandeq")||option.equalsIgnoreCase("le")||option.equalsIgnoreCase("<="))
return le(exp,finalObject);
else if (option.equalsIgnoreCase("null")||option.equalsIgnoreCase("isnull"))
return isNull(finalObject);
else if (option.equalsIgnoreCase("notnull")||option.equalsIgnoreCase("isnotnull"))
return isNotNull(finalObject);
else if (option.equalsIgnoreCase("like")||option.equalsIgnoreCase("matchor"))
return matchor(exp,finalObject);
else if (option.equalsIgnoreCase("leftlike")||option.equalsIgnoreCase("startswith")||option.equalsIgnoreCase("begin"))
return leftmatchor(exp,finalObject);
else if (option.equalsIgnoreCase("rightlike")||option.equalsIgnoreCase("endswith")||option.equalsIgnoreCase("end"))
return rightmatchor(exp,finalObject);
else if (option.equalsIgnoreCase("match")||option.equalsIgnoreCase("matchand")||option.equalsIgnoreCase("matches"))
return matchand(exp,finalObject);
else if (option.equalsIgnoreCase("in"))
return in(exp,finalObject);
else if (option.equalsIgnoreCase("notin"))
return notin(exp,finalObject);
else if (option.equalsIgnoreCase("NOTLIKE"))
return notmatchor(exp,finalObject);
else if (option.equalsIgnoreCase("LEFTNOTLIKE"))
return !leftmatchor(exp,finalObject);
else if (option.equalsIgnoreCase("RIGHTNOTLIKE"))
return !rightmatchor(exp,finalObject);
else if (option.equalsIgnoreCase("NOTMATCHES"))
return notmatchand(exp,finalObject);
else
return false;
}
public static boolean equal(Object exp, Object object, String members)
{
return equal(exp,getObj(object, members));
}
public static boolean equal(Object exp, Object finalObject)
{
if(exp==null)
return false;
if(finalObject ==null)
return false;
if(exp instanceof String && ((String) exp).length()==10 && finalObject instanceof Timestamp)
{
return dateFormat.format(finalObject).equals(exp);
}
else if(exp instanceof Timestamp && finalObject instanceof Timestamp)
{
return dateFormat.format(finalObject).equals(dateFormat.format(exp));
}
else if(finalObject instanceof Timestamp)
{
Timestamp tm=DataObject.getTimestampValue(exp,null);
if(tm == null) return false;
return ObjectUtils.nullSafeEquals(tm,finalObject);
}
if(ObjectUtils.nullSafeEquals(exp,finalObject))
return true;
if(exp.toString().equalsIgnoreCase(finalObject.toString()))
return true;
return false;
}
public static boolean gt(Object exp, Object object, String members)
{
return gt(exp,getObj(object, members));
}
public static boolean gt(Object exp, Object finalObject)
{
if(ObjectUtils.isEmpty(exp))
return false;
if(ObjectUtils.isEmpty(finalObject))
return false;
try
{
if(finalObject instanceof java.sql.Timestamp)
{
java.sql.Timestamp finalTime=(java.sql.Timestamp)finalObject;
Timestamp tm=null;
if (exp instanceof java.sql.Timestamp)
{
tm=(java.sql.Timestamp)exp;
}
else
{
tm=DataObject.getTimestampValue(exp,null);
if(tm==null)
return false;
}
return finalTime.getTime()>tm.getTime();
}
else if (finalObject instanceof Integer)
{
return ((Integer) finalObject) > DataObject.getIntegerValue(exp,Integer.MAX_VALUE);
}
else if (finalObject instanceof Double)
{
return ((Double) finalObject) > DataObject.getDoubleValue(exp,Double.MAX_VALUE);
}
else if (finalObject instanceof Float)
{
return ((Float) finalObject) > DataObject.getFloatValue(exp,Float.MAX_VALUE);
}
else if (finalObject instanceof BigDecimal)
{
return ((BigDecimal) finalObject).compareTo(DataObject.getBigDecimalValue(exp,BigDecimal.valueOf(Double.MAX_VALUE)))>0;
}
else if (finalObject instanceof BigInteger)
{
return ((BigInteger) finalObject).compareTo(DataObject.getBigIntegerValue(exp,BigInteger.valueOf(Long.MAX_VALUE)))>0;
}
else if (finalObject instanceof Long)
{
return ((Long) finalObject) > DataObject.getLongValue(exp,Long.MAX_VALUE);
}
else if (finalObject instanceof String)
{
return finalObject.toString().compareToIgnoreCase(exp.toString())>0;
}
else
return false;
}
catch(Exception ex)
{
return false;
}
}
public static boolean lt(Object exp, Object object, String members)
{
return lt(exp,getObj(object, members));
}
public static boolean lt(Object exp, Object finalObject)
{
if(ObjectUtils.isEmpty(exp))
return false;
if(ObjectUtils.isEmpty(finalObject))
return false;
try
{
if(finalObject instanceof java.sql.Timestamp)
{
java.sql.Timestamp finalTime=(java.sql.Timestamp)finalObject;
Timestamp tm=null;
if((exp instanceof String)&& (exp.toString().trim().length()==10))
{
tm=new Timestamp(dateFormat.parse(exp.toString().trim()).getTime());
}
else if (exp instanceof java.sql.Timestamp)
{
tm=(java.sql.Timestamp)exp;
}
else
{
return false;
}
return finalTime.getTime()<tm.getTime();
}
else if (finalObject instanceof Integer)
{
return (((Integer) finalObject).intValue() < ((Integer)exp).intValue());
}
else if (finalObject instanceof Double)
{
return (((Double) finalObject).doubleValue() < ((Double)exp).doubleValue());
}
else if (finalObject instanceof Float)
{
return (((Float) finalObject).floatValue() < ((Float)exp).floatValue());
}
else if (finalObject instanceof String)
{
return finalObject.toString().compareToIgnoreCase(exp.toString())<0;
}
else
return false;
}
catch(Exception ex)
{
return false;
}
}
public static boolean ge(Object exp, Object object, String members)
{
return ge(exp,getObj(object, members));
}
public static boolean ge(Object exp, Object finalObject)
{
return (!(lt(exp, finalObject)));
}
public static boolean le(Object exp, Object object, String members)
{
return le(exp,getObj(object, members));
}
public static boolean le(Object exp, Object finalObject)
{
return (!(gt(exp, finalObject)));
}
public static boolean notin(Object expObj, Object object, String members)
{
return notin(expObj,getObj(object, members));
}
public static boolean notin(Object expObj, Object finalObject)
{
return (!in(expObj,finalObject));
}
public static boolean in(Object expObj, Object object, String members)
{
return in(expObj,getObj(object, members));
}
public static boolean in(Object expObj, Object finalObject)
{
if (ObjectUtils.isEmpty(finalObject))
return false;
String tvs=expObj.toString().trim();
if(StringUtils.isEmpty(tvs))
return false;
if (finalObject instanceof Integer)
{
tvs="i:"+tvs;
}
else if (finalObject instanceof String)
{
tvs="s:"+tvs;
}
List acts = parseTvs(tvs);
for (Iterator localIterator = acts.iterator(); localIterator.hasNext();)
{
Object act = localIterator.next();
if (equal(act,finalObject))
return true;
}
return false;
}
public static boolean isNotNull(Object object, String members)
{
return isNotNull(getObj(object, members));
}
public static boolean isNotNull(Object finalObject)
{
return !isNull(finalObject);
}
public static boolean isNull(Object object, String members)
{
return isNull(getObj(object, members));
}
public static boolean isNull(Object finalObject)
{
if(finalObject instanceof String)
return StringUtils.isEmpty(finalObject.toString().trim());
return (ObjectUtils.isEmpty(finalObject));
}
public static boolean notmatchor(Object expObj, Object object, String members)
{
return notmatchor(expObj,getObj(object, members));
}
public static boolean notmatchor(Object expObj, Object obj)
{
return (!matchor(expObj,obj));
}
public static boolean notmatchand(Object expObj, Object object, String members)
{
return notmatchand(expObj,getObj(object, members));
}
public static boolean notmatchand(Object expObj, Object finalObject)
{
return (!matchand(expObj,finalObject));
}
public static boolean matchor(Object expObj,Object object,String members)
{
return matchor(expObj,getObj(object, members));
}
public static boolean matchor(Object expObj, Object obj)
{
if(obj==null)
return false;
String exp=expObj.toString().trim();
if(StringUtils.isEmpty(exp))
return false;
exp=exp.replace(";", ",");
exp=exp.replace(";", ",");
exp=exp.replace(",", ",");
String[] arr=exp.split(",");
boolean bRt=false;
for(String strExp:arr)
{
bRt=(obj.toString()).matches("(.*)"+(strExp)+"(.*)");
if(bRt)
return true;
}
return bRt;
}
public static boolean leftmatchor(Object expObj, Object obj)
{
if(obj==null)
return false;
String exp=expObj.toString().trim();
if(StringUtils.isEmpty(exp))
return false;
exp=exp.replace(";", ",");
exp=exp.replace(";", ",");
exp=exp.replace(",", ",");
String[] arr=exp.split(",");
boolean bRt=false;
for(String strExp:arr)
{
bRt=obj.toString().matches(strExp+"(.*)");
if(bRt)
return true;
}
return bRt;
}
public static boolean rightmatchor(Object expObj, Object obj)
{
if(obj==null)
return false;
String exp=expObj.toString().trim();
if(StringUtils.isEmpty(exp))
return false;
exp=exp.replace(";", ",");
exp=exp.replace(";", ",");
exp=exp.replace(",", ",");
String[] arr=exp.split(",");
boolean bRt=false;
for(String strExp:arr)
{
bRt=obj.toString().matches("(.*)"+strExp);
if(bRt)
return true;
}
return bRt;
}
public static boolean matchand(Object expObj,Object object,String members)
{
return matchand(expObj,getObj(object, members));
}
public static boolean matchand(Object expObj,Object obj)
{
if(obj==null)
return false;
if(expObj==null)
return false;
String exp=expObj.toString().trim();
if(StringUtils.isEmpty(exp))
return false;
exp=exp.replace(";", ",");
exp=exp.replace(";", ",");
exp=exp.replace(",", ",");
String[] arr=exp.split(",");
String objstr=obj.toString();
boolean bRt=true;
for(String strExp:arr)
{
if(strExp.trim().length()==0)
continue;
bRt=(obj.toString()).matches("(.*)"+(strExp)+"(.*)");
if(!bRt)
return false;
}
return bRt;
}
private static List<Object> parseTvs(String tvs)
{
tvs=tvs.replace(";", ",");
tvs=tvs.replace(";", ",");
tvs=tvs.replace(",", ",");
String[] arrayOfString1;
int j;
int k;
String value;
String type = "s";
String values = "";
String[] tv = tvs.split(":");
if(tv.length>1)
{
type = tv[0];
values = tv[1];
}
else
{
values=tvs;
}
List acts = new ArrayList();
String str1 = type;
int i = -1;
switch (str1.hashCode())
{
case 105:
if (str1.equals("i"))
i = 0;
break;
case 115:
if (str1.equals("s"))
i = 1;
}
switch (i)
{
case 0:
arrayOfString1 = values.split(",");
j = arrayOfString1.length;
for (k = 0; k < j; ++k)
{
value = arrayOfString1[k];
acts.add(new Integer(value.trim()));
}
break;
case 1:
arrayOfString1 = values.split(",");
j = arrayOfString1.length;
for (k = 0; k < j; ++k)
{
value = arrayOfString1[k];
acts.add(value.trim());
}
}
return acts;
}
}
\ No newline at end of file
package cn.ibizlab.util.helper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
@Slf4j
public class UniqueNameGenerator extends AnnotationBeanNameGenerator {
@Override
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
//全限定类名
String beanName = definition.getBeanClassName();
return beanName;
}
}
package cn.ibizlab.util.job;
import cn.ibizlab.util.client.IBZUAAFeignClient;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONArray;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.DigestUtils;
import java.io.InputStream;
import java.util.*;
/**
* 权限:向uaa同步当前系统菜单、权限资源任务类
*/
@Slf4j
@Component
@ConditionalOnProperty( name = "ibiz.enablePermissionValid", havingValue = "true")
public class PermissionSyncJob implements ApplicationRunner {
@Autowired
@Lazy
private IBZUAAFeignClient client;
@Value("${ibiz.systemid:ibzpay}")
private String systemId;
@Value("${ibiz.systemname:ibzpay}")
private String systemName;
@Override
public void run(ApplicationArguments args) {
try {
Thread.sleep(10000);
InputStream permission= this.getClass().getResourceAsStream("/permission/systemResource.json"); //获取当前系统所有实体资源能力
String permissionResult = IOUtils.toString(permission,"UTF-8");
JSONObject system= new JSONObject();
system.put("pssystemid",systemId);
system.put("pssystemname",systemName);
system.put("sysstructure",JSONObject.parseObject(permissionResult));
system.put("md5check",DigestUtils.md5DigestAsHex(permissionResult.getBytes()));
if(client.syncSysAuthority(system)){
log.info("向[UAA]同步系统资源成功");
}else{
log.error("向[UAA]同步系统资源失败");
}
}
catch (Exception ex) {
log.error(String.format("向[UAA]同步系统资源失败,请检查[UAA]服务是否正常! [%s]",ex));
}
}
}
\ No newline at end of file
package cn.ibizlab.util.mapper;
import cn.ibizlab.util.domain.IBZConfig;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
public interface IBZConfigMapper extends BaseMapper<IBZConfig>{
}
\ No newline at end of file
package cn.ibizlab.util.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import cn.ibizlab.util.domain.IBZDataAudit;
public interface IBZDataAuditMapper extends BaseMapper<IBZDataAudit> {
}
\ No newline at end of file
package cn.ibizlab.util.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import cn.ibizlab.util.domain.IBZUSER;
public interface IBZUSERMapper extends BaseMapper<IBZUSER>{
}
\ No newline at end of file
package cn.ibizlab.util.rest;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.service.IBZConfigService;
import com.alibaba.fastjson.JSONObject;
import cn.ibizlab.util.security.AuthenticationUser;
import cn.ibizlab.util.service.AuthenticationUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@RestController
@RequestMapping(value = "")
public class AppController {
@Value("${ibiz.enablePermissionValid:false}")
boolean enablePermissionValid; //是否开启权限校验
@Value("${ibiz.systemid:ibzpay}")
private String systemId;
@Autowired
private AuthenticationUserService userDetailsService;
@RequestMapping(method = RequestMethod.GET, value = "/appdata")
public ResponseEntity<JSONObject> getAppData() {
JSONObject appData = new JSONObject() ;
Set<String> appMenu = new HashSet();
Set<String> uniRes = new HashSet();
AuthenticationUser curUser = AuthenticationUser.getAuthenticationUser();
if(enablePermissionValid){
Collection<GrantedAuthority> authorities=curUser.getAuthorities();
Iterator it = authorities.iterator();
while(it.hasNext()) {
GrantedAuthority authority = (GrantedAuthority)it.next();
String strAuthority=authority.getAuthority();
if(strAuthority.startsWith("UNIRES_"+systemId))
uniRes.add(strAuthority.substring(systemId.length()+8));
else if(strAuthority.startsWith("APPMENU_"+systemId))
appMenu.add(strAuthority.substring(systemId.length()+9));
}
}
Map<String,Object> context = new HashMap<>();
context.putAll(curUser.getSessionParams());
context.put("srfusername",curUser.getPersonname());
appData.put("context",context);
appData.put("unires",uniRes);
appData.put("appmenu",appMenu);
appData.put("enablepermissionvalid",enablePermissionValid);
if(curUser.getSuperuser()==1)
appData.put("enablepermissionvalid",false);
else
appData.put("enablepermissionvalid",enablePermissionValid);
return ResponseEntity.status(HttpStatus.OK).body(appData);
}
@RequestMapping(method = RequestMethod.GET, value = "${ibiz.auth.logoutpath:v7/logout}")
public void logout() {
if(AuthenticationUser.getAuthenticationUser()!=null){
userDetailsService.resetByUsername(AuthenticationUser.getAuthenticationUser().getUsername());
}
}
@Autowired
private IBZConfigService ibzConfigService;
@RequestMapping(method = RequestMethod.PUT, value = "/configs/{configType}/{targetType}")
public ResponseEntity<Boolean> saveConfig(@PathVariable("configType") String configType, @PathVariable("targetType") String targetType, @RequestBody JSONObject config) {
String userId=AuthenticationUser.getAuthenticationUser().getUserid();
if(StringUtils.isEmpty(userId))
throw new BadRequestAlertException("保存配置失败,参数缺失","IBZConfig",configType);
return ResponseEntity.ok(ibzConfigService.saveConfig(configType,targetType,userId,config));
}
@RequestMapping(method = RequestMethod.GET, value = "/configs/{configType}/{targetType}")
public ResponseEntity<JSONObject> getConfig(@PathVariable("configType") String configType, @PathVariable("targetType") String targetType) {
String userId=AuthenticationUser.getAuthenticationUser().getUserid();
if(StringUtils.isEmpty(userId))
throw new BadRequestAlertException("获取配置失败,参数缺失","IBZConfig",configType);
return ResponseEntity.ok(ibzConfigService.getConfig(configType,targetType,userId));
}
}
package cn.ibizlab.util.rest;
import cn.ibizlab.util.security.AuthenticationInfo;
import cn.ibizlab.util.security.AuthenticationUser;
import cn.ibizlab.util.security.AuthorizationLogin;
import cn.ibizlab.util.security.AuthTokenUtil;
import cn.ibizlab.util.service.AuthenticationUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@RestController
@RequestMapping("/")
@ConditionalOnProperty( name = "ibiz.enablePermissionValid", havingValue = "false")
public class AuthenticationController
{
@Value("${ibiz.jwt.header:Authorization}")
private String tokenHeader;
@Autowired
private AuthTokenUtil jwtTokenUtil;
@Autowired
private AuthenticationUserService userDetailsService;
@PostMapping(value = "${ibiz.auth.path:v7/login}")
public ResponseEntity<AuthenticationInfo> login(@Validated @RequestBody AuthorizationLogin authorizationLogin){
userDetailsService.resetByUsername(authorizationLogin.getUsername());
final AuthenticationUser authuserdetail = userDetailsService.loadUserByLogin(authorizationLogin.getUsername(),authorizationLogin.getPassword());
// 生成令牌
final String token = jwtTokenUtil.generateToken(authuserdetail);
// 返回 token
return ResponseEntity.ok().body(new AuthenticationInfo(token,authuserdetail));
}
@GetMapping(value = "${ibiz.auth.account:ibizutil/account}")
public ResponseEntity<AuthenticationUser> getUserInfo(){
UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
AuthenticationUser authuserdetail=new AuthenticationUser();
if(userDetails==null){
throw new RuntimeException("未能获取用户信息");
}
else if(userDetails instanceof AuthenticationUser ) {
authuserdetail= (AuthenticationUser)userDetails;
}
else {
authuserdetail= userDetailsService.loadUserByUsername(userDetails.getUsername());
}
return ResponseEntity.ok().body(authuserdetail);
}
}
package cn.ibizlab.util.rest;
import cn.ibizlab.util.domain.FileItem;
import cn.ibizlab.util.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
@Slf4j
@RestController
@RequestMapping("/")
public class FileController
{
@Autowired
private FileService fileService;
@PostMapping(value = "${ibiz.file.uploadpath:ibizutil/upload}")
public ResponseEntity<FileItem> upload(@RequestParam("file") MultipartFile multipartFile){
return ResponseEntity.ok().body(fileService.saveFile(multipartFile));
}
private final String defaultdownloadpath="ibizutil/download/{id}";
@GetMapping(value = "${ibiz.file.downloadpath:"+defaultdownloadpath+"}")
@ResponseStatus(HttpStatus.OK)
public void download(@PathVariable String id, HttpServletResponse response){
File file= fileService.getFile(id);
response.setHeader("Content-Disposition", "attachment;filename="+getFileName(file.getName()));
this.sendRespose(response, file);
}
protected void sendRespose(HttpServletResponse response, File file){
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(file));
bos = new BufferedOutputStream(response.getOutputStream());
byte[] buff = new byte[2048];
int bytesRead;
while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
}
catch (Exception e) {
//throw e;
}
finally {
if (bis != null) {
try {
bis.close();
}
catch (IOException e) {
}
}
if (bos != null) {
try {
bos.close();
}
catch (IOException e) {
}
}
}
}
protected String getFileName(String fileName){
try {
return new String(fileName.getBytes("utf-8"),"iso8859-1");//防止中文乱码
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return fileName;
}
}
\ No newline at end of file
package cn.ibizlab.util.security;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.SneakyThrows;
import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.enums.DEPredefinedFieldType;
import cn.ibizlab.util.filter.QueryWrapperContext;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
import java.util.function.Consumer;
/**
* spring security 权限管理类
* 重写权限控制方法
*/
@Component
public class AuthPermissionEvaluator implements PermissionEvaluator {
@Value("${ibiz.enablePermissionValid:false}")
boolean enablePermissionValid; //是否开启权限校验
/**
* 服务接口鉴权
* @param authentication 用户
* @param entity 实体
* @param action 操作
* @return
*/
@Override
@SneakyThrows
public boolean hasPermission(Authentication authentication, Object entity, Object action) {
if(!enablePermissionValid)
return true;
Object principal = authentication.getPrincipal();
if(ObjectUtils.isEmpty(principal))
return false;
AuthenticationUser authenticationUser= (AuthenticationUser) authentication.getPrincipal();
if(authenticationUser.getSuperuser()==1)
return true;
String strAction=String.valueOf(action);
Set<String> userAuthorities = getAuthorities(authentication,strAction);
if(userAuthorities.size()==0)
return false;
if(isAllData(strAction,userAuthorities)){
return true;
}
if(entity instanceof ArrayList){
List<EntityBase> entities= (List<EntityBase>) entity;
for(EntityBase entityBase: entities){
boolean result=actionValid(entityBase, strAction ,userAuthorities,authenticationUser);
if(!result){
return false;
}
}
}
else if (entity instanceof QueryWrapperContext){
QueryWrapperContext queryWrapperContext= (QueryWrapperContext) entity;
setPermissionCondToSearchContext(getEntity(queryWrapperContext),queryWrapperContext,userAuthorities,authenticationUser);
}
else{
EntityBase entityBase= (EntityBase) entity;
return actionValid(entityBase , strAction ,userAuthorities,authenticationUser);
}
return true;
}
/**
* 获取实体信息
* @param qc
* @return
*/
@SneakyThrows
private EntityBase getEntity(QueryWrapperContext qc){
EntityBase entity=null;
Type type =qc.getClass().getGenericSuperclass();
if(type instanceof ParameterizedType){
ParameterizedType parameterizedType= (ParameterizedType) qc.getClass().getGenericSuperclass();
Type [] typeArr= parameterizedType.getActualTypeArguments();
if(typeArr.length>0){
Class<EntityBase> entityClass = (Class) typeArr[0];
return entityClass.newInstance();
}
}
return entity;
}
/**
* 在searchContext中拼接权限条件
* @param entity 实体
* @param qc 查询上下文
* @param userAuthorities 用户权限
* @param authenticationUser 当前用户
*/
@SneakyThrows
private void setPermissionCondToSearchContext(EntityBase entity, QueryWrapperContext qc , Set<String> userAuthorities ,AuthenticationUser authenticationUser){
if(entity==null)
return ;
Map<String,String> permissionField=getPermissionField(entity);//获取组织、部门预置属性
String orgField=permissionField.get("orgfield");
String orgDeptField=permissionField.get("orgsecfield");
String createManField=permissionField.get("createmanfield");
Map<String, Set<String>> userInfo = authenticationUser.getOrgInfo();
Set<String> orgParent = userInfo.get("parentorg");
Set<String> orgChild = userInfo.get("suborg");
Set<String> orgDeptParent = userInfo.get("parentdept");
Set<String> orgDeptChild = userInfo.get("subdept");
Set<String> userOrg = new HashSet<>();
Set<String> userOrgDept = new HashSet<>();
Set<String> userCreateMan = new HashSet<>();
for(String authority:userAuthorities){
if(authority.endsWith("curorg")){ //本单位
userOrg.add(authenticationUser.getOrgid());
}
else if(authority.endsWith("porg")){//上级单位
userOrg.addAll(orgParent);
}
else if(authority.endsWith("sorg")){//下级单位
userOrg.addAll(orgChild);
}
else if(authority.endsWith("curorgdept")){//本部门
userOrgDept.add(authenticationUser.getMdeptid());
}
else if(authority.endsWith("porgdept")){//上级部门
userOrgDept.addAll(orgDeptParent);
}
else if(authority.endsWith("sorgdept")){//下级部门
userOrgDept.addAll(orgDeptChild);
}
else if (authority.endsWith("createman")){
userCreateMan.add(authority);
}
}
if(userOrg.size()==0 && userOrgDept.size()==0 && userCreateMan.size()==0){
qc.getSelectCond().apply("1<>1");
}
else{
Consumer<QueryWrapper> consumer = qw -> {
if(userOrg.size()>0){
Consumer<QueryWrapper> org = orgQw -> {
orgQw.in(orgField,userOrg);
};
qw.or(org);
}
if(userOrgDept.size()>0){
Consumer<QueryWrapper> dept = deptQw -> {
deptQw.in(orgDeptField,userOrgDept);
};
qw.or(dept);
}
if(userCreateMan.size()>0){
Consumer<QueryWrapper> createMan = createManQw -> {
createManQw.eq(createManField,authenticationUser.getUserid());
};
qw.or(createMan);
}
};
qc.getSelectCond().and(consumer);
}
}
@Override
public boolean hasPermission(Authentication authentication, Serializable id, String action, Object params) {
return true;
}
/**
* 获取用户权限资源
* @param authentication
* @param action
* @return
*/
private Set<String> getAuthorities(Authentication authentication , String action){
Collection authorities=authentication.getAuthorities();
Set<String> userAuthorities = new HashSet();
Iterator it = authorities.iterator();
while(it.hasNext()) {
GrantedAuthority authority = (GrantedAuthority)it.next();
if(authority.getAuthority().contains(action))
userAuthorities.add(authority.getAuthority());
}
return userAuthorities;
}
/**
* 是否为全部数据
* @param action
* @param entityDataRange
* @return
*/
private boolean isAllData(String action , Set<String> entityDataRange) {
for(String dataRange : entityDataRange ){
if(dataRange.endsWith(String.format("%s-all",action))){
return true;
}
}
return false;
}
/**
* 实体行为权限校验
* @param entity
* @param userAuthorities
* @return
*/
private boolean actionValid(EntityBase entity, String action , Set<String> userAuthorities ,AuthenticationUser authenticationUser){
Map<String,String> permissionField=getPermissionField(entity);//获取组织、部门预置属性
String orgField=permissionField.get("orgfield");
String orgDeptField=permissionField.get("orgsecfield");
String createManField=permissionField.get("createmanfield");
Map<String, Set<String>> userInfo = authenticationUser.getOrgInfo();
Set<String> orgParent = userInfo.get("parentorg");
Set<String> orgChild = userInfo.get("suborg");
Set<String> orgDeptParent = userInfo.get("parentdept");
Set<String> orgDeptChild = userInfo.get("subdept");
Object orgFieldValue=entity.get(orgField);
Object orgDeptFieldValue=entity.get(orgDeptField);
Object crateManFieldValue=entity.get(createManField);
Set<String> userOrg = new HashSet<>();
Set<String> userOrgDept = new HashSet<>();
for(String authority:userAuthorities){
if(authority.endsWith("curorg")){ //本单位
userOrg.add(authenticationUser.getOrgid());
}
else if(authority.endsWith("porg")){//上级单位
userOrg.addAll(orgParent);
}
else if(authority.endsWith("sorg")){//下级单位
userOrg.addAll(orgChild);
}
else if(authority.endsWith("curorgdept")){//本部门
userOrgDept.add(authenticationUser.getMdeptid());
}
else if(authority.endsWith("porgdept")){//上级部门
userOrgDept.addAll(orgDeptParent);
}
else if(authority.endsWith("sorgdept")){//下级部门
userOrgDept.addAll(orgDeptChild);
}
}
if(action.endsWith("Create") || action.endsWith("Save")){
if(!ObjectUtils.isEmpty(orgFieldValue) && !userOrg.contains(orgFieldValue))
return false;
if(!ObjectUtils.isEmpty(orgDeptFieldValue) && !userOrgDept.contains(orgDeptFieldValue))
return false;
if(!ObjectUtils.isEmpty(crateManFieldValue) && !authenticationUser.getUserid().equals(crateManFieldValue))
return false;
return true;
}
else{
if(!ObjectUtils.isEmpty(orgFieldValue) && userOrg.contains(orgFieldValue))
return true;
if(!ObjectUtils.isEmpty(orgDeptFieldValue) && userOrgDept.contains(orgDeptFieldValue))
return true;
if(!ObjectUtils.isEmpty(crateManFieldValue) && authenticationUser.getUserid().equals(crateManFieldValue))
return true;
return false;
}
}
/**
* 获取实体权限字段 orgid/orgsecid
* @param entityBase
* @return
*/
private Map<String,String> getPermissionField(EntityBase entityBase){
Map<String,String> permissionFiled=new HashMap<>();
String orgField="orgid"; //组织属性
String orgDeptField="orgsecid"; //部门属性
String createManField="createman"; //创建人属性
DEFieldCacheMap.getFieldMap(entityBase.getClass().getName());
Map <String, DEField> preFields= DEFieldCacheMap.getDEFields(entityBase.getClass()); //从缓存中获取当前类预置属性
for (Map.Entry<String,DEField> entry : preFields.entrySet()){
String fieldName=entry.getKey();//获取注解字段
DEField fieldAnnotation=entry.getValue();//获取注解值
DEPredefinedFieldType prefieldType=fieldAnnotation.preType();
if(prefieldType==prefieldType.ORGID)//用户配置系统预置属性-组织机构标识
orgField=fieldName;
if(prefieldType==prefieldType.ORGSECTORID)//用户配置系统预置属性-部门标识
orgDeptField=fieldName;
if(prefieldType==prefieldType.CREATEMAN)//用户配置系统预置属性-部门标识
createManField=fieldName;
}
permissionFiled.put("orgfield",orgField);
permissionFiled.put("orgsecfield",orgDeptField);
permissionFiled.put("createmanfield",createManField);
return permissionFiled;
}
}
\ No newline at end of file
package cn.ibizlab.util.security;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Date;
public interface AuthTokenUtil {
String generateToken(UserDetails userDetails);
Boolean validateToken(String token, UserDetails userDetails);
String getUsernameFromToken(String token);
Date getExpirationDateFromToken(String token) ;
}
package cn.ibizlab.util.security;
import org.springframework.security.core.AuthenticationException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
@Component
public class AuthenticationEntryPoint implements org.springframework.security.web.AuthenticationEntryPoint, Serializable {
private static final long serialVersionUID = -8970718410437077606L;
@Override
public void commence(HttpServletRequest request,
HttpServletResponse response,
AuthenticationException authException) throws IOException {
/**
* 当用户尝试访问安全的REST资源而不提供任何凭据时,将调用此方法发送401 响应
*/
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authException==null?"Unauthorized":authException.getMessage());
}
}
package cn.ibizlab.util.security;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.io.Serializable;
@Getter
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class AuthenticationInfo implements Serializable {
private final String token;
private final AuthenticationUser user;
}
package cn.ibizlab.util.security;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.ObjectUtils;
import java.sql.Timestamp;
import java.util.*;
import com.alibaba.fastjson.JSONObject;
@Data
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class AuthenticationUser implements UserDetails
{
public AuthenticationUser()
{
}
private String userid;
private String username;
private String personname;
private String usercode;
private String loginname;
private String password;
private String domain;
private String mdeptid;
private String mdeptcode;
private String mdeptname;
private String bcode;
private String postid;
private String postcode;
private String postname;
private String orgid;
private String orgcode;
private String orgname;
private String nickname;
private String email;
private String avatar;
private String phone;
private String reserver;
private String usericon;
private String sex;
private Timestamp birthday;
private String certcode;
private String addr;
private String theme;
private String fontsize;
private String lang;
private String memo;
private Map <String,Object> sessionParams;
@JsonIgnore
private Collection<GrantedAuthority> authorities;
private int superuser;
private JSONObject permissionList;
private String orglevel;//单位级别
private String deptlevel;//部门级别
@JsonIgnore
private Map<String,Object> userSessionParam;//用户自定义session值
private Map<String, Set<String>> orgInfo;//上下级组织信息
private String porg;
private String sorg;
private String pdept;
private String sdept;
@JsonIgnore
@Override
public boolean isAccountNonExpired() {
return true;
}
@JsonIgnore
@Override
public boolean isAccountNonLocked() {
return true;
}
@JsonIgnore
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@JsonIgnore
@Override
public String getPassword() {
return password;
}
@Override
public boolean isEnabled() {
return true;
}
public static AuthenticationUser getAuthenticationUser()
{
if(SecurityContextHolder.getContext()==null||SecurityContextHolder.getContext().getAuthentication()==null||SecurityContextHolder.getContext().getAuthentication().getPrincipal()==null){
return new AuthenticationUser();
}
Object userDetails = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
AuthenticationUser authuserdetail;
if(userDetails instanceof AuthenticationUser ) {
authuserdetail= (AuthenticationUser)userDetails;
}
else {
authuserdetail=new AuthenticationUser();
}
return authuserdetail;
}
public Map <String,Object> getSessionParams()
{
if(this.sessionParams==null)
{
sessionParams = getUserSessionParam();
sessionParams.put("srfpersonid", this.getUserid());
sessionParams.put("srfpersonname", this.getPersonname());
sessionParams.put("srforgsectorid", this.getMdeptid());
sessionParams.put("srforgsectorcode", this.getMdeptcode());
sessionParams.put("srforgsectorname", this.getMdeptname());
sessionParams.put("srforgid", this.getOrgid());
sessionParams.put("srforgcode", this.getOrgcode());
sessionParams.put("srforgname", this.getOrgname());
sessionParams.put("srfuserid", this.getUserid());
sessionParams.put("srfusername", this.getPersonname());
sessionParams.put("srfusermode", "");
sessionParams.put("srforgsectorbc", this.getBcode());
sessionParams.put("srfloginname", this.getLoginname());
sessionParams.put("srflocale", this.getLang());
sessionParams.put("srftimezone", "");
sessionParams.put("srfusercode", this.getUsercode());
sessionParams.put("srfporg", this.getPorg());
sessionParams.put("srfsorg", this.getSorg());
sessionParams.put("srfpdept", this.getPdept());
sessionParams.put("srfsdept", this.getSdept());
}
return this.sessionParams;
}
private Map<String, Object> getUserSessionParam() {
if(userSessionParam!=null)
return userSessionParam;
else
return new HashMap<>();
}
public void setOrgInfo(Map<String, Set<String>> orgInfo) {
this.orgInfo = orgInfo;
if(!ObjectUtils.isEmpty(orgInfo) && !ObjectUtils.isEmpty(orgInfo.get("parentorg"))){
porg=(String.format("'%s'",String.join("','",orgInfo.get("parentorg"))));
this.getSessionParams().put("srfporg",porg);
}
if(!ObjectUtils.isEmpty(orgInfo) && !ObjectUtils.isEmpty(orgInfo.get("suborg")) ){
sorg=(String.format("'%s'",String.join("','",orgInfo.get("suborg"))));
this.getSessionParams().put("srfsorg",sorg);
}
if(!ObjectUtils.isEmpty(orgInfo) && !ObjectUtils.isEmpty(orgInfo.get("parentdept"))){
pdept=(String.format("'%s'",String.join("','",orgInfo.get("parentdept"))));
this.getSessionParams().put("srfpdept",pdept);
}
if(!ObjectUtils.isEmpty(orgInfo) && !ObjectUtils.isEmpty(orgInfo.get("subdept"))){
sdept=(String.format("'%s'",String.join("','",orgInfo.get("subdept"))));
this.getSessionParams().put("srfsdept",sdept);
}
}
public void setPermissionList(JSONObject permissionList) {
this.permissionList = permissionList;
if(authorities==null && permissionList !=null){
if(permissionList.getJSONArray("authorities")!=null){
authorities=new ArrayList<>();
permissionList.getJSONArray("authorities").
forEach(item->authorities.add(new SimpleGrantedAuthority(String.valueOf(item))));
}
}
}
}
package cn.ibizlab.util.security;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.StringUtils;
import javax.validation.constraints.NotBlank;
@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class AuthorizationLogin
{
private String domain;
@NotBlank(message="用户名不能为空")
private String loginname;
@NotBlank(message="密码不能为空")
private String password;
public String getUsername()
{
if(!StringUtils.isEmpty(domain))
return loginname+"|"+domain;
return loginname;
}
@Override
public String toString()
{
return "AuthorizationLogin{" +
"domain='" + domain + '\'' +
", loginname='" + loginname + '\'' +
", password='××××××'}";
}
}
package cn.ibizlab.util.security;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.util.service.AuthenticationUserService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import org.springframework.beans.factory.annotation.Qualifier;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Slf4j
@Component
public class AuthorizationTokenFilter extends OncePerRequestFilter {
private final UserDetailsService userDetailsService;
private final AuthTokenUtil authTokenUtil;
private final String tokenHeader;
public AuthorizationTokenFilter(AuthenticationUserService userDetailsService, AuthTokenUtil authTokenUtil, @Value("${ibiz.jwt.header:Authorization}") String tokenHeader) {
this.userDetailsService = userDetailsService;
this.authTokenUtil = authTokenUtil;
this.tokenHeader = tokenHeader;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
final String requestHeader = request.getHeader(this.tokenHeader);
String username = null;
String authToken = null;
if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
authToken = requestHeader.substring(7);
try {
username = authTokenUtil.getUsernameFromToken(authToken);
} catch (ExpiredJwtException e) {
log.error(e.getMessage());
}
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
// It is not compelling necessary to load the use details from the database. You could also store the information
// in the token and read it from it. It's up to you ;)
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
// For simple validation it is completely sufficient to just check the token integrity. You don't have to call
// the database compellingly. Again it's up to you ;)
if (authTokenUtil.validateToken(authToken, userDetails)) {
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// log.info("authorizated user '{}', setting security context", username);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
chain.doFilter(request, response);
}
}
package cn.ibizlab.util.security;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Clock;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClock;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
@Component
@ConditionalOnExpression("(!${ibiz.enablePermissionValid:false})&&'${ibiz.auth.token.util:UAATokenUtil}'.equals('SimpleTokenUtil')")
public class SimpleTokenUtil implements AuthTokenUtil,Serializable {
private static final long serialVersionUID = -3301605591108950415L;
private Clock clock = DefaultClock.INSTANCE;
@Value("${ibiz.jwt.secret:ibzsecret}")
private String secret;
@Value("${ibiz.jwt.expiration:7200000}")
private Long expiration;
@Value("${ibiz.jwt.header:Authorization}")
private String tokenHeader;
public String getUsernameFromToken(String token) {
return getClaimFromToken(token, Claims::getSubject);
}
public Date getIssuedAtDateFromToken(String token) {
return getClaimFromToken(token, Claims::getIssuedAt);
}
public Date getExpirationDateFromToken(String token) {
return getClaimFromToken(token, Claims::getExpiration);
}
public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
final Claims claims = getAllClaimsFromToken(token);
return claimsResolver.apply(claims);
}
private Claims getAllClaimsFromToken(String token) {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}
private Boolean isTokenExpired(String token) {
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(clock.now());
}
private Boolean isCreatedBeforeLastPasswordReset(Date created, Date lastPasswordReset) {
return (lastPasswordReset != null && created.before(lastPasswordReset));
}
private Boolean ignoreTokenExpiration(String token) {
// here you specify tokens, for that the expiration is ignored
return false;
}
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return doGenerateToken(claims, userDetails.getUsername());
}
private String doGenerateToken(Map<String, Object> claims, String subject) {
final Date createdDate = clock.now();
final Date expirationDate = calculateExpirationDate(createdDate);
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(createdDate)
.setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Boolean canTokenBeRefreshed(String token, Date lastPasswordReset) {
final Date created = getIssuedAtDateFromToken(token);
return !isCreatedBeforeLastPasswordReset(created, lastPasswordReset)
&& (!isTokenExpired(token) || ignoreTokenExpiration(token));
}
public String refreshToken(String token) {
final Date createdDate = clock.now();
final Date expirationDate = calculateExpirationDate(createdDate);
final Claims claims = getAllClaimsFromToken(token);
claims.setIssuedAt(createdDate);
claims.setExpiration(expirationDate);
return Jwts.builder()
.setClaims(claims)
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Boolean validateToken(String token, UserDetails userDetails) {
AuthenticationUser user = (AuthenticationUser) userDetails;
final Date created = getIssuedAtDateFromToken(token);
return (!isTokenExpired(token) );
}
private Date calculateExpirationDate(Date createdDate) {
return new Date(createdDate.getTime() + expiration);
}
/**
* Get the login of the current user.
*
* @return the login of the current user
*/
public static Optional<String> getCurrentUserLogin() {
SecurityContext securityContext = SecurityContextHolder.getContext();
return Optional.ofNullable(securityContext.getAuthentication())
.map(authentication -> {
if (authentication.getPrincipal() instanceof UserDetails) {
UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();
return springSecurityUser.getUsername();
} else if (authentication.getPrincipal() instanceof String) {
return (String) authentication.getPrincipal();
}
return null;
});
}
/**
* Check if a user is authenticated.
*
* @return true if the user is authenticated, false otherwise
*/
public static boolean isAuthenticated() {
SecurityContext securityContext = SecurityContextHolder.getContext();
return Optional.ofNullable(securityContext.getAuthentication())
.map(authentication -> authentication.getAuthorities().stream()
.noneMatch(grantedAuthority -> grantedAuthority.getAuthority().equals("ANONYMOUS")))
.orElse(false);
}
/**
* If the current user has a specific authority (security role).
* <p>
* The name of this method comes from the isUserInRole() method in the Servlet API
*
* @param authority the authority to check
* @return true if the current user has the authority, false otherwise
*/
public static boolean isCurrentUserInRole(String authority) {
SecurityContext securityContext = SecurityContextHolder.getContext();
return Optional.ofNullable(securityContext.getAuthentication())
.map(authentication -> authentication.getAuthorities().stream()
.anyMatch(grantedAuthority -> grantedAuthority.getAuthority().equals(authority)))
.orElse(false);
}
}
package cn.ibizlab.util.security;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringContextHolder implements ApplicationContextAware
{
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextHolder.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
assertApplicationContext();
return applicationContext;
}
@SuppressWarnings("unchecked")
public static <T> T getBean(String beanName) {
assertApplicationContext();
return (T) applicationContext.getBean(beanName);
}
public static <T> T getBean(Class<T> requiredType) {
assertApplicationContext();
return applicationContext.getBean(requiredType);
}
private static void assertApplicationContext() {
if (SpringContextHolder.applicationContext == null) {
throw new RuntimeException("applicaitonContext属性为null,请检查是否注入了SpringContextHolder!");
}
}
}
\ No newline at end of file
package cn.ibizlab.util.security;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Clock;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.impl.DefaultClock;
import lombok.SneakyThrows;
import cn.ibizlab.util.client.IBZUAAFeignClient;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.FileInputStream;
import java.io.Serializable;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
@Component
@ConditionalOnExpression("${ibiz.enablePermissionValid:false}||'${ibiz.auth.token.util:UAATokenUtil}'.equals('UAATokenUtil')")
public class UAATokenUtil implements AuthTokenUtil, Serializable {
private static final long serialVersionUID = -3301605591108950415L;
private Clock clock = DefaultClock.INSTANCE;
@Value("${ibiz.jwt.secret:ibzsecret}")
private String secret;
@Value("${ibiz.jwt.expiration:7200000}")
private Long expiration;
@Value("${ibiz.jwt.header:Authorization}")
private String tokenHeader;
@Autowired
private IBZUAAFeignClient uaaFeignClient;
public String getUsernameFromToken(String token) {
return getClaimFromToken(token, Claims::getSubject);
}
public Date getIssuedAtDateFromToken(String token) {
return getClaimFromToken(token, Claims::getIssuedAt);
}
public Date getExpirationDateFromToken(String token) {
return getClaimFromToken(token, Claims::getExpiration);
}
public <T> T getClaimFromToken(String token, Function<Claims, T> claimsResolver) {
final Claims claims = getAllClaimsFromToken(token);
return claimsResolver.apply(claims);
}
public Claims getAllClaimsFromToken(String token) {
PublicKey publicKey = getPublicKey(getPublicKeyString());
return Jwts.parser()
.setSigningKey(publicKey)
.parseClaimsJws(token)
.getBody();
}
private Boolean isTokenExpired(String token) {
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(clock.now());
}
public String generateToken(UserDetails userDetails) {
return null;
}
public Boolean validateToken(String token, UserDetails userDetails) {
AuthenticationUser user = (AuthenticationUser) userDetails;
final Date created = getIssuedAtDateFromToken(token);
return (!isTokenExpired(token) );
}
private String getPublicKeyString(){
return uaaFeignClient.getPublicKey();
}
/**
* 获取PublicKey对象
* @param publicKeyBase64
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
@SneakyThrows
public PublicKey getPublicKey(String publicKeyBase64) {
byte[] byteKey = Base64.decodeBase64(publicKeyBase64);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(x509EncodedKeySpec);
}
}
package cn.ibizlab.util.service;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.security.AuthenticationUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;
public interface AuthenticationUserService extends UserDetailsService {
@Override
@Cacheable( value="ibzuaa_users",key = "'getByUsername:'+#p0")
AuthenticationUser loadUserByUsername(String username);
@Cacheable( value="ibzuaa_users",key = "'getByUsername:'+#p0")
AuthenticationUser loadUserByLogin(String username,String password);
@CacheEvict( value="ibzuaa_users",key = "'getByUsername:'+#p0")
void resetByUsername(String username);
}
package cn.ibizlab.util.service;
import cn.ibizlab.util.domain.FileItem;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
public interface FileService
{
FileItem saveFile(MultipartFile multipartFile);
File getFile(String fileid);
}
\ No newline at end of file
package cn.ibizlab.util.service;
import cn.ibizlab.util.domain.IBZConfig;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.helper.DataObject;
import cn.ibizlab.util.mapper.IBZConfigMapper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@Slf4j
@Service
public class IBZConfigService extends ServiceImpl<IBZConfigMapper, IBZConfig> implements IService<IBZConfig> {
@Value("${ibiz.systemid:ibzpay}")
private String systemId;
@Value("${ibiz.admin.userid:0100}")
private String adminuserid;
@Cacheable( value="ibzrt_configs",key = "'cfgid:'+#p0+'||'+#p1+'||'+#p2")
public JSONObject getConfig(String cfgType,String targetType,String userId)
{
if(StringUtils.isEmpty(userId)||StringUtils.isEmpty(cfgType)||StringUtils.isEmpty(targetType))
throw new BadRequestAlertException("获取配置失败,参数缺失","IBZConfig",cfgType);
IBZConfig config=this.getOne(Wrappers.query(IBZConfig.builder().systemId(systemId).cfgType(cfgType).targetType(targetType).userId(userId).build()),false);
if(config==null) {
config=this.getOne(Wrappers.query(IBZConfig.builder().systemId(systemId).cfgType(cfgType).targetType(targetType).userId(adminuserid).build()),false);
if(config==null) {
return new JSONObject();
}
}
return JSON.parseObject(config.getCfg());
}
@CacheEvict( value="ibzrt_configs",key = "'cfgid:'+#p0+'||'+#p1+'||'+#p2")
public boolean saveConfig(String cfgType,String targetType,String userId,JSONObject config)
{
if(StringUtils.isEmpty(userId)||StringUtils.isEmpty(cfgType)||StringUtils.isEmpty(targetType))
throw new BadRequestAlertException("保存配置失败,参数缺失","IBZConfig",cfgType);
String cfg="{}";
if(config!=null)
cfg=JSONObject.toJSONString(config);
return this.saveOrUpdate(IBZConfig.builder().systemId(systemId).cfgType(cfgType).targetType(targetType).userId(userId).cfg(cfg).updateDate(DataObject.getNow()).build());
}
@CacheEvict( value="ibzrt_configs",key = "'cfgid:'+#p0+'||'+#p1+'||'+#p2")
public void resetConfig(String cfgType,String targetType,String userId)
{
if(StringUtils.isEmpty(userId)||StringUtils.isEmpty(cfgType)||StringUtils.isEmpty(targetType))
throw new BadRequestAlertException("重置配置失败,参数缺失","IBZConfig",cfgType);
this.remove(Wrappers.query(IBZConfig.builder().systemId(systemId).cfgType(cfgType).targetType(targetType).userId(userId).build()));
}
}
\ No newline at end of file
package cn.ibizlab.util.service;
import cn.ibizlab.util.annotation.Audit;
import cn.ibizlab.util.domain.EntityBase;
import org.springframework.scheduling.annotation.Async;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* 实体[DataAudit] 服务对象接口
*/
public interface IBZDataAuditService {
@Async("asyncExecutor")
void createAudit(HttpServletRequest request,EntityBase entity,Object idValue,Map<String, Audit> auditFields);
@Async("asyncExecutor")
void updateAudit(HttpServletRequest request, EntityBase beforeEntity, Object serviceObj, Object idValue, Map<String, Audit> auditFields);
@Async("asyncExecutor")
void removeAudit(HttpServletRequest request,EntityBase entity,Object idValue,Map<String, Audit> auditFields);
}
\ No newline at end of file
package cn.ibizlab.util.service;
import com.alibaba.fastjson.JSONObject;
import cn.ibizlab.util.client.IBZOUFeignClient;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.client.IBZUAAFeignClient;
import cn.ibizlab.util.security.AuthenticationUser;
import cn.ibizlab.util.security.AuthorizationLogin;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
/**
* 实体[IBZUSER] 服务对象接口实现
*/
@Service("IBZUAAUserService")
@ConditionalOnExpression("${ibiz.enablePermissionValid:false}||'${ibiz.auth.service:IBZUAAUserService}'.equals('IBZUAAUserService')")
public class IBZUAAUserService implements AuthenticationUserService{
@Autowired
private IBZUAAFeignClient uaaFeignClient;
@Override
public AuthenticationUser loadUserByUsername(String username) {
AuthenticationUser user=uaaFeignClient.loginByUsername(username);
if(user==null)
throw new BadRequestAlertException("登录失败","IBZUAAUser",username);
return user;
}
@Override
public AuthenticationUser loadUserByLogin(String username, String password) {
String[] data=username.split("[|]");
String loginname=username;
String domains="";
if(data.length==2) {
loginname=data[0].trim();
domains=data[1].trim();
}
AuthorizationLogin logininfo = new AuthorizationLogin();
logininfo.setDomain(domains);
logininfo.setLoginname(loginname);
logininfo.setPassword(password);
AuthenticationUser user=uaaFeignClient.login(logininfo);
if(user==null)
throw new BadRequestAlertException("登录失败","IBZUAAUser",username);
return user;
}
@Override
public void resetByUsername(String username) {
}
}
package cn.ibizlab.util.service;
import cn.ibizlab.util.domain.IBZUSER;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 实体[IBZUSER] 服务对象接口实现
*/
public interface IBZUSERService extends IService<IBZUSER> {
}
\ No newline at end of file
package cn.ibizlab.util.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import cn.ibizlab.util.security.AuthenticationUser;
import cn.ibizlab.util.errors.BadRequestAlertException;
import cn.ibizlab.util.helper.CachedBeanCopier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import cn.ibizlab.util.mapper.IBZUSERMapper;
import cn.ibizlab.util.domain.IBZUSER;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.security.core.authority.AuthorityUtils;
/**
* 实体[IBZUSER] 服务对象接口实现
*/
@Service("IBZUSERService")
@ConditionalOnExpression("(!${ibiz.enablePermissionValid:false})&&'${ibiz.auth.service:IBZUAAUserService}'.equals('IBZUSERService')")
public class IBZUSERServiceImpl extends ServiceImpl<IBZUSERMapper, IBZUSER> implements IBZUSERService,AuthenticationUserService{
@Value("${ibiz.auth.pwencrymode:0}")
private int pwencrymode;
@Override
public AuthenticationUser loadUserByUsername(String username) {
if(StringUtils.isEmpty(username))
throw new UsernameNotFoundException("用户名为空");
QueryWrapper<IBZUSER> conds=new QueryWrapper<IBZUSER>();
String[] data=username.split("[|]");
String loginname="";
String domains="";
if(data.length>0)
loginname=data[0].trim();
if(data.length>1)
domains=data[1].trim();
if(!StringUtils.isEmpty(loginname))
conds.eq("loginname",loginname);
if(!StringUtils.isEmpty(domains))
conds.eq("domains",domains);
IBZUSER user = this.getOne(conds);
if (user == null) {
throw new UsernameNotFoundException("用户" + username + "未找到");
}
else {
user.setUsername(username);
return createUserDetails(user);
}
}
@Override
public AuthenticationUser loadUserByLogin(String username, String password){
AuthenticationUser authuserdetail = loadUserByUsername(username);
if(pwencrymode==1)
password = DigestUtils.md5DigestAsHex(password.getBytes());
else if(pwencrymode==2)
password = DigestUtils.md5DigestAsHex(String.format("%1$s||%2$s", username, password).getBytes());
if(!authuserdetail.getPassword().equals( password )){
throw new BadRequestAlertException("用户名密码错误","IBZUSER",username);
}
return authuserdetail;
}
public void resetByUsername(String username) {
}
public AuthenticationUser createUserDetails(IBZUSER user) {
AuthenticationUser userdatail = new AuthenticationUser();
CachedBeanCopier.copy(user,userdatail);
if(userdatail.getSuperuser()==1){
userdatail.setAuthorities(AuthorityUtils.createAuthorityList("ROLE_SUPERADMIN"));
}
return userdatail;
}
}
\ No newline at end of file
package cn.ibizlab.util.service;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.*;
import feign.codec.Decoder;
import feign.codec.Encoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignContext;
import org.springframework.cloud.openfeign.support.SpringDecoder;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* 自定义feigen客户端配置
*
* @author
*/
@Service
public class RemoteService {
/**
* FeignClientFactoryBean
*/
@Autowired
protected FeignContext feignContext;
/**
* FeignClient 默认LoadBalancerFeignClient
*/
@Autowired
private Client feignClient;
private static final Map<String, Object> FEIGN_CLIENTS = new ConcurrentHashMap<>();
/**
* 定义远程通用接口
*/
public interface RemoteFeignClient {
@RequestMapping(method = RequestMethod.POST, value = "/{path}")
JSONObject post( @PathVariable("path") String path, @RequestHeader("Authorization") String token,@RequestBody Map param);
@RequestMapping(method = RequestMethod.GET, value = "/{path}")
JSONObject request( @PathVariable("path") String path, @RequestHeader("Authorization") String token,Map param);
@RequestMapping(method = RequestMethod.GET, value = "/{path}")
JSONObject get( @PathVariable("path") String path, @RequestHeader("Authorization") String token);
@RequestMapping(method = RequestMethod.PUT, value = "/{path}")
JSONObject put( @PathVariable("path") String path, @RequestHeader("Authorization") String token,@RequestBody Map param);
@RequestMapping(method = RequestMethod.DELETE, value = "/{path}")
JSONObject delete( @PathVariable("path") String path, @RequestHeader("Authorization") String token);
}
/**
* @param serverId
* @return
*/
public RemoteFeignClient getClient(String serverId) {
return this.create(RemoteFeignClient.class, serverId);
}
/**
* 设置编码解码器为FastJson
*
* @param clazz
* @param serviceId
* @param <T>
* @return
*/
private synchronized <T> T create(Class<T> clazz, String serviceId) {
Object object = FEIGN_CLIENTS.get(serviceId);
if (Objects.isNull(object)) {
object = Feign.builder()
//decoder指定对象解码方式
.decoder(this.feignDecoder())
.encoder(this.feignEncoder())
.client(feignClient)
//options方法指定连接超时时长及响应超时时长
.options(new Request.Options(5000, 50000))
//retryer方法指定重试策略
//.retryer(new Retryer.Default(5000, 5000, 3))
.contract(feignContext.getInstance(serviceId, Contract.class))
//target方法绑定接口与服务端地址。返回类型为绑定的接口类型。
.target(clazz, "http://"+serviceId);
FEIGN_CLIENTS.put(serviceId, object);
}
return (T) object;
}
private Decoder feignDecoder() {
return new SpringDecoder(feignHttpMessageConverter());
}
private Encoder feignEncoder() {
return new SpringEncoder(feignHttpMessageConverter());
}
private ObjectFactory<HttpMessageConverters> feignHttpMessageConverter() {
HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(new ObjectMapper());
final HttpMessageConverters httpMessageConverters = new HttpMessageConverters(jsonConverter);
return () -> httpMessageConverters;
}
}
\ No newline at end of file
package cn.ibizlab.util.service;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import cn.ibizlab.util.annotation.Audit;
import cn.ibizlab.util.annotation.DEField;
import cn.ibizlab.util.domain.EntityBase;
import cn.ibizlab.util.domain.IBZDataAudit;
import cn.ibizlab.util.helper.DEFieldCacheMap;
import cn.ibizlab.util.mapper.IBZDataAuditMapper;
import cn.ibizlab.util.security.AuthenticationUser;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 实体[DataAudit] 服务对象接口实现
*/
@Service
@Slf4j
public class SimpleAuditService extends ServiceImpl<IBZDataAuditMapper, IBZDataAudit> implements IBZDataAuditService {
private final ExpressionParser parser = new SpelExpressionParser();
private static List cacheMap = Collections.synchronizedList(new ArrayList());
/**
* 定时保存审计记录
*/
@Scheduled(fixedRate = 10000)
public void saveAudit() {
if(cacheMap.size()>0){
log.info(String.format("正在保存审计数据,当前审计集合数量为[%s]",cacheMap.size()));
List temp=new ArrayList();
if(cacheMap.size()<500)
temp.addAll(cacheMap);
else
temp.addAll(cacheMap.subList(0,500));
this.saveBatch(temp);
cacheMap.removeAll(temp);
log.info(String.format("保存完成,当前审计集合数量为[%s]",cacheMap.size()));
}
}
/**
* 新建审计日志
* @param request
* @param entity
* @param idValue
* @param auditFields
*/
@Override
public void createAudit(HttpServletRequest request, EntityBase entity, Object idValue, Map<String, Audit> auditFields) {
IBZDataAudit dataAudit =new IBZDataAudit();
dataAudit.setOppersonid(AuthenticationUser.getAuthenticationUser().getUserid());
dataAudit.setOppersonname(String.format("%s[%s]",AuthenticationUser.getAuthenticationUser().getPersonname(),AuthenticationUser.getAuthenticationUser().getOrgname()));
dataAudit.setAudittype("CREATE");
dataAudit.setAuditobject(entity.getClass().getSimpleName());
dataAudit.setAuditobjectdata(idValue);
dataAudit.setOptime(new Timestamp(new Date().getTime()));
if(request!=null)
dataAudit.setIpaddress(getIpAddress(request, AuthenticationUser.getAuthenticationUser()));
dataAudit.setAuditinfo(getAuditInfo(entity,auditFields));
dataAudit.setIsdatachanged(1);
cacheMap.add(dataAudit);
}
/**
* 更新审计日志
* @param request
* @param beforeEntity
* @param serviceObj
* @param idValue
* @param auditFields
*/
@SneakyThrows
public void updateAudit(HttpServletRequest request, EntityBase beforeEntity, Object serviceObj, Object idValue, Map<String, Audit> auditFields){
//获取更新后的实体
EntityBase afterEntity=getEntity(serviceObj,idValue);
//获取更新后的审计内容
String auditInfo=getUpdateAuditInfo(beforeEntity,afterEntity,auditFields);//比较更新前后差异内容
int isDataChanged=1;
if(StringUtils.isEmpty(auditInfo))//审计内容是否发生变化
isDataChanged=0;
IBZDataAudit dataAudit =new IBZDataAudit();
dataAudit.setOppersonid(AuthenticationUser.getAuthenticationUser().getUserid());
dataAudit.setOppersonname(String.format("%s[%s]",AuthenticationUser.getAuthenticationUser().getPersonname(),AuthenticationUser.getAuthenticationUser().getOrgname()));
dataAudit.setAudittype("UPDATE");
dataAudit.setAuditobject(afterEntity.getClass().getSimpleName());
dataAudit.setAuditobjectdata(idValue);
dataAudit.setOptime(new Timestamp(new Date().getTime()));
if(request!=null)
dataAudit.setIpaddress(getIpAddress(request, AuthenticationUser.getAuthenticationUser()));
dataAudit.setAuditinfo(auditInfo);
dataAudit.setIsdatachanged(isDataChanged);
cacheMap.add(dataAudit);
}
/**
* 删除审计日志
* @param request
* @param entity
* @param idValue
* @param auditFields
*/
public void removeAudit(HttpServletRequest request,EntityBase entity,Object idValue,Map<String, Audit> auditFields){
IBZDataAudit dataAudit =new IBZDataAudit();
dataAudit.setOppersonid(AuthenticationUser.getAuthenticationUser().getUserid());
dataAudit.setOppersonname(String.format("%s[%s]",AuthenticationUser.getAuthenticationUser().getPersonname(),AuthenticationUser.getAuthenticationUser().getOrgname()));
dataAudit.setAudittype("REMOVE");
dataAudit.setAuditobject(entity.getClass().getSimpleName());
dataAudit.setAuditobjectdata(idValue);
dataAudit.setOptime(new Timestamp(new Date().getTime()));
if(request!=null)
dataAudit.setIpaddress(getIpAddress(request, AuthenticationUser.getAuthenticationUser()));
dataAudit.setAuditinfo(getAuditInfo(entity,auditFields));
dataAudit.setIsdatachanged(1);
cacheMap.add(dataAudit);
}
private String getAuditInfo(EntityBase entity, Map<String, Audit> auditFields){
String auditResult="";
if(auditFields.size()==0)
return auditResult;
Map<String, DEField> deFields= DEFieldCacheMap.getDEFields(entity.getClass());
if(deFields.size()==0)
return auditResult;
JSONArray auditFieldArray=new JSONArray();
for (Map.Entry<String, Audit> auditField : auditFields.entrySet()) {
Object objFieldName=auditField.getKey();
String fieldName=String.valueOf(objFieldName);
DEField deField=null;
if(deFields.containsKey(fieldName)){
deField= deFields.get(fieldName);
}
if(ObjectUtils.isEmpty(deField))
continue;
Object value=dataTransfer(entity.get(fieldName),deField.fieldType(),deField.format());
if(!StringUtils.isEmpty(value)){
JSONObject auditFieldObj=new JSONObject();
auditFieldObj.put("field",deField.value());
auditFieldObj.put("value",value);
if(!StringUtils.isEmpty(deField.dict())){
auditFieldObj.put("dict",deField.dict());
}
auditFieldArray.add(auditFieldObj);
}
}
if(auditFieldArray.size()>0){
auditResult=auditFieldArray.toString();
}
return auditResult;
}
/**
* 获取更新审计内容
* @param oldData
* @param newData
* @param auditFields
* @return
*/
private String getUpdateAuditInfo(EntityBase oldData, EntityBase newData, Map<String, Audit> auditFields){
String auditResult="";
JSONArray auditFieldArray=new JSONArray();
if(auditFields.size()==0)
return auditResult;
Map<String, DEField> deFields= DEFieldCacheMap.getDEFields(oldData.getClass());
if(deFields.size()==0)
return auditResult;
for (Map.Entry<String, Audit> auditField : auditFields.entrySet()) {
Object objFieldName=auditField.getKey();//获取注解字段
String fieldName=String.valueOf(objFieldName); //属性名称
DEField deField=null;
if(deFields.containsKey(fieldName)){
deField= deFields.get(fieldName);
}
if(ObjectUtils.isEmpty(deField))
continue;
Object oldValue=oldData.get(fieldName);//老属性值
Object newValue=newData.get(fieldName);//新属性值
if(!compare(oldValue,newValue)){
oldValue=dataTransfer(oldValue,deField.fieldType(),deField.format());//属性值转换
newValue=dataTransfer(newValue,deField.fieldType(),deField.format());//属性值转换
JSONObject auditFieldObj=new JSONObject();
auditFieldObj.put("field",deField.value());
auditFieldObj.put("beforevalue",oldValue);
auditFieldObj.put("value",newValue);
if(!StringUtils.isEmpty(deField.dict())){
auditFieldObj.put("dict",deField.dict());
}
auditFieldArray.add(auditFieldObj);
}
}
if(auditFieldArray.size()>0){
auditResult=auditFieldArray.toString();
}
return auditResult;
}
/**
* 数据转换
* @param value 转换值
* @param dataType 转换字段类型
* @param strFormat 转换字段格式化文本
* @return
*/
private String dataTransfer(Object value,String dataType, String strFormat){
if(value==null)
return "";
String transResult=value.toString();
if((dataType.equals("DATE") || dataType.equals("DATETIME") || dataType.equals("TIME")) && (!StringUtils.isEmpty(strFormat))){ //时间类型转换
Timestamp timestamp =(Timestamp)value;
Date date =timestamp;
SimpleDateFormat format =new SimpleDateFormat(strFormat);
transResult=format.format(date);
}
return transResult;
}
/**
* 对象比较
* @param sourceObj 比较源对象
* @param targetObj 比较目标对象
* @return
*/
private boolean compare(Object sourceObj,Object targetObj){
if(sourceObj==null && targetObj==null)
return true;
if(sourceObj==null && targetObj!=null)
return false;
return sourceObj.equals(targetObj);
}
/**
* 获取实体
* @param service
* @param id
* @return
*/
@SneakyThrows
private EntityBase getEntity(Object service, Object id){
EntityBase entity=null;
if(!ObjectUtils.isEmpty(service)){
EvaluationContext oldContext = new StandardEvaluationContext();
oldContext.setVariable("service",service);
oldContext.setVariable("id",id);
Expression oldExp = parser.parseExpression("#service.get(#id)");
return oldExp.getValue(oldContext, EntityBase.class);
}
return entity;
}
/**
* 获取Ip地址
* @param request
* @return
*/
public String getIpAddress(HttpServletRequest request, AuthenticationUser authenticationUser) {
//客户端有提交ip,以提交的ip为准
if(authenticationUser != null && !StringUtils.isEmpty(authenticationUser.getAddr())){
return authenticationUser.getAddr();
}
if(request == null)
return "";
String Xip = request.getHeader("X-Real-IP");
String XFor = request.getHeader("X-Forwarded-For");
if(!StringUtils.isEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){
//多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = XFor.indexOf(",");
if(index != -1){
return XFor.substring(0,index);
}else{
return XFor;
}
}
XFor = Xip;
if(!StringUtils.isEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){
return XFor;
}
if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(XFor) || "unknown".equalsIgnoreCase(XFor)) {
XFor = request.getRemoteAddr();
}
return XFor;
}
}
\ No newline at end of file
package cn.ibizlab.util.service;
import cn.ibizlab.util.domain.FileItem;
import cn.ibizlab.util.errors.InternalServerErrorException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.DigestUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
@Primary
@Slf4j
@Service
public class SimpleFileService implements FileService {
@Value("${ibiz.filePath:/app/file/}")
private String fileRoot;
@Override
public FileItem saveFile(MultipartFile multipartFile) {
FileItem item=null;
// 获取文件名
String fileName = multipartFile.getOriginalFilename();
// 获取文件后缀
String extname="."+getExtensionName(fileName);
try {
String fileid= DigestUtils.md5DigestAsHex(multipartFile.getInputStream());
String fileFullPath = this.fileRoot+"ibizutil"+File.separator+fileid+File.separator+fileName;
File file = new File(fileFullPath);
File parent = new File(file.getParent());
if(!parent.exists())
parent.mkdirs();
FileCopyUtils.copy(multipartFile.getInputStream(),Files.newOutputStream(file.toPath()));
item=new FileItem(fileid,fileName,fileid,fileName,(int)multipartFile.getSize(),extname);
} catch (IOException e) {
throw new InternalServerErrorException("文件上传失败");
}
return item;
}
@Override
public File getFile(String fileid) {
String dirpath = this.fileRoot+"ibizutil"+File.separator+fileid;
File parent = new File(dirpath);
if (parent.exists() && parent.isDirectory() && parent.listFiles().length > 0) {
return parent.listFiles()[0];
}
throw new InternalServerErrorException("文件未找到");
}
/**
* 获取文件扩展名
* @param filename
* @return
*/
public static String getExtensionName(String filename) {
if ((filename != null) && (filename.length() > 0)) {
int dot = filename.lastIndexOf('.');
if ((dot >-1) && (dot < (filename.length() - 1))) {
return filename.substring(dot + 1);
}
}
return filename;
}
}
\ No newline at end of file
package cn.ibizlab.util.service;
import cn.ibizlab.util.security.AuthenticationUser;
import cn.ibizlab.util.client.IBZUAAFeignClient;
import cn.ibizlab.util.client.IBZOUFeignClient;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.security.core.authority.AuthorityUtils;
/**
* 实体[IBZUSER] 服务对象接口实现
*/
@Primary
@Service("SimpleUserService")
@ConditionalOnExpression("(!${ibiz.enablePermissionValid:false})&&'${ibiz.auth.service:IBZUAAUserService}'.equals('SimpleUserService')")
public class SimpleUserService implements AuthenticationUserService{
@Override
public AuthenticationUser loadUserByUsername(String username) {
AuthenticationUser user = new AuthenticationUser();
String[] data=username.split("[|]");
String loginname=username;
String domains="";
String password="";
if(data.length==2) {
loginname=data[0].trim();
domains=data[1].trim();
}
user.setUserid(username);
user.setUsercode(loginname);
user.setUsername(username);
user.setLoginname(loginname);
user.setPersonname(loginname);
user.setDomain(domains);
user.setPassword(password);
user.setOrgid(domains);
user.setOrgcode(domains);
user.setOrgname(domains);
user.setSuperuser(1);
user.setAuthorities(AuthorityUtils.createAuthorityList("ROLE_SUPERADMIN"));
return user;
}
@Override
public AuthenticationUser loadUserByLogin(String username, String password) {
AuthenticationUser authuserdetail = loadUserByUsername(username);
return authuserdetail;
}
@Override
public void resetByUsername(String username) {
}
}
package cn.ibizlab.util.web;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
/**
* feign请求拦截器
* 拦截所有使用feign发出的请求,附加原始请求Header参数及Token
*/
@Configuration
public class FeignRequestInterceptor implements RequestInterceptor {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if(requestAttributes!=null){
HttpServletRequest request = requestAttributes.getRequest();
Enumeration<String> headerNames = request.getHeaderNames();
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
if(name.equalsIgnoreCase("transfer-encoding"))
continue;
String values = request.getHeader(name);
requestTemplate.header(name, values);
}
logger.info("feign interceptor header:{}",requestTemplate);
}
}
}
}
\ No newline at end of file
package cn.ibizlab.util.web;
import cn.ibizlab.util.filter.SearchContextBase;
import com.fasterxml.classmate.ResolvedType;
import com.google.common.base.Predicate;
import com.google.common.collect.FluentIterable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.service.Parameter;
import springfox.documentation.service.ResolvedMethodParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.schema.EnumTypeDeterminer;
import springfox.documentation.spi.service.OperationBuilderPlugin;
import springfox.documentation.spi.service.contexts.OperationContext;
import springfox.documentation.spi.service.contexts.ParameterContext;
import springfox.documentation.spring.web.plugins.DocumentationPluginsManager;
import springfox.documentation.spring.web.readers.parameter.ExpansionContext;
import springfox.documentation.spring.web.readers.parameter.ModelAttributeParameterExpander;
import java.lang.annotation.Annotation;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Predicates.*;
import static com.google.common.collect.Lists.*;
import static springfox.documentation.schema.Collections.*;
import static springfox.documentation.schema.Maps.*;
import static springfox.documentation.schema.Types.*;
//@Component
//@Order(Ordered.HIGHEST_PRECEDENCE)
public class IBZOperationParameterReader implements OperationBuilderPlugin {
private final ModelAttributeParameterExpander expander;
private final EnumTypeDeterminer enumTypeDeterminer;
@Autowired
private DocumentationPluginsManager pluginsManager;
@Autowired
public IBZOperationParameterReader(
ModelAttributeParameterExpander expander,
EnumTypeDeterminer enumTypeDeterminer) {
this.expander = expander;
this.enumTypeDeterminer = enumTypeDeterminer;
}
@Override
public void apply(OperationContext context) {
context.operationBuilder().parameters(context.getGlobalOperationParameters());
context.operationBuilder().parameters(readParameters(context));
}
@Override
public boolean supports(DocumentationType delimiter) {
return true;
}
private List<Parameter> readParameters(final OperationContext context) {
List<ResolvedMethodParameter> methodParameters = context.getParameters();
List<Parameter> parameters = newArrayList();
for (ResolvedMethodParameter methodParameter : methodParameters) {
ResolvedType alternate = context.alternateFor(methodParameter.getParameterType());
if (!shouldIgnore(methodParameter, alternate, context.getIgnorableParameterTypes())) {
ParameterContext parameterContext = new ParameterContext(methodParameter,
new ParameterBuilder(),
context.getDocumentationContext(),
context.getGenericsNamingStrategy(),
context);
if (shouldExpand(methodParameter, alternate)) {
parameters.addAll(
expander.expand(
new ExpansionContext("", alternate, context)));
} else {
parameters.add(pluginsManager.parameter(parameterContext));
}
}
}
return FluentIterable.from(parameters).filter(not(hiddenParams())).toList();
}
private Predicate<Parameter> hiddenParams() {
return new Predicate<Parameter>() {
@Override
public boolean apply(Parameter input) {
return input.isHidden();
}
};
}
private boolean shouldIgnore(
final ResolvedMethodParameter parameter,
ResolvedType resolvedParameterType,
final Set<Class> ignorableParamTypes) {
if (ignorableParamTypes.contains(resolvedParameterType.getErasedType())) {
return true;
}
return FluentIterable.from(ignorableParamTypes)
.filter(isAnnotation())
.filter(parameterIsAnnotatedWithIt(parameter)).size() > 0;
}
private Predicate<Class> parameterIsAnnotatedWithIt(final ResolvedMethodParameter parameter) {
return new Predicate<Class>() {
@Override
public boolean apply(Class input) {
return parameter.hasParameterAnnotation(input);
}
};
}
private Predicate<Class> isAnnotation() {
return new Predicate<Class>() {
@Override
public boolean apply(Class input) {
return Annotation.class.isAssignableFrom(input);
}
};
}
private boolean shouldExpand(final ResolvedMethodParameter parameter, ResolvedType resolvedParamType) {
return !parameter.hasParameterAnnotation(RequestBody.class)
&& !parameter.hasParameterAnnotation(RequestPart.class)
&& !parameter.hasParameterAnnotation(RequestParam.class)
&& !parameter.hasParameterAnnotation(PathVariable.class)
&& !isBaseType(typeNameFor(resolvedParamType.getErasedType()))
&& !enumTypeDeterminer.isEnum(resolvedParamType.getErasedType())
&& !isContainerType(resolvedParamType)
&& !isMapType(resolvedParamType)
&& !SearchContextBase.class.isAssignableFrom(resolvedParamType.getErasedType());
}
}
package cn.ibizlab.util.web;
import cn.ibizlab.util.filter.SearchContextBase;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Slf4j
@Configuration
public class SearchContextHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Value("${ibiz.pageLimit:1000}")
private int pageLimit=1000;
private static ObjectMapper objectMapper=new ObjectMapper();
@Override
public boolean supportsParameter(MethodParameter parameter) {
return SearchContextBase.class.isAssignableFrom(parameter.getParameterType());
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
Map<String, String[]> params = webRequest.getParameterMap();
LinkedHashMap<String,Object> set=new LinkedHashMap<>();
for (String key : params.keySet()) {
set.put(key,params.get(key)[0]);
}
if((!set.containsKey("size")) ){
set.put("size",pageLimit);
}
String json=objectMapper.writeValueAsString(set);
return objectMapper.readValue(json,parameter.getParameterType());
}
}
\ No newline at end of file
#eureka配置中心
spring:
cloud:
nacos:
discovery:
enabled: false
eureka:
client:
enabled: true
serviceUrl:
defaultZone: http://127.0.0.1:8762/eureka/
#nacos配置中心
spring:
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
enabled: true
eureka:
client:
enabled: false
#缓存、数据源
spring:
cache:
redis:
time-to-live: 3600
caffeine:
spec: initialCapacity=5,maximumSize=500,expireAfterWrite=3600s
redis:
host: 127.0.0.1
port: 6379
password:
database: 0
lettuce:
pool:
max-active: 32
max-wait: 300ms
max-idle: 16
min-idle: 8
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
datasource:
username: root
password: 'root'
url: jdbc:mysql://127.0.0.1:3306/ibzpay?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useOldAliasMetadataBehavior=true&allowMultiQueries=true
driver-class-name: com.mysql.jdbc.Driver
filters: stat,wall,log4j2
#配置初始化大小/最小/最大
initial-size: 1
min-idle: 1
max-active: 20
#获取连接等待超时时间
max-wait: 60000
#间隔多久进行一次检测,检测需要关闭的空闲连接
time-between-eviction-runs-millis: 60000
#一个连接在池中最小生存的时间
min-evictable-idle-time-millis: 300000
validation-query: SELECT 1 FROM DUAL
test-while-idle: true
test-on-borrow: false
test-on-return: false
#打开PSCache,并指定每个连接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false
pool-prepared-statements: false
max-pool-prepared-statement-per-connection-size: 20
isSyncDBSchema: false
defaultSchema: root
conf: classpath:liquibase/master.xml
#Mybatis-plus配置
mybatis-plus:
global-config:
refresh-mapper: true
db-config:
# 全局逻辑已删除默认值
logic-delete-value: 0
# 全局逻辑未删除默认值
logic-not-delete-value: 1
mapper-locations: classpath*:/mapper/*/*/*.xml
configuration:
jdbc-type-for-null: 'null'
map-underscore-to-camel-case: false
#阿里sentinel熔断器
feign:
httpclient:
enabled: true
sentinel:
enabled: true
compression:
request:
enabled: true
mime-types: application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain
min-response-size: 10240
response:
enabled: true
#Log配置
logging:
level:
cn.ibizlab: debug
org.springframework.boot.autoconfigure: ERROR
#zuul网关超时设置
ribbon:
ReadTimeout: 60000
ConnectTimeout: 60000
#系统是否开启权限验证、是否开启缓存
#缓存级别:无缓存(无配置项)、一级缓存(L1)、二级缓存(L2)
ibiz:
enablePermissionValid: true
cacheLevel: L1 #(L1)一级本地caffeine缓存;(L2)caffeine缓存+Redis缓存
### jobs
jobs:
#admin-address: http://127.0.0.1:40005
app-name: ibzpay
app-port: 9999
#app-ip: 127.0.0.1
### 启用Gzip压缩
server:
compression:
enabled: true
mime-types: application/javascript,text/css,application/json,application/xml,text/html,text/xml,text/plain
min-response-size: 10240
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>ibzpay</artifactId>
<groupId>cn.ibizlab</groupId>
<version>1.0.0.0</version>
<name>Ibzpay</name>
<description></description>
<packaging>pom</packaging>
<parent>
<groupId>cn.ibizlab</groupId>
<artifactId>ibzpay-dependencies</artifactId>
<version>1.0.0.0</version>
<relativePath>ibzpay-dependencies/pom.xml</relativePath>
</parent>
<modules>
<!-- dependencies -->
<module>ibzpay-dependencies</module>
<!-- utils -->
<module>ibzpay-util</module>
<!-- cores -->
<module>ibzpay-core</module>
<!-- services -->
<module>ibzpay-provider</module>
<!-- apps -->
<module>ibzpay-app</module>
<!-- boot -->
<module>ibzpay-boot</module>
</modules>
<repositories>
<repository>
<id>aliyunmaven</id>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public/</url>
<layout>default</layout>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
</project>
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册