修改项目包名称为mdd

This commit is contained in:
TinyAnts
2022-08-19 09:39:25 +08:00
parent ac835fb2e1
commit 6352e12427
203 changed files with 712 additions and 725 deletions

View File

@@ -0,0 +1,44 @@
package com.mdd.common.config;
/**
* 全局配置
*/
public class GlobalConfig {
// 开启调试模式
public static Boolean debug = true;
// 获取地址开关
public static Boolean isAddressEnabled = false;
// 当前代码版本
public static String version = "v1.2.0";
// 系统加密字符
public static String secret = "UVTIyzCy";
// Mysql表前缀
public static String tablePrefix = "la_";
// Redis键前缀
public static String redisPrefix = "Like:";
// 资源访问前缀
public static String publicPrefix = "api/uploads";
// 上传映射目录
public static String uploadDirectory = "/www/like-admin/uploads/";
// 上传图片限制
public static Integer uploadImageSize = 1024 * 1024 * 10;
// 上传视频限制
public static Integer uploadVideoSize = 1024 * 1024 * 10;
// 上传图片扩展
public static String[] uploadImageExt = new String[] {"png", "jpg", "jpeg", "gif", "ico", "bmp"};
// 上传视频扩展
public static String[] uploadVideoExt = new String[] {"mp4", "mp3", "avi", "flv", "rmvb", "mov"};
}

View File

@@ -0,0 +1,31 @@
package com.mdd.common.config;
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Redis配置
*/
@Configuration
public class RedisConfig {
@Bean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
GenericJackson2JsonRedisSerializer JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setValueSerializer(JsonRedisSerializer);
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
redisTemplate.setHashValueSerializer(JsonRedisSerializer);
return redisTemplate;
}
}

View File

@@ -0,0 +1,38 @@
package com.mdd.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
* 异步线程池配置
*/
@Configuration
@EnableAsync
public class ThreadPoolConfig {
@Bean("taskExecutor")
public Executor asyncServiceExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数
executor.setCorePoolSize(5);
// 设置最大线程数
executor.setMaxPoolSize(20);
// 配置队列大小
executor.setQueueCapacity(Integer.MAX_VALUE);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(60);
// 设置默认线程名称
executor.setThreadNamePrefix("LIKE");
// 等待所有任务结束后再关闭线程
executor.setWaitForTasksToCompleteOnShutdown(true);
// 执行初始化
executor.initialize();
// 返回构建对象
return executor;
}
}

View File

@@ -0,0 +1,180 @@
package com.mdd.common.core;
import com.mdd.common.enums.HttpEnum;
import lombok.Data;
import java.io.Serializable;
import java.util.ArrayList;
@Data
public class AjaxResult implements Serializable {
private static final long serialVersionUID = 1L;
/** 状态码 **/
private Integer code;
/** 提示信息 **/
private String msg;
/** 响应数据 **/
private Object data;
/**
* 无参构造
*/
public AjaxResult() {}
/**
* 带参构造
*
* @author fzr
* @param code 状态码
* @param msg 提示信息
* @param data 响应数据
*/
public AjaxResult(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
/**
* 成功返回结果
*
* @author fzr
* @return AjaxResult
*/
public static AjaxResult success() {
return new AjaxResult(HttpEnum.SUCCESS.getCode(), HttpEnum.SUCCESS.getMsg(), new ArrayList<>());
}
/**
* 成功返回结果
*
* @author fzr
* @param code 状态码
* @return AjaxResult
*/
public static AjaxResult success(Integer code) {
return new AjaxResult(code, HttpEnum.FAILED.getMsg(), new ArrayList<>());
}
/**
* 成功返回结果
*
* @author fzr
* @param msg 提示信息
* @return AjaxResult
*/
public static AjaxResult success(String msg) {
return new AjaxResult(HttpEnum.SUCCESS.getCode(), msg, new ArrayList<>());
}
/**
* 成功返回结果
*
* @author fzr
* @param data 响应数据
* @return AjaxResult
*/
public static AjaxResult success(Object data) {
return new AjaxResult(HttpEnum.SUCCESS.getCode(), HttpEnum.SUCCESS.getMsg(), data);
}
/**
* 成功返回结果
*
* @author fzr
* @param code 状态码
* @param msg 提示信息
* @return AjaxResult
*/
public static AjaxResult success(Integer code, String msg) {
return new AjaxResult(code, msg, new ArrayList<>());
}
/**
* 成功返回结果
*
* @author fzr
* @param msg 提示信息
* @param data 响应数据
* @return AjaxResult
*/
public static AjaxResult success(String msg, Object data) {
return new AjaxResult(HttpEnum.SUCCESS.getCode(), msg, data);
}
/**
* 成功返回结果
*
* @author fzr
* @param code 状态码
* @param msg 提示信息
* @param data 响应数据
* @return AjaxResult
*/
public static AjaxResult success(Integer code, String msg, Object data) {
return new AjaxResult(code, msg, data);
}
/**
* 响应失败结果
*
* @author fzr
* @param code 状态码
* @return AjaxResult
*/
public static AjaxResult failed(Integer code) {
return new AjaxResult(code, HttpEnum.FAILED.getMsg(), new ArrayList<>());
}
/**
* 响应失败结果
*
* @author fzr
* @param msg 提示信息
* @return AjaxResult
*/
public static AjaxResult failed(String msg) {
return new AjaxResult(HttpEnum.FAILED.getCode(), msg, new ArrayList<>());
}
/**
* 响应失败结果
*
* @author fzr
* @param data 响应数据
* @return AjaxResult
*/
public static AjaxResult failed(Object data) {
return new AjaxResult(HttpEnum.FAILED.getCode(), HttpEnum.FAILED.getMsg(), data);
}
/**
* 响应失败结果
*
* @author fzr
* @param code 状态码
* @param msg 提示信息
* @return AjaxResult
*/
public static AjaxResult failed(Integer code, String msg) {
return new AjaxResult(code, msg, new ArrayList<>());
}
/**
* 响应失败结果
*
* @author fzr
* @param code 状态码
* @param msg 提示信息
* @param data 响应数据
* @return AjaxResult
*/
public static AjaxResult failed(Integer code, String msg, Object data) {
return new AjaxResult(code, msg, data);
}
}

View File

@@ -0,0 +1,85 @@
package com.mdd.common.core;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.PageInfo;
import lombok.Data;
import java.util.List;
@Data
public class PageResult<T> {
private Long count; //总记录数
private Integer pageNo; //当前页码
private Integer pageSize; //每页条数
private List<T> lists; //数据列表
/**
* PageHelper分页
*
* @author fzr
* @param list 分页数据集
* @param <T> 实体类型
* @return PageList
*/
public static <T> PageResult<T> pageHelper(List<T> list) {
PageResult<T> pageResult = new PageResult<>();
PageInfo<T> pageInfo = new PageInfo<>(list);
pageResult.setCount(pageInfo.getTotal());
pageResult.setPageNo(pageInfo.getPageNum());
pageResult.setPageSize(pageInfo.getPageSize());
pageResult.setLists(pageInfo.getList());
return pageResult;
}
/**
* PageHelper分页(数据额外处理)
*
* @author fzr
* @param list 分页数据集
* @param <T> 实体类型
* @return PageList
*/
public static <T> PageResult<T> pageHelper(List<T> list, List<T> data) {
PageResult<T> pageResult = new PageResult<>();
PageInfo<T> pageInfo = new PageInfo<>(list);
pageResult.setCount(pageInfo.getTotal());
pageResult.setPageSize(pageInfo.getPageSize());
pageResult.setPageNo(pageInfo.getPageNum());
pageResult.setLists(data);
return pageResult;
}
/**
* MyBatisPlus分页
*
* @author fzr
* @param <T> 实体类型
* @return PageList
*/
public static <T> PageResult<T> iPageHandle(IPage<T> iPage) {
PageResult<T> pageResult = new PageResult<>();
pageResult.setCount(iPage.getTotal());
pageResult.setPageNo((int) iPage.getCurrent());
pageResult.setPageSize((int) iPage.getSize());
pageResult.setLists(iPage.getRecords());
return pageResult;
}
/**
* MyBatisPlus分页(数据额外处理)
*
* @author fzr
* @param <T> 实体类型
* @return PageList
*/
public static <T> PageResult<T> iPageHandle(Long total, Long pageNo, Long size, List<T> list) {
PageResult<T> pageResult = new PageResult<>();
pageResult.setCount(total);
pageResult.setPageNo(Math.toIntExact(pageNo));
pageResult.setPageSize(Math.toIntExact(size));
pageResult.setLists(list);
return pageResult;
}
}

View File

@@ -0,0 +1,169 @@
package com.mdd.common.core;
import com.mdd.common.entity.server.*;
import com.mdd.common.utils.ArithUtil;
import com.mdd.common.utils.IpUtil;
import com.mdd.common.utils.TimeUtil;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.Util;
import java.lang.management.ManagementFactory;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 服务器相关信息
*/
public class ServerResult {
private static final int OSHI_WAIT_SECOND = 1000;
private final Cpu cpu = new Cpu(); // CPU相关信息
private final Mem mem = new Mem(); // 內存相关信息
private final Jvm jvm = new Jvm(); // JVM相关信息
private final Sys sys = new Sys(); // 服务器相关信息
private final List<Disk> disk = new LinkedList<>(); // 磁盘相关信息
/**
* 拷贝数据
*/
public Map<String, Object> copyTo() {
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
setCpuInfo(hal.getProcessor());
setMemInfo(hal.getMemory());
setSysInfo();
setJvmInfo();
setSysFiles(si.getOperatingSystem());
Map<String, Object> map = new LinkedHashMap<>();
map.put("cpu", this.cpu);
map.put("mem", this.mem);
map.put("sys", this.sys);
map.put("disk", this.disk);
map.put("jvm", this.jvm);
return map;
}
/**
* 设置CPU信息
*/
private void setCpuInfo(CentralProcessor processor) {
long[] prevTicks = processor.getSystemCpuLoadTicks();
Util.sleep(OSHI_WAIT_SECOND);
long[] ticks = processor.getSystemCpuLoadTicks();
long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
long softer = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
long ioWait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
long totalCpu = user + nice + cSys + idle + ioWait + irq + softer + steal;
cpu.setCpuNum(processor.getLogicalProcessorCount());
cpu.setTotal(ArithUtil.round(ArithUtil.mul(totalCpu, 100), 2));
cpu.setSys(ArithUtil.round(ArithUtil.mul(cSys / cpu.getTotal(), 100), 2));
cpu.setUsed(ArithUtil.round(ArithUtil.mul(user / cpu.getTotal(), 100), 2));
cpu.setWait(ArithUtil.round(ArithUtil.mul(ioWait / cpu.getTotal(), 100), 2));
cpu.setFree( ArithUtil.round(ArithUtil.mul(idle / cpu.getTotal(), 100), 2));
}
/**
* 设置内存信息
*/
private void setMemInfo(GlobalMemory memory) {
int number = (1024 * 1024 * 1024);
mem.setTotal(ArithUtil.div(memory.getTotal(), number, 2));
mem.setUsed(ArithUtil.div(memory.getTotal() - memory.getAvailable(), number, 2));
mem.setFree(ArithUtil.div(memory.getAvailable(), number, 2));
mem.setUsage(ArithUtil.mul(ArithUtil.div(mem.getUsed(), memory.getTotal(), 4), 100));
}
/**
* 设置服务器信息
*/
private void setSysInfo() {
Properties props = System.getProperties();
sys.setComputerName(IpUtil.getHostName());
sys.setComputerIp(IpUtil.getHostIp());
sys.setOsName(props.getProperty("os.name"));
sys.setOsArch(props.getProperty("os.arch"));
sys.setUserDir(props.getProperty("user.dir"));
}
/**
* 设置Java虚拟机
*/
private void setJvmInfo() {
Properties props = System.getProperties();
jvm.setTotal(ArithUtil.div(Runtime.getRuntime().totalMemory(), (1024 * 1024), 2));
jvm.setMax(ArithUtil.div(Runtime.getRuntime().maxMemory(), (1024 * 1024), 2));
jvm.setFree(ArithUtil.div(Runtime.getRuntime().freeMemory(), (1024 * 1024), 2));
jvm.setUsage(ArithUtil.mul(ArithUtil.div(jvm.getTotal() - jvm.getFree(), jvm.getTotal(), 4), 100));
jvm.setVersion(props.getProperty("java.version"));
jvm.setHome(props.getProperty("java.home"));
jvm.setName(ManagementFactory.getRuntimeMXBean().getVmName());
jvm.setInputArgs(ManagementFactory.getRuntimeMXBean().getInputArguments().toString());
jvm.setRunTime(TimeUtil.datePoor(TimeUtil.nowDate(), TimeUtil.serverStartDate()));
jvm.setStartTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(TimeUtil.serverStartDate()));
}
/**
* 设置磁盘信息
*/
private void setSysFiles(OperatingSystem os) {
FileSystem fileSystem = os.getFileSystem();
List<OSFileStore> fsArray = fileSystem.getFileStores();
for (OSFileStore fs : fsArray)
{
long free = fs.getUsableSpace();
long total = fs.getTotalSpace();
long used = total - free;
Disk sysFile = new Disk();
sysFile.setDirName(fs.getMount());
sysFile.setSysTypeName(fs.getType());
sysFile.setTypeName(fs.getName());
sysFile.setTotal(convertFileSize(total));
sysFile.setFree(convertFileSize(free));
sysFile.setUsed(convertFileSize(used));
sysFile.setUsage(ArithUtil.mul(ArithUtil.div(used, total, 4), 100));
disk.add(sysFile);
}
}
/**
* 字节转换
*/
public String convertFileSize(long size) {
long kb = 1024;
long mb = kb * 1024;
long gb = mb * 1024;
if (size >= gb)
{
return String.format("%.1f GB", (float) size / gb);
}
else if (size >= mb)
{
float f = (float) size / mb;
return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
}
else if (size >= kb)
{
float f = (float) size / kb;
return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
}
else
{
return String.format("%d B", size);
}
}
}

View File

