Commit 43cdaff0 authored by R10's avatar R10

project init

parents
/log/
/.idea/
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
This diff is collapsed.
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="AdditionalModuleElements">
<content url="file://$MODULE_DIR$" dumb="true">
<sourceFolder url="file://$MODULE_DIR$/src/main/test" isTestSource="true" />
</content>
</component>
</module>
\ No newline at end of file
<?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>
<groupId>com.tools</groupId>
<artifactId>hxyj-api</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.8.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--打成War包,排除内置Tomcat容器-->
<!-- <scope>provided</scope>-->
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.shiro</groupId>-->
<!-- <artifactId>shiro-spring-boot-web-starter</artifactId>-->
<!-- <version>1.4.1</version>-->
<!-- </dependency>-->
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
</dependency>
<!-- 邮件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.14</version>
</dependency>
<!-- 阿里云存储SDK -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.6.0</version>
</dependency>
<!-- Sa-Token 权限认证, 在线文档:http://sa-token.dev33.cn/ -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot-starter</artifactId>
<version>1.28.0</version>
</dependency>
<!-- Sa-Token 整合jwt -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
<version>1.28.0</version>
</dependency>
<!-- Sa-Token 整合 Redis (使用jdk默认序列化方式) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-dao-redis</artifactId>
<version>1.28.0</version>
</dependency>
<!-- 提供Redis连接池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>com.belerweb</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>25.1-jre</version>
</dependency>
<!-- fastdfs SDK -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.6</version>
</dependency>
<!--爬虫-->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
<!--小程序工具包-->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId>
<version>3.6.0</version>
</dependency>
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>emoji-java</artifactId>
<version>5.1.1</version>
</dependency>
<!--分布式-->
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>2.11.5</version>
</dependency>
<!--图片处理-->
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.11</version>
</dependency>
<!--定时任务-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<!--分布式文件服务SDK-->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.0.2</version>
</dependency>
<!--百度人工智能SDK-->
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.12.0</version>
</dependency>
<!-- swagger2 文档 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.6</version>
</dependency>
</dependencies>
<build>
<finalName>picture-bed</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.7.RELEASE</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package com.tools;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableScheduling;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* 启动类
*/
@EnableCaching
@EnableScheduling
@EnableSwagger2
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
logger.info("这个是航行印记项目");
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}
package com.tools.common.aop;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.RateLimiter;
import com.tools.common.exception.RrException;
import com.tools.common.util.IPUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import java.lang.reflect.Method;
import java.util.concurrent.TimeUnit;
/**
* 限流 AOP
*
*
*/
@Aspect
@Configuration
public class LimitAspect {
/**
* 根据IP分不同的令牌桶, 每天自动清理缓存 每秒只发出6个令牌
*/
private static final LoadingCache<String, RateLimiter> caches = CacheBuilder.newBuilder()
.maximumSize(1000)
.expireAfterWrite(1, TimeUnit.DAYS)
.build(new CacheLoader<String, RateLimiter>() {
@Override
public RateLimiter load(String key) {
return RateLimiter.create(6);
}
});
/**
* Service层切点 限流
*/
@Pointcut("@annotation(com.tools.common.aop.ServiceLimit)")
public void ServiceAspect() {
}
@Around("ServiceAspect()")
public Object around(ProceedingJoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
ServiceLimit limitAnnotation = method.getAnnotation(ServiceLimit.class);
ServiceLimit.LimitType limitType = limitAnnotation.limitType();
String key = limitAnnotation.key();
Object obj;
try {
if(limitType.equals(ServiceLimit.LimitType.IP)){
key = IPUtils.getIpAddr();
}
RateLimiter rateLimiter = caches.get(key);
Boolean flag = rateLimiter.tryAcquire();
if(flag){
obj = joinPoint.proceed();
}else{
throw new RrException("小同志,你访问的太频繁了");
}
} catch (Throwable e) {
e.printStackTrace();
throw new RrException("系统异常,请联系管理员同志");
}
return obj;
}
}
\ No newline at end of file
package com.tools.common.aop;
import java.lang.annotation.*;
/**
* 自定义注解 限流
*
*
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ServiceLimit {
/**
* 描述
*/
String description() default "";
/**
* key
*/
String key() default "";
/**
* 类型
*/
LimitType limitType() default LimitType.CUSTOMER;
enum LimitType {
/**
* 自定义key
*/
CUSTOMER,
/**
* 根据请求者IP
*/
IP
}
}
\ No newline at end of file
package com.tools.common.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RestController;
/**
* 通用Controller
*
*
*/
@RestController
public class AbstractController {
protected Logger logger = LoggerFactory.getLogger(getClass());
}
\ No newline at end of file
package com.tools.common.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@Configuration
@EnableJpaAuditing(auditorAwareRef="saAuditorAware")
public class EnableJpaAuditingConfig {
}
\ No newline at end of file
package com.tools.common.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* file映射项目外文件夹
*
*
*/
@Configuration
public class FileConfig implements WebMvcConfigurer {
@Value("${file.path}")
private String filePath;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/file/**").addResourceLocations("file:" + filePath+"/");
}
}
package com.tools.common.config;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
/**
* 通用访问拦截匹配
*
*
*/
@Controller
public class IndexController {
@GetMapping("login.html")
public String login() { return "login"; }
@GetMapping("index.html")
public String index() { return "index"; }
@GetMapping("console.html")
public String console() { return "console"; }
@GetMapping("{module}/{url}.html")
public String page(@PathVariable("module") String module,@PathVariable("url") String url) {
return module + "/" + url;
}
@GetMapping("{module}/{sub}/{url}.html")
public String page(@PathVariable("module") String module,
@PathVariable("url") String url,
@PathVariable("sub") String sub) {
return module + "/" + sub + "/" + url;
}
@GetMapping("{module}/{sub}/{smallSub}/{url}.html")
public String page(@PathVariable("module") String module,
@PathVariable("url") String url,
@PathVariable("sub") String sub,
@PathVariable("smallSub") String smallSub) {
return module + "/" + sub + "/" + smallSub + "/" + url;
}
}
\ No newline at end of file
package com.tools.common.config;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
/**
* redis配置类
*
*
*/
@Configuration
@EnableCaching
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(60))
.disableCachingNullValues();
return RedisCacheManager.builder(factory)
.cacheDefaults(config)
.transactionAware()
.build();
}
/**
* retemplate相关配置
* @param factory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
}
package com.tools.common.config;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
public class SaAuditorAware implements AuditorAware<Long> {
@Override
public Optional<Long> getCurrentAuditor() {
//return Optional.of((String) SecurityUtils.getSubject().getPrincipal());
Long userId = StpUtil.getLoginIdAsLong();
return Optional.of(userId);
}
}
\ No newline at end of file
package com.tools.common.config;
import cn.dev33.satoken.jwt.StpLogicJwtForStyle;
import cn.dev33.satoken.stp.StpLogic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class SaTokenConfigure implements WebMvcConfigurer {
/**
* 注册Sa-Token的拦截器
*
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册路由拦截器,自定义认证规则
// registry.addInterceptor(new SaRouteInterceptor((req, res, handler) ->
// {
// // 登录认证 -- 拦截所有路由,并排除/login 用于开放登录
// SaRouter.match("/**", "/user/login", r -> StpUtil.checkLogin());
// SaRouter.match("/systemConfig/**", () -> StpUtil.checkRoleOr("admin", "salesman"));
// SaRouter.match("/customer/addCustomer", () -> StpUtil.checkRoleOr("admin", "salesman"));
// SaRouter.match("/sales-man/**", () -> StpUtil.checkRoleOr("admin", "salesman"));
// // 权限认证:匹配restful风格路由、多个条件一起使用
// SaRouter.match(SaHttpMethod.GET).match("/admins").check(r ->StpUtil.checkPermission("admin:list"));
// SaRouter.match(SaHttpMethod.POST).match("/admin").check(r ->StpUtil.checkPermission("admin:add"));
// SaRouter.match(SaHttpMethod.PUT).match("/admin").check(r ->StpUtil.checkPermission("admin:edit"));
// SaRouter.match(SaHttpMethod.GET).match("/admin/{id}").check(r ->StpUtil.checkPermission("admin:query"));
// SaRouter.match(SaHttpMethod.DELETE).match("/admin/{id}").check(r ->StpUtil.checkPermission("admin:del"));
//
// SaRouter.match(SaHttpMethod.GET).match("/roles").check(r ->StpUtil.checkPermission("role:list"));
// SaRouter.match(SaHttpMethod.POST).match("/role").check(r ->StpUtil.checkPermission("role:add"));
// SaRouter.match(SaHttpMethod.PUT).match("/role").check(r ->StpUtil.checkPermission("role:edit"));
// SaRouter.match(SaHttpMethod.GET).match("/role/{id}").check(r ->StpUtil.checkPermission("role:query"));
// SaRouter.match(SaHttpMethod.DELETE).match("/role/{id}").check(r ->StpUtil.checkPermission("role:del"));
//
// SaRouter.match(SaHttpMethod.GET).match("/menus").check(r ->StpUtil.checkPermission("menu:list"));
// SaRouter.match(SaHttpMethod.POST).match("/menu").check(r ->StpUtil.checkPermission("menu:add"));
// SaRouter.match(SaHttpMethod.PUT).match("/menu").check(r ->StpUtil.checkPermission("menu:edit"));
// SaRouter.match(SaHttpMethod.GET).match("/menu/{id}").check(r ->StpUtil.checkPermission("menu:query"));
// SaRouter.match(SaHttpMethod.DELETE).match("/menu/{id}").check(r ->StpUtil.checkPermission("menu:del"));
// })).addPathPatterns("/**").excludePathPatterns("/price/**");
}
@Bean
public StpLogic getStpLogicJwt() {
return new StpLogicJwtForStyle();
}
}
package com.tools.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/**
* API 配置
*
*/
@Configuration
public class SwaggerConfig {
@Bean
public Docket appApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("系统应用API接口文档")
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.tools.module.app"))
.paths(PathSelectors.any()).build();
}
@Bean
public Docket sysApi() {
return new Docket(DocumentationType.SWAGGER_2)
.groupName("系统配置API接口文档")
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.basePackage("com.tools.module.sys"))
.paths(PathSelectors.any()).build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("炒鸡工具箱")
.description("一个能够让程序猿快速开发的炒鸡工具箱")
.termsOfServiceUrl("http://blog.52itstyle.vip")
.contact(new Contact("爪哇笔记 ", "http://blog.52itstyle.vip", "345849402@qq.com"))
.version("1.0").build();
}
}
package com.tools.common.constant;
/**
* 系统提示静态变量
*
*
*/
public class MsgConstant {
/**
* 操作成功
*/
public static final String MSG_OPERATION_SUCCESS = "操作成功!";
/**
* 操作失败
*/
public static final String MSG_OPERATION_FAILED = "操作失败!";
/**
* 删除时,提示有子节点无法删除
*/
public static final String MSG_HAS_CHILD = "操作失败,当前所选数据有子节点数据!";
/**
* 加载表单数据错误提示
*/
public static final String MSG_INIT_FORM = "初始化表单数据失败,请重试!";
}
package com.tools.common.constant;
/**
* 系统级静态变量
*
*/
public class SystemConstant {
public class IsDeleted{
public static final String Y = "Y";
public static final String N = "N";
}
/**
* 文件分隔符
*/
public static final String SF_FILE_SEPARATOR = System.getProperty("file.separator");
/**
* 菜单类型
*/
public enum MenuType {
/**
* 目录
*/
CATALOG(0),
/**
* 菜单
*/
MENU(1),
/**
* 按钮
*/
BUTTON(2);
private final int value;
MenuType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
/**
* 通用字典
*/
public enum MacroType {
/**
* 类型
*/
TYPE(0),
/**
* 参数
*/
PARAM(1);
private final int value;
MacroType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
/**
* 通用变量,表示可用、禁用、显示、隐藏、是、否
*/
public enum StatusType {
/**
* 禁用,隐藏
*/
DISABLE(0),
/**
* 可用,显示
*/
ENABLE(1),
/**
* 显示
*/
SHOW(1),
/**
* 隐藏
*/
HIDDEN(0),
/**
* 是
*/
YES(1),
/**
* 否
*/
NO(0);
private final int value;
StatusType(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
}
package com.tools.common.dynamicquery;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import java.util.List;
/**
* 扩展SpringDataJpa, 支持动态jpql/nativesql查询并支持分页查询
*
*/
public interface DynamicQuery {
/**
* 保存
* @param entity
*/
void save(Object entity);
/**
* 更新
* @param entity
*/
void update(Object entity);
/**
* 执行nativeSql的update,delete操作
* @param nativeSql
* @param params
* @return
*/
int nativeExecuteUpdate(String nativeSql, Object... params);
/**
* 执行nativeSql统计查询
* @param nativeSql
* @param params 占位符参数(例如?1)绑定的参数值
* @return 统计条数
*/
Long nativeQueryCount(String nativeSql, Object... params);
/**
* 执行nativeSql查询一行
* @param resultClass 查询结果类型
* @param nativeSql
* @param params 占位符参数(例如?1)绑定的参数值
* @return
*/
<T> T nativeQuerySingleResult(Class<T> resultClass, String nativeSql, Object... params);
/**
* 执行nativeSql查询 List<Object[]>
* @param nativeSql
* @param params 占位符参数(例如?1)绑定的参数值
* @return
*/
<T> List<T> query(String nativeSql, Object... params);
/**
* 执行nativeSql查询
* @param resultClass
* @param nativeSql
* @param params 占位符参数(例如?1)绑定的参数值
* @return
*/
<T> List<T> query(Class<T> resultClass, String nativeSql, Object... params);
Long nativeQueryGetCount(String nativeSql, Object... params);
/**
* 执行nativeSql分页查询
* @param resultClass 查询结果类型
* @param pageable 分页数据
* @param nativeSql
* @param params 占位符参数(例如?1)绑定的参数值
* @return 分页对象
*/
<T> Page<T> nativeQuery(Class<T> resultClass, Pageable pageable, String nativeSql, Object... params);
/**
* 执行nativeSql分页查询
* @param resultClass
* @param pageable
* @param nativeSql
* @param params
* @param List<T>
* @return
*/
<T> List<T> nativeQueryPagingList(Class<T> resultClass, Pageable pageable, String nativeSql, Object... params);
<T> Page<T> nativeQueryPageList(Class<T> resultClass, Pageable pageable, String nativeSql,
Object... params);
/**
* 查询对象列表,返回List<Map<key,value>>
* @param nativeSql
* @param params
* @return T
*/
<T> T nativeQueryMap(String nativeSql, Object... params);
/**
* 查询对象列表,返回List<组合对象>
* @param resultClass
* @param nativeSql
* @param params
* @return
*/
<T> T nativeQueryModel(Class<T> resultClass, String nativeSql, Object... params);
/**
* 查询对象列表,返回List<Map<key,value>>
* @param nativeSql
* @param params
* @return List<T>
*/
<T> List<T> nativeQueryListMap(String nativeSql, Object... params);
/**
* 查询对象列表,返回List<组合对象>
* @param resultClass
* @param nativeSql
* @param params
* @return List<T>
*/
<T> List<T> nativeQueryListModel(Class<T> resultClass, String nativeSql, Object... params);
/**
* 查询对象列表,返回List<组合对象>
* @param resultClass
* @param nativeSql
* @param params
* @return List<T>
*/
<T> List<T> nativeQueryPagingListModel(Class<T> resultClass, Pageable pageable, String nativeSql, Object... params);
}
package com.tools.common.dynamicquery;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.query.internal.NativeQueryImpl;
import org.hibernate.transform.Transformers;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;
/**
* 查询的实现类
*
*
*/
@Repository
public class DynamicQueryImpl implements DynamicQuery {
/**
* @PersistenceContext(type = PersistenceContextType.EXTENDED)
* 默认是 PersistenceContextType.TRANSACTION 开启只读事物
*/
@PersistenceContext
private EntityManager em;
public EntityManager getEntityManager() {
return em;
}
@Override
public void save(Object entity) {
em.persist(entity);
}
@Override
public void update(Object entity) {
em.merge(entity);
}
private Query createNativeQuery(String sql, Object... params) {
Query q = em.createNativeQuery(sql);
if (params != null && params.length > 0) {
for (int i = 0; i < params.length; i++) {
q.setParameter(i + 1, params[i]);
}
}
return q;
}
@Override
public int nativeExecuteUpdate(String nativeSql, Object... params) {
return createNativeQuery(nativeSql, params).executeUpdate();
}
@Override
public <T> T nativeQuerySingleResult(Class<T> resultClass, String nativeSql, Object... params) {
Query q = createNativeQuery(resultClass, nativeSql, params);
List<T> list = q.getResultList();
if (list.isEmpty()) {
return null;
}
return list.get(0);
}
private <T> Query createNativeQuery(Class<T> resultClass, String sql, Object... params) {
Query q;
if (resultClass == null) {
q = em.createNativeQuery(sql);
} else {
q = em.createNativeQuery(sql, resultClass);
}
if(params!=null){
for (int i = 0; i < params.length; i++) {
q.setParameter(i + 1, params[i]);
}
}
return q;
}
@Override
public <T> List<T> query(String nativeSql, Object... params) {
Query q = createNativeQuery(null, nativeSql, params);
return q.getResultList();
}
@Override
public <T> List<T> query(Class<T> resultClass, String nativeSql, Object... params) {
Query q = createNativeQuery(resultClass, nativeSql, params);
return q.getResultList();
}
@Override
public Long nativeQueryCount(String nativeSql, Object... params) {
nativeSql = StringUtils.substringBefore(nativeSql, "order by");
Object count = createNativeQuery(nativeSql, params).getSingleResult();
return ((Number) count).longValue();
}
@Override
public Long nativeQueryGetCount(String nativeSql, Object... params) {
nativeSql = StringUtils.substringBefore(nativeSql, "order by");
List count = createNativeQuery(nativeSql, params).getResultList();
return ((Number) count.size()).longValue();
}
@Override
public <T> Page<T> nativeQuery(Class<T> resultClass, Pageable pageable, String nativeSql, Object... params) {
List<T> rows = nativeQueryPagingList(resultClass, pageable, nativeSql, params);
Long total = nativeQueryCount(nativeSql, params);
return new PageImpl<>(rows, pageable, total);
}
@Override
public <T> List<T> nativeQueryPagingList(Class<T> resultClass, Pageable pageable, String nativeSql,
Object... params) {
Integer pageNumber = pageable.getPageNumber();
Integer pageSize = pageable.getPageSize();
Integer startPosition = pageNumber * pageSize;
return createNativeQuery(resultClass, nativeSql, params)
.setFirstResult(startPosition).setMaxResults(pageSize)
.getResultList();
}
@Override
public <T> Page<T> nativeQueryPageList(Class<T> resultClass, Pageable pageable, String nativeSql,
Object... params) {
Integer pageNumber = pageable.getPageNumber();
Integer pageSize = pageable.getPageSize();
Integer startPosition = pageNumber * pageSize;
Long total = nativeQueryGetCount(nativeSql, params);
return new PageImpl<>(createNativeQuery(resultClass, nativeSql, params)
.setFirstResult(startPosition).setMaxResults(pageSize)
.getResultList(), pageable, total);
}
@Override
public <T> T nativeQueryMap(String nativeSql, Object... params) {
Query q = createNativeQuery(nativeSql, params);
q.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
List<T> list = q.getResultList();
if (list.isEmpty()) {
return null;
}
return list.get(0);
}
@Override
public <T> T nativeQueryModel(Class<T> resultClass, String nativeSql, Object... params) {
Query q = createNativeQuery(nativeSql, params);
q.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(resultClass));
List<T> list = q.getResultList();
if (list.isEmpty()) {
return null;
}
return list.get(0);
}
@Override
public <T> List<T> nativeQueryListModel(Class<T> resultClass,
String nativeSql, Object... params) {
Query q = createNativeQuery(nativeSql, params);
q.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(resultClass));
return q.getResultList();
}
@Override
public <T> List<T> nativeQueryPagingListModel(Class<T> resultClass, Pageable pageable, String nativeSql, Object... params) {
Integer pageNumber = pageable.getPageNumber();
Integer pageSize = pageable.getPageSize();
Integer startPosition = pageNumber * pageSize;
Query q = createNativeQuery(nativeSql, params)
.setFirstResult(startPosition).setMaxResults(pageSize);
q.unwrap(NativeQueryImpl.class)
.setResultTransformer(Transformers.aliasToBean(resultClass));
return q.getResultList();
}
@Override
public <T> List<T> nativeQueryListMap(String nativeSql, Object... params) {
Query q = createNativeQuery(nativeSql, params);
q.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return q.getResultList();
}
}
package com.tools.common.excel;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
/**
* Excel 工具类
*
*/
public class ExcelUtil {
/**
* 导出 Excel :一个 sheet,带表头.
* @param response HttpServletResponse
* @param data 数据 list,每个元素为一个 BaseRowModel
* @param fileName 导出的文件名
* @param sheetName 导入文件的 sheet 名
* @param model 映射实体类,Excel 模型
* @throws Exception 异常
*/
public static void writeExcel(HttpServletResponse response, List<? extends Object> data,
String fileName, String sheetName, Class model) throws Exception {
/**
* 头的策略 设置表头居中对齐
*/
WriteCellStyle headWriteCellStyle = new WriteCellStyle();
headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
/**
* 内容的策略 设置内容靠左对齐
*/
WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.LEFT);
HorizontalCellStyleStrategy horizontalCellStyleStrategy =
new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
EasyExcel.write(getOutputStream(fileName, response), model)
.excelType(ExcelTypeEnum.XLSX)
.sheet(sheetName)
.registerWriteHandler(horizontalCellStyleStrategy)
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.doWrite(data);
}
/**
* 导出文件时为Writer生成OutputStream.
* @param fileName 文件名
* @param response response
* @return ""
*/
private static OutputStream getOutputStream(String fileName,
HttpServletResponse response) throws Exception {
try {
fileName = URLEncoder.encode(fileName, "UTF-8");
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf8");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ".xlsx");
response.setHeader("Pragma", "public");
response.setHeader("Cache-Control", "no-store");
response.addHeader("Cache-Control", "max-age=0");
return response.getOutputStream();
} catch (IOException e) {
throw new Exception("导出excel表格失败!", e);
}
}
}
\ No newline at end of file
package com.tools.common.excel;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import lombok.Data;
import java.io.Serializable;
/**
* 简单的用户封装
*
*/
@Data
@ColumnWidth(22)
@ContentRowHeight(15)
public class User implements Serializable {
/**
* value: 表头名称
* index: 列的号, 0表示第一列
*
*/
/**
* 入库时间
*/
@ExcelProperty(value = "姓名", index = 0)
private String name;
/**
* 供应商
*/
@ExcelProperty(value = "年龄", index = 1)
private String age;
/**
* 纸筒编号
*/
@ExcelProperty(value = "性别", index = 2)
private String sex;
}
package com.tools.common.exception;
import java.io.Serializable;
public class BusinessException extends RuntimeException implements ErrorCoded {
private static final long serialVersionUID = 2332608236621015980L;
private Serializable errorCode = -1;
public BusinessException() {
}
public BusinessException(String message) {
super(message);
}
public BusinessException(Serializable code, String message) {
super(message);
this.errorCode = code;
}
public BusinessException(Throwable cause) {
super(cause);
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
public BusinessException(Serializable code, String message, Throwable cause) {
super(message, cause);
this.errorCode = code;
}
public String toString() {
return "{code=" + this.errorCode + ",errors=" + super.toString() + "}";
}
public Serializable getErrorCode() {
return this.errorCode;
}
}
package com.tools.common.exception;
import java.io.Serializable;
public interface ErrorCoded {
Serializable getErrorCode();
}
package com.tools.common.exception;
/**
* 自定义异常
*
*
*/
public class RrException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String msg;
private int code = 500;
public RrException(String msg) {
super(msg);
this.msg = msg;
}
public RrException(String msg, Throwable e) {
super(msg, e);
this.msg = msg;
}
public RrException(String msg, int code) {
super(msg);
this.msg = msg;
this.code = code;
}
public RrException(String msg, int code, Throwable e) {
super(msg, e);
this.msg = msg;
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}
package com.tools.common.exception;
import com.tools.common.model.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 异常处理器
*
*
*/
@RestControllerAdvice
public class RrExceptionHandler {
private final Logger logger = LoggerFactory.getLogger(getClass());
/**
* 自定义异常
*/
@ExceptionHandler(RrException.class)
public Result handleRRException(RrException e){
Result r = new Result();
r.put("code", e.getCode());
r.put("msg", e.getMessage());
return r;
}
/**
* 自定义异常
*/
@ExceptionHandler(BusinessException.class)
public Result handleBusinessException(BusinessException e){
Result r = new Result();
r.put("code", e.getErrorCode());
r.put("msg", e.getMessage());
return r;
}
/**
* 自定义异常
*/
@ExceptionHandler(IllegalArgumentException.class)
public Result handleIllegalArgumentException(IllegalArgumentException e){
Result r = new Result();
r.put("code", "-1");
r.put("msg", e.getMessage());
return r;
}
@ExceptionHandler(DuplicateKeyException.class)
public Result handleDuplicateKeyException(DuplicateKeyException e){
logger.error(e.getMessage(), e);
return Result.error("数据库中已存在该记录");
}
@ExceptionHandler(InvalidDataAccessResourceUsageException.class)
public Result handleDuplicateKeyException(InvalidDataAccessResourceUsageException e){
logger.error(e.getMessage(), e);
return Result.error("演示环境禁止插插插");
}
@ExceptionHandler(Exception.class)
public Result handleException(Exception e){
logger.error(e.getMessage(), e);
return Result.error();
}
/**
* 异常处理参数
*/
@ExceptionHandler(value = {BindException.class})
public Result bindException(BindException e) {
return Result.error(e.getAllErrors().toString());
}
}
package com.tools.common.model;
import java.util.ArrayList;
import java.util.List;
/**
* 分页模板
*
*
*/
public class PageBean<T> {
private List<T> pageData = new ArrayList<>();
private Integer pageSize = Integer.valueOf(10);
private Integer pageNo = Integer.valueOf(1);
private Long totalCount = 0L;
private String description;
public PageBean(List<T> pageData, Long totalCount) {
this.pageData = pageData;
this.totalCount = totalCount;
}
public PageBean() {
}
public List<T> getPageData() {
return this.pageData;
}
public void setPageData(List<T> pageData) {
this.pageData = pageData;
}
public Integer getPageSize() {
return this.pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Long getTotalCount() {
return this.totalCount;
}
public void setTotalCount(Long totalCount) {
this.totalCount = totalCount;
}
public Integer getPageNo() {
return this.pageNo - 1;
}
public void setPageNo(Integer pageNo) {
this.pageNo = pageNo;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
\ No newline at end of file
package com.tools.common.model;
import java.util.HashMap;
import java.util.Map;
/**
* 页面响应
*
*
*/
public class Result extends HashMap<String, Object> {
private static final long serialVersionUID = 1L;
public Result() {
put("code", 0);
}
public static Result error() {
return error(-1, "未知异常,请联系管理员");
}
public static Result error(String msg) {
return error(-1, msg);
}
public static Result error(int code, String msg) {
Result r = new Result();
r.put("code", code);
r.put("msg", msg);
return r;
}
public static Result ok(Object msg) {
Result r = new Result();
r.put("msg", msg);
return r;
}
public static Result ok(Map<String, Object> map) {
Result r = new Result();
r.putAll(map);
return r;
}
public static Result ok() {
Result r = new Result();
r.put("msg", "操作成功");
return r;
}
@Override
public Result put(String key, Object value) {
super.put(key, value);
return this;
}
}
\ No newline at end of file
package com.tools.common.redis;
import org.redisson.api.RLock;
import org.redisson.api.RMapCache;
import org.redisson.api.RedissonClient;
import java.util.concurrent.TimeUnit;
/**
* redis分布式锁
*
*
*/
public class RedissLockUtil {
private static RedissonClient redissonClient;
public void setRedissonClient(RedissonClient locker) {
redissonClient = locker;
}
/**
* 加锁
* @param lockKey
* @return
*/
public static RLock lock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock();
return lock;
}
/**
* 释放锁
* @param lockKey
*/
public static void unlock(String lockKey) {
RLock lock = redissonClient.getLock(lockKey);
lock.unlock();
}
/**
* 释放锁
* @param lock
*/
public static void unlock(RLock lock) {
lock.unlock();
}
/**
* 带超时的锁
* @param lockKey
* @param timeout 超时时间 单位:秒
*/
public static RLock lock(String lockKey, int timeout) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(timeout, TimeUnit.SECONDS);
return lock;
}
/**
* 带超时的锁
* @param lockKey
* @param unit 时间单位
* @param timeout 超时时间
*/
public static RLock lock(String lockKey, TimeUnit unit ,int timeout) {
RLock lock = redissonClient.getLock(lockKey);
lock.lock(timeout, unit);
return lock;
}
/**
* 尝试获取锁
* @param lockKey
* @param waitTime 最多等待时间
* @param leaseTime 上锁后自动释放锁时间
* @return
*/
public static boolean tryLock(String lockKey, int waitTime, int leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
try {
return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
return false;
}
}
/**
* 尝试获取锁
* @param lockKey
* @param unit 时间单位
* @param waitTime 最多等待时间
* @param leaseTime 上锁后自动释放锁时间
* @return
*/
public static boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) {
RLock lock = redissonClient.getLock(lockKey);
try {
return lock.tryLock(waitTime, leaseTime, unit);
} catch (InterruptedException e) {
return false;
}
}
/**
* 初始红包数量
* @param key
* @param count
*/
public void initCount(String key,int count) {
RMapCache<String, Integer> mapCache = redissonClient.getMapCache("skill");
mapCache.putIfAbsent(key,count,3,TimeUnit.DAYS);
}
/**
* 递增
* @param key
* @param delta 要增加几(大于0)
* @return
*/
public int incr(String key, int delta) {
RMapCache<String, Integer> mapCache = redissonClient.getMapCache("skill");
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
return mapCache.addAndGet(key, 1);//加1并获取计算后的值
}
/**
* 递减
* @param key 键
* @param delta 要减少几(小于0)
* @return
*/
public int decr(String key, int delta) {
RMapCache<String, Integer> mapCache = redissonClient.getMapCache("skill");
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
return mapCache.addAndGet(key, -delta);//加1并获取计算后的值
}
public static RedissonClient getRedissonClient() {
return redissonClient;
}
}
\ No newline at end of file
package com.tools.common.redis;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 自动装配
*
*/
@Configuration
@ConditionalOnClass(Config.class)
@EnableConfigurationProperties(RedissonProperties.class)
public class RedissonAutoConfiguration {
@Autowired
private RedissonProperties redssionProperties;
/**
* 单机模式自动装配
* @return
*/
@Bean
RedissonClient redissonSingle() {
Config config = new Config();
SingleServerConfig serverConfig = config.useSingleServer()
.setAddress("redis://"+redssionProperties.getHost()+":"+redssionProperties.getPort())
.setTimeout(redssionProperties.getTimeout())
.setConnectionPoolSize(redssionProperties.getConnectionPoolSize())
.setConnectionMinimumIdleSize(redssionProperties.getConnectionMinimumIdleSize());
if(StringUtils.isNotBlank(redssionProperties.getPassword())) {
serverConfig.setPassword(redssionProperties.getPassword());
}
return Redisson.create(config);
}
/**
* 装配locker类,并将实例注入到RedissLockUtil中
* @return
*/
@Bean
RedissLockUtil redissLockUtil(RedissonClient redissonClient) {
RedissLockUtil redissLockUtil = new RedissLockUtil();
redissLockUtil.setRedissonClient(redissonClient);
return redissLockUtil;
}
}
package com.tools.common.redis;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 参数配置
*
*/
@Data
@ConfigurationProperties(prefix = "spring.redis")
public class RedissonProperties {
private int timeout = 3000;
private String host;
private String port;
private String password;
private int connectionPoolSize = 64;
private int connectionMinimumIdleSize=10;
private int slaveConnectionPoolSize = 250;
private int masterConnectionPoolSize = 250;
private String[] sentinelAddresses;
private String masterName;
}
package com.tools.common.util;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 日期处理
*
*/
public class DateUtils {
/** 时间格式(yyyy-MM-dd) */
public final static String DATE_PATTERN = "yyyy-MM-dd";
/** 时间格式(yyyy-MM-dd HH:mm:ss) */
public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss";
public static String format(Date date) {
return format(date, DATE_PATTERN);
}
public static String format(Date date, String pattern) {
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
return df.format(date);
}
return null;
}
public static String format(Timestamp date, String pattern) {
if (date != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
return df.format(date);
}
return null;
}
public static Date format(String str, String pattern) {
if (str != null) {
SimpleDateFormat df = new SimpleDateFormat(pattern);
try {
return df.parse(str);
} catch (ParseException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 获取当前日期
*/
public static Timestamp getTimestamp() {
return new Timestamp(System.currentTimeMillis());
}
public static String getTime() {
return format(new Timestamp(System.currentTimeMillis()),DATE_TIME_PATTERN);
}
public static void main(String[] args) {
System.out.println(DateUtils.getTime());
}
}
package com.tools.common.util;
import java.security.MessageDigest;
public class EncriptUtil {
/**
* 十六进制下数字到字符的映射数组
*/
private final static String[] hexDigits = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"};
/**把inputString加密*/
public static String md5(String inputStr){
return encodeByMD5(inputStr);
}
/**对字符串进行MD5编码*/
private static String encodeByMD5(String originString){
if (originString!=null) {
try {
//创建具有指定算法名称的信息摘要
MessageDigest md5 = MessageDigest.getInstance("MD5");
//使用指定的字节数组对摘要进行最后更新,然后完毕摘要计算
byte[] results = md5.digest(originString.getBytes());
//将得到的字节数组变成字符串返回
String result = byteArrayToHexString(results);
return result;
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
/**
* 轮换字节数组为十六进制字符串
* @param b 字节数组
* @return 十六进制字符串
*/
private static String byteArrayToHexString(byte[] b){
StringBuffer resultSb = new StringBuffer();
for(int i=0;i<b.length;i++){
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
//将一个字节转化成十六进制形式的字符串
private static String byteToHexString(byte b){
int n = b;
if(n<0) {
n=256+n;
}
int d1 = n/16;
int d2 = n%16;
return hexDigits[d1] + hexDigits[d2];
}
}
package com.tools.common.util;
import cn.hutool.core.date.DateUtil;
import com.tools.common.constant.SystemConstant;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
/**
* 文件工具
*
*/
@Component
public class FileUtils {
/**
* 判断文件大小
* @param len 文件长度
* @param size 限制大小
* @param unit 限制单位(B,K,M,G)
* @return
*/
public static boolean checkFileSize(Long len, int size, String unit) {
double fileSize = 0;
if ("B".equalsIgnoreCase(unit)) {
fileSize = (double) len;
} else if ("K".equalsIgnoreCase(unit)) {
fileSize = (double) len / 1024;
} else if ("M".equalsIgnoreCase(unit)) {
fileSize = (double) len / 1048576;
} else if ("G".equalsIgnoreCase(unit)) {
fileSize = (double) len / 1073741824;
}
return !(fileSize > size);
}
/**
* 获取上传文件的MD5值
* @param file
* @return
* @throws IOException
*/
public static String getMd5(MultipartFile file) {
try {
return DigestUtils.md5Hex(file.getBytes());
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/**
* 创建多级文件夹
* @return
*/
public static File createByDay(String filePath){
File parentFile = new File(filePath+ SystemConstant.SF_FILE_SEPARATOR+ DateUtil.thisYear());
if (!parentFile.exists()) {
parentFile.mkdirs();
}
parentFile = new File(parentFile,(DateUtil.thisMonth()+1)+"");
if (!parentFile.exists()) {
parentFile.mkdirs();
}
parentFile = new File(parentFile,DateUtil.thisDayOfMonth()+"");
if (!parentFile.exists()) {
parentFile.mkdirs();
}
return parentFile;
}
}
This diff is collapsed.
package com.tools.common.util;
/**
* 代码生成工具类
*
*/
public class GenUtils {
/**
* 由数据库表名生成实体类名
* @param tableName
* @return
*/
public static String allInitialCapital(String tableName) {
if (org.springframework.util.StringUtils.isEmpty(tableName)) {
return null;
}
tableName = allLowerCase(tableName);
String[] tableNameArray = splitName(tableName);
StringBuffer entryName = new StringBuffer();
for (String part : tableNameArray) {
entryName.append(initialCapital(part));
}
return entryName.toString();
}
/**
* 由数据库列名生成实体类属性名
* @param columnName
* @return
*/
public static String secInitialCapital(String columnName) {
if (org.springframework.util.StringUtils.isEmpty(columnName)) {
return null;
}
columnName = allLowerCase(columnName);
String[] columnNameArray = splitName(columnName);
StringBuffer fieldName = new StringBuffer();
for (int i = 0; i < columnNameArray.length; i++) {
String part = columnNameArray[i];
if (0 == i) {
fieldName.append(part);
} else {
fieldName.append(initialCapital(part));
}
}
return fieldName.toString();
}
/**
* 所有字母转成小写
* @return
*/
public static String allLowerCase(String str) {
if (org.springframework.util.StringUtils.isEmpty(str)) {
return str;
}
return str.toLowerCase();
}
/**
* 功能:将输入字符串的首字母改成大写
* @param str
* @return
*/
public static String initialCapital(String str) {
char[] ch = str.toCharArray();
if (ch[0] >= 'a' && ch[0] <= 'z') {
ch[0] = (char) (ch[0] - 32);
}
return new String(ch);
}
/**
* 分解名称
* @param str
* @return
*/
public static String[] splitName(String str) {
if (org.springframework.util.StringUtils.isEmpty(str)) {
return null;
}
return str.split("_");
}
/**
* 首字母转小写
* @param s
* @return
*/
public static String toLowerCaseFirstOne(String s){
if(Character.isLowerCase(s.charAt(0))){
return s;
} else{
return Character.toLowerCase(s.charAt(0)) + s.substring(1);
}
}
}
\ No newline at end of file
package com.tools.common.util;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@Service
public class HttpClient {
/**
* 校验网址正确性
* @param url
* @return
*/
public static Integer client(String url){
try{
HttpHeaders headers = new HttpHeaders();
headers.add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36");
HttpEntity<Resource> httpEntity = new HttpEntity<>(headers);
RestTemplate client = new RestTemplate();
ResponseEntity<String> response = client.exchange(url, HttpMethod.GET, httpEntity , String.class);
return response.getStatusCode().value();
}catch (Exception e){
e.printStackTrace();
}
return 0;
}
}
package com.tools.common.util;
import org.springframework.util.StringUtils;
import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.Map.Entry;
/**
* http、https 请求工具类
*
* @author jiaxiaoxian
*/
public class HttpUtils {
private static final String DEFAULT_CHARSET = "UTF-8";
private static final String _GET = "GET"; // GET
private static final String _POST = "POST";// POST
public static final int DEF_CONN_TIMEOUT = 30000;
public static final int DEF_READ_TIMEOUT = 30000;
/**
* 初始化http请求参数
*
* @param url
* @param method
* @param headers
* @return
* @throws Exception
*/
private static HttpURLConnection initHttp(String url, String method,
Map<String, String> headers) throws Exception {
URL _url = new URL(url);
HttpURLConnection http = (HttpURLConnection) _url.openConnection();
// 连接超时
http.setConnectTimeout(DEF_CONN_TIMEOUT);
// 读取超时 --服务器响应比较慢,增大时间
http.setReadTimeout(DEF_READ_TIMEOUT);
http.setUseCaches(false);
http.setRequestMethod(method);
http.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
http.setRequestProperty(
"User-Agent",
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
if (null != headers && !headers.isEmpty()) {
for (Entry<String, String> entry : headers.entrySet()) {
http.setRequestProperty(entry.getKey(), entry.getValue());
}
}
http.setDoOutput(true);
http.setDoInput(true);
http.connect();
return http;
}
/**
* 初始化http请求参数
*
* @param url
* @param method
* @return
* @throws Exception
*/
private static HttpsURLConnection initHttps(String url, String method,
Map<String, String> headers) throws Exception {
TrustManager[] tm = {new MyX509TrustManager()};
System.setProperty("https.protocols", "TLSv1");
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tm, new java.security.SecureRandom());
// 从上述SSLContext对象中得到SSLSocketFactory对象
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL _url = new URL(url);
HttpsURLConnection http = (HttpsURLConnection) _url.openConnection();
// 设置域名校验
http.setHostnameVerifier(new HttpUtils().new TrustAnyHostnameVerifier());
// 连接超时
http.setConnectTimeout(DEF_CONN_TIMEOUT);
// 读取超时 --服务器响应比较慢,增大时间
http.setReadTimeout(DEF_READ_TIMEOUT);
http.setUseCaches(false);
http.setRequestMethod(method);
http.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
http.setRequestProperty(
"User-Agent",
"Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
if (null != headers && !headers.isEmpty()) {
for (Entry<String, String> entry : headers.entrySet()) {
http.setRequestProperty(entry.getKey(), entry.getValue());
}
}
http.setSSLSocketFactory(ssf);
http.setDoOutput(true);
http.setDoInput(true);
http.connect();
return http;
}
/**
* @return 返回类型:
* @throws Exception
* @description 功能描述: get 请求
*/
public static String get(String url, Map<String, String> params,
Map<String, String> headers) throws Exception {
HttpURLConnection http = null;
if (isHttps(url)) {
http = initHttps(initParams(url, params), _GET, headers);
} else {
http = initHttp(initParams(url, params), _GET, headers);
}
InputStream in = http.getInputStream();
BufferedReader read = new BufferedReader(new InputStreamReader(in,
DEFAULT_CHARSET));
String valueString = null;
StringBuffer bufferRes = new StringBuffer();
// 优化,不能光使用!=null做判断。有为""的情况,防止多次空循环
while (!StringUtils.isEmpty(valueString = read.readLine())) {
bufferRes.append(valueString);
}
in.close();
if (http != null) {
http.disconnect();// 关闭连接
}
return bufferRes.toString();
}
public static String get(String url) throws Exception {
return get(url, null);
}
public static String get(String url, Map<String, String> params)
throws Exception {
return get(url, params, null);
}
public static String post(String url, String params) throws Exception {
HttpURLConnection http = null;
if (isHttps(url)) {
http = initHttps(url, _POST, null);
} else {
http = initHttp(url, _POST, null);
}
OutputStream out = http.getOutputStream();
out.write(params.getBytes(DEFAULT_CHARSET));
out.flush();
out.close();
InputStream in = http.getInputStream();
BufferedReader read = new BufferedReader(new InputStreamReader(in,
DEFAULT_CHARSET));
String valueString = null;
StringBuffer bufferRes = new StringBuffer();
while ((valueString = read.readLine()) != null) {
bufferRes.append(valueString);
}
in.close();
if (http != null) {
http.disconnect();// 关闭连接
}
return bufferRes.toString();
}
public static String post(String url, String params, Map<String, String> headers) throws Exception {
HttpURLConnection http = null;
if (isHttps(url)) {
http = initHttps(url, _POST, headers);
} else {
http = initHttp(url, _POST, headers);
}
OutputStream out = http.getOutputStream();
out.write(params.getBytes(DEFAULT_CHARSET));
out.flush();
out.close();
InputStream in = http.getInputStream();
BufferedReader read = new BufferedReader(new InputStreamReader(in,
DEFAULT_CHARSET));
String valueString = null;
StringBuffer bufferRes = new StringBuffer();
while ((valueString = read.readLine()) != null) {
bufferRes.append(valueString);
}
in.close();
if (http != null) {
http.disconnect();// 关闭连接
}
return bufferRes.toString();
}
/**
* 功能描述: 构造请求参数
*
* @return 返回类型:
* @throws Exception
*/
public static String initParams(String url, Map<String, String> params)
throws Exception {
if (null == params || params.isEmpty()) {
return url;
}
StringBuilder sb = new StringBuilder(url);
if (url.indexOf("?") == -1) {
sb.append("?");
}
sb.append(map2Url(params));
return sb.toString();
}
/**
* map构造url
*
* @return 返回类型:
* @throws Exception
*/
public static String map2Url(Map<String, String> paramToMap)
throws Exception {
if (null == paramToMap || paramToMap.isEmpty()) {
return null;
}
StringBuffer url = new StringBuffer();
boolean isfist = true;
for (Entry<String, String> entry : paramToMap.entrySet()) {
if (isfist) {
isfist = false;
} else {
url.append("&");
}
url.append(entry.getKey()).append("=");
String value = entry.getValue();
if (!StringUtils.isEmpty(value)) {
url.append(URLEncoder.encode(value, DEFAULT_CHARSET));
}
}
return url.toString();
}
/**
* 检测是否https
*
* @param url
*/
private static boolean isHttps(String url) {
return url.startsWith("https");
}
/**
* https 域名校验
* @return
*/
public class TrustAnyHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;// 直接返回true
}
}
private static class MyX509TrustManager implements X509TrustManager {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
}
public static void main(String[] args) {
String str = "";
try {
str = get("https://www.baidu.com");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(str);
}
}
\ No newline at end of file
package com.tools.common.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
/**
* IP地址
*
*/
public class IPUtils {
private static final Logger logger = LoggerFactory.getLogger(IPUtils.class);
/**
* 获取IP地址
* 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
* 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
*/
public static String getIpAddr() {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = null;
try {
ip = request.getHeader("x-forwarded-for");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
} catch (Exception e) {
logger.error("IPUtils ERROR ", e);
}
// 使用代理,则获取第一个IP地址
if (!StringUtils.isEmpty(ip) && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
return ip;
}
}
\ No newline at end of file
package com.tools.common.util;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
/**
* 图片处理
*
*/
@Component
public class ImageUtils {
@Value("${file.path}")
private String filePath;
private static File watermark;
static {
try {
watermark = ResourceUtils.getFile("classpath:static/images/watermark.png");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// 原图片地址
String imageUrl = "F:\\111.gif";
// 水印图片 相对于resource目录
String watermark = "F:\\watermark.png";
// 输出到文件
String outputFile = "F:\\222.gif";
// 不透明度
float opacity = 0.7f;
try {
// 获取原图文件
File file = new File(imageUrl);
// ImageIO读取图片
BufferedImage image = ImageIO.read(file);
System.out.println(image.getWidth());
Thumbnails.of(image)
// 设置图片大小
.size(image.getWidth(), image.getHeight())
// 加水印 参数:1.水印位置 2.水印图片 3.不透明度0.0-1.0
.watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File(watermark)), opacity)
// 输出到文件
.outputQuality(1)
.toFile(outputFile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.tools.common.util;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
/**
*/
public class PasswordEncoder {
private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d",
"e", "f" };
private final static String MD5 = "MD5";
private final static String SHA = "SHA";
private final Object salt;
private final String algorithm;
public PasswordEncoder(Object salt) {
this(salt, MD5);
}
public PasswordEncoder(Object salt, String algorithm) {
this.salt = salt;
this.algorithm = algorithm;
}
/**
* 密码加密
* @param rawPass
* @return
*/
public String encode(String rawPass) {
String result = null;
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
// 加密后的字符串
result = byteArrayToHexString(md.digest(mergePasswordAndSalt(rawPass).getBytes(StandardCharsets.UTF_8)));
} catch (Exception ex) {
}
return result;
}
/**
* 密码匹配验证
* @param encPass 密文
* @param rawPass 明文
* @return
*/
public boolean matches(String encPass, String rawPass) {
String pass1 = encPass;
String pass2 = encode(rawPass);
return pass1.equals(pass2);
}
private String mergePasswordAndSalt(String password) {
if (password == null) {
password = "";
}
if ((salt == null) || "".equals(salt)) {
return password;
} else {
return password + "{" + salt + "}";
}
}
/**
* 转换字节数组为16进制字串
*
* @param b
* 字节数组
* @return 16进制字串
*/
private String byteArrayToHexString(byte[] b) {
StringBuffer resultSb = new StringBuffer();
for (int i = 0; i < b.length; i++) {
resultSb.append(byteToHexString(b[i]));
}
return resultSb.toString();
}
/**
* 将字节转换为16进制
* @param b
* @return
*/
private static String byteToHexString(byte b) {
int n = b;
if (n < 0)
n = 256 + n;
int d1 = n / 16;
int d2 = n % 16;
return hexDigits[d1] + hexDigits[d2];
}
public static void main(String[] args) {
}
}
package com.tools.common.util;
import org.springframework.beans.factory.annotation.Value;
import java.util.UUID;
/**
*/
public class PasswordUtils {
@Value("${pwd.decrypt.key}")
public String key;
@Value("${pwd.decrypt.iv}")
private String iv;
/**
* 匹配密码
* @param salt 盐
* @param rawPass 明文
* @param encPass 密文
* @return
*/
public static boolean matches(String salt, String rawPass, String encPass) {
return new PasswordEncoder(salt).matches(encPass, rawPass);
}
/**
* 明文密码加密
* @param rawPass 明文
* @param salt
* @return
*/
public static String encode(String rawPass, String salt) {
return new PasswordEncoder(salt).encode(rawPass);
}
/**
* 获取加密盐
* @return
*/
public static String getSalt() {
return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 20);
}
}
package com.tools.common.util;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
/**
* @Author:Roger Wu
* @name:pwdUtils
* @Date:2025-06-10 0:27
*/
@Component
public class PwdUtils {
@Value("${pwd.decrypt.key}")
public String key;
@Value("${pwd.decrypt.iv}")
private String iv;
// 后端使用AES算法对密码进行解密
public String decryptPassword(String encryptedPassword) {
Assert.notNull(key);
Assert.notNull(iv);
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] original = cipher.doFinal(Base64.getDecoder().decode(encryptedPassword));
return new String(original);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
// public static void main(String[] args) {
// System.out.println(decryptPassword("QPpW6DeIaufxGD4+HLcArg=="));
// }
}
This diff is collapsed.
package com.tools.common.util;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
/**
* 工具类
*
*/
@Component
public final class SpringUtils implements BeanFactoryPostProcessor {
/**
* Spring应用上下文环境
*/
private static ConfigurableListableBeanFactory beanFactory;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
SpringUtils.beanFactory = beanFactory;
}
/**
* 获取对象
*
* @param name
* @return Object 一个以所给名字注册的bean的实例
* @throws org.springframework.beans.BeansException
*
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) throws BeansException {
return (T) beanFactory.getBean(name);
}
/**
* 获取类型为requiredType的对象
*
* @param clz
* @return
* @throws org.springframework.beans.BeansException
*
*/
public static <T> T getBean(Class<T> clz) throws BeansException {
@SuppressWarnings("unchecked")
T result = beanFactory.getBean(clz);
return result;
}
/**
* 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
*
* @param name
* @return boolean
*/
public static boolean containsBean(String name) {
return beanFactory.containsBean(name);
}
/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
* 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
*
* @param name
* @return boolean
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return beanFactory.isSingleton(name);
}
/**
* @param name
* @return Class 注册对象的类型
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getType(name);
}
/**
* 如果给定的bean名字在bean定义中有别名,则返回这些别名
*
* @param name
* @return
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
*
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return beanFactory.getAliases(name);
}
}
package com.tools.common.util;
import org.springframework.stereotype.Component;
/**
* 1)将长网址用md5算法生成32位签名串,分为4段,,每段8个字符;
*
* 2)对这4段循环处理,取每段的8个字符, 将他看成16进制字符串与0x3fffffff(30位1)的位与操作。超过30位的忽略处理。
*
* 3)将每段得到的这30位又分成6段,每5位的数字作为字母表的索引取得特定字符,依次进行获得6位字符串;
*
* 4)这样一个md5字符串能够获得4个6位串。取里面的随意一个就可作为这个长url的短url地址。
*/
@Component
public class TinyUrlUtil {
public String[] ShortText(String string){
String key = "qwe20190909";//自己定义生成MD5加密字符串前的混合KEY
String[] chars = new String[]{//要使用生成URL的字符
"a","b","c","d","e","f","g","h",
"i","j","k","l","m","n","o","p",
"q","r","s","t","u","v","w","x",
"y","z","0","1","2","3","4","5",
"6","7","8","9","A","B","C","D",
"E","F","G","H","I","J","K","L",
"M","N","O","P","Q","R","S","T",
"U","V","W","X","Y","Z"
};
String hex = EncriptUtil.md5(key + string);
int hexLen = hex.length();
int subHexLen = hexLen / 8;
String[] ShortStr = new String[4];
for (int i = 0; i < subHexLen; i++) {
String outChars = "";
int j = i + 1;
String subHex = hex.substring(i * 8, j * 8);
long idx = Long.valueOf("3FFFFFFF", 16) & Long.valueOf(subHex, 16);
for (int k = 0; k < 6; k++) {
int index = (int) (Long.valueOf("0000003D", 16) & idx);
outChars += chars[index];
idx = idx >> 5;
}
ShortStr[i] = outChars;
}
return ShortStr;
}
}
package com.tools.module.business.constants;
/**
* @Author:Roger Wu
* @name:SysUserConstants
* @Date:2025-06-09 22:32
*/
public interface SysCityConstants {
interface Status {
/**
* 正常
*/
String NORMAL ="NORMAL";
/**
* 禁用
*/
String DISABLED ="DISABLED";
}
}
package com.tools.module.business.constants;
/**
* @Author:Roger Wu
* @name:SysUserConstants
* @Date:2025-06-09 22:32
*/
public interface SysUserConstants {
interface Status {
/**
* 正常
*/
String NORMAL ="NORMAL";
/**
* 禁用
*/
String DISABLED ="DISABLED";
}
}
package com.tools.module.business.controller;
import com.tools.common.config.AbstractController;
import com.tools.common.model.Result;
import com.tools.module.business.convert.SysCityConvert;
import com.tools.module.business.dto.CityDto;
import com.tools.module.business.entity.SysCityEntity;
import com.tools.module.business.service.SysCityService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "城市管理")
@RestController
@RequestMapping("/cityRest")
public class CityController extends AbstractController {
@Autowired
private SysCityService sysCityService;
@PostMapping("/createCity")
public Result createCity(@RequestBody CityDto cityDto) throws Exception {
SysCityEntity sysCityEntity = SysCityConvert.convertDto2Entity(cityDto);
return sysCityService.save(sysCityEntity);
}
@PostMapping("/updateCity")
public Result updateCity(@RequestBody CityDto cityDto) throws Exception {
SysCityEntity sysCityEntity = SysCityConvert.convertDto2Entity(cityDto);
return sysCityService.update(sysCityEntity);
}
@PostMapping("/list")
public Result list(@RequestBody CityDto cityDto) throws Exception {
SysCityEntity sysCityEntity = SysCityConvert.convertDto2Entity(cityDto);
Pageable pageable = PageRequest.of(cityDto.getPageNo(), cityDto.getPageSize());
return sysCityService.list(sysCityEntity, pageable);
}
@PostMapping("/delete")
public Result delete(Long cityId) throws Exception {
return sysCityService.delete(cityId);
}
}
package com.tools.module.business.convert;
import com.tools.module.business.dto.CityDto;
import com.tools.module.business.entity.SysCityEntity;
import com.tools.module.business.model.SysCityModel;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import java.util.List;
import java.util.stream.Collectors;
/**
* @Author:Roger Wu
* @name:SysCityConvert
* @Date:2025-06-12 0:13
*/
public class SysCityConvert {
public static SysCityModel convertEntity2Model(SysCityEntity sysCityEntity) {
SysCityModel sysCityModel = new SysCityModel();
sysCityModel.setCityId(sysCityEntity.getCityId());
sysCityModel.setCityName(sysCityEntity.getCityName());
sysCityModel.setCityShortName(sysCityEntity.getCityShortName());
sysCityModel.setCityStatus(sysCityEntity.getCityStatus());
sysCityModel.setCityRemark(sysCityEntity.getCityRemark());
sysCityModel.setCityTop(sysCityEntity.getCityTop());
sysCityModel.setCityTopTime(sysCityEntity.getCityTopTime());
sysCityModel.setIsDeleted(sysCityEntity.getIsDeleted());
sysCityModel.setCreatedBy(sysCityEntity.getCreatedBy());
sysCityModel.setCreatedTime(sysCityEntity.getCreatedTime());
sysCityModel.setUpdatedBy(sysCityEntity.getUpdatedBy());
sysCityModel.setUpdatedTime(sysCityEntity.getUpdatedTime());
sysCityModel.setVersion(sysCityEntity.getVersion());
return sysCityModel;
}
public static SysCityEntity convertModel2Entity(SysCityModel sysCityModel) {
SysCityEntity sysCityEntity = new SysCityEntity();
sysCityEntity.setCityId(sysCityModel.getCityId());
sysCityEntity.setCityName(sysCityModel.getCityName());
sysCityEntity.setCityShortName(sysCityModel.getCityShortName());
sysCityEntity.setCityStatus(sysCityModel.getCityStatus());
sysCityEntity.setCityRemark(sysCityModel.getCityRemark());
sysCityEntity.setCityTop(sysCityModel.getCityTop());
sysCityEntity.setCityTopTime(sysCityModel.getCityTopTime());
sysCityEntity.setIsDeleted(sysCityModel.getIsDeleted());
sysCityEntity.setCreatedBy(sysCityModel.getCreatedBy());
sysCityEntity.setCreatedTime(sysCityModel.getCreatedTime());
sysCityEntity.setUpdatedBy(sysCityModel.getUpdatedBy());
sysCityEntity.setUpdatedTime(sysCityModel.getUpdatedTime());
sysCityEntity.setVersion(sysCityModel.getVersion());
return sysCityEntity;
}
public static CityDto convertEntity2Dto(SysCityEntity sysCityEntity) {
CityDto cityDto = new CityDto();
cityDto.setCityId(sysCityEntity.getCityId());
cityDto.setCityName(sysCityEntity.getCityName());
cityDto.setCityShortName(sysCityEntity.getCityShortName());
cityDto.setCityStatus(sysCityEntity.getCityStatus());
cityDto.setCityRemark(sysCityEntity.getCityRemark());
cityDto.setCityTop(sysCityEntity.getCityTop());
cityDto.setCityTopTime(sysCityEntity.getCityTopTime());
cityDto.setCreatedBy(sysCityEntity.getCreatedBy());
cityDto.setCreatedTime(sysCityEntity.getCreatedTime());
cityDto.setUpdatedBy(sysCityEntity.getUpdatedBy());
cityDto.setUpdatedTime(sysCityEntity.getUpdatedTime());
return cityDto;
}
public static SysCityEntity convertDto2Entity(CityDto cityDto) {
SysCityEntity sysCityEntity = new SysCityEntity();
sysCityEntity.setCityId(cityDto.getCityId());
sysCityEntity.setCityName(cityDto.getCityName());
sysCityEntity.setCityShortName(cityDto.getCityShortName());
sysCityEntity.setCityStatus(cityDto.getCityStatus());
sysCityEntity.setCityRemark(cityDto.getCityRemark());
sysCityEntity.setCityTop(cityDto.getCityTop());
sysCityEntity.setCityTopTime(cityDto.getCityTopTime());
sysCityEntity.setCreatedBy(cityDto.getCreatedBy());
sysCityEntity.setCreatedTime(cityDto.getCreatedTime());
sysCityEntity.setUpdatedBy(cityDto.getUpdatedBy());
sysCityEntity.setUpdatedTime(cityDto.getUpdatedTime());
return sysCityEntity;
}
public static Page<SysCityEntity> convertPageModel2Entity(Page<SysCityModel> sysCityModelPage) {
Pageable pageable = sysCityModelPage.getPageable();
List<SysCityEntity> sysCityEntityList = sysCityModelPage.get().map(item -> convertModel2Entity(item)).collect(Collectors.toList());
return new PageImpl(sysCityEntityList, pageable, sysCityModelPage.getTotalPages());
}
}
\ No newline at end of file
package com.tools.module.business.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.tools.common.model.PageBean;
import lombok.Data;
import javax.persistence.MappedSuperclass;
import java.io.Serializable;
import java.util.Date;
@Data
@MappedSuperclass
public abstract class BaseDto extends PageBean implements Serializable {
private static final long serialVersionUID = 1L;
@JsonIgnore
private Long createdBy;
@JsonIgnore
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createdTime;
@JsonIgnore
private Long updatedBy;
@JsonIgnore
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updatedTime;
}
\ No newline at end of file
package com.tools.module.business.dto;
import lombok.Data;
import java.util.Date;
/**
* @Author:Roger Wu
* @name:dto
* @Date:2025-06-11 23:36
*/
@Data
public class CityDto extends BaseDto {
private Long cityId;
private String cityName;
private String cityShortName;
private String cityStatus;
private String cityRemark;
private String cityTop;
private Date cityTopTime;
public Long getCityId() {
return cityId;
}
public void setCityId(Long cityId) {
this.cityId = cityId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public String getCityShortName() {
return cityShortName;
}
public void setCityShortName(String cityShortName) {
this.cityShortName = cityShortName;
}
public String getCityStatus() {
return cityStatus;
}
public void setCityStatus(String cityStatus) {
this.cityStatus = cityStatus;
}
public String getCityRemark() {
return cityRemark;
}
public void setCityRemark(String cityRemark) {
this.cityRemark = cityRemark;
}
public String getCityTop() {
return cityTop;
}
public void setCityTop(String cityTop) {
this.cityTop = cityTop;
}
public Date getCityTopTime() {
return cityTopTime;
}
public void setCityTopTime(Date cityTopTime) {
this.cityTopTime = cityTopTime;
}
}
package com.tools.module.business.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import javax.persistence.Version;
import java.io.Serializable;
import java.util.Date;
@Data
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 是否删除
*/
@Column(name = "is_deleted", length = 2,columnDefinition = "varchar(2) NOT NULL DEFAULT 'N' COMMENT '是否删除 N:否 Y:是'", insertable = false)
private String isDeleted;
@CreatedBy
@Column(name = "created_by", nullable = false, updatable = false)
@JsonIgnore
private Long createdBy;
@CreatedDate
@Column(name = "created_time", nullable = false, updatable = false)
@JsonIgnore
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createdTime;
@LastModifiedBy
@Column(name = "updated_by", nullable = false)
@JsonIgnore
private Long updatedBy;
@LastModifiedDate
@Column(name = "updated_time", nullable = false)
@JsonIgnore
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updatedTime;
@Version
@Column(name = "version", length = 20)
private Long version;
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
package com.tools.module.sys.entity;
import lombok.Data;
@Data
public class SysFile {
private Integer fileId;
private String name;
private Integer parentId;
private String parentPath;
private boolean directory;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment