Commit fb0b2416 authored by 侯力峰's avatar 侯力峰
Browse files

首次开源发布

parent f978a999
Pipeline #2758 canceled with stages
package cn.spatiotemporal.web.core.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.stereotype.Service;
import cn.spatiotemporal.web.core.annotation.DisableSysLog;
import cn.spatiotemporal.web.core.dao.ServiceLogDao;
import cn.spatiotemporal.web.core.domain.entity.admin.ServiceLog;
import cn.spatiotemporal.web.core.service.IServiceLogService;
@Service
@ConditionalOnMissingBean(annotation = DisableSysLog.class)
public class ServiceLogServiceImpl implements IServiceLogService {
@Autowired
private ServiceLogDao dao;
@Override
public void save(ServiceLog sysLog) {
dao.insert(sysLog);
}
}
package cn.spatiotemporal.web.core.utils;
import java.util.function.Function;
/**
* 服务端通讯安全算法
* @author marquis
*
*/
public class BackEndStream {
private byte[] stream;
private static Function<Byte, Character> byte2Char = (b) -> {
return (char) (b > 9 ? b + 55 : b + 48);
};
private static Function<Character, Byte> char2Byte = (c) -> {
return (byte) (c > 96 ? c - 87 : c > 64 ? c - 55 : c - 48);
};
private static Function<byte[], String> array2String = (a) -> {
StringBuffer sa = new StringBuffer();
StringBuffer sb = new StringBuffer();
for (byte b : a) {
sa.append(byte2Char.apply((byte) (b & 0x0f)));
sb.append(byte2Char.apply((byte) ((b >> 4) & 0x0f)));
}
return sa.append(sb).toString();
};
private static Function<String, byte[]> string2Array = (s) -> {
int len = s.length() / 2;
byte[] a = new byte[len];
for (int i = 0; i < len; i++) {
a[i] = (byte) (char2Byte.apply(s.charAt(i)) | (char2Byte.apply(s.charAt(i + len)) << 4));
}
return a;
};
BackEndStream(byte[] a) {
stream = a;
}
static BackEndStream of(String src) {
return new BackEndStream(src.getBytes());
}
static BackEndStream hex(String hex) {
return new BackEndStream(string2Array.apply(hex));
}
BackEndStream convert(Converter conveter) {
for (int i = stream.length -1; i >= 0; i--) {
stream[i] = conveter.convert((i > 0 ? stream[i - 1] : 0x00), stream[i], i);
}
return this;
}
/**
* 是否输出为hex字符串
* @param flag
* @return
*/
String output(boolean flag) {
return flag ? array2String.apply(stream) : new String(stream);
}
@FunctionalInterface
interface Converter {
byte convert(byte a, byte b, int i);
}
}
package cn.spatiotemporal.web.core.utils;
import java.util.Random;
import java.util.function.Function;
/**
* 服务端工具类
* @author marquis
*
*/
public class BackEndUtils {
private static Function<Character, Byte> char2Byte = (c) -> {
return (byte) (c > 96 ? c - 87 : c > 64 ? c - 55 : c - 48);
};
private static Function<Long, byte[]> long2Array = (l) -> {
byte[] a = new byte[8];
for (int i = 0; i < 8; i++) {
a[i] = (byte) ((l >> (i * 8)) & 0xff);
}
return a;
};
private static Function<String, byte[]> string2Array = (s) -> {
int len = s.length() / 2;
byte[] a = new byte[len];
for (int i = 0; i < len; i++) {
a[i] = (byte) (char2Byte.apply(s.charAt(i)) | (char2Byte.apply(s.charAt(i + len)) << 4));
}
return a;
};
private static Key key = (uuid, value) -> {
try {
byte[] code = string2Array.apply(uuid.replaceAll("-", ""));
long next = (new Random(value)).nextLong();
for (int i = 0; i < code.length; i+=8) {
for (int j = 0; j < 8; j++) {
next ^= (code[i + j] & 0xff) << (j * 8);
}
}
return next;
} catch (Exception e) {
return (new Random(value)).nextLong();
}
};
/**
* 解析Hex字符串
* @param request
* @param code
* @return
*/
public static String parseHex(String hex, String code) {
byte[] pis = long2Array.apply(Double.doubleToRawLongBits(Math.PI) ^ Long.parseLong(code));
return BackEndStream.hex(hex).convert((a, b, i) -> (byte)((byte)a ^ (byte)b ^ (byte)pis[i % 8])).output(false);
}
/**
* 生成Hex字符串
* @param request
* @param code
* @return
*/
public static String toHex(String src, String code) {
byte[] pis = long2Array.apply(Double.doubleToRawLongBits(Math.PI) ^ Long.parseLong(code));
return BackEndStream.of(src).convert((a, b, i) -> (byte)((byte)a ^ (byte)b ^ (byte)pis[i % 8])).output(true);
}
public static String nextCode(String device, String current) {
return String.valueOf(key.next(device, Long.parseLong(current)));
}
public static boolean valiadCode(String device, String prev, String current) {
try {
return (Long.parseLong(current) ^ Double.doubleToRawLongBits(Math.PI) ^ key.next(device, Long.parseLong(prev))) == 0;
} catch (Exception e) {
return false;
}
}
@FunctionalInterface
interface Key {
long next(String s, long l);
}
}
package cn.spatiotemporal.web.core.utils;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Year;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
/**
* @ClassName: DateUtils
* @Description: ThreadLocal线程安全的DateUtils
* @date 2020年1月9日 上午10:43:42
*
* @author Q.JI
* @version
* @since JDK 1.8
*/
public class DateUtils {
private DateUtils() {
}
private static final ZoneId ZONE_ID = ZoneId.systemDefault();
/**
* LocalDateTime转化为Date
*
* @param localDateTime
* @return
*/
public static Date toDate(LocalDateTime localDateTime) {
return Date.from(localDateTime.atZone(ZONE_ID).toInstant());
}
/**
* LocalDateTime转化为Date
*
* @param localDateTime
* @return
*/
public static Date toDate(LocalDate localDate) {
return Date.from(localDate.atStartOfDay(ZONE_ID).toInstant());
}
/**
* Date转化为LocalDateTime
*
* @param date
* @return
*/
public static LocalDateTime toLocalDateTime(Date date) {
return LocalDateTime.ofInstant(date.toInstant(), ZONE_ID);
}
/**
* LocalDate转化为LocalDateTime
*
* @param localDate
* @return
*/
public static LocalDateTime toLocalDateTime(LocalDate localDate) {
return LocalDateTime.of(localDate, LocalTime.MIN);
}
/**
* Date转化为LocalDate
*
* @param date
* @return
*/
public static LocalDate toLocalDate(Date date) {
return date.toInstant().atZone(ZONE_ID).toLocalDate();
}
/**
* Date转化为字符串
*
* @param date
* @param formatter
* @return
*/
public static String format(Date date, DateFormatter formatter) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZONE_ID);
return formatter.getDateTimeFormatter().format(localDateTime);
}
/**
* Date转化为字符串
*
* @param date
* @param format
* @return
*/
public static String format(Date date, String format) {
LocalDateTime localDateTime = LocalDateTime.ofInstant(date.toInstant(), ZONE_ID);
return DateTimeFormatter.ofPattern(format, Locale.CHINA).format(localDateTime);
}
/**
* 字符串转化为Date
*
* @param text
* @param formatter
* @return
*/
public static Date parse(String text, DateFormatter formatter) {
return formatter.parse(text);
}
/**
*
* @Title: increase
* @Description: 时间相加减运算
* @param date
* @param dateType
* @param amount
* @param formatter
* @return String
*/
public static String increase(Date date, int dateType, int amount, DateFormatter formatter) {
Date myDate = null;
if (date != null) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.add(dateType, amount);
myDate = calendar.getTime();
}
return format(myDate, formatter);
}
/**
*
* @ClassName: DateFormatter
* @Description: 时间格式枚举
* @date 2020年1月17日 下午4:04:01
*
* @author Q.JI
* @version
* @since JDK 1.8
*/
public static enum DateFormatter {
/**
* 格式yyyy
*/
YEAR_FORMATTER(DateTimeFormatter.ofPattern("yyyy", Locale.CHINA)) {
@Override
public Date parse(String text) {
Year year = Year.parse(text, dateTimeFormatter);
return Date.from(year.atDay(1).atStartOfDay(ZONE_ID).toInstant());
}
},
/**
* yyyy-MM
*/
YEAR_MONTH_FORMATTER(DateTimeFormatter.ofPattern("yyyy-MM", Locale.CHINA)) {
@Override
public Date parse(String text) {
YearMonth yearMonth = YearMonth.parse(text, dateTimeFormatter);
return Date.from(yearMonth.atDay(1).atStartOfDay(ZONE_ID).toInstant());
}
},
/**
* 格式yyyy-MM-dd
*/
DATE_FORMATTER(DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.CHINA)) {
@Override
public Date parse(String text) {
LocalDate localDate = LocalDate.parse(text, dateTimeFormatter);
return Date.from(localDate.atStartOfDay(ZONE_ID).toInstant());
}
},
/**
* 格式yyyy-MM-dd HH:mm:ss
*/
DATE_TIME_FORMATTER(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA)) {
@Override
public Date parse(String text) {
LocalDateTime localDateTime = LocalDateTime.parse(text, dateTimeFormatter);
return Date.from(localDateTime.atZone(ZONE_ID).toInstant());
}
},
/**
* 格式yyyy-MM-dd_HH
*/
DATE_HOUR_FORMATTER(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH", Locale.CHINA)) {
@Override
public Date parse(String text) {
LocalDate localDate = LocalDate.parse(text, dateTimeFormatter);
return Date.from(localDate.atStartOfDay(ZONE_ID).toInstant());
}
},
/**
* 格式yyyyMMdd
*/
YYYYMMDD_FORMATTER(DateTimeFormatter.ofPattern("yyyyMMdd", Locale.CHINA)) {
@Override
public Date parse(String text) {
LocalDateTime localDateTime = LocalDateTime.parse(text, dateTimeFormatter);
return Date.from(localDateTime.atZone(ZONE_ID).toInstant());
}
},
/**
* 格式yyyyMMddHHmmss
*/
YYYYMMDDHHMMSS_FORMATTER(DateTimeFormatter.ofPattern("yyyyMMddHHmmss", Locale.CHINA)) {
@Override
public Date parse(String text) {
LocalDateTime localDateTime = LocalDateTime.parse(text, dateTimeFormatter);
return Date.from(localDateTime.atZone(ZONE_ID).toInstant());
}
},
/**
* 格式yyyyMMdd_HHmmss
*/
YYYYMMDD_HHMMSS_FORMATTER(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss", Locale.CHINA)) {
@Override
public Date parse(String text) {
LocalDateTime localDateTime = LocalDateTime.parse(text, dateTimeFormatter);
return Date.from(localDateTime.atZone(ZONE_ID).toInstant());
}
};
protected DateTimeFormatter dateTimeFormatter;
private DateFormatter(DateTimeFormatter dateTimeFormatter) {
this.dateTimeFormatter = dateTimeFormatter;
}
public DateTimeFormatter getDateTimeFormatter() {
return dateTimeFormatter;
}
public abstract Date parse(String text);
}
}
package cn.spatiotemporal.web.core.utils;
import org.springframework.util.DigestUtils;
/**
* 密码加密用的工具类
* @author marquis
*
*/
public class EncryptUtils {
public static String encryptPassword(String password) {
return DigestUtils.md5DigestAsHex(password.getBytes());
}
}
package cn.spatiotemporal.web.core.utils;
import java.util.function.Function;
/**
* 前端通讯安全算法
* @author marquis
*
*/
public class FrontEndStream {
private byte[] stream;
private static Function<Byte, Character> byte2Char = (b) -> {
return (char) (b > 9 ? b + 55 : b + 48);
};
private static Function<Character, Byte> char2Byte = (c) -> {
return (byte) (c > 96 ? c - 87 : c > 64 ? c - 55 : c - 48);
};
private static Function<byte[], String> array2String = (a) -> {
StringBuffer sa = new StringBuffer();
StringBuffer sb = new StringBuffer();
for (byte b : a) {
sa.append(byte2Char.apply((byte) (b & 0x0f)));
sb.append(byte2Char.apply((byte) ((b >> 4) & 0x0f)));
}
return sa.append(sb).toString();
};
private static Function<String, byte[]> string2Array = (s) -> {
int len = s.length() / 2;
byte[] a = new byte[len];
for (int i = 0; i < len; i++) {
a[i] = (byte) (char2Byte.apply(s.charAt(i)) | (char2Byte.apply(s.charAt(i + len)) << 4));
}
return a;
};
FrontEndStream(byte[] a) {
stream = a;
}
static FrontEndStream of(String src) {
return new FrontEndStream(src.getBytes());
}
static FrontEndStream hex(String hex) {
return new FrontEndStream(string2Array.apply(hex));
}
FrontEndStream convert(Converter conveter) {
for (int i = 0; i < stream.length; i++) {
stream[i] = conveter.convert((i > 0 ? stream[i - 1] : 0x00), stream[i], i);
}
return this;
}
String output(boolean flag) {
return flag ? array2String.apply(stream) : new String(stream);
}
@FunctionalInterface
interface Converter {
byte convert(byte a, byte b, int i);
}
}
package cn.spatiotemporal.web.core.utils;
import java.util.Random;
import java.util.function.Function;
/**
* 前端工具集
* @author marquis
*
*/
public class FrontEndUtils {
private static Function<Character, Byte> char2Byte = (c) -> {
return (byte) (c > 96 ? c - 87 : c > 64 ? c - 55 : c - 48);
};
private static Function<Long, byte[]> long2Array = (l) -> {
byte[] a = new byte[8];
for (int i = 0; i < 8; i++) {
a[i] = (byte) ((l >> (i * 8)) & 0xff);
}
return a;
};
private static Function<byte[], Long> array2Long = (a) -> {
long value = 0;
for (int i = 0; i < 8; i++) {
value |= ((long)(a[i] & 0xff)) << (i * 8);
}
return value;
};
private static Function<String, byte[]> string2Array = (s) -> {
int len = s.length() / 2;
byte[] a = new byte[len];
for (int i = 0; i < len; i++) {
a[i] = (byte) (char2Byte.apply(s.charAt(i)) | (char2Byte.apply(s.charAt(i + len)) << 4));
}
return a;
};
private static Key key = (uuid, value) -> {
try {
byte[] code = string2Array.apply(uuid.replaceAll("-", ""));
long next = (new Random(value)).nextLong();
for (int i = 0; i < code.length; i+=8) {
for (int j = 0; j < 8; j++) {
next ^= (code[i + j] & 0xff) << (j * 8);
}
}
return next ^ Double.doubleToRawLongBits(Math.PI);
} catch (Exception e) {
return (new Random(value)).nextLong();
}
};
/**
* 解析Hex字符串
* @param request
* @param code
* @return
*/
public static String parseHex(String hex, String code) {
byte[] pis = long2Array.apply(Long.parseLong(code));
return FrontEndStream.hex(hex).convert((a, b, i) -> (byte)((byte)a ^ (byte)b ^ (byte)pis[i % 8])).output(false);
}
/**
* 生成Hex字符串
* @param src
* @param code
* @return
*/
public static String toHex(String src, String code) {
byte[] pis = long2Array.apply(Long.parseLong(code));
return FrontEndStream.of(src).convert((a, b, i) -> (byte)((byte)a ^ (byte)b ^ (byte)pis[i % 8])).output(true);
}
public static String nextCode(String device, String current) {
return String.valueOf(key.next(device, Long.parseLong(current)));
}
@FunctionalInterface
interface Key {
long next(String s, long l);
}
}
package cn.spatiotemporal.web.core.utils;
import java.net.InetAddress;
import javax.servlet.http.HttpServletRequest;
/**
* 获取IP地址的工具类
* @author marquis
*
*/
public class IPAddressUtils {
private static String serverIP = null;
/**
* 获取客户端用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
* 参考文章: http://developer.51cto.com/art/201111/305181.htm
*
* 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?
* 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
*
* 如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
* 192.168.1.100
*
* 用户真实IP为: 192.168.1.110
* @param request
* @return
*/
public static String getClientIP(HttpServletRequest request) {
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("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
/**
* 获取服务端IP
* @return
*/
public static String getServerIP() {
if (serverIP != null) {
return serverIP;
}
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
} catch (Exception e) {
e.printStackTrace();
}
String ip = inet.getHostAddress();
// 多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ip != null && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
serverIP = ip;
return serverIP;
}
}
package cn.spatiotemporal.web.core.utils;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import cn.spatiotemporal.web.core.domain.Treeable;
/**
* 树形数据结构通用工具类
* @author marquis
*
*/
public class TreeUtils {
/**
* 从列表转换成树
* @param list
* @return
*/
public static <T extends Treeable> List<T> list2Tree(List<T> list) {
Map<Serializable, Treeable> map = new HashMap<Serializable, Treeable>();
List<T> tree = new ArrayList<T>();
list.forEach(node -> {
map.put(node.getId(), node);
Treeable parent = map.get(node.getParentId());
if (parent == null) {
tree.add(node);
} else {
parent.addChild(node);
}
});
return tree;
}
/**
* 从树转换成列表
* @param tree
* @return
*/
public static <T extends Treeable> List<T> tree2List(List<T> tree) {
List<T> list = new ArrayList<T>();
tree.forEach(node -> {
list.add(node);
if (node.hasChildren()) {
list.addAll(tree2List(node.getChildren()));
}
});
return list;
}
}
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.spatiotemporal.web.core.config.restapi.RestApiConfig,\
cn.spatiotemporal.web.core.config.thread.AsyncTaskConfig,\
cn.spatiotemporal.web.core.config.web.WebMvcConfig,\
cn.spatiotemporal.web.core.exception.handler.GlobalExceptionHandler,\
cn.spatiotemporal.web.core.permission.PermissionAspect,\
cn.spatiotemporal.web.core.security.RestAccessDeniedHandler,\
cn.spatiotemporal.web.core.security.RestAuthenticationEntryPoint,\
cn.spatiotemporal.web.core.security.RestAuthenticationFailureHandler,\
cn.spatiotemporal.web.core.security.RestLogoutSuccessHandler,\
cn.spatiotemporal.web.core.service.impl.OperationLogServiceImpl,\
cn.spatiotemporal.web.core.service.impl.ServiceLogServiceImpl
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment