+{
+ private static final long serialVersionUID = -1185015143654744140L;
+
+ /**
+ * SecureRandom 鐨勫崟渚
+ *
+ */
+ private static class Holder
+ {
+ static final SecureRandom numberGenerator = getSecureRandom();
+ }
+
+ /** 姝UID鐨勬渶楂64鏈夋晥浣 */
+ private final long mostSigBits;
+
+ /** 姝UID鐨勬渶浣64鏈夋晥浣 */
+ private final long leastSigBits;
+
+ /**
+ * 绉佹湁鏋勯
+ *
+ * @param data 鏁版嵁
+ */
+ private UUID(byte[] data)
+ {
+ long msb = 0;
+ long lsb = 0;
+ assert data.length == 16 : "data must be 16 bytes in length";
+ for (int i = 0; i < 8; i++)
+ {
+ msb = (msb << 8) | (data[i] & 0xff);
+ }
+ for (int i = 8; i < 16; i++)
+ {
+ lsb = (lsb << 8) | (data[i] & 0xff);
+ }
+ this.mostSigBits = msb;
+ this.leastSigBits = lsb;
+ }
+
+ /**
+ * 浣跨敤鎸囧畾鐨勬暟鎹瀯閫犳柊鐨 UUID銆
+ *
+ * @param mostSigBits 鐢ㄤ簬 {@code UUID} 鐨勬渶楂樻湁鏁 64 浣
+ * @param leastSigBits 鐢ㄤ簬 {@code UUID} 鐨勬渶浣庢湁鏁 64 浣
+ */
+ public UUID(long mostSigBits, long leastSigBits)
+ {
+ this.mostSigBits = mostSigBits;
+ this.leastSigBits = leastSigBits;
+ }
+
+ /**
+ * 鑾峰彇绫诲瀷 4锛堜吉闅忔満鐢熸垚鐨勶級UUID 鐨勯潤鎬佸伐鍘傘 浣跨敤鍔犲瘑鐨勬湰鍦扮嚎绋嬩吉闅忔満鏁扮敓鎴愬櫒鐢熸垚璇 UUID銆
+ *
+ * @return 闅忔満鐢熸垚鐨 {@code UUID}
+ */
+ public static UUID fastUUID()
+ {
+ return randomUUID(false);
+ }
+
+ /**
+ * 鑾峰彇绫诲瀷 4锛堜吉闅忔満鐢熸垚鐨勶級UUID 鐨勯潤鎬佸伐鍘傘 浣跨敤鍔犲瘑鐨勫己浼殢鏈烘暟鐢熸垚鍣ㄧ敓鎴愯 UUID銆
+ *
+ * @return 闅忔満鐢熸垚鐨 {@code UUID}
+ */
+ public static UUID randomUUID()
+ {
+ return randomUUID(true);
+ }
+
+ /**
+ * 鑾峰彇绫诲瀷 4锛堜吉闅忔満鐢熸垚鐨勶級UUID 鐨勯潤鎬佸伐鍘傘 浣跨敤鍔犲瘑鐨勫己浼殢鏈烘暟鐢熸垚鍣ㄧ敓鎴愯 UUID銆
+ *
+ * @param isSecure 鏄惁浣跨敤{@link SecureRandom}濡傛灉鏄彲浠ヨ幏寰楁洿瀹夊叏鐨勯殢鏈虹爜锛屽惁鍒欏彲浠ュ緱鍒版洿濂界殑鎬ц兘
+ * @return 闅忔満鐢熸垚鐨 {@code UUID}
+ */
+ public static UUID randomUUID(boolean isSecure)
+ {
+ final Random ng = isSecure ? Holder.numberGenerator : getRandom();
+
+ byte[] randomBytes = new byte[16];
+ ng.nextBytes(randomBytes);
+ randomBytes[6] &= 0x0f; /* clear version */
+ randomBytes[6] |= 0x40; /* set to version 4 */
+ randomBytes[8] &= 0x3f; /* clear variant */
+ randomBytes[8] |= 0x80; /* set to IETF variant */
+ return new UUID(randomBytes);
+ }
+
+ /**
+ * 鏍规嵁鎸囧畾鐨勫瓧鑺傛暟缁勮幏鍙栫被鍨 3锛堝熀浜庡悕绉扮殑锛塙UID 鐨勯潤鎬佸伐鍘傘
+ *
+ * @param name 鐢ㄤ簬鏋勯 UUID 鐨勫瓧鑺傛暟缁勩
+ *
+ * @return 鏍规嵁鎸囧畾鏁扮粍鐢熸垚鐨 {@code UUID}
+ */
+ public static UUID nameUUIDFromBytes(byte[] name)
+ {
+ MessageDigest md;
+ try
+ {
+ md = MessageDigest.getInstance("MD5");
+ }
+ catch (NoSuchAlgorithmException nsae)
+ {
+ throw new InternalError("MD5 not supported");
+ }
+ byte[] md5Bytes = md.digest(name);
+ md5Bytes[6] &= 0x0f; /* clear version */
+ md5Bytes[6] |= 0x30; /* set to version 3 */
+ md5Bytes[8] &= 0x3f; /* clear variant */
+ md5Bytes[8] |= 0x80; /* set to IETF variant */
+ return new UUID(md5Bytes);
+ }
+
+ /**
+ * 鏍规嵁 {@link #toString()} 鏂规硶涓弿杩扮殑瀛楃涓叉爣鍑嗚〃绀哄舰寮忓垱寤簕@code UUID}銆
+ *
+ * @param name 鎸囧畾 {@code UUID} 瀛楃涓
+ * @return 鍏锋湁鎸囧畾鍊肩殑 {@code UUID}
+ * @throws IllegalArgumentException 濡傛灉 name 涓 {@link #toString} 涓弿杩扮殑瀛楃涓茶〃绀哄舰寮忎笉绗︽姏鍑烘寮傚父
+ *
+ */
+ public static UUID fromString(String name)
+ {
+ String[] components = name.split("-");
+ if (components.length != 5)
+ {
+ throw new IllegalArgumentException("Invalid UUID string: " + name);
+ }
+ for (int i = 0; i < 5; i++)
+ {
+ components[i] = "0x" + components[i];
+ }
+
+ long mostSigBits = Long.decode(components[0]).longValue();
+ mostSigBits <<= 16;
+ mostSigBits |= Long.decode(components[1]).longValue();
+ mostSigBits <<= 16;
+ mostSigBits |= Long.decode(components[2]).longValue();
+
+ long leastSigBits = Long.decode(components[3]).longValue();
+ leastSigBits <<= 48;
+ leastSigBits |= Long.decode(components[4]).longValue();
+
+ return new UUID(mostSigBits, leastSigBits);
+ }
+
+ /**
+ * 杩斿洖姝 UUID 鐨 128 浣嶅间腑鐨勬渶浣庢湁鏁 64 浣嶃
+ *
+ * @return 姝 UUID 鐨 128 浣嶅间腑鐨勬渶浣庢湁鏁 64 浣嶃
+ */
+ public long getLeastSignificantBits()
+ {
+ return leastSigBits;
+ }
+
+ /**
+ * 杩斿洖姝 UUID 鐨 128 浣嶅间腑鐨勬渶楂樻湁鏁 64 浣嶃
+ *
+ * @return 姝 UUID 鐨 128 浣嶅间腑鏈楂樻湁鏁 64 浣嶃
+ */
+ public long getMostSignificantBits()
+ {
+ return mostSigBits;
+ }
+
+ /**
+ * 涓庢 {@code UUID} 鐩稿叧鑱旂殑鐗堟湰鍙. 鐗堟湰鍙锋弿杩版 {@code UUID} 鏄浣曠敓鎴愮殑銆
+ *
+ * 鐗堟湰鍙峰叿鏈変互涓嬪惈鎰:
+ *
+ * - 1 鍩轰簬鏃堕棿鐨 UUID
+ *
- 2 DCE 瀹夊叏 UUID
+ *
- 3 鍩轰簬鍚嶇О鐨 UUID
+ *
- 4 闅忔満鐢熸垚鐨 UUID
+ *
+ *
+ * @return 姝 {@code UUID} 鐨勭増鏈彿
+ */
+ public int version()
+ {
+ // Version is bits masked by 0x000000000000F000 in MS long
+ return (int) ((mostSigBits >> 12) & 0x0f);
+ }
+
+ /**
+ * 涓庢 {@code UUID} 鐩稿叧鑱旂殑鍙樹綋鍙枫傚彉浣撳彿鎻忚堪 {@code UUID} 鐨勫竷灞銆
+ *
+ * 鍙樹綋鍙峰叿鏈変互涓嬪惈鎰忥細
+ *
+ * - 0 涓 NCS 鍚戝悗鍏煎淇濈暀
+ *
- 2 IETF RFC 4122(Leach-Salz), 鐢ㄤ簬姝ょ被
+ *
- 6 淇濈暀锛屽井杞悜鍚庡吋瀹
+ *
- 7 淇濈暀渚涗互鍚庡畾涔変娇鐢
+ *
+ *
+ * @return 姝 {@code UUID} 鐩稿叧鑱旂殑鍙樹綋鍙
+ */
+ public int variant()
+ {
+ // This field is composed of a varying number of bits.
+ // 0 - - Reserved for NCS backward compatibility
+ // 1 0 - The IETF aka Leach-Salz variant (used by this class)
+ // 1 1 0 Reserved, Microsoft backward compatibility
+ // 1 1 1 Reserved for future definition.
+ return (int) ((leastSigBits >>> (64 - (leastSigBits >>> 62))) & (leastSigBits >> 63));
+ }
+
+ /**
+ * 涓庢 UUID 鐩稿叧鑱旂殑鏃堕棿鎴冲笺
+ *
+ *
+ * 60 浣嶇殑鏃堕棿鎴冲兼牴鎹 {@code UUID} 鐨 time_low銆乼ime_mid 鍜 time_hi 瀛楁鏋勯犮
+ * 鎵寰楀埌鐨勬椂闂存埑浠 100 姣井绉掍负鍗曚綅锛屼粠 UTC锛堥氱敤鍗忚皟鏃堕棿锛 1582 骞 10 鏈 15 鏃ラ浂鏃跺紑濮嬨
+ *
+ *
+ * 鏃堕棿鎴冲间粎鍦ㄥ湪鍩轰簬鏃堕棿鐨 UUID锛堝叾 version 绫诲瀷涓 1锛変腑鎵嶆湁鎰忎箟銆
+ * 濡傛灉姝 {@code UUID} 涓嶆槸鍩轰簬鏃堕棿鐨 UUID锛屽垯姝ゆ柟娉曟姏鍑 UnsupportedOperationException銆
+ *
+ * @throws UnsupportedOperationException 濡傛灉姝 {@code UUID} 涓嶆槸 version 涓 1 鐨 UUID銆
+ */
+ public long timestamp() throws UnsupportedOperationException
+ {
+ checkTimeBase();
+ return (mostSigBits & 0x0FFFL) << 48//
+ | ((mostSigBits >> 16) & 0x0FFFFL) << 32//
+ | mostSigBits >>> 32;
+ }
+
+ /**
+ * 涓庢 UUID 鐩稿叧鑱旂殑鏃堕挓搴忓垪鍊笺
+ *
+ *
+ * 14 浣嶇殑鏃堕挓搴忓垪鍊兼牴鎹 UUID 鐨 clock_seq 瀛楁鏋勯犮俢lock_seq 瀛楁鐢ㄤ簬淇濊瘉鍦ㄥ熀浜庢椂闂寸殑 UUID 涓殑鏃堕棿鍞竴鎬с
+ *
+ * {@code clockSequence} 鍊间粎鍦ㄥ熀浜庢椂闂寸殑 UUID锛堝叾 version 绫诲瀷涓 1锛変腑鎵嶆湁鎰忎箟銆 濡傛灉姝 UUID 涓嶆槸鍩轰簬鏃堕棿鐨 UUID锛屽垯姝ゆ柟娉曟姏鍑
+ * UnsupportedOperationException銆
+ *
+ * @return 姝 {@code UUID} 鐨勬椂閽熷簭鍒
+ *
+ * @throws UnsupportedOperationException 濡傛灉姝 UUID 鐨 version 涓嶄负 1
+ */
+ public int clockSequence() throws UnsupportedOperationException
+ {
+ checkTimeBase();
+ return (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48);
+ }
+
+ /**
+ * 涓庢 UUID 鐩稿叧鐨勮妭鐐瑰笺
+ *
+ *
+ * 48 浣嶇殑鑺傜偣鍊兼牴鎹 UUID 鐨 node 瀛楁鏋勯犮傛瀛楁鏃ㄥ湪鐢ㄤ簬淇濆瓨鏈哄櫒鐨 IEEE 802 鍦板潃锛岃鍦板潃鐢ㄤ簬鐢熸垚姝 UUID 浠ヤ繚璇佺┖闂村敮涓鎬с
+ *
+ * 鑺傜偣鍊间粎鍦ㄥ熀浜庢椂闂寸殑 UUID锛堝叾 version 绫诲瀷涓 1锛変腑鎵嶆湁鎰忎箟銆
+ * 濡傛灉姝 UUID 涓嶆槸鍩轰簬鏃堕棿鐨 UUID锛屽垯姝ゆ柟娉曟姏鍑 UnsupportedOperationException銆
+ *
+ * @return 姝 {@code UUID} 鐨勮妭鐐瑰
+ *
+ * @throws UnsupportedOperationException 濡傛灉姝 UUID 鐨 version 涓嶄负 1
+ */
+ public long node() throws UnsupportedOperationException
+ {
+ checkTimeBase();
+ return leastSigBits & 0x0000FFFFFFFFFFFFL;
+ }
+
+ /**
+ * 杩斿洖姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡銆
+ *
+ *
+ * UUID 鐨勫瓧绗︿覆琛ㄧず褰㈠紡鐢辨 BNF 鎻忚堪锛
+ *
+ *
+ * {@code
+ * UUID = ----
+ * time_low = 4*
+ * time_mid = 2*
+ * time_high_and_version = 2*
+ * variant_and_sequence = 2*
+ * node = 6*
+ * hexOctet =
+ * hexDigit = [0-9a-fA-F]
+ * }
+ *
+ *
+ *
+ *
+ * @return 姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡
+ * @see #toString(boolean)
+ */
+ @Override
+ public String toString()
+ {
+ return toString(false);
+ }
+
+ /**
+ * 杩斿洖姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡銆
+ *
+ *
+ * UUID 鐨勫瓧绗︿覆琛ㄧず褰㈠紡鐢辨 BNF 鎻忚堪锛
+ *
+ *
+ * {@code
+ * UUID = ----
+ * time_low = 4*
+ * time_mid = 2*
+ * time_high_and_version = 2*
+ * variant_and_sequence = 2*
+ * node = 6*
+ * hexOctet =
+ * hexDigit = [0-9a-fA-F]
+ * }
+ *
+ *
+ *
+ *
+ * @param isSimple 鏄惁绠鍗曟ā寮忥紝绠鍗曟ā寮忎负涓嶅甫'-'鐨刄UID瀛楃涓
+ * @return 姝@code UUID} 鐨勫瓧绗︿覆琛ㄧ幇褰㈠紡
+ */
+ public String toString(boolean isSimple)
+ {
+ final StringBuilder builder = new StringBuilder(isSimple ? 32 : 36);
+ // time_low
+ builder.append(digits(mostSigBits >> 32, 8));
+ if (false == isSimple)
+ {
+ builder.append('-');
+ }
+ // time_mid
+ builder.append(digits(mostSigBits >> 16, 4));
+ if (false == isSimple)
+ {
+ builder.append('-');
+ }
+ // time_high_and_version
+ builder.append(digits(mostSigBits, 4));
+ if (false == isSimple)
+ {
+ builder.append('-');
+ }
+ // variant_and_sequence
+ builder.append(digits(leastSigBits >> 48, 4));
+ if (false == isSimple)
+ {
+ builder.append('-');
+ }
+ // node
+ builder.append(digits(leastSigBits, 12));
+
+ return builder.toString();
+ }
+
+ /**
+ * 杩斿洖姝 UUID 鐨勫搱甯岀爜銆
+ *
+ * @return UUID 鐨勫搱甯岀爜鍊笺
+ */
+ @Override
+ public int hashCode()
+ {
+ long hilo = mostSigBits ^ leastSigBits;
+ return ((int) (hilo >> 32)) ^ (int) hilo;
+ }
+
+ /**
+ * 灏嗘瀵硅薄涓庢寚瀹氬璞℃瘮杈冦
+ *
+ * 褰撲笖浠呭綋鍙傛暟涓嶄负 {@code null}銆佽屾槸涓涓 UUID 瀵硅薄銆佸叿鏈変笌姝 UUID 鐩稿悓鐨 varriant銆佸寘鍚浉鍚岀殑鍊硷紙姣忎竴浣嶅潎鐩稿悓锛夋椂锛岀粨鏋滄墠涓 {@code true}銆
+ *
+ * @param obj 瑕佷笌涔嬫瘮杈冪殑瀵硅薄
+ *
+ * @return 濡傛灉瀵硅薄鐩稿悓锛屽垯杩斿洖 {@code true}锛涘惁鍒欒繑鍥 {@code false}
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if ((null == obj) || (obj.getClass() != UUID.class))
+ {
+ return false;
+ }
+ UUID id = (UUID) obj;
+ return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits);
+ }
+
+ // Comparison Operations
+
+ /**
+ * 灏嗘 UUID 涓庢寚瀹氱殑 UUID 姣旇緝銆
+ *
+ *
+ * 濡傛灉涓や釜 UUID 涓嶅悓锛屼笖绗竴涓 UUID 鐨勬渶楂樻湁鏁堝瓧娈靛ぇ浜庣浜屼釜 UUID 鐨勫搴斿瓧娈碉紝鍒欑涓涓 UUID 澶т簬绗簩涓 UUID銆
+ *
+ * @param val 涓庢 UUID 姣旇緝鐨 UUID
+ *
+ * @return 鍦ㄦ UUID 灏忎簬銆佺瓑浜庢垨澶т簬 val 鏃讹紝鍒嗗埆杩斿洖 -1銆0 鎴 1銆
+ *
+ */
+ @Override
+ public int compareTo(UUID val)
+ {
+ // The ordering is intentionally set up so that the UUIDs
+ // can simply be numerically compared as two numbers
+ return (this.mostSigBits < val.mostSigBits ? -1 : //
+ (this.mostSigBits > val.mostSigBits ? 1 : //
+ (this.leastSigBits < val.leastSigBits ? -1 : //
+ (this.leastSigBits > val.leastSigBits ? 1 : //
+ 0))));
+ }
+
+ // -------------------------------------------------------------------------------------------------------------------
+ // Private method start
+ /**
+ * 杩斿洖鎸囧畾鏁板瓧瀵瑰簲鐨刪ex鍊
+ *
+ * @param val 鍊
+ * @param digits 浣
+ * @return 鍊
+ */
+ private static String digits(long val, int digits)
+ {
+ long hi = 1L << (digits * 4);
+ return Long.toHexString(hi | (val & (hi - 1))).substring(1);
+ }
+
+ /**
+ * 妫鏌ユ槸鍚︿负time-based鐗堟湰UUID
+ */
+ private void checkTimeBase()
+ {
+ if (version() != 1)
+ {
+ throw new UnsupportedOperationException("Not a time-based UUID");
+ }
+ }
+
+ /**
+ * 鑾峰彇{@link SecureRandom}锛岀被鎻愪緵鍔犲瘑鐨勫己闅忔満鏁扮敓鎴愬櫒 (RNG)
+ *
+ * @return {@link SecureRandom}
+ */
+ public static SecureRandom getSecureRandom()
+ {
+ try
+ {
+ return SecureRandom.getInstance("SHA1PRNG");
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new UtilException(e);
+ }
+ }
+
+ /**
+ * 鑾峰彇闅忔満鏁扮敓鎴愬櫒瀵硅薄
+ * ThreadLocalRandom鏄疛DK 7涔嬪悗鎻愪緵骞跺彂浜х敓闅忔満鏁帮紝鑳藉瑙e喅澶氫釜绾跨▼鍙戠敓鐨勭珵浜変簤澶恒
+ *
+ * @return {@link ThreadLocalRandom}
+ */
+ public static ThreadLocalRandom getRandom()
+ {
+ return ThreadLocalRandom.current();
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/DateUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/DateUtils.java
new file mode 100644
index 0000000..6f25dcf
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/DateUtils.java
@@ -0,0 +1,155 @@
+package com.zhentao.common.core.utils;
+
+import java.lang.management.ManagementFactory;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+/**
+ * 鏃堕棿宸ュ叿绫
+ *
+ * @author ruoyi
+ */
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils
+{
+ public static String YYYY = "yyyy";
+
+ public static String YYYY_MM = "yyyy-MM";
+
+ public static String YYYY_MM_DD = "yyyy-MM-dd";
+
+ public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+
+ public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
+
+ private static String[] parsePatterns = {
+ "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
+ "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
+ "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
+
+ /**
+ * 鑾峰彇褰撳墠Date鍨嬫棩鏈
+ *
+ * @return Date() 褰撳墠鏃ユ湡
+ */
+ public static Date getNowDate()
+ {
+ return new Date();
+ }
+
+ /**
+ * 鑾峰彇褰撳墠鏃ユ湡, 榛樿鏍煎紡涓簓yyy-MM-dd
+ *
+ * @return String
+ */
+ public static String getDate()
+ {
+ return dateTimeNow(YYYY_MM_DD);
+ }
+
+ public static final String getTime()
+ {
+ return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
+ }
+
+ public static final String dateTimeNow()
+ {
+ return dateTimeNow(YYYYMMDDHHMMSS);
+ }
+
+ public static final String dateTimeNow(final String format)
+ {
+ return parseDateToStr(format, new Date());
+ }
+
+ public static final String dateTime(final Date date)
+ {
+ return parseDateToStr(YYYY_MM_DD, date);
+ }
+
+ public static final String parseDateToStr(final String format, final Date date)
+ {
+ return new SimpleDateFormat(format).format(date);
+ }
+
+ public static final Date dateTime(final String format, final String ts)
+ {
+ try
+ {
+ return new SimpleDateFormat(format).parse(ts);
+ }
+ catch (ParseException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * 鏃ユ湡璺緞 鍗冲勾/鏈/鏃 濡2018/08/08
+ */
+ public static final String datePath()
+ {
+ Date now = new Date();
+ return DateFormatUtils.format(now, "yyyy/MM/dd");
+ }
+
+ /**
+ * 鏃ユ湡璺緞 鍗冲勾/鏈/鏃 濡20180808
+ */
+ public static final String dateTime()
+ {
+ Date now = new Date();
+ return DateFormatUtils.format(now, "yyyyMMdd");
+ }
+
+ /**
+ * 鏃ユ湡鍨嬪瓧绗︿覆杞寲涓烘棩鏈 鏍煎紡
+ */
+ public static Date parseDate(Object str)
+ {
+ if (str == null)
+ {
+ return null;
+ }
+ try
+ {
+ return parseDate(str.toString(), parsePatterns);
+ }
+ catch (ParseException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * 鑾峰彇鏈嶅姟鍣ㄥ惎鍔ㄦ椂闂
+ */
+ public static Date getServerStartDate()
+ {
+ long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+ return new Date(time);
+ }
+
+ /**
+ * 璁$畻涓や釜鏃堕棿宸
+ */
+ public static String getDatePoor(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 + "鍒嗛挓";
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ExceptionUtil.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ExceptionUtil.java
new file mode 100644
index 0000000..faff3a1
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ExceptionUtil.java
@@ -0,0 +1,40 @@
+package com.zhentao.common.core.utils;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+
+/**
+ * 閿欒淇℃伅澶勭悊绫汇
+ *
+ * @author ruoyi
+ */
+public class ExceptionUtil
+{
+ /**
+ * 鑾峰彇exception鐨勮缁嗛敊璇俊鎭
+ */
+ public static String getExceptionMessage(Throwable e)
+ {
+ StringWriter sw = new StringWriter();
+ e.printStackTrace(new PrintWriter(sw, true));
+ String str = sw.toString();
+ return str;
+ }
+
+ public static String getRootErrorMseeage(Exception e)
+ {
+ Throwable root = ExceptionUtils.getRootCause(e);
+ root = (root == null ? e : root);
+ if (root == null)
+ {
+ return "";
+ }
+ String msg = root.getMessage();
+ if (msg == null)
+ {
+ return "null";
+ }
+ return StringUtils.defaultString(msg);
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/IdUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/IdUtils.java
new file mode 100644
index 0000000..1ff1c23
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/IdUtils.java
@@ -0,0 +1,51 @@
+package com.zhentao.common.core.utils;
+
+import com.zhentao.common.core.text.UUID;
+
+/**
+ * ID鐢熸垚鍣ㄥ伐鍏风被
+ *
+ * @author ruoyi
+ */
+public class IdUtils
+{
+ /**
+ * 鑾峰彇闅忔満UUID
+ *
+ * @return 闅忔満UUID
+ */
+ public static String randomUUID()
+ {
+ return UUID.randomUUID().toString();
+ }
+
+ /**
+ * 绠鍖栫殑UUID锛屽幓鎺変簡妯嚎
+ *
+ * @return 绠鍖栫殑UUID锛屽幓鎺変簡妯嚎
+ */
+ public static String simpleUUID()
+ {
+ return UUID.randomUUID().toString(true);
+ }
+
+ /**
+ * 鑾峰彇闅忔満UUID锛屼娇鐢ㄦц兘鏇村ソ鐨凾hreadLocalRandom鐢熸垚UUID
+ *
+ * @return 闅忔満UUID
+ */
+ public static String fastUUID()
+ {
+ return UUID.fastUUID().toString();
+ }
+
+ /**
+ * 绠鍖栫殑UUID锛屽幓鎺変簡妯嚎锛屼娇鐢ㄦц兘鏇村ソ鐨凾hreadLocalRandom鐢熸垚UUID
+ *
+ * @return 绠鍖栫殑UUID锛屽幓鎺変簡妯嚎
+ */
+ public static String fastSimpleUUID()
+ {
+ return UUID.fastUUID().toString(true);
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ReUtil.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ReUtil.java
new file mode 100644
index 0000000..19c9734
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ReUtil.java
@@ -0,0 +1,163 @@
+package com.zhentao.common.core.utils;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.zhentao.common.core.text.Convert;
+
+public class ReUtil
+{
+ public final static Pattern GROUP_VAR = Pattern.compile("\\$(\\d+)");
+
+ /**
+ * 姝e垯涓渶瑕佽杞箟鐨勫叧閿瓧
+ */
+ public final static Set RE_KEYS = new HashSet<>(
+ Arrays.asList('$', '(', ')', '*', '+', '.', '[', ']', '?', '\\', '^', '{', '}', '|'));;
+
+ /**
+ * 姝e垯鏇挎崲鎸囧畾鍊
+ * 閫氳繃姝e垯鏌ユ壘鍒板瓧绗︿覆锛岀劧鍚庢妸鍖归厤鍒扮殑瀛楃涓插姞鍏ュ埌replacementTemplate涓紝$1琛ㄧず鍒嗙粍1鐨勫瓧绗︿覆
+ *
+ *
+ * 渚嬪锛氬師瀛楃涓叉槸锛氫腑鏂1234锛屾垜鎯虫妸1234鎹㈡垚(1234)锛屽垯鍙互锛
+ *
+ *
+ * ReUtil.replaceAll("涓枃1234", "(\\d+)", "($1)"))
+ *
+ * 缁撴灉锛氫腑鏂(1234)
+ *
+ *
+ * @param content 鏂囨湰
+ * @param regex 姝e垯
+ * @param replacementTemplate 鏇挎崲鐨勬枃鏈ā鏉匡紝鍙互浣跨敤$1绫讳技鐨勫彉閲忔彁鍙栨鍒欏尮閰嶅嚭鐨勫唴瀹
+ * @return 澶勭悊鍚庣殑鏂囨湰
+ */
+ public static String replaceAll(CharSequence content, String regex, String replacementTemplate)
+ {
+ final Pattern pattern = Pattern.compile(regex, Pattern.DOTALL);
+ return replaceAll(content, pattern, replacementTemplate);
+ }
+
+ /**
+ * 姝e垯鏇挎崲鎸囧畾鍊
+ * 閫氳繃姝e垯鏌ユ壘鍒板瓧绗︿覆锛岀劧鍚庢妸鍖归厤鍒扮殑瀛楃涓插姞鍏ュ埌replacementTemplate涓紝$1琛ㄧず鍒嗙粍1鐨勫瓧绗︿覆
+ *
+ * @param content 鏂囨湰
+ * @param pattern {@link Pattern}
+ * @param replacementTemplate 鏇挎崲鐨勬枃鏈ā鏉匡紝鍙互浣跨敤$1绫讳技鐨勫彉閲忔彁鍙栨鍒欏尮閰嶅嚭鐨勫唴瀹
+ * @return 澶勭悊鍚庣殑鏂囨湰
+ * @since 3.0.4
+ */
+ public static String replaceAll(CharSequence content, Pattern pattern, String replacementTemplate)
+ {
+ if (StringUtils.isEmpty(content))
+ {
+ return StringUtils.EMPTY;
+ }
+
+ final Matcher matcher = pattern.matcher(content);
+ boolean result = matcher.find();
+ if (result)
+ {
+ final Set varNums = findAll(GROUP_VAR, replacementTemplate, 1, new HashSet<>());
+ final StringBuffer sb = new StringBuffer();
+ do
+ {
+ String replacement = replacementTemplate;
+ for (String var : varNums)
+ {
+ int group = Integer.parseInt(var);
+ replacement = replacement.replace("$" + var, matcher.group(group));
+ }
+ matcher.appendReplacement(sb, escape(replacement));
+ result = matcher.find();
+ }
+ while (result);
+ matcher.appendTail(sb);
+ return sb.toString();
+ }
+ return Convert.toStr(content);
+ }
+
+ /**
+ * 鍙栧緱鍐呭涓尮閰嶇殑鎵鏈夌粨鏋
+ *
+ * @param 闆嗗悎绫诲瀷
+ * @param pattern 缂栬瘧鍚庣殑姝e垯妯″紡
+ * @param content 琚煡鎵剧殑鍐呭
+ * @param group 姝e垯鐨勫垎缁
+ * @param collection 杩斿洖鐨勯泦鍚堢被鍨
+ * @return 缁撴灉闆
+ */
+ public static > T findAll(Pattern pattern, CharSequence content, int group,
+ T collection)
+ {
+ if (null == pattern || null == content)
+ {
+ return null;
+ }
+
+ if (null == collection)
+ {
+ throw new NullPointerException("Null collection param provided!");
+ }
+
+ final Matcher matcher = pattern.matcher(content);
+ while (matcher.find())
+ {
+ collection.add(matcher.group(group));
+ }
+ return collection;
+ }
+
+ /**
+ * 杞箟瀛楃锛屽皢姝e垯鐨勫叧閿瓧杞箟
+ *
+ * @param c 瀛楃
+ * @return 杞箟鍚庣殑鏂囨湰
+ */
+ public static String escape(char c)
+ {
+ final StringBuilder builder = new StringBuilder();
+ if (RE_KEYS.contains(c))
+ {
+ builder.append('\\');
+ }
+ builder.append(c);
+ return builder.toString();
+ }
+
+ /**
+ * 杞箟瀛楃涓诧紝灏嗘鍒欑殑鍏抽敭瀛楄浆涔
+ *
+ * @param content 鏂囨湰
+ * @return 杞箟鍚庣殑鏂囨湰
+ */
+ public static String escape(CharSequence content)
+ {
+ if (StringUtils.isBlank(content))
+ {
+ return StringUtils.EMPTY;
+ }
+
+ final StringBuilder builder = new StringBuilder();
+ int len = content.length();
+ char current;
+ for (int i = 0; i < len; i++)
+ {
+ current = content.charAt(i);
+ if (RE_KEYS.contains(current))
+ {
+ builder.append('\\');
+ }
+ builder.append(current);
+ }
+ return builder.toString();
+ }
+
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/SecurityUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/SecurityUtils.java
new file mode 100644
index 0000000..92c8b23
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/SecurityUtils.java
@@ -0,0 +1,89 @@
+package com.zhentao.common.core.utils;
+
+import javax.servlet.http.HttpServletRequest;
+
+import com.zhentao.common.core.constant.CacheConstants;
+import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
+import com.zhentao.common.core.text.Convert;
+
+/**
+ * 鏉冮檺鑾峰彇宸ュ叿绫
+ *
+ * @author ruoyi
+ */
+public class SecurityUtils
+{
+ /**
+ * 鑾峰彇鐢ㄦ埛
+ */
+ public static String getUsername()
+ {
+ String username = ServletUtils.getRequest().getHeader(CacheConstants.DETAILS_USERNAME);
+ return ServletUtils.urlDecode(username);
+ }
+
+ /**
+ * 鑾峰彇鐢ㄦ埛ID
+ */
+ public static Long getUserId()
+ {
+ return Convert.toLong(ServletUtils.getRequest().getHeader(CacheConstants.DETAILS_USER_ID));
+ }
+
+ /**
+ * 鑾峰彇璇锋眰token
+ */
+ public static String getToken()
+ {
+ return getToken(ServletUtils.getRequest());
+ }
+
+ /**
+ * 鏍规嵁request鑾峰彇璇锋眰token
+ */
+ public static String getToken(HttpServletRequest request)
+ {
+ String token = ServletUtils.getRequest().getHeader(CacheConstants.HEADER);
+ if (StringUtils.isNotEmpty(token) && token.startsWith(CacheConstants.TOKEN_PREFIX))
+ {
+ token = token.replace(CacheConstants.TOKEN_PREFIX, "");
+ }
+ return token;
+ }
+
+ /**
+ * 鏄惁涓虹鐞嗗憳
+ *
+ * @param userId 鐢ㄦ埛ID
+ * @return 缁撴灉
+ */
+ public static boolean isAdmin(Long userId)
+ {
+ return userId != null && 1L == userId;
+ }
+
+ /**
+ * 鐢熸垚BCryptPasswordEncoder瀵嗙爜
+ *
+ * @param password 瀵嗙爜
+ * @return 鍔犲瘑瀛楃涓
+ */
+ public static String encryptPassword(String password)
+ {
+ BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
+ return passwordEncoder.encode(password);
+ }
+
+ /**
+ * 鍒ゆ柇瀵嗙爜鏄惁鐩稿悓
+ *
+ * @param rawPassword 鐪熷疄瀵嗙爜
+ * @param encodedPassword 鍔犲瘑鍚庡瓧绗
+ * @return 缁撴灉
+ */
+ public static boolean matchesPassword(String rawPassword, String encodedPassword)
+ {
+ BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
+ return passwordEncoder.matches(rawPassword, encodedPassword);
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ServletUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ServletUtils.java
new file mode 100644
index 0000000..bd09a1c
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ServletUtils.java
@@ -0,0 +1,217 @@
+package com.zhentao.common.core.utils;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.Enumeration;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import com.zhentao.common.core.constant.Constants;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import com.zhentao.common.core.text.Convert;
+
+/**
+ * 瀹㈡埛绔伐鍏风被
+ *
+ * @author ruoyi
+ */
+public class ServletUtils
+{
+ /**
+ * 鑾峰彇String鍙傛暟
+ */
+ public static String getParameter(String name)
+ {
+ return getRequest().getParameter(name);
+ }
+
+ /**
+ * 鑾峰彇String鍙傛暟
+ */
+ public static String getParameter(String name, String defaultValue)
+ {
+ return Convert.toStr(getRequest().getParameter(name), defaultValue);
+ }
+
+ /**
+ * 鑾峰彇Integer鍙傛暟
+ */
+ public static Integer getParameterToInt(String name)
+ {
+ return Convert.toInt(getRequest().getParameter(name));
+ }
+
+ /**
+ * 鑾峰彇Integer鍙傛暟
+ */
+ public static Integer getParameterToInt(String name, Integer defaultValue)
+ {
+ return Convert.toInt(getRequest().getParameter(name), defaultValue);
+ }
+
+ /**
+ * 鑾峰彇request
+ */
+ public static HttpServletRequest getRequest()
+ {
+ try
+ {
+ return getRequestAttributes().getRequest();
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * 鑾峰彇response
+ */
+ public static HttpServletResponse getResponse()
+ {
+ try
+ {
+ return getRequestAttributes().getResponse();
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * 鑾峰彇session
+ */
+ public static HttpSession getSession()
+ {
+ return getRequest().getSession();
+ }
+
+ public static ServletRequestAttributes getRequestAttributes()
+ {
+ try
+ {
+ RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
+ return (ServletRequestAttributes) attributes;
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+ public static Map getHeaders(HttpServletRequest request)
+ {
+ Map map = new LinkedHashMap<>();
+ Enumeration enumeration = request.getHeaderNames();
+ if (enumeration != null)
+ {
+ while (enumeration.hasMoreElements())
+ {
+ String key = enumeration.nextElement();
+ String value = request.getHeader(key);
+ map.put(key, value);
+ }
+ }
+ return map;
+ }
+
+ /**
+ * 灏嗗瓧绗︿覆娓叉煋鍒板鎴风
+ *
+ * @param response 娓叉煋瀵硅薄
+ * @param string 寰呮覆鏌撶殑瀛楃涓
+ * @return null
+ */
+ public static String renderString(HttpServletResponse response, String string)
+ {
+ try
+ {
+ response.setStatus(200);
+ response.setContentType("application/json");
+ response.setCharacterEncoding("utf-8");
+ response.getWriter().print(string);
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * 鏄惁鏄疉jax寮傛璇锋眰
+ *
+ * @param request
+ */
+ public static boolean isAjaxRequest(HttpServletRequest request)
+ {
+ String accept = request.getHeader("accept");
+ if (accept != null && accept.indexOf("application/json") != -1)
+ {
+ return true;
+ }
+
+ String xRequestedWith = request.getHeader("X-Requested-With");
+ if (xRequestedWith != null && xRequestedWith.indexOf("XMLHttpRequest") != -1)
+ {
+ return true;
+ }
+
+ String uri = request.getRequestURI();
+ if (StringUtils.inStringIgnoreCase(uri, ".json", ".xml"))
+ {
+ return true;
+ }
+
+ String ajax = request.getParameter("__ajax");
+ if (StringUtils.inStringIgnoreCase(ajax, "json", "xml"))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 鍐呭缂栫爜
+ *
+ * @param str 鍐呭
+ * @return 缂栫爜鍚庣殑鍐呭
+ */
+ public static String urlEncode(String str)
+ {
+ try
+ {
+ return URLEncoder.encode(str, Constants.UTF8);
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ return "";
+ }
+ }
+
+ /**
+ * 鍐呭瑙g爜
+ *
+ * @param str 鍐呭
+ * @return 瑙g爜鍚庣殑鍐呭
+ */
+ public static String urlDecode(String str)
+ {
+ try
+ {
+ return URLDecoder.decode(str, Constants.UTF8);
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ return "";
+ }
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/SpringUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/SpringUtils.java
new file mode 100644
index 0000000..a9558a7
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/SpringUtils.java
@@ -0,0 +1,114 @@
+package com.zhentao.common.core.utils;
+
+import org.springframework.aop.framework.AopContext;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * spring宸ュ叿绫 鏂逛究鍦ㄩ潪spring绠$悊鐜涓幏鍙朾ean
+ *
+ * @author ruoyi
+ */
+@Component
+public final class SpringUtils implements BeanFactoryPostProcessor
+{
+ /** Spring搴旂敤涓婁笅鏂囩幆澧 */
+ private static ConfigurableListableBeanFactory beanFactory;
+
+ @Override
+ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException
+ {
+ SpringUtils.beanFactory = beanFactory;
+ }
+
+ /**
+ * 鑾峰彇瀵硅薄
+ *
+ * @param name
+ * @return Object 涓涓互鎵缁欏悕瀛楁敞鍐岀殑bean鐨勫疄渚
+ * @throws org.springframework.beans.BeansException
+ *
+ */
+ @SuppressWarnings("unchecked")
+ public static T getBean(String name) throws BeansException
+ {
+ return (T) beanFactory.getBean(name);
+ }
+
+ /**
+ * 鑾峰彇绫诲瀷涓簉equiredType鐨勫璞
+ *
+ * @param clz
+ * @return
+ * @throws org.springframework.beans.BeansException
+ *
+ */
+ public static T getBean(Class clz) throws BeansException
+ {
+ T result = (T) beanFactory.getBean(clz);
+ return result;
+ }
+
+ /**
+ * 濡傛灉BeanFactory鍖呭惈涓涓笌鎵缁欏悕绉板尮閰嶇殑bean瀹氫箟锛屽垯杩斿洖true
+ *
+ * @param name
+ * @return boolean
+ */
+ public static boolean containsBean(String name)
+ {
+ return beanFactory.containsBean(name);
+ }
+
+ /**
+ * 鍒ゆ柇浠ョ粰瀹氬悕瀛楁敞鍐岀殑bean瀹氫箟鏄竴涓猻ingleton杩樻槸涓涓猵rototype銆 濡傛灉涓庣粰瀹氬悕瀛楃浉搴旂殑bean瀹氫箟娌℃湁琚壘鍒帮紝灏嗕細鎶涘嚭涓涓紓甯革紙NoSuchBeanDefinitionException锛
+ *
+ * @param name
+ * @return boolean
+ * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
+ *
+ */
+ public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException
+ {
+ return beanFactory.isSingleton(name);
+ }
+
+ /**
+ * @param name
+ * @return Class 娉ㄥ唽瀵硅薄鐨勭被鍨
+ * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
+ *
+ */
+ public static Class> getType(String name) throws NoSuchBeanDefinitionException
+ {
+ return beanFactory.getType(name);
+ }
+
+ /**
+ * 濡傛灉缁欏畾鐨刡ean鍚嶅瓧鍦╞ean瀹氫箟涓湁鍒悕锛屽垯杩斿洖杩欎簺鍒悕
+ *
+ * @param name
+ * @return
+ * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
+ *
+ */
+ public static String[] getAliases(String name) throws NoSuchBeanDefinitionException
+ {
+ return beanFactory.getAliases(name);
+ }
+
+ /**
+ * 鑾峰彇aop浠g悊瀵硅薄
+ *
+ * @param invoker
+ * @return
+ */
+ @SuppressWarnings("unchecked")
+ public static T getAopProxy(T invoker)
+ {
+ return (T) AopContext.currentProxy();
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/StringUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/StringUtils.java
new file mode 100644
index 0000000..63a4a79
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/StringUtils.java
@@ -0,0 +1,523 @@
+package com.zhentao.common.core.utils;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import com.zhentao.common.core.text.StrFormatter;
+
+/**
+ * 瀛楃涓插伐鍏风被
+ *
+ * @author ruoyi
+ */
+public class StringUtils extends org.apache.commons.lang3.StringUtils
+{
+ /** 绌哄瓧绗︿覆 */
+ private static final String NULLSTR = "";
+
+ /** 涓嬪垝绾 */
+ private static final char SEPARATOR = '_';
+
+ /** 鏄熷彿 */
+ private static final String START = "*";
+
+ /**
+ * 鑾峰彇鍙傛暟涓嶄负绌哄
+ *
+ * @param value defaultValue 瑕佸垽鏂殑value
+ * @return value 杩斿洖鍊
+ */
+ public static T nvl(T value, T defaultValue)
+ {
+ return value != null ? value : defaultValue;
+ }
+
+ /**
+ * * 鍒ゆ柇涓涓狢ollection鏄惁涓虹┖锛 鍖呭惈List锛孲et锛孮ueue
+ *
+ * @param coll 瑕佸垽鏂殑Collection
+ * @return true锛氫负绌 false锛氶潪绌
+ */
+ public static boolean isEmpty(Collection> coll)
+ {
+ return isNull(coll) || coll.isEmpty();
+ }
+
+ /**
+ * * 鍒ゆ柇涓涓狢ollection鏄惁闈炵┖锛屽寘鍚獿ist锛孲et锛孮ueue
+ *
+ * @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);
+ }
+
+ /**
+ * * 鍒ゆ柇涓涓狹ap鏄惁涓虹┖
+ *
+ * @param map 瑕佸垽鏂殑Map
+ * @return true锛氫负绌 false锛氶潪绌
+ */
+ public static boolean isEmpty(Map, ?> map)
+ {
+ return isNull(map) || map.isEmpty();
+ }
+
+ /**
+ * * 鍒ゆ柇涓涓狹ap鏄惁涓虹┖
+ *
+ * @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) || NULLSTR.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);
+ }
+
+ /**
+ * * 鍒ゆ柇涓涓璞℃槸鍚︽槸鏁扮粍绫诲瀷锛圝ava鍩烘湰鍨嬪埆鐨勬暟缁勶級
+ *
+ * @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 NULLSTR;
+ }
+
+ if (start < 0)
+ {
+ start = str.length() + start;
+ }
+
+ if (start < 0)
+ {
+ start = 0;
+ }
+ if (start > str.length())
+ {
+ return NULLSTR;
+ }
+
+ 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 NULLSTR;
+ }
+
+ 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 NULLSTR;
+ }
+
+ if (start < 0)
+ {
+ start = 0;
+ }
+ if (end < 0)
+ {
+ end = 0;
+ }
+
+ return str.substring(start, end);
+ }
+
+ /**
+ * 鏍煎紡鍖栨枃鏈, {} 琛ㄧず鍗犱綅绗
+ * 姝ゆ柟娉曞彧鏄畝鍗曞皢鍗犱綅绗 {} 鎸夌収椤哄簭鏇挎崲涓哄弬鏁
+ * 濡傛灉鎯宠緭鍑 {} 浣跨敤 \\杞箟 { 鍗冲彲锛屽鏋滄兂杈撳嚭 {} 涔嬪墠鐨 \ 浣跨敤鍙岃浆涔夌 \\\\ 鍗冲彲
+ * 渚嬶細
+ * 閫氬父浣跨敤锛歠ormat("this is {} for {}", "a", "b") -> this is a for b
+ * 杞箟{}锛 format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 杞箟\锛 format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ *
+ * @param template 鏂囨湰妯℃澘锛岃鏇挎崲鐨勯儴鍒嗙敤 {} 琛ㄧず
+ * @param params 鍙傛暟鍊
+ * @return 鏍煎紡鍖栧悗鐨勬枃鏈
+ */
+ public static String format(String template, Object... params)
+ {
+ if (isEmpty(params) || isEmpty(template))
+ {
+ return template;
+ }
+ return StrFormatter.format(template, params);
+ }
+
+ /**
+ * 涓嬪垝绾胯浆椹煎嘲鍛藉悕
+ */
+ public static String toUnderScoreCase(String str)
+ {
+ if (str == null)
+ {
+ return null;
+ }
+ StringBuilder sb = new StringBuilder();
+ // 鍓嶇疆瀛楃鏄惁澶у啓
+ boolean preCharIsUpperCase = true;
+ // 褰撳墠瀛楃鏄惁澶у啓
+ boolean curreCharIsUpperCase = true;
+ // 涓嬩竴瀛楃鏄惁澶у啓
+ boolean nexteCharIsUpperCase = 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;
+ }
+
+ curreCharIsUpperCase = Character.isUpperCase(c);
+
+ if (i < (str.length() - 1))
+ {
+ nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
+ }
+
+ if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase)
+ {
+ sb.append(SEPARATOR);
+ }
+ else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase)
+ {
+ sb.append(SEPARATOR);
+ }
+ sb.append(Character.toLowerCase(c));
+ }
+
+ return sb.toString();
+ }
+
+ /**
+ * 鏄惁鍖呭惈瀛楃涓
+ *
+ * @param str 楠岃瘉瀛楃涓
+ * @param strs 瀛楃涓茬粍
+ * @return 鍖呭惈杩斿洖true
+ */
+ public static boolean inStringIgnoreCase(String str, String... strs)
+ {
+ if (str != null && strs != null)
+ {
+ for (String s : strs)
+ {
+ if (str.equalsIgnoreCase(trim(s)))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 灏嗕笅鍒掔嚎澶у啓鏂瑰紡鍛藉悕鐨勫瓧绗︿覆杞崲涓洪┘宄板紡銆傚鏋滆浆鎹㈠墠鐨勪笅鍒掔嚎澶у啓鏂瑰紡鍛藉悕鐨勫瓧绗︿覆涓虹┖锛屽垯杩斿洖绌哄瓧绗︿覆銆 渚嬪锛欻ELLO_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();
+ }
+
+ /**
+ * 椹煎嘲寮忓懡鍚嶆硶 渚嬪锛歶ser_name->userName
+ */
+ 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 strs 闇瑕佹鏌ョ殑瀛楃涓叉暟缁
+ * @return 鏄惁鍖归厤
+ */
+ public static boolean matches(String str, List strs)
+ {
+ if (isEmpty(str) || isEmpty(strs))
+ {
+ return false;
+ }
+ for (String testStr : strs)
+ {
+ if (matches(str, testStr))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀尮閰嶆寚瀹氬瓧绗︿覆鏁扮粍涓殑浠绘剰涓涓瓧绗︿覆
+ *
+ * @param str 鎸囧畾瀛楃涓
+ * @param strs 闇瑕佹鏌ョ殑瀛楃涓叉暟缁
+ * @return 鏄惁鍖归厤
+ */
+ public static boolean matches(String str, String... strs)
+ {
+ if (isEmpty(str) || isEmpty(strs))
+ {
+ return false;
+ }
+ for (String testStr : strs)
+ {
+ if (matches(str, testStr))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 鏌ユ壘鎸囧畾瀛楃涓叉槸鍚﹀尮閰
+ *
+ * @param str 鎸囧畾瀛楃涓
+ * @param pattern 闇瑕佹鏌ョ殑瀛楃涓
+ * @return 鏄惁鍖归厤
+ */
+ public static boolean matches(String str, String pattern)
+ {
+ if (isEmpty(pattern) || isEmpty(str))
+ {
+ return false;
+ }
+
+ pattern = pattern.replaceAll("\\s*", ""); // 鏇挎崲绌烘牸
+ int beginOffset = 0; // pattern鎴彇寮濮嬩綅缃
+ int formerStarOffset = -1; // 鍓嶆槦鍙风殑鍋忕Щ浣嶇疆
+ int latterStarOffset = -1; // 鍚庢槦鍙风殑鍋忕Щ浣嶇疆
+
+ String remainingURI = str;
+ String prefixPattern = "";
+ String suffixPattern = "";
+
+ boolean result = false;
+ do
+ {
+ formerStarOffset = indexOf(pattern, START, beginOffset);
+ prefixPattern = substring(pattern, beginOffset, formerStarOffset > -1 ? formerStarOffset : pattern.length());
+
+ // 鍖归厤鍓嶇紑Pattern
+ result = remainingURI.contains(prefixPattern);
+ // 宸茬粡娌℃湁鏄熷彿锛岀洿鎺ヨ繑鍥
+ if (formerStarOffset == -1)
+ {
+ return result;
+ }
+
+ // 鍖归厤澶辫触锛岀洿鎺ヨ繑鍥
+ if (!result)
+ return false;
+
+ if (!isEmpty(prefixPattern))
+ {
+ remainingURI = substringAfter(str, prefixPattern);
+ }
+
+ // 鍖归厤鍚庣紑Pattern
+ latterStarOffset = indexOf(pattern, START, formerStarOffset + 1);
+ suffixPattern = substring(pattern, formerStarOffset + 1, latterStarOffset > -1 ? latterStarOffset : pattern.length());
+
+ result = remainingURI.contains(suffixPattern);
+ // 鍖归厤澶辫触锛岀洿鎺ヨ繑鍥
+ if (!result)
+ return false;
+
+ if (!isEmpty(suffixPattern))
+ {
+ remainingURI = substringAfter(str, suffixPattern);
+ }
+
+ // 绉诲姩鎸囬拡
+ beginOffset = latterStarOffset + 1;
+
+ }
+ while (!isEmpty(suffixPattern) && !isEmpty(remainingURI));
+
+ return true;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static T cast(Object obj)
+ {
+ return (T) obj;
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/bean/BeanUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/bean/BeanUtils.java
new file mode 100644
index 0000000..ceceff2
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/bean/BeanUtils.java
@@ -0,0 +1,110 @@
+package com.zhentao.common.core.utils.bean;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Bean 宸ュ叿绫
+ *
+ * @author ruoyi
+ */
+public class BeanUtils extends org.springframework.beans.BeanUtils
+{
+ /** Bean鏂规硶鍚嶄腑灞炴у悕寮濮嬬殑涓嬫爣 */
+ private static final int BEAN_METHOD_PROP_INDEX = 3;
+
+ /** * 鍖归厤getter鏂规硶鐨勬鍒欒〃杈惧紡 */
+ private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");
+
+ /** * 鍖归厤setter鏂规硶鐨勬鍒欒〃杈惧紡 */
+ private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");
+
+ /**
+ * Bean灞炴у鍒跺伐鍏锋柟娉曘
+ *
+ * @param dest 鐩爣瀵硅薄
+ * @param src 婧愬璞
+ */
+ public static void copyBeanProp(Object dest, Object src)
+ {
+ try
+ {
+ copyProperties(src, dest);
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * 鑾峰彇瀵硅薄鐨剆etter鏂规硶銆
+ *
+ * @param obj 瀵硅薄
+ * @return 瀵硅薄鐨剆etter鏂规硶鍒楄〃
+ */
+ public static List getSetterMethods(Object obj)
+ {
+ // setter鏂规硶鍒楄〃
+ List setterMethods = new ArrayList();
+
+ // 鑾峰彇鎵鏈夋柟娉
+ Method[] methods = obj.getClass().getMethods();
+
+ // 鏌ユ壘setter鏂规硶
+
+ for (Method method : methods)
+ {
+ Matcher m = SET_PATTERN.matcher(method.getName());
+ if (m.matches() && (method.getParameterTypes().length == 1))
+ {
+ setterMethods.add(method);
+ }
+ }
+ // 杩斿洖setter鏂规硶鍒楄〃
+ return setterMethods;
+ }
+
+ /**
+ * 鑾峰彇瀵硅薄鐨刧etter鏂规硶銆
+ *
+ * @param obj 瀵硅薄
+ * @return 瀵硅薄鐨刧etter鏂规硶鍒楄〃
+ */
+
+ public static List getGetterMethods(Object obj)
+ {
+ // getter鏂规硶鍒楄〃
+ List getterMethods = new ArrayList();
+ // 鑾峰彇鎵鏈夋柟娉
+ Method[] methods = obj.getClass().getMethods();
+ // 鏌ユ壘getter鏂规硶
+ for (Method method : methods)
+ {
+ Matcher m = GET_PATTERN.matcher(method.getName());
+ if (m.matches() && (method.getParameterTypes().length == 0))
+ {
+ getterMethods.add(method);
+ }
+ }
+ // 杩斿洖getter鏂规硶鍒楄〃
+ return getterMethods;
+ }
+
+ /**
+ * 妫鏌ean鏂规硶鍚嶄腑鐨勫睘鎬у悕鏄惁鐩哥瓑銆
+ * 濡俫etName()鍜宻etName()灞炴у悕涓鏍凤紝getName()鍜宻etAge()灞炴у悕涓嶄竴鏍枫
+ *
+ * @param m1 鏂规硶鍚1
+ * @param m2 鏂规硶鍚2
+ * @return 灞炴у悕涓鏍疯繑鍥瀟rue锛屽惁鍒欒繑鍥瀎alse
+ */
+
+ public static boolean isMethodPropEquals(String m1, String m2)
+ {
+ return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/FileTypeUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/FileTypeUtils.java
new file mode 100644
index 0000000..3250bb6
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/FileTypeUtils.java
@@ -0,0 +1,76 @@
+package com.zhentao.common.core.utils.file;
+
+import java.io.File;
+import org.apache.commons.lang3.StringUtils;
+
+/**
+ * 鏂囦欢绫诲瀷宸ュ叿绫
+ *
+ * @author ruoyi
+ */
+public class FileTypeUtils
+{
+ /**
+ * 鑾峰彇鏂囦欢绫诲瀷
+ *
+ * 渚嬪: ruoyi.txt, 杩斿洖: txt
+ *
+ * @param file 鏂囦欢鍚
+ * @return 鍚庣紑锛堜笉鍚".")
+ */
+ public static String getFileType(File file)
+ {
+ if (null == file)
+ {
+ return StringUtils.EMPTY;
+ }
+ return getFileType(file.getName());
+ }
+
+ /**
+ * 鑾峰彇鏂囦欢绫诲瀷
+ *
+ * 渚嬪: ruoyi.txt, 杩斿洖: txt
+ *
+ * @param fileName 鏂囦欢鍚
+ * @return 鍚庣紑锛堜笉鍚".")
+ */
+ public static String getFileType(String fileName)
+ {
+ int separatorIndex = fileName.lastIndexOf(".");
+ if (separatorIndex < 0)
+ {
+ return "";
+ }
+ return fileName.substring(separatorIndex + 1).toLowerCase();
+ }
+
+ /**
+ * 鑾峰彇鏂囦欢绫诲瀷
+ *
+ * @param photoByte 鏂囦欢瀛楄妭鐮
+ * @return 鍚庣紑锛堜笉鍚".")
+ */
+ public static String getFileExtendName(byte[] photoByte)
+ {
+ String strFileExtendName = "JPG";
+ if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
+ && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
+ {
+ strFileExtendName = "GIF";
+ }
+ else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
+ {
+ strFileExtendName = "JPG";
+ }
+ else if ((photoByte[0] == 66) && (photoByte[1] == 77))
+ {
+ strFileExtendName = "BMP";
+ }
+ else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
+ {
+ strFileExtendName = "PNG";
+ }
+ return strFileExtendName;
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/FileUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/FileUtils.java
new file mode 100644
index 0000000..f287277
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/FileUtils.java
@@ -0,0 +1,260 @@
+package com.zhentao.common.core.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.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.lang3.ArrayUtils;
+import com.zhentao.common.core.utils.StringUtils;
+
+/**
+ * 鏂囦欢澶勭悊宸ュ叿绫
+ *
+ * @author ruoyi
+ */
+public class FileUtils extends org.apache.commons.io.FileUtils
+{
+ /** 瀛楃甯搁噺锛氭枩鏉 {@code '/'} */
+ public static final char SLASH = '/';
+
+ /** 瀛楃甯搁噺锛氬弽鏂滄潬 {@code '\\'} */
+ public static final char BACKSLASH = '\\';
+
+ public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
+
+ /**
+ * 杈撳嚭鎸囧畾鏂囦欢鐨刡yte鏁扮粍
+ *
+ * @param filePath 鏂囦欢璺緞
+ * @param os 杈撳嚭娴
+ * @return
+ */
+ public static void writeBytes(String filePath, OutputStream os) throws IOException
+ {
+ FileInputStream fis = null;
+ try
+ {
+ File file = new File(filePath);
+ if (!file.exists())
+ {
+ throw new FileNotFoundException(filePath);
+ }
+ fis = new FileInputStream(file);
+ byte[] b = new byte[1024];
+ int length;
+ while ((length = fis.read(b)) > 0)
+ {
+ os.write(b, 0, length);
+ }
+ }
+ catch (IOException e)
+ {
+ throw e;
+ }
+ finally
+ {
+ if (os != null)
+ {
+ try
+ {
+ os.close();
+ }
+ catch (IOException e1)
+ {
+ e1.printStackTrace();
+ }
+ }
+ if (fis != null)
+ {
+ try
+ {
+ fis.close();
+ }
+ catch (IOException e1)
+ {
+ e1.printStackTrace();
+ }
+ }
+ }
+ }
+
+ /**
+ * 鍒犻櫎鏂囦欢
+ *
+ * @param filePath 鏂囦欢
+ * @return
+ */
+ public static boolean deleteFile(String filePath)
+ {
+ boolean flag = false;
+ File file = new File(filePath);
+ // 璺緞涓烘枃浠朵笖涓嶄负绌哄垯杩涜鍒犻櫎
+ if (file.isFile() && file.exists())
+ {
+ file.delete();
+ flag = true;
+ }
+ return flag;
+ }
+
+ /**
+ * 鏂囦欢鍚嶇О楠岃瘉
+ *
+ * @param filename 鏂囦欢鍚嶇О
+ * @return true 姝e父 false 闈炴硶
+ */
+ public static boolean isValidFilename(String filename)
+ {
+ return filename.matches(FILENAME_PATTERN);
+ }
+
+ /**
+ * 妫鏌ユ枃浠舵槸鍚﹀彲涓嬭浇
+ *
+ * @param resource 闇瑕佷笅杞界殑鏂囦欢
+ * @return true 姝e父 false 闈炴硶
+ */
+ public static boolean checkAllowDownload(String resource)
+ {
+ // 绂佹鐩綍涓婅烦绾у埆
+ if (StringUtils.contains(resource, ".."))
+ {
+ return false;
+ }
+
+ // 妫鏌ュ厑璁镐笅杞界殑鏂囦欢瑙勫垯
+ if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
+ {
+ return true;
+ }
+
+ // 涓嶅湪鍏佽涓嬭浇鐨勬枃浠惰鍒
+ return false;
+ }
+
+ /**
+ * 涓嬭浇鏂囦欢鍚嶉噸鏂扮紪鐮
+ *
+ * @param request 璇锋眰瀵硅薄
+ * @param fileName 鏂囦欢鍚
+ * @return 缂栫爜鍚庣殑鏂囦欢鍚
+ */
+ public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
+ {
+ final String agent = request.getHeader("USER-AGENT");
+ String filename = fileName;
+ if (agent.contains("MSIE"))
+ {
+ // IE娴忚鍣
+ filename = URLEncoder.encode(filename, "utf-8");
+ filename = filename.replace("+", " ");
+ }
+ else if (agent.contains("Firefox"))
+ {
+ // 鐏嫄娴忚鍣
+ filename = new String(fileName.getBytes(), "ISO8859-1");
+ }
+ else if (agent.contains("Chrome"))
+ {
+ // google娴忚鍣
+ filename = URLEncoder.encode(filename, "utf-8");
+ }
+ else
+ {
+ // 鍏跺畠娴忚鍣
+ filename = URLEncoder.encode(filename, "utf-8");
+ }
+ return filename;
+ }
+
+ /**
+ * 杩斿洖鏂囦欢鍚
+ *
+ * @param filePath 鏂囦欢
+ * @return 鏂囦欢鍚
+ */
+ public static String getName(String filePath)
+ {
+ if (null == filePath)
+ {
+ return null;
+ }
+ int len = filePath.length();
+ if (0 == len)
+ {
+ return filePath;
+ }
+ if (isFileSeparator(filePath.charAt(len - 1)))
+ {
+ // 浠ュ垎闅旂缁撳熬鐨勫幓鎺夌粨灏惧垎闅旂
+ len--;
+ }
+
+ int begin = 0;
+ char c;
+ for (int i = len - 1; i > -1; i--)
+ {
+ c = filePath.charAt(i);
+ if (isFileSeparator(c))
+ {
+ // 鏌ユ壘鏈鍚庝竴涓矾寰勫垎闅旂锛/鎴栬匼锛
+ begin = i + 1;
+ break;
+ }
+ }
+
+ return filePath.substring(begin, len);
+ }
+
+ /**
+ * 鏄惁涓篧indows鎴栬匧inux锛圲nix锛夋枃浠跺垎闅旂
+ * Windows骞冲彴涓嬪垎闅旂涓篭锛孡inux锛圲nix锛変负/
+ *
+ * @param c 瀛楃
+ * @return 鏄惁涓篧indows鎴栬匧inux锛圲nix锛夋枃浠跺垎闅旂
+ */
+ public static boolean isFileSeparator(char c)
+ {
+ return SLASH == c || BACKSLASH == c;
+ }
+
+ /**
+ * 涓嬭浇鏂囦欢鍚嶉噸鏂扮紪鐮
+ *
+ * @param response 鍝嶅簲瀵硅薄
+ * @param realFileName 鐪熷疄鏂囦欢鍚
+ * @return
+ */
+ public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
+ {
+ String percentEncodedFileName = percentEncode(realFileName);
+
+ StringBuilder contentDispositionValue = new StringBuilder();
+ contentDispositionValue.append("attachment; filename=")
+ .append(percentEncodedFileName)
+ .append(";")
+ .append("filename*=")
+ .append("utf-8''")
+ .append(percentEncodedFileName);
+
+ response.setHeader("Content-disposition", contentDispositionValue.toString());
+ }
+
+ /**
+ * 鐧惧垎鍙风紪鐮佸伐鍏锋柟娉
+ *
+ * @param s 闇瑕佺櫨鍒嗗彿缂栫爜鐨勫瓧绗︿覆
+ * @return 鐧惧垎鍙风紪鐮佸悗鐨勫瓧绗︿覆
+ */
+ public static String percentEncode(String s) throws UnsupportedEncodingException
+ {
+ String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
+ return encode.replaceAll("\\+", "%20");
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/ImageUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/ImageUtils.java
new file mode 100644
index 0000000..82e0adb
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/ImageUtils.java
@@ -0,0 +1,86 @@
+package com.zhentao.common.core.utils.file;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+import org.apache.poi.util.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * 鍥剧墖澶勭悊宸ュ叿绫
+ *
+ * @author ruoyi
+ */
+public class ImageUtils
+{
+ private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);
+
+ public static byte[] getImage(String imagePath)
+ {
+ InputStream is = getFile(imagePath);
+ try
+ {
+ return IOUtils.toByteArray(is);
+ }
+ catch (Exception e)
+ {
+ log.error("鍥剧墖鍔犺浇寮傚父 {}", e);
+ return null;
+ }
+ finally
+ {
+ IOUtils.closeQuietly(is);
+ }
+ }
+
+ public static InputStream getFile(String imagePath)
+ {
+ try
+ {
+ byte[] result = readFile(imagePath);
+ result = Arrays.copyOf(result, result.length);
+ return new ByteArrayInputStream(result);
+ }
+ catch (Exception e)
+ {
+ log.error("鑾峰彇鍥剧墖寮傚父 {}", e);
+ }
+ return null;
+ }
+
+ /**
+ * 璇诲彇鏂囦欢涓哄瓧鑺傛暟鎹
+ *
+ * @param key 鍦板潃
+ * @return 瀛楄妭鏁版嵁
+ */
+ public static byte[] readFile(String url)
+ {
+ InputStream in = null;
+ ByteArrayOutputStream baos = null;
+ try
+ {
+ // 缃戠粶鍦板潃
+ URL urlObj = new URL(url);
+ URLConnection urlConnection = urlObj.openConnection();
+ urlConnection.setConnectTimeout(30 * 1000);
+ urlConnection.setReadTimeout(60 * 1000);
+ urlConnection.setDoInput(true);
+ in = urlConnection.getInputStream();
+ return IOUtils.toByteArray(in);
+ }
+ catch (Exception e)
+ {
+ log.error("璁块棶鏂囦欢寮傚父 {}", e);
+ return null;
+ }
+ finally
+ {
+ IOUtils.closeQuietly(baos);
+ }
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/MimeTypeUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/MimeTypeUtils.java
new file mode 100644
index 0000000..8cff3db
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/file/MimeTypeUtils.java
@@ -0,0 +1,59 @@
+package com.zhentao.common.core.utils.file;
+
+/**
+ * 濯掍綋绫诲瀷宸ュ叿绫
+ *
+ * @author ruoyi
+ */
+public class MimeTypeUtils
+{
+ public static final String IMAGE_PNG = "image/png";
+
+ public static final String IMAGE_JPG = "image/jpg";
+
+ public static final String IMAGE_JPEG = "image/jpeg";
+
+ public static final String IMAGE_BMP = "image/bmp";
+
+ public static final String IMAGE_GIF = "image/gif";
+
+ public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" };
+
+ public static final String[] FLASH_EXTENSION = { "swf", "flv" };
+
+ public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
+ "asf", "rm", "rmvb" };
+
+ public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" };
+
+ public static final String[] DEFAULT_ALLOWED_EXTENSION = {
+ // 鍥剧墖
+ "bmp", "gif", "jpg", "jpeg", "png",
+ // word excel powerpoint
+ "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
+ // 鍘嬬缉鏂囦欢
+ "rar", "zip", "gz", "bz2",
+ // 瑙嗛鏍煎紡
+ "mp4", "avi", "rmvb",
+ // pdf
+ "pdf" };
+
+ public static String getExtension(String prefix)
+ {
+ switch (prefix)
+ {
+ case IMAGE_PNG:
+ return "png";
+ case IMAGE_JPG:
+ return "jpg";
+ case IMAGE_JPEG:
+ return "jpeg";
+ case IMAGE_BMP:
+ return "bmp";
+ case IMAGE_GIF:
+ return "gif";
+ default:
+ return "";
+ }
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ip/IpUtils.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ip/IpUtils.java
new file mode 100644
index 0000000..431b925
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/ip/IpUtils.java
@@ -0,0 +1,204 @@
+package com.zhentao.common.core.utils.ip;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import javax.servlet.http.HttpServletRequest;
+import com.zhentao.common.core.utils.StringUtils;
+
+/**
+ * 鑾峰彇IP鏂规硶
+ *
+ * @author ruoyi
+ */
+public class IpUtils
+{
+ public static String getIpAddr(HttpServletRequest request)
+ {
+ String ip = null;
+
+ // X-Forwarded-For锛歋quid 鏈嶅姟浠g悊
+ String ipAddresses = request.getHeader("X-Forwarded-For");
+ if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
+ {
+ // Proxy-Client-IP锛歛pache 鏈嶅姟浠g悊
+ ipAddresses = request.getHeader("Proxy-Client-IP");
+ }
+ if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
+ {
+ // WL-Proxy-Client-IP锛歸eblogic 鏈嶅姟浠g悊
+ ipAddresses = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
+ {
+ // HTTP_CLIENT_IP锛氭湁浜涗唬鐞嗘湇鍔″櫒
+ ipAddresses = request.getHeader("HTTP_CLIENT_IP");
+ }
+ if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
+ {
+ // X-Real-IP锛歯ginx鏈嶅姟浠g悊
+ ipAddresses = request.getHeader("X-Real-IP");
+ }
+
+ // 鏈変簺缃戠粶閫氳繃澶氬眰浠g悊锛岄偅涔堣幏鍙栧埌鐨刬p灏变細鏈夊涓紝涓鑸兘鏄氳繃閫楀彿锛,锛夊垎鍓插紑鏉ワ紝骞朵笖绗竴涓猧p涓哄鎴风鐨勭湡瀹濱P
+ if (ipAddresses != null && ipAddresses.length() != 0)
+ {
+ ip = ipAddresses.split(",")[0];
+ }
+
+ // 杩樻槸涓嶈兘鑾峰彇鍒帮紝鏈鍚庡啀閫氳繃request.getRemoteAddr();鑾峰彇
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
+ {
+ ip = request.getRemoteAddr();
+ }
+ return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
+ }
+
+ public static boolean internalIp(String ip)
+ {
+ byte[] addr = textToNumericFormatV4(ip);
+ return internalIp(addr) || "127.0.0.1".equals(ip);
+ }
+
+ private static boolean internalIp(byte[] addr)
+ {
+ if (StringUtils.isNull(addr) || addr.length < 2)
+ {
+ return true;
+ }
+ final byte b0 = addr[0];
+ final byte b1 = addr[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:
+ switch (b1)
+ {
+ case SECTION_6:
+ return true;
+ }
+ default:
+ return false;
+ }
+ }
+
+ /**
+ * 灏咺Pv4鍦板潃杞崲鎴愬瓧鑺
+ *
+ * @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;
+ }
+
+ public static String getHostIp()
+ {
+ try
+ {
+ return InetAddress.getLocalHost().getHostAddress();
+ }
+ catch (UnknownHostException e)
+ {
+ }
+ return "127.0.0.1";
+ }
+
+ public static String getHostName()
+ {
+ try
+ {
+ return InetAddress.getLocalHost().getHostName();
+ }
+ catch (UnknownHostException e)
+ {
+ }
+ return "鏈煡";
+ }
+}
diff --git a/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/poi/ExcelUtil.java b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/poi/ExcelUtil.java
new file mode 100644
index 0000000..488200f
--- /dev/null
+++ b/smart-common/smart-common-core/src/main/java/com/zhentao/common/core/utils/poi/ExcelUtil.java
@@ -0,0 +1,1027 @@
+package com.zhentao.common.core.utils.poi;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+import javax.servlet.http.HttpServletResponse;
+
+import com.zhentao.common.core.annotation.Excel;
+import com.zhentao.common.core.annotation.Excels;
+import com.zhentao.common.core.utils.reflect.ReflectUtils;
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.CellType;
+import org.apache.poi.ss.usermodel.ClientAnchor;
+import org.apache.poi.ss.usermodel.DataValidation;
+import org.apache.poi.ss.usermodel.DataValidationConstraint;
+import org.apache.poi.ss.usermodel.DataValidationHelper;
+import org.apache.poi.ss.usermodel.DateUtil;
+import org.apache.poi.ss.usermodel.Drawing;
+import org.apache.poi.ss.usermodel.FillPatternType;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
+import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
+import org.apache.poi.xssf.usermodel.XSSFDataValidation;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.zhentao.common.core.text.Convert;
+import com.zhentao.common.core.utils.DateUtils;
+import com.zhentao.common.core.utils.StringUtils;
+import com.zhentao.common.core.utils.file.FileTypeUtils;
+import com.zhentao.common.core.utils.file.ImageUtils;
+
+/**
+ * Excel鐩稿叧澶勭悊
+ *
+ * @author ruoyi
+ */
+public class ExcelUtil
+{
+ private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
+
+ /**
+ * Excel sheet鏈澶ц鏁帮紝榛樿65536
+ */
+ public static final int sheetSize = 65536;
+
+ /**
+ * 宸ヤ綔琛ㄥ悕绉
+ */
+ private String sheetName;
+
+ /**
+ * 瀵煎嚭绫诲瀷锛圗XPORT:瀵煎嚭鏁版嵁锛汭MPORT锛氬鍏ユā鏉匡級
+ */
+ private Excel.Type type;
+
+ /**
+ * 宸ヤ綔钖勫璞
+ */
+ private Workbook wb;
+
+ /**
+ * 宸ヤ綔琛ㄥ璞
+ */
+ private Sheet sheet;
+
+ /**
+ * 鏍峰紡鍒楄〃
+ */
+ private Map styles;
+
+ /**
+ * 瀵煎叆瀵煎嚭鏁版嵁鍒楄〃
+ */
+ private List list;
+
+ /**
+ * 娉ㄨВ鍒楄〃
+ */
+ private List