From 7371fda1f275266693e2602377466929ea113846 Mon Sep 17 00:00:00 2001 From: solo-hx <6gEemAZ> Date: Fri, 16 Aug 2019 18:06:10 +0800 Subject: [PATCH] =?UTF-8?q?dev=E5=88=86=E6=94=AF=20=E5=90=84=E7=A7=8D?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E7=B1=BB=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ruoyi-common/pom.xml | 6 + .../com/ruoyi/common/tkmapper/MyMapper.java | 13 + .../com/ruoyi/common/utils/DateUtils.java | 11 + .../utils/buildform/BuildFormUtils.java | 40 ++++ .../utils/buildform/PrintWriterUtil.java | 117 +++++++++ .../common/utils/captchautil/CaptchaUtil.java | 131 ++++++++++ .../utils/captchautil/ValidateCode.java | 179 ++++++++++++++ .../ruoyi/common/utils/file/Base64Util.java | 52 ++++ .../ruoyi/common/utils/file/FileUtils.java | 223 +++++++++++++++++- .../common/utils/file/UploadFileUtil.java | 156 ++++++++++++ .../ruoyi/common/utils/http/HttpUtils.java | 121 +++++++++- .../common/utils/idgenerator/UUIDUtils.java | 110 +++++++++ .../common/utils/jsonutils/JsonUtils.java | 64 +++++ .../ruoyi/common/utils/random/RandomUtil.java | 20 ++ .../common/utils/random/ShareCodeUtil.java | 109 +++++++++ .../common/utils/regexutil/RegexUtil.java | 169 +++++++++++++ .../ruoyi/common/utils/security/Md5Utils.java | 81 ++++++- .../common/utils/stringutils/StrUtils.java | 144 +++++++++++ .../com/ruoyi/common/utils/tree/Ztree.java | 216 +++++++++++++++++ .../ruoyi/common/utils/tree/ZtreeUtil.java | 60 +++++ 20 files changed, 2010 insertions(+), 12 deletions(-) create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/tkmapper/MyMapper.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/buildform/BuildFormUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/buildform/PrintWriterUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/captchautil/CaptchaUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/captchautil/ValidateCode.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/Base64Util.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/file/UploadFileUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/idgenerator/UUIDUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/jsonutils/JsonUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/random/RandomUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/random/ShareCodeUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/regexutil/RegexUtil.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/stringutils/StrUtils.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/tree/Ztree.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/utils/tree/ZtreeUtil.java diff --git a/ruoyi-common/pom.xml b/ruoyi-common/pom.xml index fe5fc81cf..457a07478 100644 --- a/ruoyi-common/pom.xml +++ b/ruoyi-common/pom.xml @@ -100,6 +100,12 @@ javax.servlet javax.servlet-api + + + tk.mybatis + mapper-spring-boot-starter + 2.0.3 + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/tkmapper/MyMapper.java b/ruoyi-common/src/main/java/com/ruoyi/common/tkmapper/MyMapper.java new file mode 100644 index 000000000..235ea130c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/tkmapper/MyMapper.java @@ -0,0 +1,13 @@ +package com.ruoyi.common.tkmapper; + +import tk.mybatis.mapper.common.Mapper; +import tk.mybatis.mapper.common.MySqlMapper; + +/** + * 自定义通用mapper + * + * @author solo + * @date 2019/08/16. + */ +public interface MyMapper extends Mapper, MySqlMapper { +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java index 8ff95f1b7..8166fd9f0 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java @@ -4,6 +4,8 @@ import java.lang.management.ManagementFactory; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; + +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; /** @@ -152,4 +154,13 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils // long sec = diff % nd % nh % nm / ns; return day + "天" + hour + "小时" + min + "分钟"; } + + public static String dateToString(Date date, String pattern) { + if (date != null && StringUtils.isNotEmpty(pattern)) { + SimpleDateFormat format = new SimpleDateFormat(pattern); + return format.format(date); + } else { + return null; + } + } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/buildform/BuildFormUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/buildform/BuildFormUtils.java new file mode 100644 index 000000000..2aa0ab0d9 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/buildform/BuildFormUtils.java @@ -0,0 +1,40 @@ +package com.ruoyi.common.utils.buildform; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + +/** + * 构建一个form表单提交 + */ +public class BuildFormUtils { + + /** + * 构造提交表单HTML数据 + * + * @param sParaTemp 请求参数数组 + * @param gateway 网关地址 + * @param strMethod 提交方式。两个值可选:post、get + * @param strButtonName 确认按钮显示文字 + * @return 提交表单HTML文本 + */ + public static String buildForm(Map sParaTemp, String gateway, String strMethod, + String strButtonName) { + // 待请求参数数组 + List keys = new ArrayList(sParaTemp.keySet()); + StringBuffer sbHtml = new StringBuffer(); + sbHtml.append("正在请求处理中" + + ""); + sbHtml.append("
"); + for (int i = 0; i < keys.size(); i++) { + String name = (String) keys.get(i); + String value = (String) sParaTemp.get(name); + sbHtml.append(""); + } + // submit按钮控件请不要含有name属性 + sbHtml.append("
"); + return sbHtml.toString(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/buildform/PrintWriterUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/buildform/PrintWriterUtil.java new file mode 100644 index 000000000..b9570554c --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/buildform/PrintWriterUtil.java @@ -0,0 +1,117 @@ +package com.ruoyi.common.utils.buildform; + +import java.io.PrintWriter; + +/** + * 向前端输出一个html页面内容提示 + * @author solo + * @date 2019/08/16. + */ +public class PrintWriterUtil { + + /** + * 向前端输出一个html页面内容提示 + * + * @param pw + * @param str + */ + public static void pwPrintln(PrintWriter pw, String str) { +// String string = "" + +// "" + +// "错误提示" + +// "" + +// "
" + +// "
" + +// "

hi,你好

"+str+"

" + +// "

返回上一页

" + +// "
"; + + String string = "" + + "" + + "" + + " 错误提示" + + " " + + " " + + " " + + "" + + "" + + "" + + "" + + "
" + + "
" + + " " + + "
" + + "
" + + "
" + + "

hi,你好

" + + "

" + str + "

" + + "

" + + " 返回上一页" + + "

" + + "
" + + "
" + + "
" + + "
" + + ""; + + pw.println(string); + } + + + /** + * 向前端输出一个字符串内容提示 + * + * @param pw + * @param str + */ + public static void pwPrintlnStr(PrintWriter pw, String str) { + pw.print(str); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/captchautil/CaptchaUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/captchautil/CaptchaUtil.java new file mode 100644 index 000000000..2bc9085b8 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/captchautil/CaptchaUtil.java @@ -0,0 +1,131 @@ +package com.ruoyi.common.utils.captchautil; + +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpSession; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.util.Random; + +/** + * 验证码生成工具 + * @author solo + * @date 2019/08/16. + */ +public class CaptchaUtil { + private BufferedImage image;// 图像 + private String str;// 验证码 + private static char code[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789".toCharArray(); + private static Integer code_num=10; + public static final String SESSION_CODE_NAME="code"; + + private CaptchaUtil() { + init();// 初始化属性 + } + + /* + * 取得RandomNumUtil实例 + */ + public static CaptchaUtil Instance() { + return new CaptchaUtil(); + } + + /* + * 取得验证码图片 + */ + public BufferedImage getImage() { + return this.image; + } + + /* + * 取得图片的验证码 + */ + public String getString() { + return this.str; + } + + private void init() { + // 在内存中创建图象 + int width = 85, height = 20; + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + // 获取图形上下文 + Graphics g = image.getGraphics(); + // 生成随机类 + Random random = new Random(); + g.setFont(new Font("LucidaBrightItalic", Font.BOLD, 20)); + // 设定背景色 + g.setColor(getRandColor(200, 250)); + g.fillRect(0, 0, width, height); + // 设定字体 + g.setFont(new Font("Times New Roman", Font.PLAIN, 18)); + // 随机产生155条干扰线,使图象中的认证码不易被其它程序探测到 + g.setColor(getRandColor(160, 200)); + for (int i = 0; i < 155; i++) { + int x = random.nextInt(width); + int y = random.nextInt(height); + int xl = random.nextInt(12); + int yl = random.nextInt(12); + g.drawLine(x, y, x + xl, y + yl); + } + // 取随机产生的认证码(4位数字) + String sRand = ""; + for (int i = 0; i < 4; i++) { +// String rand = String.valueOf(code[random.nextInt(code.length)]); + String rand = String.valueOf(random.nextInt(code_num)); + sRand += rand; + // 将认证码显示到图象中 + g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110))); + // 调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成 + g.drawString(rand, 13 * i + 6, 16); + } + // 赋值验证码 + this.str = sRand; + + // 图象生效 + g.dispose(); + // ByteArrayInputStream input = null; + // ByteArrayOutputStream output = new ByteArrayOutputStream(); + // try { + // ImageOutputStream imageOut = ImageIO.createImageOutputStream(output); + // ImageIO.write(image, "JPEG", imageOut); + // imageOut.close(); + // input = new ByteArrayInputStream(output.toByteArray()); + // } catch (Exception e) { + // System.out.println("验证码图片产生出现错误:" + e.toString()); + // } + // this.image = input + this.image = image;/* 赋值图像 */ + } + + /* + * 给定范围获得随机颜色 + */ + private Color getRandColor(int fc, int bc) { + Random random = new Random(); + if (fc > 255) + fc = 255; + if (bc > 255) + bc = 255; + int r = fc + random.nextInt(bc - fc); + int g = fc + random.nextInt(bc - fc); + int b = fc + random.nextInt(bc - fc); + return new Color(r, g, b); + } + + /** + * 验证码验证 + * @param session + * @param code + */ + public static boolean checkCode(HttpSession session, String code) { + String codeSession = (String) session.getAttribute("code"); + if (StringUtils.isEmpty(codeSession)) { + return false; + } + if (StringUtils.isEmpty(code)) { + return false; + } + session.setAttribute("code", ""); + return codeSession.equalsIgnoreCase(code); + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/captchautil/ValidateCode.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/captchautil/ValidateCode.java new file mode 100644 index 000000000..fa8df750d --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/captchautil/ValidateCode.java @@ -0,0 +1,179 @@ +package com.ruoyi.common.utils.captchautil; + +import org.apache.commons.lang3.StringUtils; + +import javax.imageio.ImageIO; +import javax.servlet.http.HttpSession; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Date; +import java.util.Random; + +/** + * 验证码生成器 + * @author solo + * @date 2019/08/16. + */ +public class ValidateCode { + // 图片的宽度。 + private int width = 160; + // 图片的高度。 + private int height = 40; + // 验证码字符个数 + private int codeCount = 5; + // 验证码干扰线数 + private int lineCount = 150; + // 验证码 + private String code = null; + // 验证码图片Buffer + private BufferedImage buffImg = null; + + // 验证码范围,去掉0(数字)和O(拼音)容易混淆的(小写的1和L也可以去掉,大写不用了) + private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', + 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; + + /** + * 默认构造函数,设置默认参数 + */ + public ValidateCode() { + this.createCode(); + } + + /** + * @param width 图片宽 + * @param height 图片高 + */ + public ValidateCode(int width, int height) { + this.width = width; + this.height = height; + this.createCode(); + } + + /** + * @param width 图片宽 + * @param height 图片高 + * @param codeCount 字符个数 + * @param lineCount 干扰线条数 + */ + public ValidateCode(int width, int height, int codeCount, int lineCount) { + this.width = width; + this.height = height; + this.codeCount = codeCount; + this.lineCount = lineCount; + this.createCode(); + } + + public void createCode() { + int x = 0, fontHeight = 0, codeY = 0; + int red = 0, green = 0, blue = 0; + + x = width / (codeCount + 2);//每个字符的宽度(左右各空出一个字符) + fontHeight = height - 2;//字体的高度 + codeY = height - 4; + + // 图像buffer + buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics2D g = buffImg.createGraphics(); + // 生成随机数 + Random random = new Random(); + // 将图像填充为白色 + g.setColor(Color.WHITE); + g.fillRect(0, 0, width, height); + // 创建字体,可以修改为其它的 + Font font = new Font("Fixedsys", Font.PLAIN, fontHeight); +// Font font = new Font("Times New Roman", Font.ROMAN_BASELINE, fontHeight); + g.setFont(font); + + for (int i = 0; i < lineCount; i++) { + // 设置随机开始和结束坐标 + int xs = random.nextInt(width);//x坐标开始 + int ys = random.nextInt(height);//y坐标开始 + int xe = xs + random.nextInt(width / 8);//x坐标结束 + int ye = ys + random.nextInt(height / 8);//y坐标结束 + + // 产生随机的颜色值,让输出的每个干扰线的颜色值都将不同。 + red = random.nextInt(255); + green = random.nextInt(255); + blue = random.nextInt(255); + g.setColor(new Color(red, green, blue)); + g.drawLine(xs, ys, xe, ye); + } + + // randomCode记录随机产生的验证码 + StringBuffer randomCode = new StringBuffer(); + // 随机产生codeCount个字符的验证码。 + for (int i = 0; i < codeCount; i++) { + String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]); + // 产生随机的颜色值,让输出的每个字符的颜色值都将不同。 + red = random.nextInt(255); + green = random.nextInt(255); + blue = random.nextInt(255); + g.setColor(new Color(red, green, blue)); + g.drawString(strRand, (i + 1) * x, codeY); + // 将产生的四个随机数组合在一起。 + randomCode.append(strRand); + } + // 将四位数字的验证码保存到Session中。 + System.out.println("随机验证码"+randomCode.toString()); + code = randomCode.toString(); + } + + public void write(String path) throws IOException { + OutputStream sos = new FileOutputStream(path); + this.write(sos); + } + + public void write(OutputStream sos) throws IOException { + ImageIO.write(buffImg, "png", sos); + sos.close(); + } + + public BufferedImage getBuffImg() { + return buffImg; + } + + public String getCode() { + return code; + } + + + /** + * 验证码验证 + * @param session + * @param code + */ + public static boolean checkCode(HttpSession session, String code) { + String codeSession = (String) session.getAttribute("code"); + if (StringUtils.isEmpty(codeSession)) { + return false; + } + if (StringUtils.isEmpty(code)) { + return false; + } + if (codeSession.equalsIgnoreCase(code)) { + return true; + } else { + return false; + } + } + + + /** + * 测试函数,默认生成到d盘 + * @param args + */ + public static void main(String[] args) { + ValidateCode vCode = new ValidateCode(160,40,5,150); + try { + String path="D:/"+new Date().getTime()+".png"; + System.out.println(vCode.getCode()+" >"+path); + vCode.write(path); + } catch (IOException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/Base64Util.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/Base64Util.java new file mode 100644 index 000000000..6237efb8d --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/Base64Util.java @@ -0,0 +1,52 @@ +package com.ruoyi.common.utils.file; + +import org.apache.commons.codec.binary.Base64; + +/** + * Base64字符串编码工具类 + * + * @author Administrator + */ +public class Base64Util { + + /** + * 加密 + * + * @param data 待加密的字节数组 + * @return 加密后的字符串 + */ + public static String encode(byte[] data) { + if (data == null) { + return null; + } + Base64 base64 = new Base64(); + return new String(base64.encode(data)); + } + + /** + * 加密 + * + * @param data 待加密的字符串 + * @return 加密后的字符串 + */ + public static String encode(String data) { + if (data == null) { + return null; + } + return encode(data.getBytes()); + } + + /** + * 解密 + * + * @param str 待解密的字符串 + * @return 解密后的字符串,如果str是null或长度为0,返回str + */ + public static byte[] decode(String str) { + Base64 base64 = new Base64(); + return base64.decode(str); + } + + +} + diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java index 03f5aa2a2..eccf85573 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/FileUtils.java @@ -1,12 +1,11 @@ package com.ruoyi.common.utils.file; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.io.UnsupportedEncodingException; +import java.io.*; import java.net.URLEncoder; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.util.ArrayList; +import java.util.List; import javax.servlet.http.HttpServletRequest; /** @@ -18,6 +17,16 @@ public class FileUtils { public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+"; + /** + * 创建多级目录 + * + * @param directory 目录文件 + * @return 是否成功 + */ + private static boolean createDirectory(File directory) { + return directory.exists() || directory.mkdirs(); + } + /** * 输出指定文件的byte数组 * @@ -139,4 +148,206 @@ public class FileUtils } return filename; } + + + /** + * Buffer的大小 + */ + private static final Integer BUFFER_SIZE = 1024 * 1024 * 10; + + + /** + * 复制文件 + * + * @param resourcePath 源文件 + * @param targetPath 目标文件 + * @return 是否成功 + */ + public static boolean copy(String resourcePath, String targetPath) { + File file = new File(resourcePath); + return copy(file, targetPath); + } + + /** + * 复制文件 + * 通过该方式复制文件文件越大速度越是明显 + * + * @param file 需要处理的文件 + * @param targetFile 目标文件 + * @return 是否成功 + */ + public static boolean copy(File file, String targetFile) { + try ( + FileInputStream fin = new FileInputStream(file); + FileOutputStream fout = new FileOutputStream(new File(targetFile)) + ) { + FileChannel in = fin.getChannel(); + FileChannel out = fout.getChannel(); + //设定缓冲区 + ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE); + while (in.read(buffer) != -1) { + //准备写入,防止其他读取,锁住文件 + buffer.flip(); + out.write(buffer); + //准备读取。将缓冲区清理完毕,移动文件内部指针 + buffer.clear(); + } + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + + /** + * 创建多级目录 + * + * @param paths 需要创建的目录 + * @return 是否成功 + */ + public static boolean createPaths(String paths) { + File dir = new File(paths); + return !dir.exists() && dir.mkdir(); + } + + /** + * 创建文件支持多级目录 + * + * @param filePath 需要创建的文件 + * @return 是否成功 + */ + public static boolean createFiles(String filePath) { + File file = new File(filePath); + File dir = file.getParentFile(); + if (!dir.exists()) { + if (dir.mkdirs()) { + try { + return file.createNewFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return false; + } + + /** + * 删除一个文件 + * + * @param file 需要处理的文件 + * @return 是否成功 + */ + public static boolean deleteFile(File file) { + return file.delete(); + } + + /** + * 删除一个目录 + * + * @param file 需要处理的文件 + * @return 是否成功 + */ + public static boolean deleteDir(File file) { + List files = listFileAll(file); + if (files == null) { + return true; + } + for (File f : files) { + if (f.isDirectory()) { + deleteDir(f); + } else { + deleteFile(f); + } + } + return file.delete(); + } + + /** + * 快速清空一个超大的文件 + * + * @param file 需要处理的文件 + * @return 是否成功 + */ + public static boolean cleanFile(File file) { + try ( + FileWriter fw = new FileWriter(file) + ) { + fw.write(""); + return true; + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + /** + * 快速的删除超大的文件 + * + * @param file 需要处理的文件 + * @return 是否成功 + */ + public static boolean deleteBigFile(File file) { + return cleanFile(file) && file.delete(); + } + + + /** + * 复制目录 + * + * @param filePath 需要处理的文件 + * @param targetPath 目标文件 + */ + public static void copyDir(String filePath, String targetPath) { + File file = new File(filePath); + copyDir(file, targetPath); + } + + /** + * 复制目录 + * + * @param filePath 需要处理的文件 + * @param targetPath 目标文件 + */ + public static void copyDir(File filePath, String targetPath) { + File targetFile = new File(targetPath); + if (!targetFile.exists()) { + createPaths(targetPath); + } + File[] files = filePath.listFiles(); + if (files == null) { + return; + } + for (File file : files) { + String path = file.getName(); + if (file.isDirectory()) { + copyDir(file, targetPath + File.separator + path); + } else { + copy(file, targetPath + File.separator + path); + } + } + + } + + + /** + * 罗列指定路径下的全部文件包括文件夹 + * + * @param path 需要处理的文件 + * @return 返回文件列表 + */ + public static List listFileAll(File path) { + List list = new ArrayList<>(); + File[] files = path.listFiles(); + if (files == null) { + return list; + } + for (File file : files) { + list.add(file); + if (file.isDirectory()) { + list.addAll(listFileAll(file)); + } + } + return list; + } + } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/UploadFileUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/UploadFileUtil.java new file mode 100644 index 000000000..7eeb759be --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/file/UploadFileUtil.java @@ -0,0 +1,156 @@ +package com.ruoyi.common.utils.file; + +import com.ruoyi.common.utils.DateUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Date; +import java.util.UUID; + + +/** + *
+ * 功能:文件工具类
+ * 作者:Pan.ShiJu
+ * 日期:2017/4/11 23:27
+ * + * @author Administrator + */ +public class UploadFileUtil { + + private static final String BACKSLASH_REGEX = "\\\\"; + private static final String SLASH = "/"; + private static final String SPOT = "."; + private static final String COMMA = ","; + private static final String SEMICOLON = ";"; + + private static final String BASE64_START_FLAG = "data:"; + private static final Integer BASE64_SPLIT_ARRAY_LENGTH = 2; + + /** + * base64字符串转化成图片 + */ + public static String writeImageBase64ToFile(String base64ImgData, String rootPath, String urlPrefix) { + // 截取前面的标志,逗号分割 + String[] arr = base64ImgData.split(COMMA); + if (arr.length != BASE64_SPLIT_ARRAY_LENGTH) { + return null; + } + // UUID文件名 + String uuidFileName = getFileName(); + // 文件后缀 + String fileSuffix = SPOT + getImageSuffixByBase64(arr[0]); + String fileName = uuidFileName + fileSuffix; + byte[] fileBytes = Base64Util.decode(arr[1]); + return writeSingleFileToDisk(fileBytes, fileName, rootPath, urlPrefix); + } + + + /** + * 文件写入磁盘 + * + * @param file 上传的文件 + * @return 文件访问url + */ + public static String writeSingleFileToDisk(MultipartFile file, String rootPath, String urlPrefix) { + // UUID文件名 + String uuidFileName = getFileName(); + // 文件后缀 + String fileSuffix = getFileSuffix(file.getOriginalFilename()); + String fileName = uuidFileName + fileSuffix; + byte[] fileBytes; + try { + fileBytes = file.getBytes(); + } catch (IOException e) { + return null; + } + return writeSingleFileToDisk(fileBytes, fileName, rootPath, urlPrefix); + } + + /** + * 文件后缀名 + * + * @param fileName 原始文件名 + */ + public static String getFileSuffix(String fileName) { + if (fileName == null) { + return ""; + } + return fileName.substring(fileName.lastIndexOf(SPOT)).toLowerCase(); + } + + /** + * 判断是否有图片 + */ + public static boolean checkIsBase64Image(String base64) { + return base64 != null && base64.startsWith(UploadFileUtil.BASE64_START_FLAG); + } + + /** + * 字节数组写入磁盘 + * + * @param fileBytes 文件字节 + * @param fileName 文件名 + * @param rootPath 文件存放物理全路径 + * @param urlPrefix 文件访问前缀 + * @return 文件访问url + */ + private static String writeSingleFileToDisk(byte[] fileBytes, String fileName, String rootPath, String urlPrefix) { + // 相对路径 + String relativePath = getRelativePath(rootPath); + // 文件存储路径 + String fullPath = rootPath + relativePath + fileName; + try ( + FileOutputStream fileOutputStream = new FileOutputStream(new File(fullPath)); + BufferedOutputStream out = new BufferedOutputStream(fileOutputStream); + ) { + out.write(fileBytes); + out.flush(); + } catch (IOException e) { + return null; + } + // 访问的url + String fileUrl = urlPrefix + relativePath + fileName; + // 转换url的分隔符 + return fileUrl.replaceAll(BACKSLASH_REGEX, SLASH); + } + + /** + * 获取文件名称 + */ + private static String getFileName() { + return UUID.randomUUID().toString(); + } + + /** + * 上传文件的根目录,不存在就创建 + */ + private static String getRelativePath(String rootPath) { + // 图片上传的相对路径 + String relativePath = File.separator + DateUtils.dateToString(new Date(), DateUtils.YYYY_MM_DD) + File.separator; + // 图片上传的完整路径 + String fullPath = rootPath + relativePath; + File rootPathFile = new File(fullPath); + if (!rootPathFile.exists() && !rootPathFile.isDirectory()) { + if (!rootPathFile.mkdirs()) { + return File.separator; + } + } + return relativePath; + } + + /** + * 获取文件后缀 + * + * @param base64Str base64字符串 + * @return 文件后缀 + */ + private static String getImageSuffixByBase64(String base64Str) { + return base64Str.substring(base64Str.lastIndexOf(SLASH) + 1, base64Str.lastIndexOf(SEMICOLON)); + } + + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java index 323dbc1a3..2669db156 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/http/HttpUtils.java @@ -1,10 +1,6 @@ package com.ruoyi.common.utils.http; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.PrintWriter; +import java.io.*; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.URL; @@ -16,6 +12,12 @@ import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -245,4 +247,113 @@ public class HttpUtils return true; } } + + /** + * 下载excel + * + * @param workbook + * @param response + * @param fileName + */ + public static void downLoadStream(HSSFWorkbook workbook, HttpServletResponse response, HttpServletRequest request, String fileName) { + OutputStream out = null; + try { + out = response.getOutputStream(); + response.setContentType("application/vnd.ms-excel"); + if ("IE".equals(getBrowser(request))) { + fileName = java.net.URLEncoder.encode(fileName, "UTF-8"); + response.setHeader("Content-Disposition", "attachment;filename=" + fileName+ ".xls"); + }else{ + fileName = new String(fileName.getBytes("UTF-8"), "iso-8859-1"); + response.setHeader("Content-Disposition", "attachment;filename=" + fileName+ ".xls"); + } + response.setCharacterEncoding("utf-8"); + workbook.write(out); + } catch (Exception e) { + log.error("file write error", e); + } finally { + try { + if (out != null) { + out.close(); + } + } catch (IOException e) { + log.error("file io error", e); + } + } + } + + + /** + * 判断客户端浏览器类型 + * @param request + * @return + */ + private static String getBrowser(HttpServletRequest request) { + String UserAgent = request.getHeader("User-Agent").toLowerCase(); + if (UserAgent.indexOf("firefox") >= 0){ + return "FF"; + }else if(UserAgent.indexOf("safari") >= 0 ){ + return "Chrome"; + }else{ + return "IE"; + } + } + + /** + * 判断是否是非当前服务本身请求 + * + * @param request + * @return + */ + public static boolean csrfJudge(HttpServletRequest request) { + try { + boolean isCsrf = false; + String reqUrl = request.getRequestURL().toString().toLowerCase(); + //取出ServerName + String url = request.getServerName().toLowerCase(); + //取出referer + String referer = request.getHeader("referer").toLowerCase(); + String xreq = request.getHeader("X-Requested-With"); + // 判断referer是不是为空 + if (StringUtils.isNotEmpty(referer)) { + //线上入金通知接口不做拦截判断,特殊处理 + if (reqUrl.indexOf("/notice/inMoneySuccessNotice") > 0) { + return false; + } + // referer不为空,判断referer和当前请求是否同站点 + if (!referer.startsWith(url, 8) && !referer.startsWith(url, 7)) { + // 不同站点--跨站请求 + isCsrf = true; + log.error("CSRF--跨站请求伪造。reqUri:" + reqUrl + ",referer:" + referer + + ",X-Requested-With:" + xreq + ",url:" + url); + } + } + return isCsrf; + } catch (Exception e) { + return false; + } + } + + + + /** + * 清空cookie + * + * @param request + * @return + */ + public static void clearCookie(HttpServletRequest request) { + try { + javax.servlet.http.Cookie[] cookies = request.getCookies(); + if (cookies != null && cookies.length > 0) { + Cookie cookie = cookies[0]; + cookie.setMaxAge(0); + } + } catch (Exception e) { + log.error("清空cookie出现异常:{}",e); + } + } + + public static void main(String[] args) throws Exception { + } } \ No newline at end of file diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/idgenerator/UUIDUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/idgenerator/UUIDUtils.java new file mode 100644 index 000000000..577e37eee --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/idgenerator/UUIDUtils.java @@ -0,0 +1,110 @@ +package com.ruoyi.common.utils.idgenerator; + + + + +import java.text.*; +import java.util.Calendar; +import java.util.Random; +import java.util.UUID; + +/** + * uuid生成工具类,主要用一些数据表主键生成 + * + * @author solo + * @date 2019/08/16. + */ +public class UUIDUtils { + + private static final FieldPosition HELPER_POSITION = new FieldPosition(0); + + /** This Format for format the data to special format. */ + private final static Format dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + + /** This Format for format the number to special format. */ + private final static NumberFormat numberFormat = new DecimalFormat("000000"); + /** + * 序列 + */ + private static int seq = 0; + + /** + * 最大值 + */ + private static final int MAX = 999999; + + public static void main(String[] args) throws InterruptedException { + System.out.println(getStringRandom(8)); + } + /** + * 获取一个长度为32的uuid + * + * @return + */ + public static synchronized String getUUID32() { + return UUID.randomUUID().toString().replace("-", ""); + } + + + /** + * 获取一个uuid + * + * @return + */ + public static synchronized String getToken() { + return UUID.randomUUID().toString(); + } + + + /** + * 生成序列编号 + * @return + */ + public static synchronized String getSequenceNo() { + Calendar rightNow = Calendar.getInstance(); + StringBuffer sb = new StringBuffer(); + dateFormat.format(rightNow.getTime(), sb, HELPER_POSITION); + numberFormat.format(seq, sb, HELPER_POSITION); + if (seq == MAX) { + seq = 0; + } else { + seq++; + } + return sb.toString(); + } + + + + /** + * 获取一个长度为16的uuid + * + * @return + */ + public static synchronized String getUUID16() { + int machineId = 1; + int hashCodeV = UUID.randomUUID().toString().hashCode(); + if (hashCodeV < 0) { + hashCodeV = -hashCodeV; + } + return machineId + String.format("%015d", hashCodeV); + } + + //生成随机用户名,数字和字母组成, + public static String getStringRandom(int length) { + String val = ""; + Random random = new Random(); + //参数length,表示生成几位随机数 + for(int i = 0; i < length; i++) { + String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num"; + //输出字母还是数字 + if( "char".equalsIgnoreCase(charOrNum) ) { + //输出是大写字母还是小写字母 + int temp = random.nextInt(2) % 2 == 0 ? 65 : 97; + val += (char)(random.nextInt(26) + temp); + } else if( "num".equalsIgnoreCase(charOrNum) ) { + val += String.valueOf(random.nextInt(10)); + } + } + return val.toLowerCase(); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/jsonutils/JsonUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/jsonutils/JsonUtils.java new file mode 100644 index 000000000..a47c11f7b --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/jsonutils/JsonUtils.java @@ -0,0 +1,64 @@ +package com.ruoyi.common.utils.jsonutils; + +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +/** + * 金操作工具类 + * + * @author solo + * @date 2019/08/16. + **/ +public class JsonUtils { + + + /** + * 判断是不是ajax请求 + * + * @param request + * @return + */ + public static boolean isAjax(HttpServletRequest request) { + return (request.getHeader("X-Requested-With") != null + && "XMLHttpRequest".equals(request.getHeader("X-Requested-With").toString())); + } + + /** + * 判断一个字符串是不是json格式 + * + * @param jsonString + * @return + */ + public static JSONObject isGoodJson(String jsonString) { + try { + if (StringUtils.isEmpty(jsonString)) { + return null; + } + return (JSONObject) JSONObject.parse(jsonString); + } catch (Exception e) { + return null; + } + } + + + /** + * 判断一个字符串是不是json格式 + * + * @param jsonString + * @return + */ + public static boolean isJson(String jsonString) { + try { + if (StringUtils.isEmpty(jsonString)) { + return false; + } + JSONObject.parse(jsonString); + return true; + } catch (Exception e) { + return false; + } + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/random/RandomUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/random/RandomUtil.java new file mode 100644 index 000000000..44d46b384 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/random/RandomUtil.java @@ -0,0 +1,20 @@ +package com.ruoyi.common.utils.random; + +/** + * 生成随机数 + * + * @author solo + * @date 2019/08/16. + */ +public class RandomUtil { + /** + * 随机生成6位数的验证码 + * @param min + * @param max + * @return + */ + public static String getRandNum(int min, int max) { + int randNum = min + (int)(Math.random() * ((max - min) + 1)); + return String.valueOf(randNum); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/random/ShareCodeUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/random/ShareCodeUtil.java new file mode 100644 index 000000000..31592841a --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/random/ShareCodeUtil.java @@ -0,0 +1,109 @@ +package com.ruoyi.common.utils.random; + +import java.util.Random; +import java.util.UUID; + +/** + * 邀请码生成器,算法原理:
+ * 1) 获取id: 1127738
+ * 2) 使用自定义进制转为:gpm6
+ * 3) 转为字符串,并在后面加'o'字符:gpm6o
+ * 4)在后面随机产生若干个随机数字字符:gpm6o7
+ * 转为自定义进制后就不会出现o这个字符,然后在后面加个'o',这样就能确定唯一性。最后在后面产生一些随机字符进行补全。
+ * + * @author jiayu.qiu + */ +public class ShareCodeUtil { + + /** + * 自定义进制 + */ + private static final char[] DIGITS = new char[]{'q', 'w', 'e', '8', 'a', 's', '2', 'd', 'z', 'x', '9', 'c', '7', 'p', '5', 'i', 'k', '3', 'm', 'j', 'u', 'f', 'r', '4', 'v', 'y', 'l', 't', 'n', '6', 'b', 'g', 'h'}; + + /** + * 进制长度 + */ + private static final int DIGITS_LENGTH = DIGITS.length; + + /** + * 序列最小长度 + */ + private static final int MIN_LENGTH = 6; + + + public static String toSerialCode(String uuid) { + if (uuid == null) { + uuid = UUID.randomUUID().toString().replaceAll("-", ""); + } + StringBuilder sb = new StringBuilder(); + for (byte b : uuid.getBytes()) { + sb.append(b); + } + + Random random = new Random(); + int mod = random.nextInt(19); + mod = mod < 8 ? 8 : mod; + + Long sum = 0L; + int l = sb.length() / mod; + for (int i = 0; i < l; i++) { + int start = i * mod; + int end = (i + 1) * mod; + sum += Long.parseLong(sb.substring(start, end)); + } + return toSerialCode(sum); + } + + /** + * 根据ID生成六位随机码 + * + * @param id ID + * @return 随机码 + */ + public static String toSerialCode(long id) { + char[] buf = new char[32]; + int charPos = 32; + + while ((id / DIGITS_LENGTH) > 0) { + int ind = (int) (id % DIGITS_LENGTH); + buf[--charPos] = DIGITS[ind]; + id /= DIGITS_LENGTH; + } + buf[--charPos] = DIGITS[(int) (id % DIGITS_LENGTH)]; + String str = new String(buf, charPos, (32 - charPos)); + // 不够长度的自动随机补全 + if (str.length() < MIN_LENGTH) { + StringBuilder sb = new StringBuilder(); + sb.append('o'); + Random rnd = new Random(); + for (int i = 1; i < MIN_LENGTH - str.length(); i++) { + sb.append(DIGITS[rnd.nextInt(DIGITS_LENGTH)]); + } + str += sb.toString(); + } + return str.substring(0, MIN_LENGTH).toUpperCase(); + } + + + /** + * 生成指定长度的随机数,全数字 + * @param codeLen + * @return + */ + public static String getNewRandomCode(int codeLen) { + StringBuffer sb = new StringBuffer(); + String str = "0123456789"; + Random r = new Random(); + for(int i=0;i0){ + return true; + } + return false; + } + return false; + } + + /** + * 是否有特殊字符 + * @param str + * @return + */ + public static boolean isSpecialString(String str){ + if(StringUtils.isEmpty(str)){ + return true; + } + String reg = "^[\\u4E00-\\u9FA5a-zA-Z0-9]*$"; + Pattern r = Pattern.compile(reg); + Matcher m = r.matcher(str); + return !m.matches(); + } + + + /** + * 是否有特殊字符 + * @param str + * @return + */ + public static boolean isSpecialString1(String str){ + String reg = "^[\\u4E00-\\u9FA5a-zA-Z0-9_【】]*$"; + Pattern r = Pattern.compile(reg); + Matcher m = r.matcher(str); + return m.matches(); + } + + + /** + * 是否有特殊字符 + * @param str + * @return + */ + public static boolean isSpecialAccount(String str){ + if(StringUtils.isEmpty(str)){ + return true; + } + String reg = "^[\\u4E00-\\u9FA5a-zA-Z0-9@._-]*$"; + Pattern r = Pattern.compile(reg); + Matcher m = r.matcher(str); + return !m.matches(); + } + + + /** + * 只能输入英文数字组合 长度在5-20之间 + * @param str + * @return + */ + public static boolean isEN(String str){ + if(StringUtils.isEmpty(str)){ + return false; + } + String reg = "^(?!([a-zA-Z]+|\\d+)$)[a-zA-Z\\d]{5,20}$"; + Pattern r = Pattern.compile(reg); + Matcher m = r.matcher(str); + return m.matches(); + } + + /** + * 只能输入英文和数字 长度在2-32之间 + * @param str + * @return + */ + public static boolean isEnNumber(String str){ + if(StringUtils.isEmpty(str)){ + return false; + } + String reg = "^[a-zA-Z0-9]{2,32}$"; + Pattern r = Pattern.compile(reg); + Matcher m = r.matcher(str); + return m.matches(); + } + + /** + * 只能输入英文和数字 长度在6-32之间 主要针对提现密码 + * @param str + * @return + */ + public static boolean isEnNumberForPassword(String str){ + if(StringUtils.isEmpty(str)){ + return false; + } + String reg = "^[a-zA-Z0-9]{6,32}$"; + Pattern r = Pattern.compile(reg); + Matcher m = r.matcher(str); + return m.matches(); + } + + /** + * 微信号格式数字字母下划线减号@和. + * @param str + * @return + */ + public static boolean checkWeChatNOIsOk(String str){ + if(StringUtils.isBlank(str)){ + return false; + } + String reg = "^[a-zA-Z0-9_\\-@.]{5,20}$"; + Pattern r = Pattern.compile(reg); + Matcher m = r.matcher(str); + return m.matches(); + } + + + + public static void main(String[] args) { + System.out.print(isEnNumberForPassword("23456")); + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/security/Md5Utils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/security/Md5Utils.java index 40e80304a..22764be2d 100644 --- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/security/Md5Utils.java +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/security/Md5Utils.java @@ -1,13 +1,19 @@ package com.ruoyi.common.utils.security; +import java.math.BigDecimal; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +import org.apache.commons.lang3.StringUtils; +import org.apache.shiro.crypto.SecureRandomNumberGenerator; +import org.apache.shiro.crypto.hash.SimpleHash; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Md5加密方法 * - * @author ruoyi + * @author solo */ public class Md5Utils { @@ -63,4 +69,77 @@ public class Md5Utils return s; } } + + public static final int HASH_ITERATIONS = 3; + + /** + * 加密解密算法 执行一次加密,两次解密 + */ + public final static String convertMD5(String inStr) { + char[] a = inStr.toCharArray(); + for (int i = 0; i < a.length; i++) { + a[i] = (char) (a[i] ^ '1'); + } + String s = new String(a); + return s; + } + + /** + * MD532加密 + * + * @param readyEncryptStr + * @param saltKey + * @return + */ + public static String MD532(String readyEncryptStr, String saltKey) { + if (StringUtils.isNotEmpty(readyEncryptStr) && saltKey != null) { + readyEncryptStr = readyEncryptStr + saltKey; + //Get MD5 digest algorithm's MessageDigest's instance. + MessageDigest md = null; + try { + md = MessageDigest.getInstance("MD5"); + //Use specified byte update digest. + md.update(readyEncryptStr.getBytes()); + //Get cipher text + byte[] b = md.digest(); + //The cipher text converted to hexadecimal string + StringBuilder su = new StringBuilder(); + //byte array switch hexadecimal number. + for (byte aB : b) { + String haxHex = Integer.toHexString(aB & 0xFF); + if (haxHex.length() < 2) { + su.append("0"); + } + su.append(haxHex); + } + return su.toString(); + } catch (NoSuchAlgorithmException e) { + return ""; + } + } else { + return ""; + } + } + + + /** + * shiro MD5 加密 + * @param password + * @param userToken + * @return + */ + public static String ShiroMD5(String password, String userToken) { + SimpleHash hash = new SimpleHash("md5", password, + userToken, HASH_ITERATIONS); + return hash.toHex(); + } + + public static String createToken(){ + SecureRandomNumberGenerator secureRandomNumberGenerator = new SecureRandomNumberGenerator(); + return secureRandomNumberGenerator.nextBytes().toHex(); + } + + public static void main(String[] args) { + log.debug(new BigDecimal(832232).setScale(2, BigDecimal.ROUND_HALF_UP)+""); + } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/stringutils/StrUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/stringutils/StrUtils.java new file mode 100644 index 000000000..d7a65d6a7 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/stringutils/StrUtils.java @@ -0,0 +1,144 @@ +package com.ruoyi.common.utils.stringutils; + +import org.apache.commons.lang3.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 字符串操作工具类 + */ +public class StrUtils { + private static final String regEx_script = "]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式 + private static final String regEx_style = "]*?>[\\s\\S]*?<\\/style>"; // 定义style的正则表达式 + private static final String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式 + private static final String regEx_space = "\\s*|\t|\r|\n";//定义空格回车换行符 + + + + public static void main(String[] args) throws Exception { + String strhours = "23232323"; + System.out.println(hideStr(strhours, 2,3)); + } + + + /** + * @param htmlStr + * @return + * 删除script标签 + */ + public static String delScriptTag(String htmlStr) { + if(StringUtils.isEmpty(htmlStr)){ + return ""; + } + String regEx_script0 = "]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式 + String regEx_script1 = "]*?>[\\s\\S]*?"; // 定义script的正则表达式 + String regEx_script2 = "<[^>]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式 + Pattern p_script0 = Pattern.compile(regEx_script0, Pattern.CASE_INSENSITIVE); + Matcher m_script0 = p_script0.matcher(htmlStr); + htmlStr = m_script0.replaceAll(""); // 过滤script标签 + + Pattern p_script1 = Pattern.compile(regEx_script1, Pattern.CASE_INSENSITIVE); + Matcher m_script1 = p_script1.matcher(htmlStr); + htmlStr = m_script1.replaceAll(""); // 过滤script标签 + + Pattern p_script2 = Pattern.compile(regEx_script2, Pattern.CASE_INSENSITIVE); + Matcher m_script2 = p_script2.matcher(htmlStr); + htmlStr = m_script2.replaceAll(""); // 过滤script标签 + return htmlStr.trim(); // 返回文本字符串 + } + + /** + * @param htmlStr + * @return + * 删除Html标签 + */ + public static String delHTMLTag(String htmlStr) { + if(StringUtils.isEmpty(htmlStr)){ + return ""; + } + Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE); + Matcher m_script = p_script.matcher(htmlStr); + htmlStr = m_script.replaceAll(""); // 过滤script标签 + + Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE); + Matcher m_style = p_style.matcher(htmlStr); + htmlStr = m_style.replaceAll(""); // 过滤style标签 + + Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE); + Matcher m_html = p_html.matcher(htmlStr); + htmlStr = m_html.replaceAll(""); // 过滤html标签 + + Pattern p_space = Pattern.compile(regEx_space, Pattern.CASE_INSENSITIVE); + Matcher m_space = p_space.matcher(htmlStr); + htmlStr = m_space.replaceAll(""); // 过滤空格回车标签 + return htmlStr.trim(); // 返回文本字符串 + } + + /** + * 从字符串末尾截取字符串 + * + * @param str + * @param length + * @return + */ + public static String subStringByEnd(String str, Integer length) { + if (StringUtils.isEmpty(str)) { + return ""; + } + if (str.length() < length) { + return str; + } + return str.substring(str.length() - length, str.length()); + + } + + /** + * 448 * 替换字符串 + * 449 * @param args + * 450 * @throws IOException + * 451 + */ + public static String strReplaceAll(String name,String str1,String str2) { + if (name != null && !"".equals(name)) { + if(StringUtils.isBlank(str2)){ + str2 = ""; + } + return name.replaceAll(str1, str2); + } else { + return name; + } + } + + + /** + * 安全性隐藏,字符串指定位置中间的字符通过*代替 + * @param str + * @param front + * @param end + * @return + */ + public static String hideStr(String str, int front, int end) { + //字符串不能为空 + if (StringUtils.isEmpty(str)) { + return ""; + } + //需要截取的长度不能大于身份证号长度 + if ((front + end) > str.length()) { + return str; + } + //需要截取的不能小于0 + if (front < 0 || end < 0) { + return str; + } + //计算*的数量 + int asteriskCount = str.length() - (front + end); + StringBuilder asteriskStr = new StringBuilder(); + for (int i = 0; i < asteriskCount; i++) { + asteriskStr.append("*"); + } + String regex = "(\\w{" + String.valueOf(front) + "})(\\w+)(\\w{" + String.valueOf(end) + "})"; + return str.replaceAll(regex, "$1" + asteriskStr + "$3"); + } + +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/tree/Ztree.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/tree/Ztree.java new file mode 100644 index 000000000..b5957d432 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/tree/Ztree.java @@ -0,0 +1,216 @@ +package com.ruoyi.common.utils.tree; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * tree结构 + * + * @author solo + * @date 2019/08/16. + */ +public class Ztree { + private String id; + private String text; + private String state; + private boolean isParent; + private boolean checked;; + private int locked; + private List children; + private String iconCls; + private String pid; + private Map attributes = new HashMap(); + private String comment; + private String link; + private String url; + private String target; + private Integer types; + private String code; + private String path; + private Date createtime; + private Date updatetime; + private String object_class; + private String title; + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + @JsonProperty(value = "isParent") + public boolean getIsParent() { + return isParent; + } + + public void setIsParent(boolean isParent) { + this.isParent = isParent; + } + + public boolean isChecked() { + return checked; + } + + public void setChecked(boolean checked) { + this.checked = checked; + } + + public int getLocked() { + return locked; + } + + public void setLocked(int locked) { + this.locked = locked; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public String getIconCls() { + return iconCls; + } + + public void setIconCls(String iconCls) { + this.iconCls = iconCls; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + public Map getAttributes() { + return attributes; + } + + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getLink() { + return link; + } + + public void setLink(String link) { + this.link = link; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public Integer getTypes() { + return types; + } + + public void setTypes(Integer types) { + this.types = types; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public Date getCreatetime() { + return createtime; + } + + public void setCreatetime(Date createtime) { + this.createtime = createtime; + } + + public Date getUpdatetime() { + return updatetime; + } + + public void setUpdatetime(Date updatetime) { + this.updatetime = updatetime; + } + + public String getObject_class() { + return object_class; + } + + public void setObject_class(String object_class) { + this.object_class = object_class; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/tree/ZtreeUtil.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/tree/ZtreeUtil.java new file mode 100644 index 000000000..064fa7207 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/tree/ZtreeUtil.java @@ -0,0 +1,60 @@ +package com.ruoyi.common.utils.tree; + + +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * tree结构工具类 + * + * @author solo + * @date 2019/08/16. + */ +public class ZtreeUtil { + + public static List ztreeList(List list,String pid) { + List returnList = new ArrayList(); + for (Ztree t : list) { + if (StringUtils.equals(t.getPid(), pid)) { + recursionFn(list, t); + returnList.add(t); + } + } + return returnList; + } + + private static void recursionFn(List list, Ztree t) { + List childList = getChildList(list, t);// 得到子节点列表 + t.setChildren(childList); + t.setState("open"); + t.setIsParent(false); + for (Ztree tChild : childList) { + t.setState("closed"); + t.setIsParent(true); + if (hasChild(list, tChild)) {// 判断是否有子节点 + for (Ztree n : childList) { + recursionFn(list, n); + } + } + } + } + + + // 得到子节点列表 + private static List getChildList(List list, Ztree t) { + List tlist = new ArrayList(); + for (Ztree n : list) { + if (StringUtils.equals(n.getPid(), t.getId())) { + tlist.add(n); + } + } + return tlist; + } + + // 判断是否有子节点 + private static boolean hasChild(List list, Ztree t) { + return getChildList(list, t).size() > 0; + } +}