@@ -0,0 +1,309 @@
package com.mdd.common.core.basics;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.yulichang.base.MPJBaseMapper;
import com.github.yulichang.query.MPJQueryWrapper;
import com.mdd.common.utils.TimeUtil;
import org.apache.ibatis.annotations.Mapper;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* 基类Mapper
* @param <T>
*/
@Mapper
public interface IBaseMapper<T> extends MPJBaseMapper<T> {
/**
* 求和聚合
*
* @param field 字段名
* @param queryWrapper 条件构造器
* @return Long
*/
default BigDecimal sum(String field, QueryWrapper<T> queryWrapper) {
queryWrapper.select("IFNULL(sum("+field+"), 0) as totalValue");
List<Object> objects = this.selectObjs(queryWrapper);
if (objects.size() > 0) {
return (BigDecimal) objects.get(0);
}
return new BigDecimal(0);
}
/**
* 设置搜索条件
*
* @author fzr
* @param queryWrapper 条件构造器
* @param params 参数[条件:键@数据库字段:类型]
* @param conditions 条件
*/
default void setSearch(MPJQueryWrapper<T> queryWrapper, Map<String, String> params, String[] conditions) {
for (String condition : conditions) {
String[] array = condition.split(":");
String type = array.length > 2 ? array[2].trim() : "";
String[] keyArr = array[1].trim().split("@");
String where = array[0].trim();
String key = keyArr[0].trim();
String value = params.getOrDefault(key, "");
String field = keyArr.length > 1 ? keyArr[1].trim() : keyArr[0].trim();
if (!where.equals("datetime") && (value == null || value.equals(""))) {
continue;
}
if ((!type.equals("") && !Arrays.asList("long", "str", "int").contains(type))) {
System.out.println("搜索参数类型不在固定值内[int,long,str]");
continue;
}
Object val = value;
switch (where) {
case "=":
case "<>":
case ">=":
case ">":
case "<=":
case "<":
if (type.equals("int")) {
val = Integer.parseInt(value);
} else if (type.equals("long")) {
val = Long.parseLong(value);
}
break;
case "notIn":
case "in":
if (type.equals("long")){
List<Long> longData = new ArrayList<>();
for (String v : value.split(",")) {
longData.add(Long.parseLong(v.trim()));
}
val = longData;
} else if (type.equals("int")) {
List<Integer> intData = new ArrayList<>();
for (String v : value.split(",")) {
intData.add(Integer.parseInt(v.trim()));
}
val = intData;
}
break;
}
switch (where) {
case "<>":
queryWrapper.ne(field, val);
break;
case "=":
queryWrapper.eq(field, val);
break;
case ">":
queryWrapper.gt(field, val);
break;
case ">=":
queryWrapper.ge(field, val);
break;
case "<":
queryWrapper.lt(field, val);
break;
case "<=":
queryWrapper.le(field, val);
break;
case "between":
String[] betArr = value.split(",");
if (!type.equals("") && type.equals("int")) {
queryWrapper.between(field, Integer.parseInt(betArr[0]), Integer.parseInt(betArr[1]));
} else if (type.equals("long")){
queryWrapper.between(field, Long.parseLong(betArr[0]), Long.parseLong(betArr[1]));
} else {
queryWrapper.between(field, betArr[0], betArr[1]);
}
break;
case "notBetween":
String[] notBetArr = value.split(",");
if (!type.equals("") && type.equals("int")) {
queryWrapper.notBetween(field, Integer.parseInt(notBetArr[0]), Integer.parseInt(notBetArr[1]));
} else if (type.equals("long")){
queryWrapper.notBetween(field, Long.parseLong(notBetArr[0]), Long.parseLong(notBetArr[1]));
} else {
queryWrapper.notBetween(field, notBetArr[0], notBetArr[1]);
}
break;
case "like":
queryWrapper.like(field, val);
break;
case "notLike":
queryWrapper.notLike(field, val);
break;
case "likeLeft":
queryWrapper.likeLeft(field, val);
break;
case "likeRight":
queryWrapper.likeRight(field, val);
break;
case "in":
queryWrapper.in(field, val);
break;
case "notIn":
queryWrapper.notIn(field, val);
break;
case "datetime":
String[] dateKeys = key.split("-");
String dateStart = params.getOrDefault(dateKeys[0].trim(), "");
String dateEnd = dateKeys.length > 1 ? params.getOrDefault(dateKeys[1].trim(), "") : "";
if (type.equals("long")) {
if (!dateEnd.equals("")) { queryWrapper.le(field, Long.parseLong(dateEnd)); }
if (!dateStart.equals("")) { queryWrapper.ge(field, Long.parseLong(dateStart)); };
} else {
if (!dateStart.equals("")) { queryWrapper.ge(field, TimeUtil.dateToTimestamp(dateStart)); }
if (!dateEnd.equals("")) { queryWrapper.le(field, TimeUtil.dateToTimestamp(dateEnd)); }
}
break;
}
}
}
/**
* 设置搜索条件
*
* @author fzr
* @param queryWrapper 条件构造器
* @param params 参数[条件:键@数据库字段:类型]
* @param conditions 条件
*/
default void setSearch(QueryWrapper<T> queryWrapper, Map<String, String> params, String[] conditions) {
for (String condition : conditions) {
String[] array = condition.split(":");
String type = array.length > 2 ? array[2].trim() : "";
String where = array[0].trim();
String[] keyArr = array[1].trim().split("@");
String key = keyArr[0].trim();
String field = keyArr.length > 1 ? keyArr[1].trim() : keyArr[0].trim();
String value = params.getOrDefault(key, "");
if (value.equals("") && !where.equals("datetime")) {
continue;
}
if ((!type.equals("") && !Arrays.asList("int", "long", "str").contains(type))) {
System.out.println("搜索参数类型不在固定值内[int,long,str]");
continue;
}
Object val = value;
switch (where) {
case "=":
case "<>":
case ">":
case ">=":
case "<":
case "<=":
if (type.equals("int")) {
val = Integer.parseInt(value);
} else if (type.equals("long")) {
val = Long.parseLong(value);
}
break;
case "in":
case "notIn":
if (type.equals("int")) {
List<Integer> intData = new ArrayList<>();
for (String v : value.split(",")) {
intData.add(Integer.parseInt(v.trim()));
}
val = intData;
} else if (type.equals("long")){
List<Long> longData = new ArrayList<>();
for (String v : value.split(",")) {
longData.add(Long.parseLong(v.trim()));
}
val = longData;
}
break;
}
switch (where) {
case "=":
queryWrapper.eq(field, val);
break;
case "<>":
queryWrapper.ne(field, val);
break;
case ">":
queryWrapper.gt(field, val);
break;
case ">=":
queryWrapper.ge(field, val);
break;
case "<":
queryWrapper.lt(field, val);
break;
case "<=":
queryWrapper.le(field, val);
break;
case "between":
String[] betArr = value.split(",");
if (type.equals("int")) {
queryWrapper.between(field, Integer.parseInt(betArr[0]), Integer.parseInt(betArr[1]));
} else if (type.equals("long")){
queryWrapper.between(field, Long.parseLong(betArr[0]), Long.parseLong(betArr[1]));
} else {
queryWrapper.between(field, betArr[0], betArr[1]);
}
break;
case "notBetween":
String[] notBetArr = value.split(",");
if (type.equals("int")) {
queryWrapper.notBetween(field, Integer.parseInt(notBetArr[0]), Integer.parseInt(notBetArr[1]));
} else if (type.equals("long")){
queryWrapper.notBetween(field, Long.parseLong(notBetArr[0]), Long.parseLong(notBetArr[1]));
} else {
queryWrapper.notBetween(field, notBetArr[0], notBetArr[1]);
}
break;
case "like":
queryWrapper.like(field, val);
break;
case "notLike":
queryWrapper.notLike(field, val);
break;
case "likeLeft":
queryWrapper.likeLeft(field, val);
break;
case "likeRight":
queryWrapper.likeRight(field, val);
break;
case "in":
queryWrapper.in(field, val);
break;
case "notIn":
queryWrapper.notIn(field, val);
break;
case "datetime":
String[] dateKeys = key.split("-");
String dateStart = params.getOrDefault(dateKeys[0].trim(), "");
String dateEnd = dateKeys.length > 1 ? params.getOrDefault(dateKeys[1].trim(), "") : "";
if (type.equals("long")) {
if (!dateStart.equals("")) { queryWrapper.ge(field, Long.parseLong(dateStart)); }
if (!dateEnd.equals("")) { queryWrapper.le(field, Long.parseLong(dateEnd)); }
} else {
if (!dateStart.equals("")) { queryWrapper.ge(field, TimeUtil.dateToTimestamp(dateStart)); };
if (!dateEnd.equals("")) { queryWrapper.le(field, TimeUtil.dateToTimestamp(dateEnd)); }
}
break;
}
}
}
}

View File

@@ -0,0 +1,32 @@
package com.mdd.common.entity.album;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 相册实体
*/
@Data
public class Album implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键ID
private Integer cid; // 类目ID
private Integer aid; // 管理ID
private Integer uid; // 用户ID
private Integer type; // 文件类型: [10=图片, 20=视频]
private String name; // 文件名称
private String uri; // 文件路径
private String ext; // 文件扩展
private Long size; // 文件大小
private Integer isDelete; // 是否删除: [0=否, 1=是]
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
private Long deleteTime; // 删除时间
}

View File

@@ -0,0 +1,27 @@
package com.mdd.common.entity.album;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 相册分类实体
*/
@Data
public class AlbumCate implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键ID
private Integer pid; // 父级ID
private Integer type; // 分类类型: [10=图片,20=视频]
private String name; // 分类名称
private Integer isDelete; // 是否删除: 0=否1=是
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
private Long deleteTime; // 删除时间
}

View File

@@ -0,0 +1,32 @@
package com.mdd.common.entity.article;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 文章实体
*/
@Data
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
private Integer cid; // 分类
private String title; // 标题
private String intro; // 简介
private String image; // 封面
private String content; // 内容
private Integer visit; // 浏览
private Integer sort; // 排序
private Integer isShow; // 是否显示: [0=否, 1=是]
private Integer isDelete; // 是否删除: [0=否, 1=是]
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
private Long deleteTime; // 删除时间
}

View File

@@ -0,0 +1,27 @@
package com.mdd.common.entity.article;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 文章分类实体
*/
@Data
public class ArticleCategory implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
private String name; // 名称
private Integer sort; // 排序
private Integer isShow; // 是否显示: [0=否, 1=是]
private Integer isDelete; // 是否删除: [0=否, 1=是]
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
private Long deleteTime; // 删除时间
}

View File

@@ -0,0 +1,45 @@
package com.mdd.common.entity.server;
import lombok.Data;
import java.io.Serializable;
/**
* CPU相关信息
*/
@Data
public class Cpu implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 核心数
*/
private int cpuNum;
/**
* CPU总的使用率
*/
private double total;
/**
* CPU系统使用率
*/
private double sys;
/**
* CPU用户使用率
*/
private double used;
/**
* CPU当前等待率
*/
private double wait;
/**
* CPU当前空闲率
*/
private double free;
}

View File

@@ -0,0 +1,50 @@
package com.mdd.common.entity.server;
import lombok.Data;
import java.io.Serializable;
/**
* 系统文件相关信息
*/
@Data
public class Disk implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 盘符路径
*/
private String dirName;
/**
* 盘符类型
*/
private String sysTypeName;
/**
* 文件类型
*/
private String typeName;
/**
* 总大小
*/
private String total;
/**
* 剩余大小
*/
private String free;
/**
* 已经使用量
*/
private String used;
/**
* 资源的使用率
*/
private double usage;
}

View File

@@ -0,0 +1,64 @@
package com.mdd.common.entity.server;
import lombok.Data;
import java.io.Serializable;
/**
* JVM相关信息
*/
@Data
public class Jvm implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 当前JVM占用的内存总数(M)
*/
private double total;
/**
* JVM最大可用内存总数(M)
*/
private double max;
/**
* JVM空闲内存(M)
*/
private double free;
/**
* JVM内存使用率
*/
private double usage;
/**
* JDK版本
*/
private String version;
/**
* JDK路径
*/
private String home;
/**
* JDK名称
*/
private String name;
/**
* 运行参数
*/
private String inputArgs;
/**
* JDK运行时间
*/
private String runTime;
/**
* JDK启动时间
*/
private String startTime;
}

View File

@@ -0,0 +1,35 @@
package com.mdd.common.entity.server;
import lombok.Data;
import java.io.Serializable;
/**
* 內存相关信息
*/
@Data
public class Mem implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 内存总量
*/
private double total;
/**
* 已用内存
*/
private double used;
/**
* 剩余内存
*/
private double free;
/**
* 使用率
*/
private double usage;
}

View File

@@ -0,0 +1,40 @@
package com.mdd.common.entity.server;
import lombok.Data;
import java.io.Serializable;
/**
* 系统相关信息
*/
@Data
public class Sys implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 服务器名称
*/
private String computerName;
/**
* 服务器Ip
*/
private String computerIp;
/**
* 项目路径
*/
private String userDir;
/**
* 操作系统
*/
private String osName;
/**
* 系统架构
*/
private String osArch;
}

View File

@@ -0,0 +1,30 @@
package com.mdd.common.entity.setting;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 字典数据实体
*/
@Data
public class DictData implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
private Integer typeId; // 类型
private String name; // 键名
private String value; // 数值
private String remark; // 备注
private Integer sort; // 排序
private Integer status; // 状态: [0=停用, 1-正常]
private Integer isDelete; // 是否删除: [0=否, 1=是]
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
private Long deleteTime; // 删除时间
}

View File

@@ -0,0 +1,28 @@
package com.mdd.common.entity.setting;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 字典类型实体
*/
@Data
public class DictType implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 字典主键
private String dictName; // 字典名称
private String dictType; // 字典类型
private String dictRemark; // 字典备注
private Integer dictStatus; // 字典状态: [0=停用, 1=正常]
private Integer isDelete; // 是否删除: [0=否, 1=是]
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
private Long deleteTime; // 删除时间
}

View File

@@ -0,0 +1,37 @@
package com.mdd.common.entity.system;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 系统管理员实体
*/
@Data
public class SystemAuthAdmin implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type=IdType.AUTO)
private Integer id; // 主键
private Integer deptId; // 部门ID
private Integer postId; // 岗位ID
private String nickname; // 用户账号
private String username; // 用户昵称
private String password; // 用户密码
private String avatar; // 用户头像
private String salt; // 角色主键
private Integer role; // 加密盐巴
private Integer sort; // 排序编号
private Integer isMultipoint; // 多端登录: [0=否, 1=是]
private Integer isDisable; // 是否禁用: [0=否, 1=是]
private Integer isDelete; // 是否删除: [0=否, 1=是]
private String lastLoginIp; // 最后登录IP
private Long lastLoginTime; // 最后登录时间
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
private Long deleteTime; // 删除时间
}

View File

@@ -0,0 +1,30 @@
package com.mdd.common.entity.system;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 系统岗位实体
*/
@Data
public class SystemAuthDept implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
private Integer pid; // 上级部门
private String name; // 部门名称
private String duty; // 负责人名
private String mobile; // 联系电话
private Integer sort; // 排序编号
private Integer isStop; // 是否禁用: [0=否, 1=是]
private Integer isDelete; // 是否删除: [0=否, 1=是]
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
private Long deleteTime; // 删除时间
}

View File

@@ -0,0 +1,35 @@
package com.mdd.common.entity.system;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 系统菜单实体
*/
@Data
public class SystemAuthMenu implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
private Integer pid; // 上级菜单
private String menuType; // 权限类型: [M=目录, C=菜单, A=按钮]
private String menuName; // 菜单名称
private String menuIcon; // 菜单图标
private Integer menuSort; // 菜单排序
private String perms; // 权限标识
private String paths; // 路由地址
private String component; // 前端组件
private String selected; // 选中路径
private String params; // 路由参数
private Integer isCache; // 是否缓存: [0=否, 1=是]
private Integer isShow; // 是否显示: [0=否, 1=是]
private Integer isDisable; // 是否禁用: [0=否, 1=是]
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
}

View File

@@ -0,0 +1,22 @@
package com.mdd.common.entity.system;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 系统角色菜单实体
*/
@Data
public class SystemAuthPerm implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_UUID)
private String id; // 主键
private Integer roleId; // 角色ID
private Integer menuId; // 菜单ID
}

View File

@@ -0,0 +1,29 @@
package com.mdd.common.entity.system;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 系统岗位管理
*/
@Data
public class SystemAuthPost implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
private String code; // 岗位编码
private String name; // 岗位名称
private String remarks; // 岗位备注
private Integer sort; // 岗位排序
private Integer isStop; // 是否停用: [0=否, 1=是]
private Integer isDelete; // 是否删除: [0=否, 1=是]
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
private Long deleteTime; // 删除时间
}

View File

@@ -0,0 +1,26 @@
package com.mdd.common.entity.system;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 系统角色实体
*/
@Data
public class SystemAuthRole implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
private String name; // 角色名称
private String remark; // 备注信息
private Integer sort; // 角色排序
private Integer isDisable; // 是否禁用: [0=否, 1=是]
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
}

View File

@@ -0,0 +1,25 @@
package com.mdd.common.entity.system;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 系统配置实体
*/
@Data
public class SystemConfig implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
private String type; // 类型
private String name; // 键
private String value; // 值
private Long createTime; // 创建时间
private Long updateTime; // 更新时间
}

View File

@@ -0,0 +1,27 @@
package com.mdd.common.entity.system;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 系统登录日志实体
*/
@Data
public class SystemLogLogin implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
private Integer adminId; // 管理员ID
private String username; // 登录账号
private String ip; // 登录IP
private String os; // 操作系统
private String browser; // 浏览器
private Integer status; // 操作状态: [1=成功, 2=失败]
private Long createTime; // 创建时间
}

View File

@@ -0,0 +1,33 @@
package com.mdd.common.entity.system;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
/**
* 系统操作日志实体
*/
@Data
public class SystemLogOperate implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value="id", type= IdType.AUTO)
private Integer id; // 主键
private Integer adminId; // 操作人ID
private String type; // 请求类型: GET/POST/PUT
private String title; // 操作标题
private String method; // 请求方法
private String ip; // 请求IP
private String url; // 请求接口
private String args; // 请求参数
private String error; // 错误信息
private Integer status; // 执行状态: [1=成功, 2=失败]
private Long startTime; // 开始时间
private Long endTime; // 结束时间
private Long taskTime; // 执行耗时
private Long createTime; // 创建时间
}

View File

@@ -0,0 +1,41 @@
package com.mdd.common.enums;
/**
* 相册枚举
*/
public enum AlbumEnum {
IMAGE(10, "图片"),
Video(20, "视频");
/**
* 构造方法
*/
private final int code;
private final String msg;
AlbumEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 获取状态码
*
* @author fzr
* @return Long
*/
public int getCode() {
return this.code;
}
/**
* 获取提示
*
* @author fzr
* @return String
*/
public String getMsg() {
return this.msg;
}
}

View File

@@ -0,0 +1,53 @@
package com.mdd.common.enums;
public enum HttpEnum {
SUCCESS(200, "成功"),
FAILED(300, "失败"),
PARAMS_VALID_ERROR(310, "参数校验错误"),
PARAMS_TYPE_ERROR(311, "参数类型错误"),
REQUEST_METHOD_ERROR(312, "请求方法错误"),
ASSERT_ARGUMENT_ERROR(313, "断言参数错误"),
ASSERT_MYBATIS_ERROR(314, "断言Mybatis错误"),
LOGIN_ACCOUNT_ERROR(330, "登录账号或密码错误"),
LOGIN_DISABLE_ERROR(331, "登录账号已被禁用了"),
TOKEN_EMPTY(332, "token参数为空"),
TOKEN_INVALID(333, "token参数无效"),
NO_PERMISSION(403, "无相关权限"),
REQUEST_404_ERROR(404, "请求接口不存在"),
SYSTEM_ERROR(500, "系统错误");
/**
* 构造方法
*/
private final int code;
private final String msg;
HttpEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 获取状态码
*
* @author fzr
* @return Long
*/
public int getCode() {
return this.code;
}
/**
* 获取提示
*
* @author fzr
* @return String
*/
public String getMsg() {
return this.msg;
}
}

View File

@@ -0,0 +1,21 @@
package com.mdd.common.exception;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 异常基类
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class BaseException extends RuntimeException {
private Integer code;
private String msg;
public BaseException(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
}

View File

@@ -0,0 +1,139 @@
package com.mdd.common.exception;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.mdd.common.config.GlobalConfig;
import com.mdd.common.core.AjaxResult;
import com.mdd.common.enums.HttpEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.*;
import java.util.Objects;
/**
* 全局异常处理
*/
@Slf4j
@ControllerAdvice
public class GlobalException {
/**
* 处理所有不可知异常
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(Exception.class)
@ResponseBody
public AjaxResult handleException(Exception e) {
if (GlobalConfig.debug) {
e.printStackTrace();
System.out.println(e.getMessage());
}
log.error("系统异常 {}", e.getMessage());
return AjaxResult.failed(HttpEnum.SYSTEM_ERROR.getCode(), HttpEnum.SYSTEM_ERROR.getMsg());
}
/**
* 拦截自定义抛出异常
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(BaseException.class)
@ResponseBody
public AjaxResult handleException(BaseException e) {
int code = e.getCode();
String msg = e.getMsg();
return AjaxResult.failed(code, msg);
}
/**
* 拦截表单参数校验FROM
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(BindException.class)
@ResponseBody
public AjaxResult handleBindException(BindException e) {
BindingResult bindingResult = e.getBindingResult();
Integer code = HttpEnum.PARAMS_VALID_ERROR.getCode();
String msg = Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();
return AjaxResult.failed(code, msg);
}
/**
* 拦截路径参数校验PATH
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(MissingServletRequestParameterException.class)
@ResponseBody
public AjaxResult handlePathException(MissingServletRequestParameterException e) {
Integer code = HttpEnum.PARAMS_VALID_ERROR.getCode();
String msg = Objects.requireNonNull(e.getMessage());
return AjaxResult.failed(code, msg);
}
/**
* 拦截JSON参数校验
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public AjaxResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
BindingResult bindingResult = e.getBindingResult();
Integer code = HttpEnum.PARAMS_VALID_ERROR.getCode();
String msg = Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();
return AjaxResult.failed(code, msg);
}
/**
* 拦截参数类型不正确
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseBody
public AjaxResult handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
Integer code = HttpEnum.PARAMS_TYPE_ERROR.getCode();
String msg = Objects.requireNonNull(e.getMessage());
return AjaxResult.failed(code, msg.split(";")[0]);
}
/**
* 拦截请求方法
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
@ResponseBody
public AjaxResult handleRequestMethodException(HttpRequestMethodNotSupportedException e) {
Integer code = HttpEnum.REQUEST_METHOD_ERROR.getCode();
String msg = Objects.requireNonNull(e.getMessage());
return AjaxResult.failed(code, msg);
}
/**
* 拦截断言异常
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public AjaxResult handleIllegalArgumentException(IllegalArgumentException e) {
Integer code = HttpEnum.ASSERT_ARGUMENT_ERROR.getCode();
String msg = Objects.requireNonNull(e.getMessage());
return AjaxResult.failed(code, msg);
}
/**
* 拦截MybatisPlus异常
*/
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(MybatisPlusException.class)
@ResponseBody
public AjaxResult handleMybatisPlusException(MybatisPlusException e) {
Integer code = HttpEnum.ASSERT_MYBATIS_ERROR.getCode();
String msg = Objects.requireNonNull(e.getMessage());
return AjaxResult.failed(code, msg);
}
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.exception;
/**
* 登录异常类
*/
public class LoginException extends BaseException {
public LoginException(Integer code, String msg) {
super(code, msg);
}
}

View File

@@ -0,0 +1,14 @@
package com.mdd.common.exception;
import com.mdd.common.enums.HttpEnum;
/**
* 操作系统异常
*/
public class OperateException extends BaseException {
public OperateException(String msg) {
super(HttpEnum.FAILED.getCode(), msg);
}
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.album;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.album.AlbumCate;
import org.apache.ibatis.annotations.Mapper;
/**
* 相册分类
*/
@Mapper
public interface AlbumCateMapper extends IBaseMapper<AlbumCate> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.album;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.album.Album;
import org.apache.ibatis.annotations.Mapper;
/**
* 相册
*/
@Mapper
public interface AlbumMapper extends IBaseMapper<Album> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.article;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.article.ArticleCategory;
import org.apache.ibatis.annotations.Mapper;
/**
* 文章分类
*/
@Mapper
public interface ArticleCategoryMapper extends IBaseMapper<ArticleCategory> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.article;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.article.Article;
import org.apache.ibatis.annotations.Mapper;
/**
* 文章
*/
@Mapper
public interface ArticleMapper extends IBaseMapper<Article> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.setting;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.setting.DictData;
import org.apache.ibatis.annotations.Mapper;
/**
* 字典数据Mapper
*/
@Mapper
public interface DictDataMapper extends IBaseMapper<DictData> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.setting;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.setting.DictType;
import org.apache.ibatis.annotations.Mapper;
/**
* 字典类型Mapper
*/
@Mapper
public interface DictTypeMapper extends IBaseMapper<DictType> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.system;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.system.SystemAuthAdmin;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统管理员Mapper
*/
@Mapper
public interface SystemAuthAdminMapper extends IBaseMapper<SystemAuthAdmin> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.system;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.system.SystemAuthDept;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统岗位Mapper
*/
@Mapper
public interface SystemAuthDeptMapper extends IBaseMapper<SystemAuthDept> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.system;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.system.SystemAuthMenu;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统菜单Mapper
*/
@Mapper
public interface SystemAuthMenuMapper extends IBaseMapper<SystemAuthMenu> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.system;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.system.SystemAuthPerm;
import org.apache.ibatis.annotations.Mapper;
/**
* 角色菜单Mapper
*/
@Mapper
public interface SystemAuthPermMapper extends IBaseMapper<SystemAuthPerm> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.system;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.system.SystemAuthPost;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统岗位Mapper
*/
@Mapper
public interface SystemAuthPostMapper extends IBaseMapper<SystemAuthPost> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.system;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.system.SystemAuthRole;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统角色Mapper
*/
@Mapper
public interface SystemAuthRoleMapper extends IBaseMapper<SystemAuthRole> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.system;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.system.SystemConfig;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统配置
*/
@Mapper
public interface SystemConfigMapper extends IBaseMapper<SystemConfig> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.system;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.system.SystemLogLogin;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统登录日志
*/
@Mapper
public interface SystemLogLoginMapper extends IBaseMapper<SystemLogLogin> {
}

View File

@@ -0,0 +1,12 @@
package com.mdd.common.mapper.system;
import com.mdd.common.core.basics.IBaseMapper;
import com.mdd.common.entity.system.SystemLogOperate;
import org.apache.ibatis.annotations.Mapper;
/**
* 系统操作日志
*/
@Mapper
public interface SystemLogOperateMapper extends IBaseMapper<SystemLogOperate> {
}

View File

@@ -0,0 +1,76 @@
package com.mdd.common.plugin.sms;
import com.alibaba.fastjson.JSON;
import com.mdd.common.plugin.sms.engine.AliSms;
import com.mdd.common.plugin.sms.engine.TencentSms;
import com.mdd.common.utils.ConfigUtil;
import java.util.Map;
public class SmsDriver {
private String mobile; // 手机号码
private String templateId; // 短信模板
private String smsContent; // 短信内容
private Map<String, String> param; // 短信参数
private final String engine; // 短信引擎
private final Map<String, String> config; // 短信配置
/**
* 构造方法
*/
public SmsDriver() {
this.engine = ConfigUtil.get("sms", "default", "aliyun");
this.config = ConfigUtil.getMap("sms", this.engine);
}
/**
* 设置手机号
*
* @author fzr
* @param mobile 手机号
* @return SmsDriver
*/
public SmsDriver setMobile(String mobile) {
this.mobile = mobile;
return this;
}
/**
* 设置参数
*
* @author fzr
* @param param 参数
* @return SmsDriver
*/
public SmsDriver setParam(Map<String, String> param) {
this.param = param;
return this;
}
/**
* 发送短信
*
* @author fzr
*/
public void sendSms() {
String templateParam = JSON.toJSONString(param);
switch (this.engine) {
case "aliyun":
AliSms aliSms = new AliSms(this.config);
aliSms.setMobile(this.mobile)
.setTemplateId(this.templateId)
.setTemplateParams(templateParam)
.send();
break;
case "tencent":
TencentSms tencentSms = new TencentSms(this.config);
tencentSms.setMobile(this.mobile)
.setTemplateId(this.templateId)
.setTemplateParams(templateParam.split(","))
.send();
break;
}
}
}

View File

@@ -0,0 +1,106 @@
package com.mdd.common.plugin.sms.engine;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.mdd.common.exception.OperateException;
import java.util.Map;
/**
* 阿里云短信
*/
public class AliSms {
private String mobile; // 手机号码
private String templateId; // 短信模板
private String templateParams; // 短信参数
private final Map<String, String> config; // 短信配置
/**
* 构造方法
*
* @author fzr
* @param config 短信配置
*/
public AliSms(Map<String, String> config) {
this.config = config;
}
/**
* 设置手机号
*
* @author fzr
* @param mobile 手机号码
* @return AliSms
*/
public AliSms setMobile(String mobile) {
this.mobile = mobile;
return this;
}
/**
* 设置模板id
*
* @author fzr
* @param templateId 模板id
* @return AliSms
*/
public AliSms setTemplateId(String templateId) {
this.templateId = templateId;
return this;
}
/**
* 设置模板参数
*
* @author fzr
* @param templateParams 模板参数
* @return AliSms
*/
public AliSms setTemplateParams(String templateParams) {
this.templateParams = templateParams;
return this;
}
/**
* 发送短信
*
* @author fzr
* @return String
*/
public String send() {
DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", this.config.get("app_key"), this.config.get("secret_key"));
IAcsClient client = new DefaultAcsClient(profile);
CommonRequest request = new CommonRequest();
request.setSysMethod(MethodType.POST);
request.setSysDomain("dysmsapi.aliyuncs.com");
request.setSysVersion("2017-05-25");
request.setSysAction("SendSms");
request.putQueryParameter("PhoneNumbers", this.mobile);
request.putQueryParameter("SignName", this.config.get("sign"));
request.putQueryParameter("TemplateCode", this.templateId);
request.putQueryParameter("TemplateParam", this.templateParams);
try {
System.out.println("来来来来来");
CommonResponse response = client.getCommonResponse(request);
System.out.println(response);
JSONObject res = JSONObject.parseObject(response.getData());
if (!res.get("Code").equals("OK") || !res.get("Message").equals("OK")) {
throw new OperateException(res.get("Message").toString());
}
return response.getData();
} catch (Exception e) {
System.out.println(e.getMessage());
throw new OperateException("短信发送异常:" + e.getMessage());
}
}
}

View File

@@ -0,0 +1,108 @@
package com.mdd.common.plugin.sms.engine;
import com.mdd.common.exception.OperateException;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.common.profile.ClientProfile;
import com.tencentcloudapi.common.profile.HttpProfile;
import com.tencentcloudapi.sms.v20210111.SmsClient;
import com.tencentcloudapi.sms.v20210111.models.SendSmsRequest;
import com.tencentcloudapi.sms.v20210111.models.SendSmsResponse;
import java.util.Map;
/**
* 腾讯短信驱
*/
public class TencentSms {
private String mobile;
private String templateId;
private String[] templateParams;
private final Map<String, String> config;
public TencentSms(Map<String, String> config) {
this.config = config;
}
/**
* 设置手机号
* @author fzr
* @param mobile 手机号码
* @return AliSms
*/
public TencentSms setMobile(String mobile) {
this.mobile = mobile;
return this;
}
/**
* 设置模板id
* @author fzr
* @param templateId 模板id
* @return AliSms
*/
public TencentSms setTemplateId(String templateId) {
this.templateId = templateId;
return this;
}
/**
* 设置模板参数
* @author fzr
* @param templateParams 模板参数
* @return AliSms
*/
public TencentSms setTemplateParams(String[] templateParams) {
this.templateParams = templateParams;
return this;
}
/**
* 发送短信
*
* @param config 配置
* @return String
*/
public String send() {
try {
/*认证对象*/
Credential cred = new Credential(this.config.get("secret_id").toString(), config.get("secret_key").toString());
HttpProfile httpProfile = new HttpProfile();
httpProfile.setReqMethod("POST");
httpProfile.setConnTimeout(60);
httpProfile.setEndpoint("sms.tencentcloudapi.com");
/*客户端配置*/
ClientProfile clientProfile = new ClientProfile();
clientProfile.setSignMethod("HmacSHA256");
clientProfile.setHttpProfile(httpProfile);
/*参数配置*/
SmsClient client = new SmsClient(cred, "ap-guangzhou",clientProfile);
SendSmsRequest req = new SendSmsRequest();
req.setSignName(config.get("sign").toString());
req.setSmsSdkAppId(config.get("app_id").toString());
req.setTemplateId(this.templateId);
/*手机号码*/
String[] phoneNumberSet = {"+86"+this.mobile};
req.setPhoneNumberSet(phoneNumberSet);
/*模板参数*/
String[] templateParamSet = this.templateParams;
req.setTemplateParamSet(templateParamSet);
/*发起请求*/
SendSmsResponse res = client.SendSms(req);
if (!res.getSendStatusSet()[0].getCode().equals("Ok")) {
throw new Exception(res.getSendStatusSet()[0].getMessage());
}
return res.getSendStatusSet()[0].getMessage();
} catch (Exception e) {
throw new OperateException("短信发送异常:" + e.getMessage());
}
}
}

View File

@@ -0,0 +1,130 @@
package com.mdd.common.plugin.storage;
import com.mdd.common.config.GlobalConfig;
import com.mdd.common.exception.OperateException;
import com.mdd.common.plugin.storage.engine.AliyunStorage;
import com.mdd.common.plugin.storage.engine.LocalStorage;
import com.mdd.common.plugin.storage.engine.QcloudStorage;
import com.mdd.common.plugin.storage.engine.QiniuStorage;
import com.mdd.common.utils.ConfigUtil;
import com.mdd.common.utils.TimeUtil;
import com.mdd.common.utils.UrlUtil;
import org.springframework.web.multipart.MultipartFile;
import java.util.*;
public class StorageDriver {
/**
* 当前存储引擎
*/
private final String engine;
/**
* 存储引擎配置
*/
private final Map<String, String> config;
/**
* 构造方法
*/
public StorageDriver() {
this.engine = ConfigUtil.get("storage", "default", "local");
Map<String, String> config1;
config1 = ConfigUtil.getMap("storage", this.engine);
if (config1 == null) {
config1 = new HashMap<>();
}
this.config = config1;
}
/**
* 根据引擎类型上传文件
*
* @author fzr
* @param multipartFile 文件对象
* @param folder 文件夹
* @param type 类型: 10=图片, 20=视频
*/
public Map<String, Object> upload(MultipartFile multipartFile, String folder, Integer type) {
this.checkFile(multipartFile, type);
String key = this.buildSaveName(multipartFile);
switch (this.engine) {
case "local":
LocalStorage local = new LocalStorage();
local.upload(multipartFile, key, folder);
break;
case "qiniu":
QiniuStorage qiniu = new QiniuStorage(this.config);
qiniu.upload(multipartFile, folder + "/" + key);
break;
case "aliyun":
AliyunStorage aliyun = new AliyunStorage(this.config);
aliyun.upload(multipartFile, folder + "/" + key);
break;
case "qcloud":
QcloudStorage qcloud = new QcloudStorage(this.config);
qcloud.upload(multipartFile, folder + "/" + key);
break;
}
String origFileName = Objects.requireNonNull(multipartFile.getOriginalFilename());
String origFileExt = origFileName.substring(origFileName.lastIndexOf(".")).replace(".", "");
String newFileName = folder + "/" + key;
Map<String, Object> map = new LinkedHashMap<>();
map.put("id", 0);
map.put("name", multipartFile.getOriginalFilename());
map.put("size", multipartFile.getSize());
map.put("ext", origFileExt.toLowerCase());
map.put("url", newFileName);
map.put("path", UrlUtil.toAbsoluteUrl(newFileName));
return map;
}
/**
* 生成文件名称
*
* @author fzr
* @param multipartFile 文件对象
* @return String
*/
private String buildSaveName(MultipartFile multipartFile) {
String name = multipartFile.getOriginalFilename();
String ext = Objects.requireNonNull(name).substring(name.lastIndexOf("."));
String date = TimeUtil.timestampToDate(TimeUtil.timestamp(), "yyyyMMdd");
return date + "/" + UUID.randomUUID() + ext.toLowerCase();
}
/**
* 文件验证
*
* @author fzr
* @param multipartFile 文件对象
* @param type 类型: 10=图片, 20=视频
*/
private void checkFile(MultipartFile multipartFile, Integer type) {
String fileName = Objects.requireNonNull(multipartFile.getOriginalFilename());
String fileExt = fileName.substring(fileName.lastIndexOf(".")).replace(".", "").toLowerCase();
long fileSize = multipartFile.getSize();
if (type == 10) {
if (!Arrays.asList(GlobalConfig.uploadImageExt).contains(fileExt)) {
throw new OperateException("不被支持的扩展:" + fileExt);
}
if (fileSize > GlobalConfig.uploadImageSize) {
throw new OperateException("上传图片不能超出限制:" + GlobalConfig.uploadImageSize);
}
} else if (type == 20) {
if (!Arrays.asList(GlobalConfig.uploadVideoExt).contains(fileExt)) {
throw new OperateException("不被支持的扩展:" + fileExt);
}
if (fileSize > GlobalConfig.uploadVideoSize) {
throw new OperateException("上传视频不能超出限制:" + GlobalConfig.uploadImageSize);
}
}
}
}

View File

@@ -0,0 +1,67 @@
package com.mdd.common.plugin.storage.engine;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import com.mdd.common.exception.OperateException;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.util.Map;
/**
* 阿里云存储
*/
public class AliyunStorage {
/**
* 存储配置
*/
private final Map<String, String> config;
/**
* 构造方法
*/
public AliyunStorage(Map<String, String> config) {
this.config = config;
}
/**
* 鉴权令牌
*
* @author fzr
* @return String
*/
public OSS ossClient() {
String endpoint = "https://oss-cn-shenzhen.aliyuncs.com";
String accessKeyId = this.config.get("accessKey");
String accessKeySecret = this.config.get("secretKey");
return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
}
/**
* 上传文件
*
* @param multipartFile 文件对象
* @param key 文件名称 20220331/11.png
*/
public void upload(MultipartFile multipartFile, String key) {
try {
PutObjectRequest putObjectRequest = new PutObjectRequest(
this.config.get("bucket"), key,
new ByteArrayInputStream(multipartFile.getBytes())
);
this.ossClient().putObject(putObjectRequest);
} catch (OSSException oe) {
throw new OperateException(oe.getMessage());
} catch (Exception ce) {
throw new OperateException(ce.getMessage());
} finally {
if (this.ossClient() != null) {
this.ossClient().shutdown();
}
}
}
}

View File

@@ -0,0 +1,52 @@
package com.mdd.common.plugin.storage.engine;
import com.mdd.common.config.GlobalConfig;
import com.mdd.common.exception.OperateException;
import com.mdd.common.utils.YmlUtil;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
/**
* 本地存储
*/
public class LocalStorage {
/**
* 本地上传
*
* @author fzr
* @param multipartFile 上传对象
* @param key 文件名称 20220331/122.jpg
* @param folder 文件夹
*/
public void upload(MultipartFile multipartFile, String key, String folder) {
// 映射目录
String directory = YmlUtil.get("like.upload-directory");
if (directory == null || directory.equals("")) {
directory = GlobalConfig.uploadDirectory;
}
// 文件信息
String saveName = key.split("/")[1];
String savePath = (directory + folder + "/" + key.split("/")[0]).replace("\\", "/");
// 创建目录
File fileExist = new File(savePath);
if (!fileExist.exists()) {
if (!fileExist.mkdirs()) {
throw new OperateException("创建上传目录失败");
}
}
// 保存文件
try {
File dest = new File(savePath, saveName);
multipartFile.transferTo(dest);
} catch (Exception e) {
throw new OperateException("上传文件失败:"+e.getMessage());
}
}
}

View File

@@ -0,0 +1,75 @@
package com.mdd.common.plugin.storage.engine;
import com.mdd.common.exception.OperateException;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.exception.CosClientException;
import com.qcloud.cos.http.HttpProtocol;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.region.Region;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.Map;
/**
* 腾讯云存储
*/
public class QcloudStorage {
/**
* 存储配置
*/
private final Map<String, String> config;
/**
* 构造方法
*/
public QcloudStorage(Map<String, String> config) {
this.config = config;
}
/**
* 鉴权客户端
*
* @author fzr
* @return String
*/
public COSClient cosClient() {
String secretId = this.config.get("accessKey");
String secretKey = this.config.get("secretKey");
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
Region region = new Region(this.config.get("region"));
ClientConfig clientConfig = new ClientConfig(region);
clientConfig.setHttpProtocol(HttpProtocol.https);
return new COSClient(cred, clientConfig);
}
/**
* 上传文件
*
* @param multipartFile 文件对象
* @param key 文件名称 20220331/11.png
*/
public void upload(MultipartFile multipartFile, String key) {
try {
byte[] data = multipartFile.getBytes();
InputStream inputStream = new ByteArrayInputStream(data);
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentLength(multipartFile.getSize());
PutObjectRequest putObjectRequest = new PutObjectRequest(this.config.get("bucket"), key, inputStream, objectMetadata);
this.cosClient().putObject(putObjectRequest);
} catch (CosClientException e) {
e.printStackTrace();
} catch (Exception e) {
throw new OperateException(e.getMessage());
}
}
}

View File

@@ -0,0 +1,66 @@
package com.mdd.common.plugin.storage.engine;
import com.google.gson.Gson;
import com.mdd.common.exception.OperateException;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.Map;
/**
* 七牛云存储
*/
public class QiniuStorage {
/**
* 存储配置
*/
private final Map<String, String> config;
/**
* 构造方法
*/
public QiniuStorage(Map<String, String> config) {
this.config = config;
}
/**
* 鉴权令牌
*
* @author fzr
* @return String
*/
public String upToken() {
String accessKey = this.config.getOrDefault("accessKey", "");
String secretKey = this.config.getOrDefault("secretKey", "");
String bucket = this.config.getOrDefault("bucket", "");
Auth auth = Auth.create(accessKey, secretKey);
return auth.uploadToken(bucket);
}
/**
* 上传文件
*
* @author fzr
* @param multipartFile 文件对象
* @param key 保存文件的名称
*/
public void upload(MultipartFile multipartFile, String key) {
Configuration cfg = new Configuration(Region.region2());
UploadManager uploadManager = new UploadManager(cfg);
try {
Response response = uploadManager.put(multipartFile.getBytes(), key, this.upToken());
new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
} catch (IOException ex) {
throw new OperateException(ex.getMessage());
}
}
}

View File

@@ -0,0 +1,110 @@
package com.mdd.common.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 算术运算工具
*/
public class ArithUtil {
/** 默认除法运算精度 */
private static final int DEF_DIV_SCALE = 10;
/** 这个类不能实例化 */
private ArithUtil() {}
/**
* 提供精确的加法运算
*
* @param v1 被加数
* @param v2 加数
* @return 两个参数的和
*/
public static double add(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.add(b2).doubleValue();
}
/**
* 提供精确的减法运算
*
* @param v1 被减数
* @param v2 减数
* @return 两个参数的差
*/
public static double sub(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.subtract(b2).doubleValue();
}
/**
* 提供精确的乘法运算
*
* @param v1 被乘数
* @param v2 乘数
* @return 两个参数的积
*/
public static double mul(double v1, double v2) {
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
return b1.multiply(b2).doubleValue();
}
/**
* 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
* 小数点以后10位,以后的数字四舍五入
*
* @param v1 被除数
* @param v2 除数
* @return 两个参数的商
*/
public static double div(double v1, double v2) {
return div(v1, v2, DEF_DIV_SCALE);
}
/**
* 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
* 定精度,以后的数字四舍五入。
*
* @param v1 被除数
* @param v2 除数
* @param scale 表示表示需要精确到小数点以后几位。
* @return 两个参数的商
*/
public static double div(double v1, double v2, int scale) {
if (scale < 0)
{
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b1 = new BigDecimal(Double.toString(v1));
BigDecimal b2 = new BigDecimal(Double.toString(v2));
if (b1.compareTo(BigDecimal.ZERO) == 0)
{
return BigDecimal.ZERO.doubleValue();
}
return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
}
/**
* 提供精确的小数位四舍五入处理
*
* @param v 需要四舍五入的数字
* @param scale 小数点后保留几位
* @return 四舍五入后的结果
*/
public static double round(double v, int scale) {
if (scale < 0)
{
throw new IllegalArgumentException(
"The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = BigDecimal.ONE;
return b.divide(one, scale, RoundingMode.HALF_UP).doubleValue();
}
}

View File

@@ -0,0 +1,309 @@
package com.mdd.common.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.*;
/**
* 数组工具类
*/
public class ArrayUtil {
/**
* JSONArray转树形结构
*
* @author fzr
* @param arr JSON数组
* @param id 主键字段名
* @param pid 上级字段名
* @param child 子级字段名
* @return JSONArray
*/
public static JSONArray listToTree(JSONArray arr, String id, String pid, String child) {
JSONArray r = new JSONArray();
JSONObject hash = new JSONObject();
//将数组转为Object的形式,key为数组中的id
for (Object o : arr) {
JSONObject json = (JSONObject) o;
hash.put(json.getString(id), json);
}
//遍历结果集
for (Object o : arr) {
//单条记录
JSONObject aVal = (JSONObject) o;
//在hash中取出key为单条记录中pid的值
JSONObject hashVP = (JSONObject) hash.get(aVal.get(pid).toString());
//如果记录的pid存在,则说明它有父节点,将她添加到孩子节点的集合中
if (hashVP != null) {
//检查是否有child属性
if (hashVP.get(child) != null) {
JSONArray ch = (JSONArray) hashVP.get(child);
ch.add(aVal);
hashVP.put(child, ch);
} else {
JSONArray ch = new JSONArray();
ch.add(aVal);
hashVP.put(child, ch);
}
} else {
r.add(aVal);
}
}
return r;
}
/**
* List去重,不打乱原来顺序,泛型list对象
* 对象重写hashCode和equals
*
* @author fzr
* @param <T> 泛型
* @param list 列表
* @return List
*/
public static <T> List<T> uniqueBySetOrder(List<T> list){
Set<T> set = new HashSet<T>();
List<T> newList = new ArrayList<T>();
for(T t: list){
if(set.add(t)){
newList.add(t);
}
}
return newList;
}
/**
* List去重,可能打乱原来顺序,泛型list对象
* 对象重写hashCode和equals
*
* @author fzr
* @param list 列表
* @return List
*/
public static <T> List<T> uniqueBySet(List<T> list){
return new ArrayList<T>(new HashSet<T>(list));
}
/**
* 列表转字符串
*
* @author fzr
* @param list 列表 [1, 2, 4] -> 1,2,3
* @param separator 分割符号
* @return String
*/
public static String listToStringByLong(List<Long> list, String separator) {
StringBuilder sb = new StringBuilder();
for (Object o : list) {
sb.append(o).append(separator);
}
return list.isEmpty() ? "" : sb.substring(0, sb.toString().length() - 1);
}
/**
* 列表转字符串
*
* @author fzr
* @param list 列表 [1, 2, 4] -> 1,2,3
* @param separator 分割符号
* @return String
*/
public static String listToStringByInt(List<Integer> list, String separator) {
StringBuilder sb = new StringBuilder();
for (Object o : list) {
sb.append(o).append(separator);
}
return list.isEmpty() ? "" : sb.substring(0, sb.toString().length() - 1);
}
/**
* 列表转字符串
*
* @author fzr
* @param list 列表 ["1", "2", "3"] -> 1,2,3
* @param separator 分割符号
* @return String
*/
public static String listToStringByStr(List<String> list, String separator) {
StringBuilder sb = new StringBuilder();
for (Object o : list) {
sb.append(o).append(separator);
}
return list.isEmpty() ? "" : sb.substring(0, sb.toString().length() - 1);
}
/**
* 字符串分割,转化为数组
*
* @author fzr
* @param str 字符串
* @param regex 分隔符
* @return List<Long>
*/
public static List<Long> stringToListAsLong(String str, String regex){
List<Long> list = new ArrayList<>();
if (str.contains(regex)){
String[] split = str.split(regex);
for (String value : split) {
if(!StringUtil.isBlank(value)){
list.add(Long.parseLong(value.trim()));
}
}
}else {
list.add(Long.parseLong(str));
}
return list;
}
/**
* 字符串分割,转化为数组
*
* @author fzr
* @param str 字符串
* @param regex 分隔符
* @return List<Integer>
*/
public static List<Integer> stringToListAsInt(String str, String regex){
List<Integer> list = new ArrayList<>();
if (str.contains(regex)){
String[] split = str.split(regex);
for (String value : split) {
if(!StringUtil.isBlank(value)){
list.add(Integer.parseInt(value.trim()));
}
}
}else {
list.add(Integer.parseInt(str));
}
return list;
}
/**
* 字符串分割,转化为数组
*
* @author fzr
* @param str 字符串
* @param regex 分隔符
* @return List<String>
*/
public static List<String> stringToListAsStr(String str, String regex){
List<String> list = new ArrayList<>();
if (str.contains(regex)){
String[] split = str.split(regex);
for (String value : split) {
if(!StringUtil.isBlank(value)){
list.add(value.trim());
}
}
}else {
list.add(str);
}
return list;
}
/**
* 字符串转列表Map
*
* @author fzr
* @param s 字符串
* @return Map<String, Long>
*/
public static List<Map<String, Long>> stringToListAsMapLong(String s) {
Type type = new TypeToken<List<Map<String, Long>>>() {}.getType();
return JSON.parseObject(s, type);
}
/**
* 字符串转列表Map
*
* @author fzr
* @param s 字符串
* @return Map<String, Integer>
*/
public static List<Map<String, Integer>> stringToListAsMapInt(String s) {
Type type = new TypeToken<List<Map<String, Integer>>>() {}.getType();
return JSON.parseObject(s, type);
}
/**
* 字符串转列表Map
*
* @author fzr
* @param s 字符串
* @return Map<String, Object>
*/
public static List<Map<String, Object>> stringToListAsMapObj(String s) {
if (StringUtil.isEmpty(s)) {
return Collections.emptyList();
}
Type type = new TypeToken<List<Map<String, Object>>>() {}.getType();
return JSON.parseObject(s, type);
}
/**
* 字符串转列表Map
*
* @author fzr
* @param s 字符串
* @return Map<String, String>
*/
public static List<Map<String, String>> stringToListAsMapStr(String s) {
if (StringUtil.isEmpty(s)) {
return Collections.emptyList();
}
Type type = new TypeToken<List<Map<String, String>>>() {}.getType();
return JSON.parseObject(s, type);
}
/**
* 对象转List
*
* @author fzr
* @param object 对象
* @return List<Long>
*/
public static List<Integer> objectToListAsLong(Object object) {
if (StringUtil.isNull(object)) {
return Collections.emptyList();
}
Type type = new TypeToken<List<Long>>() {}.getType();
return JSON.parseObject(JSONObject.toJSONString(object), type);
}
/**
* 对象转List
*
* @author fzr
* @param object 对象
* @return List<Integer>
*/
public static List<Integer> objectToListAsInt(Object object) {
if (StringUtil.isNull(object)) {
return Collections.emptyList();
}
Type type = new TypeToken<List<Integer>>() {}.getType();
return JSON.parseObject(JSONObject.toJSONString(object), type);
}
/**
* 对象转List
*
* @author fzr
* @param object 对象
* @return List<String>
*/
public static List<Integer> objectToListAsStr(Object object) {
if (StringUtil.isNull(object)) {
return Collections.emptyList();
}
Type type = new TypeToken<List<String>>() {}.getType();
return JSON.parseObject(JSONObject.toJSONString(object), type);
}
}

View File

@@ -0,0 +1,142 @@
package com.mdd.common.utils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.mdd.common.entity.system.SystemConfig;
import com.mdd.common.mapper.system.SystemConfigMapper;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* 数据库配置操作工具
*/
public class ConfigUtil {
/**
* 根据类型获取配置
*
* @author fzr
* @param type 类型
* @return Map<String, String>
*/
public static Map<String, String> get(String type) {
SystemConfigMapper model = SpringUtil.getBean(SystemConfigMapper.class);
List<SystemConfig> configs = model.selectList(
new QueryWrapper<SystemConfig>()
.select("id", "type", "name", "value")
.eq("type", type));
Map<String, String> map = new LinkedHashMap<>();
for (SystemConfig config : configs) {
map.put(config.getName(), config.getValue());
}
return map;
}
/**
* 根据类型和名称获取配置
*
* @author fzr
* @param type 类型
* @param name 名称
* @return String
*/
public static String get(String type, String name) {
SystemConfigMapper model = SpringUtil.getBean(SystemConfigMapper.class);
SystemConfig config = model.selectOne(
new QueryWrapper<SystemConfig>()
.select("id", "type", "name", "value")
.eq("type", type)
.eq("name", name));
return config.getValue();
}
/**
* 根据类型和名称获取配置
*
* @author fzr
* @param type 类型
* @param name 名称
* @return String
*/
public static String get(String type, String name, String defaults) {
SystemConfigMapper model = SpringUtil.getBean(SystemConfigMapper.class);
SystemConfig config = model.selectOne(
new QueryWrapper<SystemConfig>()
.select("id", "type", "name", "value")
.eq("type", type)
.eq("name", name));
if (config == null) {
return defaults;
}
return config.getValue();
}
/**
* 根据类型和名称获取配置(JSON自定转Map)
*
* @author fzr
* @param type 类型
* @param name 名称
* @return String
*/
public static Map<String, String> getMap(String type, String name) {
SystemConfigMapper model = SpringUtil.getBean(SystemConfigMapper.class);
SystemConfig config = model.selectOne(
new QueryWrapper<SystemConfig>()
.select("id", "type", "name", "value")
.eq("type", type)
.eq("name", name));
if (config == null) {
return null;
}
if (config.getValue().equals("") || config.getValue().equals("[]") || config.getValue().equals("{}")) {
return new LinkedHashMap<>();
}
return ToolsUtil.jsonToMap(config.getValue());
}
/**
* 设置配置的值
*
* @author fzr
* @param type 类型
* @param name 名称
* @param val 值
*/
public static void set(String type, String name, String val) {
SystemConfigMapper model = SpringUtil.getBean(SystemConfigMapper.class);
SystemConfig config = model.selectOne(
new QueryWrapper<SystemConfig>()
.eq("type", type)
.eq("name", name));
if (config != null) {
config.setValue(val);
config.setUpdateTime(System.currentTimeMillis() / 1000);
model.updateById(config);
} else {
SystemConfig systemConfig = new SystemConfig();
systemConfig.setType(type);
systemConfig.setName(name);
systemConfig.setValue(val);
systemConfig.setCreateTime(System.currentTimeMillis() / 1000);
systemConfig.setUpdateTime(System.currentTimeMillis() / 1000);
model.insert(systemConfig);
}
}
}

View File

@@ -0,0 +1,223 @@
package com.mdd.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.*;
import java.io.*;
import java.net.*;
import java.nio.charset.StandardCharsets;
import java.security.cert.X509Certificate;
/**
* HTTP工具类
*/
public class HttpUtil {
private static final Logger log = LoggerFactory.getLogger(HttpUtil.class);
/**
* 向指定URL发送GET方法的请求 (不带参)
*
* @param url 发送请求的 URL
* @return 所代表远程资源的响应结果
*/
public static String sendGet(String url) {
return sendGet(url, StringUtil.EMPTY);
}
/**
* 向指定URL发送GET方法的请求 (带参固定编码)
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
return sendGet(url, param, "UTF-8");
}
/**
* 向指定URL发送GET方法的请求 (带参指定编码)
*
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @param contentType 编码类型
* @return 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param, String contentType) {
StringBuilder result = new StringBuilder();
BufferedReader in = null;
try {
String urlNameString = StringUtil.isNotBlank(param) ? url + "?" + param : url;
log.info("sendGet - {}", urlNameString);
URL realUrl = new URL(urlNameString);
URLConnection connection = realUrl.openConnection();
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
connection.connect();
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
log.info("rev - {}", result);
} catch (ConnectException e) {
log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
} catch (SocketTimeoutException e) {
log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
} catch (IOException e) {
log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
} catch (Exception e) {
log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
} finally {
try {
if (in != null) {
in.close();
}
} catch (Exception ex) {
log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
}
}
return result.toString();
}
/**
* 向指定 URL 发送POST方法的请求
*
* @author fzr
* @param url 发送请求的 URL
* @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
StringBuilder result = new StringBuilder();
try {
log.info("sendPost - {}", url);
URL realUrl = new URL(url);
URLConnection conn = realUrl.openConnection();
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8");
conn.setDoOutput(true);
conn.setDoInput(true);
out = new PrintWriter(conn.getOutputStream());
out.print(param);
out.flush();
in = new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8));
String line;
while ((line = in.readLine()) != null) {
result.append(line);
}
log.info("rev - {}", result);
}
catch (ConnectException e) {
log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
} catch (SocketTimeoutException e) {
log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
} catch (IOException e) {
log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
}
catch (Exception e) {
log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
} finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (IOException ex) {
log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
}
}
return result.toString();
}
/**
* 发送SSL的POST请求
*
* @author fzr
* @param url 请求地址
* @param param 请求参数
* @return String
*/
public static String sendSSLPost(String url, String param) {
StringBuilder result = new StringBuilder();
String urlNameString = url + "?" + param;
try {
log.info("sendSSLPost - {}", urlNameString);
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
URL console = new URL(urlNameString);
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setSSLSocketFactory(sc.getSocketFactory());
conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
conn.connect();
InputStream is = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String ret;
while ((ret = br.readLine()) != null) {
if (!"".equals(ret.trim())) {
result.append(new String(ret.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
}
}
log.info("rev - {}", result);
conn.disconnect();
br.close();
}
catch (ConnectException e) {
log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
} catch (SocketTimeoutException e) {
log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
} catch (IOException e) {
log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e);
} catch (Exception e) {
log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e);
}
return result.toString();
}
/**
* SSL证书协议接口
*/
private static class TrustAnyTrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[] {};
}
}
/**
* POST请求安全接口
*/
private static class TrustAnyHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
}

View File

@@ -0,0 +1,269 @@
package com.mdd.common.utils;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.mdd.common.config.GlobalConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* IP工具类
*/
public class IpUtil {
private static final Logger log = LoggerFactory.getLogger(IpUtil.class);
/**
* 获取客户端IP
*
* @author fzr
* @return IP地址 (113.67.10.194)
*/
public static String getIpAddress() {
HttpServletRequest request = RequestUtil.handler();
if (request == null) {
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : getMultistageReverseProxyIp(ip);
}
/**
* 根据IP获取所在地址
*
* @author fzr
* @param ip Ip地址
* @return String (广州省 广州市)
*/
public static String getRealAddressByIP(String ip) {
String IP_URL = "https://whois.pconline.com.cn/ipJson.jsp";
String UNKNOWN = "XX XX";
// 内网不查询
if (IpUtil.internalIp(ip)) {
return "内网IP";
}
if (GlobalConfig.isAddressEnabled) {
try {
String rspStr = HttpUtil.sendGet(IP_URL, "ip=" + ip + "&json=true", "GBK");
if (StringUtil.isEmpty(rspStr)) {
log.error("获取地理位置异常 {}", ip);
return UNKNOWN;
}
JSONObject obj = JSONObject.parseObject(rspStr);
String region = obj.getString("pro");
String city = obj.getString("city");
return String.format("%s %s", region, city);
}
catch (Exception e) {
log.error("获取地理位置异常 {}", ip);
}
}
return UNKNOWN;
}
/**
* 检查是否为内部IP地址
*
* @param ip IP地址
* @return 结果
*/
public static boolean internalIp(String ip) {
byte[] address = textToNumericFormatV4(ip);
return internalIp(address) || "127.0.0.1".equals(ip);
}
/**
* 检查是否为内部IP地址
*
* @author fzr
* @param address byte地址
* @return 结果
*/
private static boolean internalIp(byte[] address) {
if (address == null || address.length < 2) {
return true;
}
final byte b0 = address[0];
final byte b1 = address[1];
// 10.x.x.x/8
final byte SECTION_1 = 0x0A;
// 172.16.x.x/12
final byte SECTION_2 = (byte) 0xAC;
final byte SECTION_3 = (byte) 0x10;
final byte SECTION_4 = (byte) 0x1F;
// 192.168.x.x/16
final byte SECTION_5 = (byte) 0xC0;
final byte SECTION_6 = (byte) 0xA8;
switch (b0) {
case SECTION_1:
return true;
case SECTION_2:
if (b1 >= SECTION_3 && b1 <= SECTION_4) {
return true;
}
case SECTION_5:
if (b1 == SECTION_6) {
return true;
}
default:
return false;
}
}
/**
* 将IPv4地址转换成字节
*
* @author fzr
* @param text IPv4地址
* @return byte 字节
*/
public static byte[] textToNumericFormatV4(String text) {
if (text.length() == 0) {
return null;
}
byte[] bytes = new byte[4];
String[] elements = text.split("\\.", -1);
try {
long l;
int i;
switch (elements.length) {
case 1:
l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L)) {
return null;
}
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 2:
l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L)) {
return null;
}
bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L)) {
return null;
}
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 3:
for (i = 0; i < 2; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L)) {
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L)) {
return null;
}
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 4:
for (i = 0; i < 4; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L)) {
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
break;
default:
return null;
}
} catch (NumberFormatException e) {
return null;
}
return bytes;
}
/**
* 获取IP地址
*
* @author fzr
* @return 本地IP地址
*/
public static String getHostIp() {
try {
return InetAddress.getLocalHost().getHostAddress();
}
catch (UnknownHostException ignored) { }
return "127.0.0.1";
}
/**
* 获取主机名
*
* @author fzr
* @return 本地主机名
*/
public static String getHostName() {
try {
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException ignored) {}
return "未知";
}
/**
* 从多级反向代理中获得第一个非unknown IP地址
*
* @author fzr
* @param ip 获得的IP地址
* @return 第一个非unknown IP地址
*/
public static String getMultistageReverseProxyIp(String ip) {
if (ip != null && ip.indexOf(",") > 0) {
final String[] ips = ip.trim().split(",");
for (String subIp : ips) {
if (!isUnknown(subIp)) {
ip = subIp;
break;
}
}
}
return ip;
}
/**
* 检测给定字符串是否为未知,多用于检测HTTP请求相关
*
* @author fzr
* @param checkString 被检测的字符串
* @return 是否未知
*/
public static boolean isUnknown(String checkString) {
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
}
}

View File

@@ -0,0 +1,634 @@
package com.mdd.common.utils;
import com.mdd.common.config.GlobalConfig;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtil {
private static RedisTemplate<String, Object> redisTemplate;
private static final String redisPrefix = GlobalConfig.redisPrefix;
/**
* 注入Redis
*
* @author fzr
* @param redisTemplate Redis对象
*/
@Resource
public void setRedisTemplate(RedisTemplate<String, Object> redisTemplate) {
RedisUtil.redisTemplate = redisTemplate;
}
/**
* 对象句柄
*
* @author fzr
* @return RedisTemplate
*/
public static RedisTemplate<String, Object> handler() {
return redisTemplate;
}
/**
* 指定缓存失效时间
*
* @author fzr
* @param key 键
* @param second 时间(秒)
*/
public static void expire(String key, Long second) {
key = redisPrefix + key;
redisTemplate.expire(key, second, TimeUnit.SECONDS);
}
/**
* 指定缓存失效时间
*
* @author fzr
* @param key 键
* @param millisecond 时间(毫秒)
*/
public static void pExpire(String key, Long millisecond) {
key = redisPrefix + key;
redisTemplate.expire(key, millisecond, TimeUnit.MILLISECONDS);
}
/**
* 指定缓存永久有效
*
* @author fzr
* @param key 键
*/
public static void persist(String key) {
key = redisPrefix + key;
redisTemplate.persist(key);
}
/**
* 根据key获取过期时间
*
* @author fzr
* @param key 键不能为null
* @return 返回0代表为永久有效(秒)
*/
public static Long ttl(String key) {
key = redisPrefix + key;
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 根据key获取过期时间
*
* @author fzr
* @param key 键不能为null
* @return 返回0代表为永久有效(毫秒)
*/
public static Long pTtl(String key) {
key = redisPrefix + key;
return redisTemplate.getExpire(key, TimeUnit.MILLISECONDS);
}
/**
* 判断key是否存在
*
* @author fzr
* @param key 键
* @return true=存在,false=不存在
*/
public static Boolean exists(String key) {
key = redisPrefix + key;
return redisTemplate.hasKey(key);
}
/**
* 删除1个或多个键
*
* @author fzr
* @param key 键(一个或多个)
*/
@SuppressWarnings("unchecked")
public static void del(String... key) {
if (key.length == 1) {
key[0] = redisPrefix + key[0];
redisTemplate.delete(key[0]);
} else {
for (int i=0; key.length > i; i++) {
key[i] = redisPrefix + key[i];
}
redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
}
}
/**
* 给key赋值一个新的key名
*
* @author fzr
* @param oldKey 旧的key
* @param newKey 新的key
*/
public static void rename(String oldKey, String newKey) {
oldKey = redisPrefix + oldKey;
newKey = redisPrefix + newKey;
redisTemplate.rename(oldKey, newKey);
}
/**
* 将当前数据库的key移动到给定的数据库db当中
*
* @author fzr
* @param key 键
* @param db 库
* @return Boolean
*/
public static Boolean move(String key, int db) {
key = redisPrefix + key;
return redisTemplate.move(key, db);
}
/**
* 获取匹配的key值
*
* @author fzr
* @author fzr
* @param pattern 通配符(*, ?, [])
* @return Set
*/
public static Set<String> keys(String pattern) {
return redisTemplate.keys(pattern);
}
/**
* 随机返回一个key
*
* @author fzr
* @author fzr
* @return String
*/
public static String randomKey() {
return redisTemplate.randomKey();
}
/* ***************** common end *************** */
/**
* 获取key的值
*
* @author fzr
* @param key 键
* @return Object
*/
public static Object get(String key) {
key = redisPrefix + key;
return redisTemplate.opsForValue().get(key);
}
/**
* 获取旧值并设置新值
*
* @author fzr
* @param key 键
* @param newVal 新值
* @return Object
*/
public static Object getSet(String key, Object newVal) {
key = redisPrefix + key;
return redisTemplate.opsForValue().getAndSet(key, newVal);
}
/**
* 设置键值对
*
* @author fzr
* @param key 键
* @param value 值
*/
public static void set(String key, Object value) {
key = redisPrefix + key;
redisTemplate.opsForValue().set(key, value);
}
/**
* 设置键值对并设置时间
*
* @author fzr
* @param key 键
* @param value 值
* @param time time要大于0 如果time小于等于0 将设置无限期
*/
public static void set(String key, Object value, long time) {
key = redisPrefix + key;
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
}
/**
* 递增
*
* @author fzr
* @param key 键
* @param delta 要增加几(大于0)
* @return Long
*/
public static Long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递增因子必须大于0");
}
key = redisPrefix + key;
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
*
* @author fzr
* @param key 键
* @param delta 要减少几(小于0)
* @return Long
*/
public static Long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("递减因子必须大于0");
}
key = redisPrefix + key;
return redisTemplate.opsForValue().increment(key, -delta);
}
/* ***************** String end *************** */
/**
* 获取key中field域的值
*
* @author fzr
* @param key 键 不能为null
* @param field 项 不能为null
* @return 值
*/
public static Object hGet(String key, String field) {
key = redisPrefix + key;
return redisTemplate.opsForHash().get(key, field);
}
/**
* 判断key中有没有field域名
*
* @author fzr
* @param key 键
* @param field 字段
* @return Boolean
*/
public static Boolean hExists(String key, Object field) {
key = redisPrefix + key;
return redisTemplate.opsForHash().hasKey(key, field);
}
/**
* 获取hashKey对应的所有键值
*
* @author fzr
* @param key 键
* @return 对应的多个键值
*/
public Map<Object, Object> hmGet(String key) {
key = redisPrefix + key;
return redisTemplate.opsForHash().entries(key);
}
/**
* 设置field1->N个域,对应的值是value1->N
*
* @author fzr
* @param key 键
* @param map 对应多个键值
*/
public static void hmSet(String key, Map<String, Object> map) {
key = redisPrefix + key;
redisTemplate.opsForHash().putAll(key, map);
}
/**
* HashSet 并设置时间
*
* @author fzr
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
*/
public static void hmSet(String key, Map<String, Object> map, long time) {
key = redisPrefix + key;
redisTemplate.opsForHash().putAll(key, map);
if (time > 0) {
expire(key, time);
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @author fzr
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public static void hSet(String key, String item, Object value) {
key = redisPrefix + key;
redisTemplate.opsForHash().put(key, item, value);
}
/**
* 向一张hash表中放入数据,如果不存在将创建
*
* @author fzr
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public static boolean hSet(String key, String item, Object value, long time) {
key = redisPrefix + key;
redisTemplate.opsForHash().put(key, item, value);
if (time > 0) {
expire(key, time);
}
return true;
}
/**
* 删除hash表中的值
*
* @author fzr
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public static void hDel(String key, Object... item) {
key = redisPrefix + key;
redisTemplate.opsForHash().delete(key, item);
}
/**
* 判断hash表中是否有该项的值
*
* @author fzr
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public static boolean hHasKey(String key, String item) {
key = redisPrefix + key;
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个并把新增后的值返回
*
* @author fzr
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return double
*/
public static double hIncr(String key, String item, long by) {
key = redisPrefix + key;
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
*
* @author fzr
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return double
*/
public static double hDecr(String key, String item, long by) {
key = redisPrefix + key;
return redisTemplate.opsForHash().increment(key, item, -by);
}
/* ***************** Map end *************** */
/**
* 根据key获取Set中的所有值
*
* @author fzr
* @param key 键
* @return Set
*/
public static Set<Object> sGet(String key) {
key = redisPrefix + key;
return redisTemplate.opsForSet().members(key);
}
/**
* 根据value从一个set中查询,是否存在
*
* @author fzr
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public Boolean sHasKey(String key, Object value) {
key = redisPrefix + key;
return redisTemplate.opsForSet().isMember(key, value);
}
/**
* 将数据放入set缓存
*
* @author fzr
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public Long sSet(String key, Object... values) {
key = redisPrefix + key;
return redisTemplate.opsForSet().add(key, values);
}
/**
* 将set数据放入缓存
*
* @author fzr
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public Long sSetAndTime(String key, long time, Object... values) {
key = redisPrefix + key;
return redisTemplate.opsForSet().add(key, values);
}
/**
* 获取set缓存的长度
*
* @author fzr
* @param key 键
* @return Long
*/
public Long sGetSetSize(String key) {
key = redisPrefix + key;
return redisTemplate.opsForSet().size(key);
}
/**
* 移除值为value的
*
* @author fzr
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public Long setRemove(String key, Object... values) {
key = redisPrefix + key;
return redisTemplate.opsForSet().remove(key, values);
}
/* ***************** Set end *************** */
/**
* 获取list缓存的内容
*
* @author fzr
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return List
*/
public List<Object> lGet(String key, long start, long end) {
key = redisPrefix + key;
return redisTemplate.opsForList().range(key, start, end);
}
/**
* 获取list缓存的长度
*
* @author fzr
* @param key 键
* @return Long
*/
public Long lGetListSize(String key) {
key = redisPrefix + key;
return redisTemplate.opsForList().size(key);
}
/**
* 通过索引获取list中的值
*
* @author fzr
* @param key 键
* @param index 索引 index>=0时,0 表头1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素依次类推
* @return Object
*/
public Object lGetIndex(String key, long index) {
key = redisPrefix + key;
return redisTemplate.opsForList().index(key, index);
}
/**
* 将list放入缓存
*
* @author fzr
* @param key 键
* @param value 值
* @return boolean
*/
public boolean lSet(String key, Object value) {
key = redisPrefix + key;
redisTemplate.opsForList().rightPush(key, value);
return true;
}
/**
* 将list放入缓存
*
* @author fzr
* @param key 键
* @param value 值
* @param second 时间(秒)
* @return boolean
*/
public boolean lSet(String key, Object value, long second) {
key = redisPrefix + key;
redisTemplate.opsForList().rightPush(key, value);
if (second > 0)
expire(key, second);
return true;
}
/**
* 将list放入缓存
*
* @author fzr
* @param key 键
* @param value 值
* @return boolean
*/
public boolean lSet(String key, List<Object> value) {
key = redisPrefix + key;
redisTemplate.opsForList().rightPushAll(key, value);
return true;
}
/**
* 将list放入缓存
*
* @author fzr
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return boolean
*/
public boolean lSet(String key, List<Object> value, Long time) {
key = redisPrefix + key;
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0)
expire(key, time);
return true;
}
/**
* 根据索引修改list中的某条数据
*
* @author fzr
* @param key 键
* @param index 索引
* @param value 值
* @return boolean
*/
public boolean lUpdateIndex(String key, Long index, Object value) {
key = redisPrefix + key;
redisTemplate.opsForList().set(key, index, value);
return true;
}
/**
* 移除N个值为value
*
* @author fzr
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public Long lRemove(String key, Long count, Object value) {
key = redisPrefix + key;
return redisTemplate.opsForList().remove(key, count, value);
}
}

View File

@@ -0,0 +1,173 @@
package com.mdd.common.utils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;
/**
* 请求工具类
*/
public class RequestUtil {
/**
* 获取请求对象
*
* @author fzr
* @return HttpServletRequest
*/
public static HttpServletRequest handler() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (servletRequestAttributes != null) {
return servletRequestAttributes.getRequest();
}
return null;
}
/**
* 获取不带参请求URl
* 示例: https://127.0.0.1:8082/api/system/menu/menus
*
* @author fzr
* @return String
*/
public static String url() {
HttpServletRequest request = RequestUtil.handler();
if (request != null) {
return request.getRequestURL().toString();
}
return "";
}
/**
* 获取带端口的请求地址
* 示例: https://127.0.0.1:8082
*
* @author fzr
* @return String
*/
public static String uri() {
String domain = RequestUtil.domain();
if (!Arrays.asList(443,80,0).contains(RequestUtil.port())) {
domain += ":" + RequestUtil.port();
}
return domain;
}
/**
* 获取请求路由
* 示例: /api/system/menu/menus
*
* @author fzr
* @return String
*/
public static String route() {
HttpServletRequest request = RequestUtil.handler();
if (request != null) {
return request.getRequestURI();
}
return "";
}
/**
* 获取请求端口
* 示例: 443/80
*
* @author fzr
* @return Integer
*/
public static Integer port() {
HttpServletRequest request = RequestUtil.handler();
if (request != null) {
return request.getServerPort();
}
return 0;
}
/**
* 获取请求域名
* 示例: https://127.0.0.1
*
* @author fzr
* @return String
*/
public static String domain() {
HttpServletRequest request = RequestUtil.handler();
if (request != null) {
String requestUrl = request.getRequestURL().toString();
List<String> urls = Arrays.asList(requestUrl.split("/"));
String agree = "http:";
if (request.getServerPort() == 443) {
agree = "https:";
}
return agree + "//" + urls.get(2).split(":")[0];
}
return null;
}
/**
* 判断是否是GET请求
*
* @author fzr
* @return Boolean
*/
public static Boolean isGet() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (servletRequestAttributes != null) {
HttpServletRequest request = servletRequestAttributes.getRequest();
return request.getMethod().equals("GET");
}
return false;
}
/**
* 判断是否是POST请求
*
* @author fzr
* @return Boolean
*/
public static Boolean isPost() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (servletRequestAttributes != null) {
HttpServletRequest request = servletRequestAttributes.getRequest();
return request.getMethod().equals("POST");
}
return false;
}
/**
* 判断是否是PUT请求
*
* @author fzr
* @return Boolean
*/
public static Boolean isPUT() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (servletRequestAttributes != null) {
HttpServletRequest request = servletRequestAttributes.getRequest();
return request.getMethod().equals("PUT");
}
return false;
}
/**
* 判断是否是DELETE请求
*
* @author fzr
* @return Boolean
*/
public static Boolean isDelete() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (servletRequestAttributes != null) {
HttpServletRequest request = servletRequestAttributes.getRequest();
return request.getMethod().equals("DELETE");
}
return false;
}
}

View File

@@ -0,0 +1,70 @@
package com.mdd.common.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
/**
* 设置容器对象
*
* @author fzr
* @param applicationContext applicationContext
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if(SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
/**
* 获取applicationContext
*
* @author fzr
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext(){
return applicationContext;
}
/**
* 通过name获取Bean
*
* @author fzr
* @param name 名称
* @return Object
*/
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
/**
* 通过class获取Bean.
*
* @author fzr
* @param clazz 类
* @return <T>
*/
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
/**
* 通过name和Clazz返回指定的Bean
*
* @author fzr
* @param name 名称
* @param clazz 类
* @return <T>
*/
public static <T> T getBean(String name, Class<T> clazz){
return getApplicationContext().getBean(name, clazz);
}
}

View File

@@ -0,0 +1,538 @@
package com.mdd.common.utils;
import org.springframework.util.AntPathMatcher;
import java.util.*;
/**
* 字符串工具类
*/
public class StringUtil extends org.apache.commons.lang3.StringUtils {
/**
* 空字符串
*/
private static final String NULL_STR = "";
/**
* 下划线
*/
private static final char SEPARATOR = '_';
/**
* 获取参数不为空值
*
* @param value defaultValue 要判断的value
* @return value 返回值
*/
public static <T> T nvl(T value, T defaultValue) {
return value != null ? value : defaultValue;
}
/**
* 判断一个Collection是否为空,包含List, Set, Queue
*
* @param coll 要判断的Collection
* @return true=为空, false=非空
*/
public static boolean isEmpty(Collection<?> coll) {
return isNull(coll) || coll.isEmpty();
}
/**
* 判断一个Collection是否非空,包含List, Set, Queue
*
* @param coll 要判断的Collection
* @return true=非空, false=空
*/
public static boolean isNotEmpty(Collection<?> coll) {
return !isEmpty(coll);
}
/**
* 判断一个对象数组是否为空
*
* @param objects 要判断的对象数组
* @return true=为空, false=非空
*/
public static boolean isEmpty(Object[] objects) {
return isNull(objects) || (objects.length == 0);
}
/**
* 判断一个对象数组是否非空
*
* @param objects 要判断的对象数组
* @return true=非空, false=空
*/
public static boolean isNotEmpty(Object[] objects) {
return !isEmpty(objects);
}
/**
* 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true=为空, false=非空
*/
public static boolean isEmpty(Map<?, ?> map) {
return isNull(map) || map.isEmpty();
}
/**
* 判断一个Map是否为空
*
* @param map 要判断的Map
* @return true=非空, false=空
*/
public static boolean isNotEmpty(Map<?, ?> map) {
return !isEmpty(map);
}
/**
* 判断一个字符串是否为空串
*
* @param str String
* @return true=为空, false=非空
*/
public static boolean isEmpty(String str) {
return isNull(str) || NULL_STR.equals(str.trim());
}
/**
* 判断一个字符串是否为非空串
*
* @param str String
* @return true=非空串, false=空串
*/
public static boolean isNotEmpty(String str) {
return !isEmpty(str);
}
/**
* 判断一个对象是否为空
*
* @param object Object
* @return true=为空, false=非空
*/
public static boolean isNull(Object object) {
return object == null;
}
/**
* 判断一个对象是否非空
*
* @param object Object
* @return true=非空, false=空
*/
public static boolean isNotNull(Object object) {
return !isNull(object);
}
/**
* 判断一个对象是否是数组类型Java基本型别的数组
*
* @param object 对象
* @return true=是数组, false=不是数组
*/
public static boolean isArray(Object object) {
return isNotNull(object) && object.getClass().isArray();
}
/**
* 去空格
*/
public static String trim(String str) {
return (str == null ? "" : str.trim());
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @return 结果
*/
public static String substring(final String str, int start) {
if (str == null) {
return NULL_STR;
}
if (start < 0) {
start = str.length() + start;
}
if (start < 0) {
start = 0;
}
if (start > str.length()) {
return NULL_STR;
}
return str.substring(start);
}
/**
* 截取字符串
*
* @param str 字符串
* @param start 开始
* @param end 结束
* @return 结果
*/
public static String substring(final String str, int start, int end) {
if (str == null) {
return NULL_STR;
}
if (end < 0) {
end = str.length() + end;
}
if (start < 0) {
start = str.length() + start;
}
if (end > str.length()) {
end = str.length();
}
if (start > end) {
return NULL_STR;
}
if (start < 0) {
start = 0;
}
if (end < 0) {
end = 0;
}
return str.substring(start, end);
}
/**
* 字符串转set
*
* @param str 字符串
* @param sep 分隔符
* @return set集合
*/
public static Set<String> str2Set(String str, String sep) {
return new HashSet<String>(str2List(str, sep, true, false));
}
/**
* 字符串转list
*
* @param str 字符串
* @param sep 分隔符
* @param filterBlank 过滤纯空白
* @param trim 去掉首尾空白
* @return list集合
*/
public static List<String> str2List(String str, String sep, boolean filterBlank, boolean trim) {
List<String> list = new ArrayList<String>();
if (StringUtil.isEmpty(str)) {
return list;
}
// 过滤空白字符串
if (filterBlank && StringUtil.isBlank(str)) {
return list;
}
String[] split = str.split(sep);
for (String string : split) {
if (filterBlank && StringUtil.isBlank(string)) {
continue;
}
if (trim) {
string = string.trim();
}
list.add(string);
}
return list;
}
/**
* 查找指定字符串是否包含指定字符串列表中的任意一个字符串同时串忽略大小写
*
* @param cs 指定字符串
* @param searchCharSequences 需要检查的字符串数组
* @return 是否包含任意一个字符串
*/
public static boolean containsAnyIgnoreCase(CharSequence cs, CharSequence... searchCharSequences) {
if (isEmpty(cs) || isEmpty(searchCharSequences))
{
return false;
}
for (CharSequence testStr : searchCharSequences)
{
if (containsIgnoreCase(cs, testStr))
{
return true;
}
}
return false;
}
/**
* 驼峰转下划线命名
*/
public static String toUnderScoreCase(String str) {
if (str == null) {
return null;
}
StringBuilder sb = new StringBuilder();
// 前置字符是否大写
boolean preCharIsUpperCase = true;
// 当前字符是否大写
boolean cureCharIsUpperCase = true;
// 下一字符是否大写
boolean nextCharIsUpperCase = true;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if (i > 0) {
preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
} else {
preCharIsUpperCase = false;
}
cureCharIsUpperCase = Character.isUpperCase(c);
if (i < (str.length() - 1)) {
nextCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
}
if (preCharIsUpperCase && cureCharIsUpperCase && !nextCharIsUpperCase) {
sb.append(SEPARATOR);
} else if ((i != 0 && !preCharIsUpperCase) && cureCharIsUpperCase)
{
sb.append(SEPARATOR);
}
sb.append(Character.toLowerCase(c));
}
return sb.toString();
}
/**
* 是否包含字符串
*
* @param str 验证字符串
* @param strArr 字符串组
* @return 包含返回true
*/
public static boolean inStringIgnoreCase(String str, String... strArr) {
if (str != null && strArr != null) {
for (String s : strArr) {
if (str.equalsIgnoreCase(trim(s))) {
return true;
}
}
}
return false;
}
/**
* 将下划线大写方式命名的字符串转换为驼峰式。
* 如果转换前的下划线大写方式命名的字符串为空,
* 则返回空字符串。 例如HELLO_WORLD->HelloWorld
*
* @param name 转换前的下划线大写方式命名的字符串
* @return 转换后的驼峰式命名的字符串
*/
public static String convertToCamelCase(String name) {
StringBuilder result = new StringBuilder();
// 快速检查
if (name == null || name.isEmpty()) {
// 没必要转换
return "";
}
else if (!name.contains("_")) {
// 不含下划线,仅将首字母大写
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
// 用下划线将原始字符串分割
String[] camels = name.split("_");
for (String camel : camels) {
// 跳过原始字符串中开头、结尾的下换线或双重下划线
if (camel.isEmpty()) {
continue;
}
// 首字母大写
result.append(camel.substring(0, 1).toUpperCase());
result.append(camel.substring(1).toLowerCase());
}
return result.toString();
}
/**
* 驼峰式命名法 例如user_name->userName
*
* @param s 字符串
* @return 驼峰字符串
*/
public static String toCamelCase(String s) {
if (s == null) {
return null;
}
s = s.toLowerCase();
StringBuilder sb = new StringBuilder(s.length());
boolean upperCase = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == SEPARATOR) {
upperCase = true;
} else if (upperCase) {
sb.append(Character.toUpperCase(c));
upperCase = false;
} else {
sb.append(c);
}
}
return sb.toString();
}
/**
* 查找指定字符串是否匹配指定字符串列表中的任意一个字符串
*
* @param str 指定字符串
* @param strArr 需要检查的字符串数组
* @return 是否匹配
*/
public static boolean matches(String str, List<String> strArr) {
if (isEmpty(str) || isEmpty(strArr)) {
return false;
}
for (String pattern : strArr) {
if (isMatch(pattern, str)) {
return true;
}
}
return false;
}
/**
* 判断url是否与规则配置:
* ? 表示单个字符;
* * 表示一层路径内的任意字符串,不可跨层级;
* ** 表示任意层路径;
*
* @param pattern 匹配规则
* @param url 需要匹配的url
* @return boolean
*/
public static boolean isMatch(String pattern, String url) {
AntPathMatcher matcher = new AntPathMatcher();
return matcher.match(pattern, url);
}
/**
* 数字左边补齐0,使之达到指定长度。
* 注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
*
* @param num 数字对象
* @param size 字符串指定长度
* @return 返回数字的字符串格式,该字符串为指定长度。
*/
public static String padL(final Number num, final int size) {
return padL(num.toString(), size, '0');
}
/**
* 字符串左补齐
* 如果原始字符串s长度大于size,则只保留最后size个字符。
*
* @param s 原始字符串
* @param size 字符串指定长度
* @param c 用于补齐的字符
* @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
*/
public static String padL(final String s, final int size, final char c) {
final StringBuilder sb = new StringBuilder(size);
if (s != null) {
final int len = s.length();
if (s.length() <= size) {
for (int i = size - len; i > 0; i--) {
sb.append(c);
}
sb.append(s);
} else {
return s.substring(len - size, len);
}
} else {
for (int i = size; i > 0; i--) {
sb.append(c);
}
}
return sb.toString();
}
/**
* 格式化文本, {} 表示占位符<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* 例:<br>
* 通常使用format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{} format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\ format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
*
* @param strPattern 文本模板,被替换的部分用 {} 表示
* @param argArray 参数值
* @return 格式化后的文本
*/
public static String format(String strPattern, Object... argArray) {
String EMPTY_JSON = "{}";
char C_BACKSLASH = '\\';
char C_DELIM_START = '{';
if (isEmpty(argArray) || isEmpty(strPattern)) {
return strPattern;
}
final int strPatternLength = strPattern.length();
StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
int handledPosition = 0;
int delimIndex;
for (int argIndex = 0; argIndex < argArray.length; argIndex++) {
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
if (delimIndex == -1) {
if (handledPosition == 0) {
return strPattern;
} else {
sbuf.append(strPattern, handledPosition, strPatternLength);
return sbuf.toString();
}
} else {
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) {
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) {
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(argArray[argIndex]);
handledPosition = delimIndex + 2;
} else {
// 占位符被转义
argIndex--;
sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(C_DELIM_START);
handledPosition = delimIndex + 1;
}
} else {
// 正常占位符
sbuf.append(strPattern, handledPosition, delimIndex);
sbuf.append(argArray[argIndex]);
handledPosition = delimIndex + 2;
}
}
}
sbuf.append(strPattern, handledPosition, strPattern.length());
return sbuf.toString();
}
}

View File

@@ -0,0 +1,538 @@
package com.mdd.common.utils;
import java.lang.management.ManagementFactory;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
public class TimeUtil {
/**
* 时间戳转日期(默认格式)
*
* @author fzr
* @param time 时间戳
* @return String
*/
public static String timestampToDate(Long time) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(time * 1000));
}
/**
* 时间戳转日期(默认格式)
*
* @author fzr
* @param time 时间戳
* @return String
*/
public static String timestampToDate(String time) {
if (time == null) {
time = "0";
}
long longTime = Long.parseLong(time);
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(longTime * 1000));
}
/**
* 时间戳转日期(指定格式)
*
* @author fzr
* @param time 时间戳
* @param format 格式串
* @return String
*/
public static String timestampToDate(Long time, String format) {
return new SimpleDateFormat(format).format(new Date(time * 1000));
}
/**
* 时间戳转日期(指定格式)
*
* @author fzr
* @param time 时间戳
* @param format 格式串
* @return String
*/
public static String timestampToDate(String time, String format) {
long longTime = Long.parseLong(time);
return new SimpleDateFormat(format).format(new Date(longTime * 1000));
}
/**
* 日期转时间戳
*
* @author fzr
* @param date 日期
* @return Long
*/
public static Long dateToTimestamp(String date) {
String dateTime = TimeUtil.formatDate(date);
return (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).parse(dateTime, new ParsePosition(0)).getTime() / 1000;
}
/**
* 毫秒转日期时间
*
* @author fzr
* @param time 毫秒
* @return String
*/
public static String millisecondToDate(Long time) {
Date date = new Date();
date.setTime(time);
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
}
/**
* 毫秒转日期时间
*
* @author fzr
* @param time 毫秒
* @return String
*/
public static String millisecondToDate(String time) {
Date date = new Date();
date.setTime(Long.parseLong(time));
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
}
/**
* 毫秒转日期时间
*
* @author fzr
* @param time 毫秒
* @param format 格式串
* @return String
*/
public static String millisecondToDate(Long time, String format) {
Date date = new Date();
date.setTime(time);
return new SimpleDateFormat(format).format(date);
}
/**
* 毫秒转日期时间
*
* @author fzr
* @param time 毫秒
* @param format 格式串
* @return String
*/
public static String millisecondToDate(String time, String format) {
Date date = new Date();
date.setTime(Long.parseLong(time));
return new SimpleDateFormat(format).format(date);
}
/**
* 日期转固定格式 yyyy-MM-dd HH:mm:ss
*
* @author fzr
* @param dateStr 日期时间
* @return String
*/
public static String formatDate(String dateStr){
dateStr = dateStr.trim();
HashMap<String, String> dateRegFormat = new HashMap<>();
dateRegFormat.put("^\\d{4}\\D+\\d{1,2}\\D+\\d{1,2}\\D+\\d{1,2}\\D+\\d{1,2}\\D+\\d{1,2}\\D*$", "yyyy-MM-dd-HH-mm-ss");//2014年3月12日 13时5分34秒2014-03-12 12:05:342014/3/12 12:5:34
dateRegFormat.put("^\\d{4}\\D+\\d{2}\\D+\\d{2}\\D+\\d{2}\\D+\\d{2}$", "yyyy-MM-dd-HH-mm");//2014-03-12 12:05
dateRegFormat.put("^\\d{4}\\D+\\d{2}\\D+\\d{2}\\D+\\d{2}$", "yyyy-MM-dd-HH");//2014-03-12 12
dateRegFormat.put("^\\d{4}\\D+\\d{2}\\D+\\d{2}$", "yyyy-MM-dd");//2014-03-12
dateRegFormat.put("^\\d{4}\\D+\\d{2}$", "yyyy-MM");//2014-03
dateRegFormat.put("^\\d{4}$", "yyyy");//2014
dateRegFormat.put("^\\d{14}$", "yyyyMMddHHmmss");//20140312120534
dateRegFormat.put("^\\d{12}$", "yyyyMMddHHmm");//201403121205
dateRegFormat.put("^\\d{10}$", "yyyyMMddHH");//2014031212
dateRegFormat.put("^\\d{8}$", "yyyyMMdd");//20140312
dateRegFormat.put("^\\d{6}$", "yyyyMM");//201403
dateRegFormat.put("^\\d{2}\\s*:\\s*\\d{2}\\s*:\\s*\\d{2}$", "yyyy-MM-dd-HH-mm-ss");//13:05:34 拼接当前日期
dateRegFormat.put("^\\d{2}\\s*:\\s*\\d{2}$", "yyyy-MM-dd-HH-mm");//13:05 拼接当前日期
dateRegFormat.put("^\\d{2}\\D+\\d{1,2}\\D+\\d{1,2}$", "yy-MM-dd");//14.10.18(年.月.日)
dateRegFormat.put("^\\d{1,2}\\D+\\d{1,2}$", "yyyy-dd-MM");//30.12(日.月) 拼接当前年份
dateRegFormat.put("^\\d{1,2}\\D+\\d{1,2}\\D+\\d{4}$", "dd-MM-yyyy");//12.21.2013(日.月.年)
String curDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
DateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DateFormat formatter2;
String dateReplace;
String strSuccess = "";
try {
for (String key : dateRegFormat.keySet()) {
if (Pattern.compile(key).matcher(dateStr).matches()) {
formatter2 = new SimpleDateFormat(dateRegFormat.get(key));
if (key.equals("^\\d{2}\\s*:\\s*\\d{2}\\s*:\\s*\\d{2}$") || key.equals("^\\d{2}\\s*:\\s*\\d{2}$")) {
// 13:05:34 或 13:05 拼接当前日期
dateStr = curDate + "-" + dateStr;
} else if (key.equals("^\\d{1,2}\\D+\\d{1,2}$")) {
//21.1 (日.月) 拼接当前年份
dateStr = curDate.substring(0, 4) + "-" + dateStr;
}
dateReplace = dateStr.replaceAll("\\D+", "-");
strSuccess = formatter1.format(formatter2.parse(dateReplace));
break;
}
}
return strSuccess;
} catch (Exception ignored) { }
return "";
}
/**
* 返回当前时间戳
*
* @author fzr
* @return Long
*/
public static Long timestamp() {
return System.currentTimeMillis() / 1000;
}
/**
* 返回当前Date型日期
*
* @author fzr
* @return Date() 当前日期
*/
public static Date nowDate() {
return new Date();
}
/**
* 返回今日开始和结束的时间戳
*
* @author fzr
* @return List
*/
public static List<Long> today() {
List<Long> list = new ArrayList<>();
// 开始时间
Calendar todayStart = Calendar.getInstance();
todayStart.set(Calendar.HOUR, 0);
todayStart.set(Calendar.MINUTE, 0);
todayStart.set(Calendar.SECOND, 0);
todayStart.set(Calendar.MILLISECOND, 0);
list.add(todayStart.getTime().getTime() / 1000 - 43200);
// 结束时间
Calendar todayEnd = Calendar.getInstance();
todayEnd.set(Calendar.HOUR_OF_DAY, 23);
todayEnd.set(Calendar.MINUTE, 59);
todayEnd.set(Calendar.SECOND, 59);
todayEnd.set(Calendar.MILLISECOND, 999);
list.add(todayEnd.getTime().getTime() / 1000);
return list;
}
/**
* 返回昨日开始和结束的时间戳
*
* @author fzr
* @return List
*/
public static List<Long> yesterday() {
List<Long> today = TimeUtil.today();
List<Long> list = new ArrayList<>();
list.add(today.get(0) - 86400);
list.add(today.get(1) - 86400);
return list;
}
/**
* 返回本周开始和结束的时间戳
*
* @author fzr
* @return List
*/
public static List<Long> week() {
List<Long> list = new ArrayList<>();
// 开始时间
Calendar cal = Calendar.getInstance();
cal.set(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0,0);
cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
list.add(cal.getTimeInMillis() / 1000);
// 结束时间
list.add(list.get(0) + ((7 * 24 * 60 * 60 * 1000) / 1000)-1);
return list;
}
/**
* 返回上周开始和结束的时间戳
*
* @author fzr
* @return List
*/
public static List<Long> lastWeek() {
List<Long> week = TimeUtil.week();
List<Long> list = new ArrayList<>();
list.add(week.get(0) - 604800);
list.add(week.get(1) - 604800);
return list;
}
/**
* 返回今天是周几
*
* @author fzr
* @return Long
*/
public static Long dayOfWeek() {
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
boolean isFirstSunday = (cal.getFirstDayOfWeek() == Calendar.SUNDAY);
long week = cal.get(Calendar.DAY_OF_WEEK);
if(isFirstSunday){
week = (week -1) == 0? 7:(week - 1);
}
return week;
}
/**
* 返回本月开始和结束的时间戳
*
* @author fzr
* @return List
*/
public static List<Long> month() {
List<Long> list = new ArrayList<>();
// 开始时间
Calendar calStart = Calendar.getInstance();
calStart.set(calStart.get(Calendar.YEAR),calStart.get(Calendar.MONTH), calStart.get(Calendar.DAY_OF_MONTH), 0, 0,0);
calStart.set(Calendar.DAY_OF_MONTH,calStart.getActualMinimum(Calendar.DAY_OF_MONTH));
list.add(calStart.getTimeInMillis() / 1000);
// 结束时间
Calendar calEnd = Calendar.getInstance();
calEnd.set(calEnd.get(Calendar.YEAR),calEnd.get(Calendar.MONTH), calEnd.get(Calendar.DAY_OF_MONTH), 0, 0,0);
calEnd.set(Calendar.DAY_OF_MONTH, calEnd.getActualMaximum(Calendar.DAY_OF_MONTH));
calEnd.set(Calendar.HOUR_OF_DAY, 24);
list.add(calEnd.getTimeInMillis() / 1000 - 1);
return list;
}
/**
* 返回上个月开始和结束的时间戳
*
* @author fzr
* @return List
*/
public static List<Long> lastMonth() {
List<Long> list = new ArrayList<>();
// 开始时间
Calendar calStart = Calendar.getInstance();
calStart.add(Calendar.MONTH, -1);
calStart.set(Calendar.DAY_OF_MONTH,1);
calStart.set(Calendar.HOUR, 0);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
list.add((calStart.getTimeInMillis() / 1000) - 43200);
// 结束时间
Calendar calEnd = Calendar.getInstance();
calEnd.set(calEnd.get(Calendar.YEAR),calEnd.get(Calendar.MONTH), calEnd.get(Calendar.DAY_OF_MONTH), 0, 0,0);
calEnd.set(Calendar.DAY_OF_MONTH,calEnd.getActualMinimum(Calendar.DAY_OF_MONTH));
list.add((calEnd.getTimeInMillis() / 1000)-1);
return list;
}
/**
* 返回今年开始和结束的时间戳
*
* @author fzr
* @return List
*/
public static List<Long> year() {
List<Long> list = new ArrayList<>();
// 开始时间
Calendar calStart = Calendar.getInstance();
calStart.add(Calendar.YEAR, 0);
calStart.add(Calendar.DATE, 0);
calStart.add(Calendar.MONTH, 0);
calStart.set(Calendar.DAY_OF_YEAR, 1);
calStart.set(Calendar.HOUR_OF_DAY, 0);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
list.add(calStart.getTimeInMillis() / 1000);
// 结束时间
Calendar calEnd = Calendar.getInstance();
int year = calEnd.get(Calendar.YEAR);
calEnd.clear();
calEnd.set(Calendar.YEAR, year);
calEnd.set(Calendar.HOUR_OF_DAY, 23);
calEnd.set(Calendar.MINUTE, 59);
calEnd.set(Calendar.SECOND, 59);
calEnd.set(Calendar.MILLISECOND, 999);
calEnd.roll(Calendar.DAY_OF_YEAR, -1);
list.add(calEnd.getTimeInMillis() / 1000);
return list;
}
/**
* 返回去年开始和结束的时间戳
*
* @author fzr
* @return List
*/
public static List<Long> lastYear() {
List<Long> list = new ArrayList<>();
// 开始时间
Calendar calStart = Calendar.getInstance();
calStart.add(Calendar.YEAR, -1);
calStart.set(Calendar.HOUR_OF_DAY, 0);
calStart.set(Calendar.DAY_OF_YEAR, 1);
calStart.set(Calendar.MINUTE, 0);
calStart.set(Calendar.SECOND, 0);
calStart.set(Calendar.MILLISECOND, 0);
list.add(calStart.getTimeInMillis() / 1000);
// 结束时间
Calendar calEnd = Calendar.getInstance();
calEnd.add(Calendar.YEAR, -1);
calEnd.set(Calendar.MONTH, calEnd.getActualMaximum(Calendar.MONTH));
calEnd.set(Calendar.DAY_OF_MONTH, calEnd.getActualMaximum(Calendar.DAY_OF_MONTH));
calEnd.set(Calendar.HOUR_OF_DAY, 23);
calEnd.set(Calendar.MINUTE, 59);
calEnd.set(Calendar.SECOND, 59);
calEnd.set(Calendar.MILLISECOND, 999);
list.add(calEnd.getTimeInMillis() / 1000);
return list;
}
/**
* 获取几天前零点到现在/昨日结束的时间戳
*
* @author fzr
* @return List
*/
public static List<Long> dayToNow(int day) {
List<Long> today = TimeUtil.today();
List<Long> list = new ArrayList<>();
list.add(today.get(0) - day * 86400L);
list.add(today.get(0) -1);
return list;
}
/**
* 返回几天前的时间戳
*
* @author fzr
* @param day (天)
* @return Long
*/
public Long daysAgo(long day) {
long currTime = System.currentTimeMillis() / 1000;
return currTime - (day * 86400);
}
/**
* 返回几天后的时间戳
*
* @author fzr
* @param day (天)
* @return Long
*/
public Long daysAfter(long day) {
long currTime = System.currentTimeMillis() / 1000;
return currTime + (day * 86400);
}
/**
* 返回月份第几天
*
* @author fzr
* @return int
*/
public static Integer monthDay(){
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal.get(Calendar.DAY_OF_MONTH);
}
/**
* 获取几天前的日期列表
*
* @author fzr
* @param day 获取多少天
* @return [2022-03-29, 2022-03-30, 2022-03-31, 2022-04-01]
*/
public static List<String> daysAgoDate(Integer day) {
long time = TimeUtil.today().get(0);
List<String> data = new ArrayList<>();
for (int i=0; i<day; i++) {
if (i != 0) {
time -= 86400;
}
data.add(TimeUtil.timestampToDate(time, "yyyy-MM-dd"));
}
Collections.reverse(data);
return data;
}
/**
* 获取几天前的日期列表
*
* @author fzr
* @param day 获取多少天
* @return [1648483200, 1648569600, 1648656000, 1648742400]
*/
public static List<Long> daysAgoTime(Integer day) {
long time = TimeUtil.today().get(0);
List<Long> data = new ArrayList<>();
for (int i=0; i<day; i++) {
if (i != 0) {
time -= 86400;
}
data.add(time);
}
Collections.reverse(data);
return data;
}
/**
* 返回服务器启动时间
*/
public static Date serverStartDate() {
long time = ManagementFactory.getRuntimeMXBean().getStartTime();
return new Date(time);
}
/**
* 计算两个时间差
*
* @author fzr
* @param endDate 结束时间
* @param nowDate 开始时间
* @return String
*/
public static String datePoor(Date endDate, Date nowDate) {
long nd = 1000 * 24 * 60 * 60;
long nh = 1000 * 60 * 60;
long nm = 1000 * 60;
// long ns = 1000;
// 获得两个时间的毫秒时间差异
long diff = endDate.getTime() - nowDate.getTime();
// 计算差多少天
long day = diff / nd;
// 计算差多少小时
long hour = diff % nd / nh;
// 计算差多少分钟
long min = diff % nd % nh / nm;
// 计算差多少秒//输出结果
// long sec = diff % nd % nh % nm / ns;
return day + "" + hour + "小时" + min + "分钟";
}
}

View File

@@ -0,0 +1,182 @@
package com.mdd.common.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.reflect.TypeToken;
import com.mdd.common.config.GlobalConfig;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.*;
/**
* 常用工具集合
*/
public class ToolsUtil {
/**
* 制作UUID
*
* @author fzr
* @return String
*/
public static String makeUUID(){
return UUID.randomUUID().toString().replaceAll("-","").substring(0,32);
}
/**
* 制作MD5
*
* @author fzr
* @param data 需加密的数据
* @return String
*/
public static String makeMd5(String data){
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte [] array = md5.digest(data.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte item : array) {
sb.append(Integer.toHexString((item & 0xFF) | 0x100), 1, 3);
}
return sb.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**
* 生成唯一Token
*
* @author fzr
* @return String
*/
public static String makeToken() {
long millisecond = System.currentTimeMillis();
String randStr = ToolsUtil.randomString(8);
String secret = GlobalConfig.secret;
String token = ToolsUtil.makeMd5(ToolsUtil.makeUUID() + millisecond + randStr);
return ToolsUtil.makeMd5(token + secret) + ToolsUtil.randomString(6);
}
/**
* 返回随机字符串
*
* @author fzr
* @param length 要生成的长度
* @return String
*/
public static String randomString(int length) {
Random random = new Random();
StringBuilder stringBuffer = new StringBuilder();
String str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
int strLength = str.length();
for (int i = 0; i < length; i++) {
int index = random.nextInt(strLength);
stringBuffer.append(str.charAt(index));
}
return stringBuffer.toString();
}
/**
* 返回随机数字字符串
*
* @author fzr
* @param length 要生成的长度
* @return String
*/
public static String randomInt(int length) {
Random random = new Random();
StringBuilder stringBuffer = new StringBuilder();
String str = "0123456789";
for (int i = 0; i < length; i++) {
int index = random.nextInt(10);
stringBuffer.append(str.charAt(index));
}
return stringBuffer.toString();
}
/**
* 转换存储单位: KB MB GB TB
*
* @author fzr
* @return String
*/
public static String storageUnit(Long size) {
if (size == null) {
return "0B";
}
if (size < 1024) {
return size + "B";
} else {
size = size / 1024;
}
if (size < 1024) {
return size + "KB";
} else {
size = size / 1024;
}
if (size < 1024) {
size = size * 100;
return (size / 100) + "." + (size % 100) + "MB";
} else {
size = size * 100 / 1024;
return (size / 100) + "." + (size % 100) + "GB";
}
}
/**
* JSON转 Map<String, String>
*
* @author fzr
* @param json 对象
* @return Map<String, String>
*/
public static Map<String, String> jsonToMap(String json){
Type type = new TypeToken<Map<String, String>>() {}.getType();
return JSON.parseObject(json, type);
}
/**
* JSON转Map<String, String>
*
* @author fzr
* @param object 对象
* @return Map<String, String>
*/
public static Map<String, String> objectToMap(Object object){
Type type = new TypeToken<Map<String, String>>() {}.getType();
return JSON.parseObject(JSONObject.toJSONString(object), type);
}
/**
* 对象类型Map合并
*
* @author fzr
* @param map 对象
* @return Object
*/
public static Map<String, Object> mergeMapByObj(Map<String, Object> map, Map<String, Object> map1){
HashMap<String, Object> map2 = new HashMap<>();
map2.putAll(map);
map2.putAll(map1);
return map2;
}
/**
* 字符串类型Map合并
*
* @author fzr
* @param map 对象
* @return Object
*/
public static Map<String, String> mergeMapByStr(Map<String, String> map, Map<String, String> map1){
HashMap<String, String> map2 = new HashMap<>();
map2.putAll(map);
map2.putAll(map1);
return map2;
}
}

View File

@@ -0,0 +1,103 @@
package com.mdd.common.utils;
import com.mdd.common.config.GlobalConfig;
import java.util.Map;
/**
* 文件路径处理工具
*/
public class UrlUtil {
/**
* 访问前缀
*/
private static final String uploadPrefix = GlobalConfig.publicPrefix;
/**
* 转绝对路径
* 转前: uploads/11.png
* 转后: https://127.0.0.1/uploads/11.png
*
* @author fzr
* @param url 相对路径
* @return String
*/
public static String toAbsoluteUrl(String url) {
if (url == null || url.equals("")) {
return "";
}
if(url.indexOf("/") != 0) {
url = "/" + url;
}
if (url.startsWith("/api/static/")) {
return RequestUtil.uri() + url;
}
String engine = ConfigUtil.get("storage", "default", "local");
engine = engine.equals("") ? "local" : engine;
if (engine.equals("local")) {
return RequestUtil.uri() + "/" + uploadPrefix + url;
}
Map<String, String> config = ConfigUtil.getMap("storage", engine);
if (config != null) {
return config.getOrDefault("domain", "") + url;
}
return url;
}
/**
* 转相对路径
* 转前: https://127.0.0.1/uploads/11.png
* 转后: uploads/11.png
*
* @author fzr
* @param url 绝对路径
* @return String
*/
public static String toRelativeUrl(String url) {
if (url == null || url.equals("")) {
return "";
}
String engine = ConfigUtil.get("storage", "default", "local");
engine = engine.equals("") ? "local" : engine;
if (engine.equals("local")) {
return url.replace(RequestUtil.uri(), "")
.replace("/" + uploadPrefix + "/", "");
}
Map<String, String> config = ConfigUtil.getMap("storage", engine);
if (config != null) {
return url.replace(config.getOrDefault("domain", ""), "")
.replace( "/" + uploadPrefix + "/", "");
}
return url;
}
/**
* 获取存储域名
* 示例: https://127.0.0.1/
*
* @author fzr
* @return String
*/
public static String domain() {
String engine = ConfigUtil.get("storage", "default", "local");
engine = engine.equals("") ? "local" : engine;
if (engine.equals("local")) {
return RequestUtil.uri() + "/";
}
Map<String, String> config = ConfigUtil.getMap("storage", engine);
if (config != null) {
return config.getOrDefault("domain", "") + "/";
}
return "";
}
}

View File

@@ -0,0 +1,37 @@
package com.mdd.common.utils;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
/**
* 系统文件配置操作工具
*/
@Component
public class YmlUtil implements EnvironmentAware {
private static Environment env;
/**
* 设置环境变量
*
* @author fzr
* @param environment 环境变量
*/
@Override
public void setEnvironment(Environment environment) {
YmlUtil.env = environment;
}
/**
* 根据Key获取值
*
* @author fzr
* @param key 键
* @return String
*/
public static String get(String key) {
return env.getProperty(key);
}
}

View File

@@ -0,0 +1,23 @@
package com.mdd.common.validator;
import com.mdd.common.validator.annotation.IDMust;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* 验证主键ID参数
*/
public class IDMustValidator implements ConstraintValidator<IDMust, Integer> {
@Override
public void initialize(IDMust constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext constraintValidatorContext) {
return value != null && value > 0;
}
}

View File

@@ -0,0 +1,28 @@
package com.mdd.common.validator;
import com.mdd.common.validator.annotation.IntArrayEmpty;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
/**
* 验证整数数组是否为空
*/
public class IntArrayEmptyValidator implements ConstraintValidator<IntArrayEmpty, int[]> {
@Override
public void initialize(IntArrayEmpty constraintAnnotation) {
ConstraintValidator.super.initialize(constraintAnnotation);
}
@Override
public boolean isValid(int[] value, ConstraintValidatorContext context) {
if (value == null) {
return false;
}
return value.length > 0;
}
}

View File

@@ -0,0 +1,35 @@
package com.mdd.common.validator;
import com.mdd.common.validator.annotation.IntegerContains;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;
/**
* 验证数字是否在数组中
*/
public class IntegerContainsValidator implements ConstraintValidator<IntegerContains, Integer> {
private Set<Integer> limitValues;
@Override
public void initialize (IntegerContains integerContains) {
HashSet<Integer> set = new HashSet<>();
for (int i : integerContains.values()) {
set.add(i);
}
limitValues = set;
}
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
if (value == null) {
return true;
}
return limitValues.contains(value);
}
}

View File

@@ -0,0 +1,32 @@
package com.mdd.common.validator;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.mdd.common.validator.annotation.StringContains;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 验证字符串是否在数组中
*/
public class StringContainsValidator implements ConstraintValidator<StringContains, String> {
private Set<String> limitValues;
@Override
public void initialize (StringContains stringContains) {
limitValues = Arrays.stream(stringContains.values()).collect(Collectors.toSet());
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (StringUtils.isBlank(value)) {
return true;
}
return limitValues.contains(value.trim());
}
}

View File

@@ -0,0 +1,21 @@
package com.mdd.common.validator.annotation;
import com.mdd.common.validator.IDMustValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = IDMustValidator.class)
@Target({ ElementType.PARAMETER,ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface IDMust {
String message() default "id参数必须存在且大于0";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default { };
}

View File

@@ -0,0 +1,20 @@
package com.mdd.common.validator.annotation;
import com.mdd.common.validator.IntArrayEmptyValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = IntArrayEmptyValidator.class)
@Target({ ElementType.PARAMETER,ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface IntArrayEmpty {
String message() default "数组不允许为空";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default { };
}

View File

@@ -0,0 +1,23 @@
package com.mdd.common.validator.annotation;
import com.mdd.common.validator.IntegerContainsValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = IntegerContainsValidator.class)
@Target({ ElementType.PARAMETER,ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface IntegerContains {
String message() default "数值不符合规则";
int[] values() default {};
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default { };
}

View File

@@ -0,0 +1,23 @@
package com.mdd.common.validator.annotation;
import com.mdd.common.validator.StringContainsValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;
@Documented
@Constraint(validatedBy = StringContainsValidator.class)
@Target({ ElementType.PARAMETER,ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface StringContains {
String message() default "字符串不符合规则";
String[] values() default {};
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default { };
}