35 changed files with 1346 additions and 5 deletions
@ -0,0 +1,13 @@ |
|||
package com.example.guoyan.common; |
|||
|
|||
/** |
|||
* 自定义一个运行时异常 |
|||
* |
|||
*/ |
|||
public class CustomerException extends RuntimeException{ |
|||
|
|||
public CustomerException(String message) { |
|||
|
|||
super(message); |
|||
} |
|||
} |
@ -0,0 +1,58 @@ |
|||
package com.example.guoyan.common; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.stereotype.Controller; |
|||
import org.springframework.web.bind.annotation.ControllerAdvice; |
|||
import org.springframework.web.bind.annotation.ExceptionHandler; |
|||
import org.springframework.web.bind.annotation.ResponseBody; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
|
|||
import java.sql.SQLIntegrityConstraintViolationException; |
|||
|
|||
/** |
|||
* 全局异常处理 |
|||
* 基于代理实现,也就是通过AOP来对这些异常进行拦截 |
|||
* 如果抛异常了,就一起来这里进行处理 |
|||
* @ControllerAdvice(拦截哪些controller) |
|||
* @ControllerAdvice(annotations = {RestController.class, Controller.class})加入了@RestController、@Controller的注解 |
|||
* @ResponseBody 返回Result对象时解析成json |
|||
*/ |
|||
@ControllerAdvice(annotations = {RestController.class, Controller.class}) |
|||
@ResponseBody |
|||
@Slf4j |
|||
public class GloableExceptionHandler { |
|||
/** |
|||
* @ExceptionHandler({异常类型.class,异常类型.class}) |
|||
* @param exception 异常对象,后面Get信息要用 |
|||
* @return 返回Result对象,既然都抓异常了,肯定就要Result.error("失败信息") |
|||
*/ |
|||
@ExceptionHandler({SQLIntegrityConstraintViolationException.class,NullPointerException.class}) |
|||
public Result<String> exceptionHandler(SQLIntegrityConstraintViolationException exception){ |
|||
log.error(exception.getMessage()); |
|||
//这里判断出来是添加员工时出现的异常
|
|||
if (exception.getMessage().contains("Duplicate entry")){ |
|||
//exception对象分割,同时存储
|
|||
String []splitErrorMessage=exception.getMessage().split(" "); |
|||
/** |
|||
* splitErrorMessage数组内存的信息 |
|||
* Duplicate entry '新增的账号' for key 'idx_username' |
|||
* 下标位2是新增账号,下标位5是关联的字段名 |
|||
*/ |
|||
String errorMessage = "这个账号重复了" + splitErrorMessage[2]; |
|||
return Result.error(errorMessage); |
|||
} |
|||
return Result.error("失败了"); |
|||
} |
|||
|
|||
/** |
|||
* 自定义的全局异常处理 |
|||
* @param customerException 自定义异常对象 |
|||
* @return |
|||
*/ |
|||
@ExceptionHandler({CustomerException.class}) |
|||
public Result<String> exceptionHandlerCustomer(CustomerException customerException){ |
|||
log.error(customerException.getMessage()); |
|||
//直接返回处理信息
|
|||
return Result.error(customerException.getMessage()); |
|||
} |
|||
} |
@ -0,0 +1,54 @@ |
|||
package com.example.guoyan.common; |
|||
|
|||
import com.fasterxml.jackson.databind.DeserializationFeature; |
|||
import com.fasterxml.jackson.databind.ObjectMapper; |
|||
import com.fasterxml.jackson.databind.module.SimpleModule; |
|||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; |
|||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; |
|||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; |
|||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; |
|||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; |
|||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; |
|||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; |
|||
import java.math.BigInteger; |
|||
import java.time.LocalDate; |
|||
import java.time.LocalDateTime; |
|||
import java.time.LocalTime; |
|||
import java.time.format.DateTimeFormatter; |
|||
import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; |
|||
|
|||
/** |
|||
* 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象 |
|||
* 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象] |
|||
* 从Java对象生成JSON的过程称为 [序列化Java对象到JSON] |
|||
*/ |
|||
public class JacksonObjectMapper extends ObjectMapper { |
|||
|
|||
public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd"; |
|||
public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; |
|||
public static final String DEFAULT_TIME_FORMAT = "HH:mm:ss"; |
|||
|
|||
public JacksonObjectMapper() { |
|||
super(); |
|||
//收到未知属性时不报异常
|
|||
this.configure(FAIL_ON_UNKNOWN_PROPERTIES, false); |
|||
|
|||
//反序列化时,属性不存在的兼容处理
|
|||
this.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); |
|||
|
|||
|
|||
SimpleModule simpleModule = new SimpleModule() |
|||
.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) |
|||
.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) |
|||
.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))) |
|||
|
|||
.addSerializer(BigInteger.class, ToStringSerializer.instance) |
|||
.addSerializer(Long.class, ToStringSerializer.instance) |
|||
.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT))) |
|||
.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT))) |
|||
.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_TIME_FORMAT))); |
|||
|
|||
//注册功能模块 例如,可以添加自定义序列化器和反序列化器
|
|||
this.registerModule(simpleModule); |
|||
} |
|||
} |
@ -0,0 +1,65 @@ |
|||
package com.example.guoyan.common; |
|||
|
|||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; |
|||
import org.apache.ibatis.reflection.MetaObject; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import javax.servlet.http.HttpServletRequest; |
|||
import java.time.LocalDateTime; |
|||
|
|||
/** |
|||
* 自定义元数据处理器 |
|||
* MP提供的自动填充功能,通过实现MetaObjectHandler(元数据处理器),来实现服务 |
|||
* 为加入@TableField的注解提供自动填充的功能 |
|||
*/ |
|||
@Component |
|||
public class MyMetaObjectHandler implements MetaObjectHandler { |
|||
|
|||
/*退而求其次选择了注入Request对象*/ |
|||
@Autowired |
|||
HttpServletRequest httpServletRequest; |
|||
|
|||
/** |
|||
* @param metaObject 插入时自动填充 |
|||
*/ |
|||
@Override |
|||
public void insertFill(MetaObject metaObject) { |
|||
|
|||
//填充创建时间
|
|||
metaObject.setValue("createTime", LocalDateTime.now()); |
|||
//填充 更新的时间
|
|||
metaObject.setValue("updateTime", LocalDateTime.now()); |
|||
//BaseContext工具类获取当前登陆人员信息
|
|||
//填充创建人信息
|
|||
metaObject.setValue("createUser", httpServletRequest.getSession().getAttribute("employee")); |
|||
//填充更新人信息
|
|||
metaObject.setValue("updateUser", httpServletRequest.getSession().getAttribute("employee")); |
|||
/* |
|||
这里有Bug,就是封装好的BaseContext通过ThreadLocal获取不了对象,虽然都是一个线程的 |
|||
但就是获取不到,所以这里先写死了,后面慢慢再改吧 |
|||
* */ |
|||
/*//填充创建人信息
|
|||
metaObject.setValue("createUser", 1L); |
|||
//填充更新人信息
|
|||
metaObject.setValue("updateUser", 1L);*/ |
|||
|
|||
} |
|||
|
|||
/** |
|||
* @param metaObject 更新时自动填充 |
|||
*/ |
|||
@Override |
|||
public void updateFill(MetaObject metaObject) { |
|||
//因为是更新,所以不用操作创建时间
|
|||
//更新 更新的时间
|
|||
metaObject.setValue("updateTime", LocalDateTime.now()); |
|||
//更新更新人员
|
|||
/* |
|||
这里有Bug,就是封装好的BaseContext通过ThreadLocal获取不了对象,所以这里先写死了,后面慢慢再改吧 |
|||
metaObject.setValue("updateUser", 1L); |
|||
* */ |
|||
|
|||
metaObject.setValue("updateUser", httpServletRequest.getSession().getAttribute("employee")); |
|||
} |
|||
} |
@ -0,0 +1,43 @@ |
|||
package com.example.guoyan.common; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
import java.util.HashMap; |
|||
import java.util.Map; |
|||
|
|||
/** |
|||
* 通用返回结果,服务端响应的数据最终都会封装成此对象 |
|||
* @param <T> |
|||
*/ |
|||
@Data |
|||
public class Result<T> implements Serializable { |
|||
|
|||
private Integer code; //编码:1成功,0和其它数字为失败
|
|||
|
|||
private String msg; //错误信息
|
|||
|
|||
private T data; //数据
|
|||
|
|||
private Map map = new HashMap(); //动态数据
|
|||
|
|||
public static <T> Result<T> success(T object) { |
|||
Result<T> r = new Result<T>(); |
|||
r.data = object; |
|||
r.code = 1; |
|||
return r; |
|||
} |
|||
|
|||
public static <T> Result<T> error(String msg) { |
|||
Result r = new Result(); |
|||
r.msg = msg; |
|||
r.code = 0; |
|||
return r; |
|||
} |
|||
|
|||
public Result<T> add(String key, Object value) { |
|||
this.map.put(key, value); |
|||
return this; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,24 @@ |
|||
package com.example.guoyan.config; |
|||
|
|||
import com.baomidou.mybatisplus.annotation.DbType; |
|||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; |
|||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.mybatis.spring.annotation.MapperScan; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
|
|||
/** |
|||
* MybatisPlus分页插件配置类 |
|||
*/ |
|||
@Configuration |
|||
public class MybatisPlusConfig { |
|||
|
|||
//分页插件
|
|||
@Bean |
|||
public MybatisPlusInterceptor mybatisPlusInterceptor(){ |
|||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); |
|||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); |
|||
return interceptor; |
|||
} |
|||
} |
@ -0,0 +1,20 @@ |
|||
package com.example.guoyan.config; |
|||
|
|||
import org.springframework.cache.annotation.CachingConfigurerSupport; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.data.redis.connection.RedisConnectionFactory; |
|||
import org.springframework.data.redis.core.RedisTemplate; |
|||
import org.springframework.data.redis.serializer.StringRedisSerializer; |
|||
|
|||
@Configuration |
|||
public class RedisConfig extends CachingConfigurerSupport { |
|||
@Bean |
|||
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) { |
|||
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>(); |
|||
//默认的Key序列化器为:JdkSerializationRedisSerializer
|
|||
redisTemplate.setKeySerializer(new StringRedisSerializer()); |
|||
redisTemplate.setConnectionFactory(connectionFactory); |
|||
return redisTemplate; |
|||
} |
|||
} |
@ -0,0 +1,185 @@ |
|||
package com.example.guoyan.config; |
|||
|
|||
import lombok.NonNull; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.apache.http.Header; |
|||
import org.apache.http.client.HttpClient; |
|||
import org.apache.http.client.config.RequestConfig; |
|||
import org.apache.http.config.Registry; |
|||
import org.apache.http.config.RegistryBuilder; |
|||
import org.apache.http.conn.socket.ConnectionSocketFactory; |
|||
import org.apache.http.conn.socket.PlainConnectionSocketFactory; |
|||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
|||
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; |
|||
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; |
|||
import org.apache.http.impl.client.HttpClientBuilder; |
|||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
|||
import org.apache.http.message.BasicHeader; |
|||
import org.springframework.beans.factory.annotation.Value; |
|||
import org.springframework.boot.web.client.RestTemplateBuilder; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.http.HttpHeaders; |
|||
import org.springframework.http.HttpMethod; |
|||
import org.springframework.http.HttpRequest; |
|||
import org.springframework.http.HttpStatus; |
|||
import org.springframework.http.client.*; |
|||
import org.springframework.util.StreamUtils; |
|||
import org.springframework.web.client.RestTemplate; |
|||
|
|||
|
|||
import java.io.ByteArrayInputStream; |
|||
import java.io.IOException; |
|||
import java.io.InputStream; |
|||
import java.nio.charset.StandardCharsets; |
|||
import java.util.ArrayList; |
|||
import java.util.List; |
|||
|
|||
@Configuration |
|||
|
|||
public class RestTemplateConfig { |
|||
|
|||
@Value("${http.maxTotal}") |
|||
private Integer maxTotal; |
|||
|
|||
@Value("${http.defaultMaxPerRoute}") |
|||
private Integer defaultMaxPerRoute; |
|||
|
|||
@Value("${http.connectTimeout}") |
|||
private Integer connectTimeout; |
|||
|
|||
@Value("${http.connectionRequestTimeout}") |
|||
private Integer connectionRequestTimeout; |
|||
|
|||
@Value("${http.socketTimeout}") |
|||
private Integer socketTimeout; |
|||
|
|||
@Value("${http.staleConnectionCheckEnabled}") |
|||
private boolean staleConnectionCheckEnabled; |
|||
|
|||
@Value("${http.validateAfterInactivity}") |
|||
private Integer validateAfterInactivity; |
|||
|
|||
|
|||
@Bean |
|||
public RestTemplate restTemplate() { |
|||
return new RestTemplate(httpRequestFactory()); |
|||
} |
|||
|
|||
@Bean |
|||
public ClientHttpRequestFactory httpRequestFactory() { |
|||
return new HttpComponentsClientHttpRequestFactory(httpClient()); |
|||
} |
|||
|
|||
@Bean |
|||
public HttpClient httpClient() { |
|||
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() |
|||
.register("http", PlainConnectionSocketFactory.getSocketFactory()) |
|||
.register("https", SSLConnectionSocketFactory.getSocketFactory()) |
|||
.build(); |
|||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); |
|||
connectionManager.setMaxTotal(maxTotal); // 最大连接数
|
|||
connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute); //单个路由最大连接数
|
|||
connectionManager.setValidateAfterInactivity(validateAfterInactivity); // 最大空间时间
|
|||
|
|||
RequestConfig requestConfig = RequestConfig.custom() |
|||
.setSocketTimeout(socketTimeout) //服务器返回数据(response)的时间,超过抛出read timeout
|
|||
.setConnectTimeout(connectTimeout) //连接上服务器(握手成功)的时间,超出抛出connect timeout
|
|||
.setStaleConnectionCheckEnabled(staleConnectionCheckEnabled) // 提交前检测是否可用
|
|||
.setConnectionRequestTimeout(connectionRequestTimeout)//从连接池中获取连接的超时时间,超时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool
|
|||
.build(); |
|||
|
|||
//headers
|
|||
List<Header> headers = new ArrayList<>(); |
|||
headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36")); |
|||
headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate")); |
|||
headers.add(new BasicHeader("Accept-Language", "zh-CN")); |
|||
headers.add(new BasicHeader("Connection", "Keep-Alive")); |
|||
headers.add(new BasicHeader("Content-type", "application/json;charset=UTF-8")); |
|||
|
|||
return HttpClientBuilder.create() |
|||
.setDefaultRequestConfig(requestConfig) |
|||
.setConnectionManager(connectionManager) |
|||
.setDefaultHeaders(headers) |
|||
// 保持长连接配置,需要在头添加Keep-Alive
|
|||
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) |
|||
//重试次数,默认是3次,没有开启
|
|||
.setRetryHandler(new DefaultHttpRequestRetryHandler(2, true)) |
|||
.build(); |
|||
} |
|||
@Bean |
|||
public RestTemplate restTemplate(RestTemplateBuilder builder) { |
|||
return builder |
|||
.requestFactory(() -> new HttpComponentsClientHttpRequestFactory(httpClient())) |
|||
.interceptors(new CustomClientHttpRequestInterceptor()) |
|||
.build(); |
|||
} |
|||
@Slf4j |
|||
static class CustomClientHttpRequestInterceptor implements ClientHttpRequestInterceptor { |
|||
@Override |
|||
@NonNull |
|||
public ClientHttpResponse intercept(HttpRequest request, @NonNull byte[] bytes, @NonNull ClientHttpRequestExecution execution) throws IOException { |
|||
log.info("HTTP Method: {}, URI: {}, Headers: {}", request.getMethod(), request.getURI(), request.getHeaders()); |
|||
request.getMethod(); |
|||
if (request.getMethod().equals(HttpMethod.POST)) { |
|||
log.info("HTTP body: {}", new String(bytes, StandardCharsets.UTF_8)); |
|||
} |
|||
|
|||
ClientHttpResponse response = execution.execute(request, bytes); |
|||
ClientHttpResponse responseWrapper = new BufferingClientHttpResponseWrapper(response); |
|||
|
|||
String body = StreamUtils.copyToString(responseWrapper.getBody(), StandardCharsets.UTF_8); |
|||
log.info("RESPONSE body: {}", body); |
|||
|
|||
return responseWrapper; |
|||
} |
|||
} |
|||
static class BufferingClientHttpResponseWrapper implements ClientHttpResponse { |
|||
|
|||
private final ClientHttpResponse response; |
|||
private byte[] body; |
|||
|
|||
BufferingClientHttpResponseWrapper(ClientHttpResponse response) { |
|||
this.response = response; |
|||
} |
|||
|
|||
// @NonNull
|
|||
// public HttpStatusCode getStatusCode() throws IOException {
|
|||
// return this.response.getStatusCode();
|
|||
// }
|
|||
|
|||
@Override |
|||
public HttpStatus getStatusCode() throws IOException { |
|||
return this.response.getStatusCode(); |
|||
} |
|||
|
|||
@Override |
|||
public int getRawStatusCode() throws IOException { |
|||
return this.response.getRawStatusCode(); |
|||
} |
|||
|
|||
@NonNull |
|||
public String getStatusText() throws IOException { |
|||
return this.response.getStatusText(); |
|||
} |
|||
|
|||
@NonNull |
|||
public HttpHeaders getHeaders() { |
|||
return this.response.getHeaders(); |
|||
} |
|||
|
|||
@NonNull |
|||
public InputStream getBody() throws IOException { |
|||
if (this.body == null) { |
|||
this.body = StreamUtils.copyToByteArray(this.response.getBody()); |
|||
} |
|||
return new ByteArrayInputStream(this.body); |
|||
} |
|||
|
|||
public void close() { |
|||
this.response.close(); |
|||
} |
|||
} |
|||
|
|||
|
|||
} |
@ -0,0 +1,78 @@ |
|||
package com.example.guoyan.config; |
|||
|
|||
import com.example.guoyan.common.JacksonObjectMapper; |
|||
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.cache.annotation.EnableCaching; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
import org.springframework.http.converter.HttpMessageConverter; |
|||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; |
|||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; |
|||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; |
|||
import springfox.documentation.builders.ApiInfoBuilder; |
|||
import springfox.documentation.builders.PathSelectors; |
|||
import springfox.documentation.builders.RequestHandlerSelectors; |
|||
import springfox.documentation.service.ApiInfo; |
|||
import springfox.documentation.spi.DocumentationType; |
|||
import springfox.documentation.spring.web.plugins.Docket; |
|||
import springfox.documentation.swagger2.annotations.EnableSwagger2; |
|||
|
|||
import java.util.List; |
|||
|
|||
|
|||
/** |
|||
* 前端资源放行配置类 |
|||
* */ |
|||
@Configuration |
|||
@Slf4j |
|||
@EnableSwagger2 |
|||
@EnableKnife4j |
|||
public class WebMvcConfig extends WebMvcConfigurationSupport { |
|||
/** |
|||
* 设置静态资源映射 |
|||
* */ |
|||
@Override |
|||
protected void addResourceHandlers(ResourceHandlerRegistry registry) { |
|||
//添加映射
|
|||
log.info("映射资源开始"); |
|||
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); |
|||
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); |
|||
registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/"); |
|||
registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/"); |
|||
} |
|||
|
|||
/** |
|||
* 扩展mvc框架的消息转换器 |
|||
* @param converters |
|||
*/ |
|||
@Override |
|||
protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) { |
|||
log.info("扩展消息转换器..........."); |
|||
//创建消息转换器对象
|
|||
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); |
|||
//设置对象转换器,底层使用我们定义的对象转换器通过JackJson将java对象转换为json
|
|||
messageConverter.setObjectMapper(new JacksonObjectMapper()); |
|||
//将上面的消息转换器对象追加到mvc框架的转换器集合中
|
|||
converters.add(0,messageConverter); //0表示最先执行我们的追加的转换器
|
|||
} |
|||
|
|||
@Bean |
|||
public Docket createRestApi() { |
|||
// 文档类型
|
|||
return new Docket(DocumentationType.SWAGGER_2) |
|||
.apiInfo(apiInfo()) |
|||
.select() |
|||
.apis(RequestHandlerSelectors.basePackage("com.cc.controller")) |
|||
.paths(PathSelectors.any()) |
|||
.build(); |
|||
} |
|||
|
|||
private ApiInfo apiInfo() { |
|||
return new ApiInfoBuilder() |
|||
.title("接口文档") |
|||
.version("1.0") |
|||
.description("接口文档") |
|||
.build(); |
|||
} |
|||
} |
@ -0,0 +1,56 @@ |
|||
package com.example.guoyan.entity; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import javax.validation.constraints.NotNull; |
|||
|
|||
@Data |
|||
public class ContractInfo { |
|||
|
|||
/** |
|||
*合同编号 |
|||
*/ |
|||
@NotNull(message = "contractCode 必填") |
|||
private String contractCode; |
|||
/** |
|||
* 合同名称 |
|||
*/ |
|||
@NotNull(message = "contractName 必填") |
|||
private String contractName; |
|||
/** |
|||
* 项目编号 |
|||
*/ |
|||
@NotNull(message = "projectNo 必填") |
|||
private String projectNo; |
|||
/** |
|||
* 高新 1 是 0 否 |
|||
*/ |
|||
@NotNull(message = "highTech 必填") |
|||
private Integer highTech; |
|||
/** |
|||
* 中标方式 字典-中标方式 |
|||
*/ |
|||
@NotNull(message = "winningBidWay 必填") |
|||
private String winningBidWay; |
|||
|
|||
/** |
|||
* 合同金额 |
|||
*/ |
|||
private String contractAmount; |
|||
|
|||
/** |
|||
* 签出 |
|||
*/ |
|||
@NotNull(message ="signOut 必填" ) |
|||
private Integer signOut; |
|||
/** |
|||
* 签回 |
|||
*/ |
|||
@NotNull(message = "signIn 必填 ") |
|||
private Integer signIn; |
|||
/** |
|||
* 确认日期 |
|||
*/ |
|||
@NotNull(message = "confirmDate 必填") |
|||
private String confirmDate; |
|||
} |
@ -0,0 +1,37 @@ |
|||
package com.example.guoyan.entity; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 保存流程已读日志(Readlog)实体类 |
|||
* |
|||
* @author makejava |
|||
* @since 2024-01-09 16:15:55 |
|||
*/ |
|||
@Data |
|||
public class Readlog implements Serializable { |
|||
private static final long serialVersionUID = 778641858893674888L; |
|||
|
|||
private String id; |
|||
|
|||
private String dataid; |
|||
|
|||
private String staffid; |
|||
|
|||
private String stepid; |
|||
|
|||
private String readnum; |
|||
|
|||
private String adddate; |
|||
|
|||
private String lastaccessdate; |
|||
|
|||
private String memo; |
|||
|
|||
private String resid; |
|||
|
|||
|
|||
} |
|||
|
@ -0,0 +1,64 @@ |
|||
package com.example.guoyan.entity; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* (Requestlog)实体类 |
|||
* |
|||
* @author makejava |
|||
* @since 2024-01-09 16:28:31 |
|||
*/ |
|||
@Data |
|||
public class Requestlog implements Serializable { |
|||
private static final long serialVersionUID = -12899290814932077L; |
|||
|
|||
private String requestid; |
|||
|
|||
private String staffid; |
|||
|
|||
private Integer isedit; |
|||
|
|||
private String createdate; |
|||
|
|||
private String stepid; |
|||
|
|||
private Integer ntype; |
|||
|
|||
private String info; |
|||
|
|||
private String attachids; |
|||
|
|||
private Integer istodo; |
|||
|
|||
private String typeinfo; |
|||
|
|||
private String id; |
|||
|
|||
private String nextstepid; |
|||
|
|||
private String clienttype; |
|||
|
|||
private String field1; |
|||
|
|||
private String field2; |
|||
|
|||
private String field3; |
|||
|
|||
private String field4; |
|||
|
|||
private String field5; |
|||
|
|||
private Integer intfield1; |
|||
|
|||
private Integer intfield2; |
|||
|
|||
private Integer intfield3; |
|||
|
|||
private String agentbyid; |
|||
|
|||
private String oristepid; |
|||
|
|||
} |
|||
|
@ -0,0 +1,52 @@ |
|||
package com.example.guoyan.entity; |
|||
|
|||
import com.baomidou.mybatisplus.extension.activerecord.Model; |
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 保存04节点审批人及操作 实体表 |
|||
* |
|||
* @author makejava |
|||
* @since 2024-01-09 16:20:14 |
|||
*/ |
|||
@Data |
|||
public class Requestoperator implements Serializable { |
|||
|
|||
private String id; |
|||
|
|||
private String requestid; |
|||
|
|||
private String stepid; |
|||
|
|||
private String stepoperid; |
|||
|
|||
private Integer issubmit; |
|||
|
|||
private String agentbyid; |
|||
|
|||
private String staffid; |
|||
|
|||
private String receivedate; |
|||
|
|||
private String submitdate; |
|||
|
|||
private Integer opertype; |
|||
|
|||
private Integer isremind; |
|||
|
|||
private String lastreminddate; |
|||
|
|||
private Integer isorioperator; |
|||
|
|||
private String wfagentid; |
|||
|
|||
private String oristepid; |
|||
|
|||
private Integer dsporder; |
|||
|
|||
private String dingrecordid; |
|||
|
|||
} |
|||
|
@ -0,0 +1,31 @@ |
|||
package com.example.guoyan.entity; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* (Requeststatus)实体类 |
|||
* |
|||
* @author makejava |
|||
* @since 2024-01-09 16:26:51 |
|||
*/ |
|||
@Data |
|||
public class Requeststatus implements Serializable { |
|||
private static final long serialVersionUID = -31534422220247331L; |
|||
|
|||
private String id; |
|||
|
|||
private String requestid; |
|||
|
|||
private String stepid; |
|||
|
|||
private String prestepid; |
|||
|
|||
private Integer nstatus; |
|||
|
|||
private String modifydate; |
|||
|
|||
|
|||
} |
|||
|
@ -0,0 +1,109 @@ |
|||
package com.example.guoyan.entity; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 开票申请审批(ScKpsqsp)实体类 |
|||
* |
|||
* @author makejava |
|||
* @since 2024-01-09 16:25:35 |
|||
*/ |
|||
@Data |
|||
public class ScKpsqsp implements Serializable { |
|||
private static final long serialVersionUID = 466211042633160123L; |
|||
|
|||
private String requestid; |
|||
|
|||
private String id; |
|||
|
|||
private String cjr; |
|||
|
|||
private String khx; |
|||
|
|||
private String nsrsbh; |
|||
|
|||
private String zh; |
|||
|
|||
private String dh; |
|||
|
|||
private String dz; |
|||
|
|||
private String kprq; |
|||
|
|||
private String fphm; |
|||
|
|||
private String ssbm; |
|||
|
|||
private Double ssje; |
|||
|
|||
private String bz; |
|||
|
|||
private String fpfj; |
|||
|
|||
private String fplx; |
|||
|
|||
private String tssm; |
|||
|
|||
private String gw; |
|||
|
|||
private String cjrq; |
|||
|
|||
private String xmmc; |
|||
|
|||
private String xmbh; |
|||
|
|||
private String xsfzr; |
|||
|
|||
private String xmfzr; |
|||
|
|||
private String qy; |
|||
|
|||
private String xmlx; |
|||
|
|||
private String sfgx; |
|||
|
|||
private String bckpbl; |
|||
|
|||
private String htbh; |
|||
|
|||
private String ljkpbl000; |
|||
|
|||
private String htskjd; |
|||
|
|||
private Double htje0y0; |
|||
|
|||
private String xmjd; |
|||
|
|||
private Double kpje0y0; |
|||
|
|||
private String schz; |
|||
|
|||
private String zmwj; |
|||
|
|||
private String kpnr; |
|||
|
|||
private String sl; |
|||
|
|||
private String fpzl; |
|||
|
|||
private String kpbl0; |
|||
|
|||
private String kpbl; |
|||
|
|||
private Double kpje; |
|||
|
|||
private String kpdwmc; |
|||
|
|||
private String skrq; |
|||
|
|||
private Double qrsr; |
|||
|
|||
private String qrrq; |
|||
|
|||
private String csry; |
|||
|
|||
|
|||
} |
|||
|
@ -0,0 +1,42 @@ |
|||
package com.example.guoyan.entity; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* 更新sc_xglcb(当前节点、是否归档、最后提交人、最后提交时间) 相关流程(ScXglc)实体类 |
|||
* |
|||
* @author makejava |
|||
* @since 2024-01-09 16:23:49 |
|||
*/ |
|||
@Data |
|||
public class ScXglc implements Serializable { |
|||
private static final long serialVersionUID = 122201132500120334L; |
|||
|
|||
private String requestid; |
|||
|
|||
private String id; |
|||
|
|||
private String cjr; |
|||
|
|||
private String cjrq; |
|||
|
|||
private String dqjd; |
|||
|
|||
private String xm; |
|||
|
|||
private String lc; |
|||
|
|||
private String lcmc; |
|||
|
|||
private String gxry; |
|||
|
|||
private String sfgd; |
|||
|
|||
private String zhtjsj; |
|||
|
|||
private String zhtjr; |
|||
|
|||
} |
|||
|
@ -0,0 +1,55 @@ |
|||
package com.example.guoyan.entity; |
|||
|
|||
import lombok.Data; |
|||
|
|||
import java.io.Serializable; |
|||
|
|||
/** |
|||
* (Wfrequest)实体类 |
|||
* |
|||
* @author makejava |
|||
* @since 2024-01-09 16:27:40 |
|||
*/ |
|||
@Data |
|||
public class Wfrequest implements Serializable { |
|||
private static final long serialVersionUID = 783536966169674807L; |
|||
|
|||
private String name; |
|||
|
|||
private String workflowid; |
|||
|
|||
private String dataid; |
|||
|
|||
private String createdate; |
|||
|
|||
private String lastmodifydate; |
|||
|
|||
private String creatorid; |
|||
|
|||
private String id; |
|||
|
|||
private String laststaffid; |
|||
|
|||
private String requestnum; |
|||
|
|||
private String field1; |
|||
|
|||
private String field2; |
|||
|
|||
private String field3; |
|||
|
|||
private String field4; |
|||
|
|||
private String field5; |
|||
|
|||
private Integer intfield1; |
|||
|
|||
private Integer intfield2; |
|||
|
|||
private Integer intfield3; |
|||
|
|||
private Integer status; |
|||
|
|||
|
|||
} |
|||
|
@ -0,0 +1,9 @@ |
|||
package com.example.guoyan.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.example.guoyan.entity.Readlog; |
|||
import org.apache.ibatis.annotations.Mapper; |
|||
|
|||
@Mapper |
|||
public interface ReadlogMapper extends BaseMapper<Readlog> { |
|||
} |
@ -0,0 +1,7 @@ |
|||
package com.example.guoyan.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.example.guoyan.entity.Requestlog; |
|||
|
|||
public interface RequestlogMapper extends BaseMapper<Requestlog> { |
|||
} |
@ -0,0 +1,7 @@ |
|||
package com.example.guoyan.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.example.guoyan.entity.Requestoperator; |
|||
|
|||
public interface RequestoperatorMapper extends BaseMapper<Requestoperator> { |
|||
} |
@ -0,0 +1,7 @@ |
|||
package com.example.guoyan.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.example.guoyan.entity.Requeststatus; |
|||
|
|||
public interface RequeststatusMapper extends BaseMapper<Requeststatus> { |
|||
} |
@ -0,0 +1,4 @@ |
|||
package com.example.guoyan.mapper; |
|||
|
|||
public interface ScKpsqspMapper { |
|||
} |
@ -0,0 +1,7 @@ |
|||
package com.example.guoyan.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.example.guoyan.entity.ScXglc; |
|||
|
|||
public interface ScXglcMapper extends BaseMapper<ScXglc> { |
|||
} |
@ -0,0 +1,7 @@ |
|||
package com.example.guoyan.mapper; |
|||
|
|||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
|||
import com.example.guoyan.entity.Wfrequest; |
|||
|
|||
public interface WfrequestMapper extends BaseMapper<Wfrequest> { |
|||
} |
@ -0,0 +1,12 @@ |
|||
package com.example.guoyan.response; |
|||
|
|||
import lombok.Data; |
|||
|
|||
@Data |
|||
public class ResponseBeanForBeiJing { |
|||
|
|||
private Integer Status; |
|||
private String code; |
|||
private Object message; |
|||
private Object data; |
|||
} |
@ -0,0 +1,19 @@ |
|||
package com.example.guoyan.scheduled; |
|||
|
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.scheduling.annotation.Scheduled; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.Date; |
|||
|
|||
@Component |
|||
@Slf4j |
|||
public class ProcessScheduled { |
|||
|
|||
@Scheduled(cron = "0 0/5 * * * ?") |
|||
public void invoice_request_Process_Scheduled(){ |
|||
//先查询开票申请的流程
|
|||
|
|||
log.info(new Date ().toString()); |
|||
} |
|||
} |
@ -0,0 +1,32 @@ |
|||
package com.example.guoyan.utils; |
|||
|
|||
import java.security.MessageDigest; |
|||
import java.security.NoSuchAlgorithmException; |
|||
|
|||
public class MD5Util { |
|||
public static String getMD5(String password) { |
|||
try { |
|||
// 得到一个信息摘要器
|
|||
MessageDigest digest = MessageDigest.getInstance("md5"); |
|||
byte[] result = digest.digest(password.getBytes()); |
|||
StringBuffer buffer = new StringBuffer(); |
|||
// 把每一个byte 做一个与运算 0xff;
|
|||
for (byte b : result) { |
|||
// 与运算
|
|||
int number = b & 0xff;// 加盐
|
|||
String str = Integer.toHexString(number); |
|||
if (str.length() == 1) { |
|||
buffer.append("0"); |
|||
} |
|||
buffer.append(str); |
|||
} |
|||
|
|||
// 标准的md5加密后的结果
|
|||
return buffer.toString(); |
|||
} catch (NoSuchAlgorithmException e) { |
|||
e.printStackTrace(); |
|||
return ""; |
|||
} |
|||
} |
|||
|
|||
} |
@ -0,0 +1,43 @@ |
|||
package com.example.guoyan.utils; |
|||
|
|||
import java.util.Random; |
|||
|
|||
/** |
|||
* 随机生成验证码工具类 |
|||
*/ |
|||
public class ValidateCodeUtils { |
|||
/** |
|||
* 随机生成验证码 |
|||
* @param length 长度为4位或者6位 |
|||
* @return |
|||
*/ |
|||
public static Integer generateValidateCode(int length){ |
|||
Integer code =null; |
|||
if(length == 4){ |
|||
code = new Random().nextInt(9999);//生成随机数,最大为9999
|
|||
if(code < 1000){ |
|||
code = code + 1000;//保证随机数为4位数字
|
|||
} |
|||
}else if(length == 6){ |
|||
code = new Random().nextInt(999999);//生成随机数,最大为999999
|
|||
if(code < 100000){ |
|||
code = code + 100000;//保证随机数为6位数字
|
|||
} |
|||
}else{ |
|||
throw new RuntimeException("只能生成4位或6位数字验证码"); |
|||
} |
|||
return code; |
|||
} |
|||
|
|||
/** |
|||
* 随机生成指定长度字符串验证码 |
|||
* @param length 长度 |
|||
* @return |
|||
*/ |
|||
public static String generateValidateCode4String(int length){ |
|||
Random rdm = new Random(); |
|||
String hash1 = Integer.toHexString(rdm.nextInt()); |
|||
String capstr = hash1.substring(0, length); |
|||
return capstr; |
|||
} |
|||
} |
@ -0,0 +1,9 @@ |
|||
spring: |
|||
datasource: |
|||
druid: |
|||
driver-class-name: com.mysql.cj.jdbc.Driver |
|||
# |
|||
#serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true |
|||
url: jdbc:mysql://116.62.210.190:3306/guoyantest?autoReconnect=true&useUnicode=true&characterEncoding=UTF8&mysqlEncoding=utf8&zeroDateTimeBehavior=convertToNull |
|||
username: test |
|||
password: Jyy83086775 |
@ -0,0 +1,9 @@ |
|||
spring: |
|||
datasource: |
|||
druid: |
|||
driver-class-name: com.mysql.cj.jdbc.Driver |
|||
# |
|||
#serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true |
|||
url: jdbc:mysql://116.62.210.190:3306/guoyan?autoReconnect=true&useUnicode=true&characterEncoding=UTF8&mysqlEncoding=utf8&zeroDateTimeBehavior=convertToNull |
|||
username: root |
|||
password: Guoyan83086775 |
@ -1 +0,0 @@ |
|||
|
@ -0,0 +1,33 @@ |
|||
server: |
|||
port: 9001 |
|||
|
|||
spring: |
|||
application: |
|||
name: Guoyan |
|||
profiles: |
|||
active: dev |
|||
# 是否允许定义重名的bean对象覆盖原有的bean (spring boot默认是false) |
|||
# main: |
|||
# allow-bean-definition-overriding: true |
|||
|
|||
mybatis-plus: |
|||
configuration: |
|||
#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,开启按照驼峰命名法映射 |
|||
map-underscore-to-camel-case: true |
|||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl |
|||
global-config: |
|||
db-config: |
|||
id-type: ASSIGN_UUID |
|||
|
|||
logging: |
|||
# 配置日志文件存储位置 |
|||
file: |
|||
path: F:\log |
|||
http: |
|||
maxTotal: 100 #最大连接数 |
|||
defaultMaxPerRoute: 20 #并发数 |
|||
connectTimeout: 1000 #创建连接的最长时间 |
|||
connectionRequestTimeout: 500 #从连接池中获取到连接的最长时间 |
|||
socketTimeout: 10000 #数据传输的最长时间 |
|||
staleConnectionCheckEnabled: true #提交请求前测试连接是否可用 |
|||
validateAfterInactivity: 3000000 #可用空闲连接过期时间,重用空闲连接时会先检查是否空闲时间超过这个时间,如果超过,释放socket重新建立 |
@ -0,0 +1,81 @@ |
|||
package com.example.guoyan; |
|||
|
|||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|||
import com.example.guoyan.common.Result; |
|||
import com.example.guoyan.entity.ContractInfo; |
|||
import com.example.guoyan.entity.Readlog; |
|||
import com.example.guoyan.mapper.ReadlogMapper; |
|||
import com.example.guoyan.response.ResponseBeanForBeiJing; |
|||
import lombok.extern.slf4j.Slf4j; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.http.HttpMethod; |
|||
import org.springframework.http.HttpEntity; |
|||
import org.springframework.http.HttpHeaders; |
|||
import org.springframework.web.bind.annotation.GetMapping; |
|||
import org.springframework.web.bind.annotation.RequestMapping; |
|||
import org.springframework.web.bind.annotation.RestController; |
|||
import org.springframework.web.client.RestTemplate; |
|||
|
|||
import javax.annotation.Resource; |
|||
import java.util.HashMap; |
|||
import java.util.List; |
|||
|
|||
@RestController |
|||
@RequestMapping("/test") |
|||
@Slf4j |
|||
public class TestController { |
|||
@Resource |
|||
private RestTemplate restTemplate; |
|||
@Autowired |
|||
private ReadlogMapper readlogMapper; |
|||
|
|||
@GetMapping() |
|||
public Result<String> upLoadFile(){ |
|||
String url = "http://123.57.82.48:13310/api/auth/login"; |
|||
|
|||
|
|||
//提交参数设置
|
|||
HashMap<String, String> map = new HashMap<>(); |
|||
map.put("username", "0519999"); |
|||
map.put("password", "123456"); |
|||
|
|||
//发起请求
|
|||
ResponseBeanForBeiJing responseBean = restTemplate.postForObject(url,map, ResponseBeanForBeiJing.class); |
|||
System.out.println(responseBean.toString()); |
|||
String data = responseBean.getData().toString(); |
|||
|
|||
HttpHeaders headers = new HttpHeaders(); |
|||
//headers.setBearerAuth(data);
|
|||
headers.set("Authorization",data); |
|||
// headers.setContentType(MediaType.APPLICATION_JSON);
|
|||
ContractInfo contractInfo = new ContractInfo(); |
|||
contractInfo.setContractCode("83086775"); |
|||
contractInfo.setContractName("测试合同"); |
|||
contractInfo.setConfirmDate("2023-01-02"); |
|||
contractInfo.setProjectNo("83086775"); |
|||
contractInfo.setHighTech(1); |
|||
contractInfo.setSignIn(1); |
|||
contractInfo.setSignOut(1); |
|||
contractInfo.setWinningBidWay("公开招标"); |
|||
// 组装请求体
|
|||
HttpEntity<ContractInfo> request = new HttpEntity<>(contractInfo, headers); |
|||
try{ |
|||
Object object = restTemplate.exchange("http://123.57.82.48:13310/api/nb/contract", HttpMethod.POST, request, Object.class); |
|||
System.out.println(object.toString()); |
|||
}catch (Exception E){ |
|||
log.info(E.getMessage()); |
|||
} |
|||
log.info("测试成功"); |
|||
return Result.success("成功"); |
|||
} |
|||
|
|||
@GetMapping("/t") |
|||
public Result<String> test(){ |
|||
LambdaQueryWrapper<Readlog> readlogLambdaQueryWrapper = new LambdaQueryWrapper(); |
|||
readlogLambdaQueryWrapper.eq(Readlog::getId,"0008e8b65fd7e3c55354664279ed7b9b"); |
|||
List<Readlog> readlogs = readlogMapper.selectList(readlogLambdaQueryWrapper); |
|||
log.info(readlogs.toString()); |
|||
log.info("测试成功"); |
|||
return Result.success("成功"); |
|||
} |
|||
} |
Loading…
Reference in new issue