package com.mixsmart.utils;


import com.jfireel.expression.Expression;
import com.jfirer.baseutil.encrypt.Md5Util;
import com.mixsmart.constant.IMixConstant;
import com.mixsmart.exception.NullArgumentException;
import com.mixsmart.sort.ChinaNumSort;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;


/**
 * @Description:字符串处理工具类
 * @author:rock
 * @time:2020年4月21日 下午12:05:04
 * @version 1.0
 */
public class StringUtils {

	private StringUtils() {
		throw new UnsupportedOperationException("StringUtils类无法实例化"); 
	}

	private static final String CHARSET_NAME = "UTF-8";

	
	/**
	 * 判断是否为空
	 * @param value 内容
	 * @return 为空返回：true；否则返回：false
	 */
	public static boolean isEmpty(String value) {
		return (null==value || value.trim().length()==0);
	}

	/**
	 * @Description 批量判读为空
	 * @Param [values]
	 * @return boolean
	 * @Author yangyj
	 * @Date 2021.11.05 13:42
	 **/
	public static boolean isEmpty(Object ...values) {
			for(Object value:values){
				if(!isEmpty(value)){
					return false;
				}
			}
			return true;
	}

	
	/**
	 * 判断是否不为空
	 * @param value　内容
	 * @return 不为空返回：true；否则返回：false
	 */
	public static boolean isNotEmpty(String value) {
		return !isEmpty(value);
	}
	
	/**
	 * 判断参数；如果参数<code>value</code> 为空；
	 * 则抛出参数为空异常（运行时异常）
	 * @param value 需要判断的参数
	 * @param msg 提示信息
	 */
	public static void isAssert(Object value, String msg) {
		msg = isEmpty(msg)?"提供的参数为空":msg;
		if(null == value) {
			throw new NullArgumentException(msg);
		}
		if(value instanceof String) {
			if(isEmpty(value.toString())) {
				throw new NullArgumentException(msg);
			}
		} else if(value instanceof Collection) {
		    if(CollectionUtils.isEmpty((Collection<?>)value)) {
		        throw new NullArgumentException(msg);
		    }
		} else if(value.getClass().isArray()) {
		    if(ArrayUtils.isEmpty((Object[])value)) {
		        throw new NullArgumentException(msg);
		    }
		}
	}
	
	/**
	 * 判断值是否相等
	 * @param value1
	 * @param value2
	 * @return 相等返回：true；否则返回：false
	 */
	public static boolean isEquals(Object value1, Object value2) {
		boolean is = false;
		if(null != value1 && null != value2) {
			is = value1.toString().equals(value2.toString());
		} else if(null == value1 && null == value2) {
			is = true;
		}
		return is;
	}
	
	/**
	 * 判断值是否不相等
	 * @param value1
	 * @param value2
	 * @return 相等返回：true；否则返回：false
	 */
	public static boolean isNotEquals(Object value1, Object value2) {
		return !isEquals(value1, value2);
	}
	
	/**
	 * 判断值是否相等（不区分大小写）
	 * @param value1
	 * @param value2
	 * @return 相等返回：true；否则返回：false
	 */
	public static boolean isEqualsIgnoreCase(Object value1, Object value2) {
		boolean is = false;
		if(null != value1 && null != value1) {
			is = value1.toString().equalsIgnoreCase(value2.toString());
		} else if(null == value1 && null == value1) {
			is = true;
		}
		return is;
	}
	
	/**
	 * 判断值是否不相等（不区分大小写）
	 * @param value1
	 * @param value2
	 * @return 相等返回：true；否则返回：false
	 */
	public static boolean isNotEqualsIgnoreCase(Object value1, Object value2) {
		return !isEqualsIgnoreCase(value1, value2);
	}
	
	/**
	 * null转换为“”
	 * @param obj
	 * @return 返回处理后的结果
	 */
	public static String handleNull(Object obj) {
		if (null == obj) {
			return "";
		} else {
			return obj.toString().trim();
		}
	}
	
	/**
	 * 当值为null转化为“null”
	 * @param obj
	 * @return 返回处理后的结果
	 */
	public static String nullToStr(Object obj) {
		if (null == obj) {
			return "null";
		} else {
			return obj.toString().trim();
		}
	}
	
	/**
     * 对象转化为整型
     * <p>注：该方法已过时，请用{@link #handleObj2Integer(Object)} 代替</p>
     * @param obj
     * @return 返回转化结果
     */
	public static Integer handObj2Integer(Object obj) {
	    return handleObj2Integer(obj);
	}
	
	
	/**
	 * 对象转化为整型
	 * @param obj
	 * @return 返回转化结果
	 */
	public static Integer handleObj2Integer(Object obj) {
		if (null == obj) {
			return 0;
		} else {
			double value = 0;
			try {
			   value = Double.parseDouble(obj.toString());
			} catch (Exception ex) {
				value = 0;
			}
			return (int)value;
		}
	}


	/**
	 * @Description  对象转Double
	 * @Param [obj, scale]
	 * @return java.lang.Double
	 * @Author yangyj
	 * @Date 2022.04.20 14:15
	 **/
	public static Double obj2Double(Object obj,Object scale){
		if(StringUtils.isNumber(obj)){
			if(StringUtils.isNumber(scale)){
				obj=new BigDecimal(StringUtils.number2String(obj,scale));
			}
			BigDecimal big = new BigDecimal(obj.toString());
			return big.doubleValue();
		}
		return null;
	}
	public static Double obj2Double(Object obj){
		return obj2Double(obj,null);
	}
	/**
	 * 数字null转换为“0”
	 * @param obj
	 * @return 返回转化结果
	 */
	public static String handleNumNull(Object obj) {
		if (null == obj) {
			return "0";
		} else {
			return obj.toString().trim();
		}
	}
	
	/**
	 * 判断是否为数字(包括小数)
	 * @param value
	 * @return 数字返回：true；否则返回：false
	 */
	public static boolean isNum(Object value) {
		boolean is = false;
		if(value != null) {
			Pattern pattern = Pattern.compile("\\d+|\\d+\\.\\d+");
			Matcher matcher = pattern.matcher(value.toString());
			if(matcher.matches()) {
				is = true;
			} else {
				is = false;
			}
		}
		return is;
	}
	
	
	/**
	 * 判断是否数字整数
	 * @param value
	 * @return 是返回：true；否则返回：false
	 */
	public static boolean isInteger(String value) {
		boolean is = false;
		Pattern pattern = Pattern.compile("\\d+");
		if(null != value && value.length()>1) {
			pattern = Pattern.compile("^[1-9]\\d+");
		}
		Matcher matcher = pattern.matcher(value);
		if(matcher.matches()) {
			is = true;
		} else {
			is = false;
		}
		return is;
	} 
	
	/**
	 * 判断是否小数
	 * @param value
	 * @return 是返回：true；否则返回：false
	 */
	public static boolean isDecimal(String value) {
		boolean is = false;
		Pattern pattern = Pattern.compile("\\d+\\.\\d+");
		Matcher matcher = pattern.matcher(value);
		if(matcher.matches()) {
			is = true;
		} else {
			is = false;
		}
		return is;
	} 
	
	
	/**
	 * 随机生成数
	 * @param num 要生成随机数的个数
	 * @return 返回随机生成数
	 */
	public static String randomNum(int num) {
		Random random = new Random();
		String numStr = "";
		for (int i = 0; i < num; i++) {
			numStr += random.nextInt(10);
		}
		return numStr;
	}
	
	
	/**
	 * 按日期格式生成序列号
	 * @param dateFormaterStr 日期格式
	 * @return 返回序列号
	 */
	public static String createSerialNum(String dateFormaterStr) {
		String serialNum = null;
		if(isNotEmpty(dateFormaterStr)) {
			SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormaterStr);
			serialNum = dateFormatter.format(new Date());
			dateFormatter = null;
		}
		return serialNum;
	}
	
	
	/**
	 * 生成序列号；
	 * TODO 改为采用UUID生成序列号
	 * 生成的序列号；如：U+时间＋５位随机序列号
	 * 如:U141264925197606685
	 * @return 返回系统自动生成的序列号
	 */
	public static String createSerialNum() {
		/*long time = System.currentTimeMillis();
		return "U"+time+randomNum(5);*/
	    return uuid();
	}
	
	/**
	 * 生成UUID序列号
	 * @return 返回UUID
	 */
	public static String uuid() {
		String value = UUID.randomUUID().toString();
		value = value.replaceAll("-", "");
		return value.substring(0, 28);
	}

	public static String uuid(int max) {
		String value = UUID.randomUUID().toString();
		value = value.replaceAll("-", "");
		return value.substring(0, max);
	}

	/**
	 * 获取文件后缀
	 * @param fileName
	 * @return 返回文件后缀
	 */
	public static String getFileSuffix(String fileName) {
		int index = fileName.lastIndexOf(".");
		if(index != -1) {
			return fileName.substring(index + 1);
		}
		return "";
	}
	
	
	/**
	 * 去掉文件后缀
	 * @param fileName
	 * @return 返回文件后缀
	 */
	public static String trimFileSuffix(String fileName) {
		return fileName.substring(0,fileName.lastIndexOf("."));
	}
	
	
	/**
	 * 大写字母直接用下划线分割，并把大写转换为小写 <br />
	 * 如:HelloWorld转换为hello_world
	 * @param value
	 * @return 返回处理结果
	 */
	public static String upperSeparateUnderline(String value) {
		StringBuilder strBuilder = null;
		if(isNotEmpty(value)) {
		    strBuilder = new StringBuilder();
			byte[] values = value.getBytes();
			for (int i = 0; i < values.length; i++) {
				if(values[i]>=65 && values[i]<=90) {
					if(i>0 && i<(values.length-1)) {
					    strBuilder.append("_"+(char)((int)values[i]+32));
					} else {
					    strBuilder.append(String.valueOf((char)((int)values[i]+32)));
					}
				} else {
				    strBuilder.append(String.valueOf((char)values[i]));
				}
			}
			values = null;
		}
		return strBuilder != null ? strBuilder.toString() : null;
	}
	
	/**
	 * 首字母转为大写
	 * @param value
	 * @return 返回处理后的结果
	 */
	public static String firstToUppercase(String value) {
		if(isNotEmpty(value)) {
			String firstChar = value.substring(0, 1);
			String otherChar = value.substring(1);
			firstChar = firstChar.toUpperCase();
			value = firstChar+otherChar;
		}
		return value;
	}
	
	
	/**
	 * 过滤HTML标签.
	 * @param htmlContent
	 * @return 返回过滤后的结果
	 */
	public static String html2Text(String htmlContent) {
		if(isEmpty(htmlContent))
			return htmlContent;
		Pattern pScript, pStyle, pHtml; //定义规则
	    Matcher mScript, mStyle, mHtml; //匹配规则
	    
	    //定义script的正则表达式{或<script[^>]*?>[\\s\\S]*?<\\/script>
        String regExScript = "<[\\s]*?script[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?script[\\s]*?>"; 
        //定义style的正则表达式{或<style[^>]*?>[\\s\\S]*?<\\/style>
        String regExStyle = "<[\\s]*?style[^>]*?>[\\s\\S]*?<[\\s]*?\\/[\\s]*?style[\\s]*?>";
         //定义HTML标签的正则表达式
        String regExHtml = "<[^>]+>";
        
        //过滤script标签
        pScript = Pattern.compile(regExScript, Pattern.CASE_INSENSITIVE);
        mScript = pScript.matcher(htmlContent);
        htmlContent = mScript.replaceAll(""); 

        //过滤style标签
        pStyle = Pattern.compile(regExStyle, Pattern.CASE_INSENSITIVE);
        mStyle = pStyle.matcher(htmlContent);
        htmlContent = mStyle.replaceAll(""); 

        //过滤html标签
        pHtml = Pattern.compile(regExHtml, Pattern.CASE_INSENSITIVE);
        mHtml = pHtml.matcher(htmlContent);
        htmlContent = mHtml.replaceAll("");
	    
		return htmlContent;
	}
	
	
	/**
	 * 验证手机号码
	 * @param phoneNo
	 * @return 验证成功返回：true；否则返回：false
	 */
	public static boolean isPhoneNO(String phoneNo){
		Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");
		Matcher m = p.matcher(phoneNo);
		return m.matches();
	}
	
	
	/**
	 * 验证固定电话号码
	 * @param tel
	 * @return 验证成功返回：true；否则返回：false
	 */
	public static boolean isFixedTelephone(String tel) {
		Pattern p = Pattern.compile("^[0][0-9]{2,3}-[2-9][0-9]{6,7}(-[0-9]{1,4})?");
		Matcher m = p.matcher(tel);
		return m.matches();
	}
	
	
	/**
	 * 验证匿名
	 * @param anonymous
	 * @return 验证成功返回：true；否则返回：false
	 */
	public static boolean isAnonymous(String anonymous){
		Pattern p = Pattern.compile("^[\\u4e00-\\u9fa5|A-Za-z]([\\w|\\u4e00-\\u9fa5]){1,7}$");
		Matcher m = p.matcher(anonymous);
		return m.matches();
	}
	
	/**
	 * 验证汉字
	 * @param value
	 * @return 验证成功返回：true；否则返回：false
	 */
	public static boolean isChinese(String value){
		Pattern p = Pattern.compile("^[\\u4E00-\\u9FFF]+$");
		Matcher m = p.matcher(value);
		boolean is = m.matches();
		return is;
	}
	
	/**
	 * 验证正则表达式
	 * @param value
	 * @return 验证成功返回：true；否则返回：false
	 */
	public static boolean isCheckRegex(String value,String regex){
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(value);
		boolean is = m.matches();
		return is;
	}
	
	/**
	 * 验证QQ号码
	 * @param value
	 * @return 验证成功返回：true；否则返回：false
	 */
	public static boolean isQQ(String value) {
		Pattern p = Pattern.compile("^[1-9]\\d{6,11}$");
		Matcher m = p.matcher(value);
		return m.matches();
	}
	
	
	/**
	 * 验证email
	 * @param email
	 * @return 验证成功返回：true；否则返回：false
	 */
	public static boolean isEmail(String email) {
		Pattern p = Pattern.compile("^([a-zA-Z0-9]+[_|\\_|\\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\\_|\\.]?)*[a-zA-Z0-9]+\\.[a-zA-Z]{2,3}$");
		Matcher m = p.matcher(email);
		return m.matches();
	}
	
	/**
	 * 秒转化为:HH:mm:SS格式
	 * @param second
	 * @return 返回转化后的结果
	 */
	public static String secondToHHMMSS(long second){
		long h=0,m=0,s=0,tmp=0;
		if(second>=3600){
		   h= second/3600;
		   tmp = second%36000;
		   if(tmp>=60) {
			   m = tmp/60;
			   s = tmp%60;
		   }else {
		     s = tmp;
		   }
		}else if(second>=60){
		   m = second/60;
		   s = second%60;
		}else {
		   s = second;
		}
		return (h>9?h:"0"+h)+":"+(m>9?m:"0"+m)+":"+(s>9?s:"0"+s);
	 }
	
	
	/**
	 * 过滤特殊字符
	 * @param params
	 * @return 返回过滤后的结果
	 */
	public static String filterSQLParams(String params) {
		if(!isEmpty(params)) {
		    StringBuilder strBuilder = new StringBuilder();
		    strBuilder.append("'|\"|update|delete|select|drop|insert|=|;|0x|\\(|\\)|\\s|\\*|\\?|\\%|\\$");
		    strBuilder.append("|and|exec|execute|chr|mid|master|truncate|char|declare|sitename|net user|xp_cmdshell|or");
		    strBuilder.append("|\\+|,|like'|table|from|grant|use|group_concat|column_name|information_schema.columns");
		    strBuilder.append("|table_schema|union|where|order|by|count");
		    strBuilder.append("|--|,|like|//|/|#");
		    String params1 = params.toLowerCase();

		    params1 = params1.replaceAll(strBuilder.toString(), "");
		    if("".equals(params1)&&!"''".equals(params)){
		    	params = params1;
		    }
			params = params.replaceAll("&", "&amp");
			params = params.replaceAll("<", "&lt");
			params = params.replaceAll(">", "&gt");	
		}
		return params;
	}
	
	/**
	 * 根据regex分隔字符串
	 * 然后用逗号","重组
	 * @param ids
	 * @param regex
	 * @return 返回处理后的结果
	 */
	public static String splitIds(String ids,String regex){
		String newIds = "";
		if(isNotEmpty(ids)) {
			String[] idsArr = ids.split(regex);
			for (int i = 0; i < idsArr.length; i++) {
				if(i != (idsArr.length-1)) {
					newIds += "'"+idsArr[i]+"',";
				} else {
					newIds += "'"+idsArr[i]+"'";
				}
			}
		}
		return newIds;
	}
	
	
	/**
	 * 计算出文件大小
	 * @param size
	 * @return 返回处理后的结果;<br />
	 * 格式为："100 KB"或”100 M“或”100 G“
	 */
	public static String fileSize(long size) {
		DecimalFormat df = new DecimalFormat("0.0#");
		long KB = 1024;
		long MB = KB*1024;
		long GB = MB*1024;
		String valueStr = null;
		if(size<0) {
			valueStr = "0 KB";
		} else if(size<KB*1024) {
			double value = (double)size/KB;
			valueStr = df.format(value)+" KB";
		} else if(size<MB*1024) {
			double value = (double)size/MB;
			valueStr = df.format(value)+" M";
		} else {
			double value = (double)size/GB;
			valueStr = df.format(value)+" G";
		}
		df = null;
		return valueStr;
	}
	
	
	/**
	 * 过滤目录结构(防止参数传递目录结构)
	 * @param value
	 * @return 返回过滤后的结果
	 */
	public static String filterFilePath(String value) {
		if(!StringUtils.isEmpty(value)) {
			value.replaceAll("\\.|/|\\\\\\\\|\\\\|:|%2F|%2E|25%|20%|%5C|60%|27%|%3A|%2A","");
		}
	    return value;
	}
	
	/**
	 * 判断是否含有contain指定的值
	 * @param value
	 * @param contain
	 * @return 包含返回：true；否则返回：false
	 */
	public static boolean isContains(String value,String contain) {
		boolean is = false;
		if(!isEmpty(value) && null != contain) {
			is = value.indexOf(contain)>-1?true:false;
		}
		return is;
	}
	
	
	/**
	 * list转换为数组
	 * @param values
	 * @return 返回转化结果
	 */
	public static String[] list2Array(Collection<String> values) {
		String[] valueArray = null;
		if(null != values && values.size()>0) {
			valueArray = new String[values.size()];
			values.toArray(valueArray);
		}
		return valueArray;
	}
	
	/**
	 * 验证IP地址
	 * @param ip
	 * @return 验证成功返回：true；否则返回：false
	 */
	public static boolean checkIp(String ip) {
		boolean is = false;
		String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\."
                + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\."
                + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$";
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(ip);
		if(matcher.matches()) {
			is = true;
		}
		return is;
	}
	
	
	/**
	 * 集合转换为字符串，字符串之间用separater提供的参数分隔
	 * @param values
	 * @param separater
	 * @return 返回处理后的结果
	 */
	public static <T> String collection2String(Collection<T> values,String separater) {
	    StringBuilder strBuilder = null;
		if(null != values && values.size()>0) {
		    strBuilder = new StringBuilder();
			if(isEmpty(separater)) {
				separater = "";
			}
			for (T value : values) {
			    strBuilder.append(StringUtils.handleNull(value) + separater);
			}
			if(isNotEmpty(separater)) {
			    strBuilder.delete(strBuilder.length()-1, strBuilder.length());
			}
		}
		return strBuilder != null ? strBuilder.toString():null;
	}
	
	
	/**
	 * 替换多个空格、换行、回车、tab符等为一个空格
	 * @param value 预处理的字符串
	 * @return 返回处理后的字符串
	 */
	public static String removeMultiSpace(String value) {
		if(StringUtils.isNotEmpty(value)) {
			value = value.replaceAll("\\s+|\n|\r|\n|\t", " ");
		}
		return value;
	}
	
	/**
	 * 替换特殊字符
	 * @param value 预处理的字符串
	 * @return 返回处理后的结果
	 */
	public static String repaceSpecialChar(String value) {
		if(isNotEmpty(value)) {
			value = value.replaceAll("\r|\n|\t", "");
		}
		return value;
	}

	public static String changeQuotation (String value) {
		if(isNotEmpty(value)) {
			value = value.replaceAll("'", "\\\\u0027");
		}
		return value;
	}
	/**
	 * 替换斜杠
	 * @param value
	 * @return 返回处理后的结果
	 */
	public static String repaceSlash(String value) {
		if(isNotEmpty(value)) {
			//value = value.replaceAll("\\\\", "\\\\\\\\\\\\\\\\");
			value = value.replaceAll("\\\\", "\\\\\\\\");
			value = value.replaceAll("`", "\\\\`");
			value = value.replaceAll("'", "\\\\`");
		}
		return value;
	}

	/**
	 * 替换斜杠
	 * @param value
	 * @return 返回处理后的结果
	 */
	public static String repaceSlashCopyTable(String value) {
		if(isNotEmpty(value)) {
			//value = value.replaceAll("\\\\", "\\\\\\\\\\\\\\\\");
			//value = value.replaceAll("\\\\", "\\\\\\\\");
			value = value.replaceAll("`", "\\\\`");
		}
		return value;
	}

	/**
	 * 去空格
	 * @param value
	 * @return 返回处理后的结果
	 */
	public static String repaceBlank(String value) {
		if(isNotEmpty(value)) {
			value = value.replaceAll("\\s", "");
		}
		return value;
	}
	
	/**
	 * 字符串转换为list
	 * @param value 要转换的字符串
	 * @param separater 分隔符
	 * @return 返回转换后的List
	 */
	public static List<String> string2List(String value, String separater) {
		List<String> lists = null;
		if(isNotEmpty(value)) {
			separater = isEmpty(separater)?",":separater;
			String[] array = value.split(separater);
			lists = Arrays.asList(array);
		}
		return lists;
	}
	
	/**
     * 字符串转换为Set
     * @param value 要转换的字符串
     * @param separater 分隔符
     * @return 返回转换后的Set
     */
    public static Set<String> string2Set(String value, String separater) {
        Set<String> sets = null;
        if(isNotEmpty(value)) {
            separater = isEmpty(separater) ? "," : separater;
            String[] array = value.split(separater);
            sets = new HashSet<String>();
            sets.addAll(Arrays.asList(array));
        }
        return sets;
    }
	
	/**
	 * 含有中文数字的排序（比较两值）
	 * @param value1
	 * @param value2
	 * @return 返回比较结果
	 */
	public static int chinaNumSort(String value1, String value2) {
		//判断同一个位置是否含有中文数字
		return ChinaNumSort.getIntance().sort(value1, value2);
	}
	
	/**
	 * 处理URL参数；
	 * 判断 <code>url</code> 中是否有“?”；
	 * 如果有则会在 <code>url</code> 后面加“&”，没有则加“?”
	 * @param url URL字符串
	 * @return 返回处理后的URL
	 */
	public static String handleUrlParam(String url) {
	    if(isEmpty(url)) {
	        return url;
	    }
	    StringBuilder urlBuilder = new StringBuilder(url);
	    if(url.indexOf("?") == -1) {
	        urlBuilder.append("?");
	    } else {
	        urlBuilder.append("&");
	    }
	    return urlBuilder.toString();
	}

	/**
	 * 处理路径；判断路径后是否有"/"；如果没有则加上，如果有则不处理
	 * @param path 路径
	 * @return 返回处理后的路径
	 */
	public static String handlePath(String path) {
		if(isEmpty(path)) {
			return path;
		}
		if(!path.endsWith("/")) {
			path = path + "/";
		}
		return path;
	}
	
	/**
	 * 如果值为空“”转换为NULL
	 * @param value
	 * @return
	 */
	public static String empty2Null(String value) {
	    return isEmpty(value) ? null : value;
	}
	
	/**
	 * 移除多值，只获取第一个值；多值之间通过英文逗号分隔
	 * @param value 需要处理的值
	 * @return 返回处理后的值
	 */
	public static String removeMultiValue(String value) {
	    if(isEmpty(value)) {
	        return value;
	    }
	    int p = value.indexOf(IMixConstant.MULTI_VALUE_SPLIT);
	    if(p >= 0) {
	        value = value.substring(0, p);
	    }
	    return value;   
	}

	/**
	 *  @author: willSir
	 *  @Date:  2020/8/17 - 13:57
	 *  @Description:  根据分隔符移除多余值
	 *
	 */
	public static String removeMultiValueBySplit(String value,String removeStr,String split) {
		if(isEmpty(value)||isEmpty(removeStr)) {
			return value;
		}
		int p = value.indexOf(split);
		if(p >= 0) {
			String[] valueAarry = value.split(split);
			String[] removeStrAarry = removeStr.split(split);
	 		List<String> asList = Arrays.asList(valueAarry);
	 		List<String> valueAarryList = new ArrayList();
	 		for (String v:asList){valueAarryList.add(v);}
			for (int i = 0; i < removeStrAarry.length; i++) {
				if(valueAarryList.contains(removeStrAarry[i])){
					valueAarryList.remove(removeStrAarry[i]);
				}
			}
			StringBuilder stringBuffer = new StringBuilder();
			for (int i = 0; i < valueAarryList.size(); i++) {
				stringBuffer.append(valueAarryList.get(i));
				if(i!=valueAarryList.size()-1){
					stringBuffer.append(split);
				}
			}
			value = stringBuffer.toString();
		}
		return value;
	}

	/**
	 * 数组转化为字符串；
	 * 如果<code>separate</code>为空，则采用默认值；默认值为：{@link IMixConstant#MULTI_VALUE_SPLIT}
	 * @param objs 数组
	 * @param separate 分隔符
	 * @return 返回数组转化成功后的字符串;失败返回：null
	 */
	public static String arrayToString(Object[] objs,String separate) {
		StringBuilder strBuff = null;
		if(null == objs || objs.length == 0) {
			return null;
		}
		if(StringUtils.isEmpty(separate)) {
			separate = IMixConstant.MULTI_VALUE_SPLIT;
		}
		strBuff = new StringBuilder();
		for (int i=0;i<objs.length;i++) {
			if(i < objs.length-1 ) {
				strBuff.append(String.valueOf(objs[i]) + separate);
			} else {
				strBuff.append(String.valueOf(objs[i]));
			}
		}//for
		objs = null;
		return (null != strBuff)?strBuff.toString():null;
	}


	/**
	 * 字符串转化为数组；
	 * 如果<code>separate</code>为空，则采用默认值；默认值为：{@link IMixConstant#MULTI_VALUE_SPLIT}
	 * @param value 原字符串
	 * @param separate 分隔符
	 * @return 返回字符串分割成功后的数组
	 */
	public static String[] stringToArray(String value, String separate) {
		String[] array = null;
		if(isEmpty(separate)) {
			separate = IMixConstant.MULTI_VALUE_SPLIT;
		}
		if(isNotEmpty(value)) {
			array = value.split(separate);
		}
		value = null;
		return array;
	}


	/**
	 * 按separate分离成数组,判断该数组里面是否包含subStr；
	 * 如果<code>separate</code>为空，则采用默认值；默认值为：{@link IMixConstant#MULTI_VALUE_SPLIT}
	 * @param str 字符串
	 * @param subStr 子字符串
	 * @param separate 分隔符
	 * @return 包含返回：true；否则返回：false
	 */
	public static boolean isArrayContains(String str,String subStr,String separate) {
		if(isEmpty(str)) {
			return isEmpty(subStr);
		}
		if(null == subStr) {
			return true;
		}
		boolean is = false;
		if(isEmpty(separate)) {
			separate = IMixConstant.MULTI_VALUE_SPLIT;
		}
		String[] strArray = str.split(separate);
		for (int i = 0; i < strArray.length; i++) {
			if(subStr.equals(strArray[i].trim())) {
				is = true;
				break;
			}
		}//for
		return is;
	}

	/**
	 * 填补位数；如果<code>fillText</code>为空，则默认填充内容为“0”
	 * @param value 需要填补的值
	 * @param num 需要填补的位数
	 * @param fillText 填充内容
	 * @return 返回处理后的值
	 */
	public static String supplementDigit(String value, int num, String fillText) {
		if(isEmpty(value)) {
			return value;
		}
		if(value.length() >= num) {
			return value;
		}
		if(isEmpty(fillText)) {
			fillText = "0";
		}
		StringBuilder stringBuilder = new StringBuilder();
		int fillNum = num - value.length();
		for(int i = 0; i < fillNum; i++) {
			stringBuilder.append(fillText);
		}
		stringBuilder.append(value);
		return stringBuilder.toString();
	}

	/**
	 * 判断对象是否为空，或转换为字符串后的值是否为空
	 * @param value 需要判断的值
	 * @return 为空（null或“”）返回true；否则返回false
	 */
	public static boolean isEmpty(Object value) {
		if(null == value) {
			return true;
		} else {
			return isEmpty(handleNull(value));
		}
	}

	/**
	 * 判断对象是否不为空；
	 * @param value 需要判断的值
	 * @return 如果不为空返回true；否则返回false
	 */
	public static boolean isNotEmpty(Object value) {
		return !isEmpty(value);
	}

	/**
	 * @Description 批量非空校验
	 * @Param [values]
	 * @return boolean
	 * @Author yangyj
	 * @Date 2021.10.19 17:04
	 **/
	public static boolean isNotEmpty(Object ...values) {
		for(Object value:values){
			if(isEmpty(value)){
				return false;
			}
		}
		return true;
	}
	
	/**
	 * HTML转义(解码) <br />
	 * 引入了StringEscapeUtils类
	 * @param value
	 * @return 返回处理后的结果
	 */
//	public static String unescapeHtml(String value) {
//		if(!isEmpty(value)) {
//			value = StringEscapeUtils.unescapeHtml4(value);
//		}
//		return value;
//	}
	
	/**
	 * HTML转义(编码) <br />
	 * 引入了StringEscapeUtils类
	 * @param value
	 * @return 返回处理后的结果
	 * 
	 */
//	public static String escapeHtml(String value) {
//		if(!isEmpty(value)) {
//			value = StringEscapeUtils.escapeHtml4(value);
//			value = value.replaceAll(" ", "&nbsp;");
//			value = value.replaceAll("\r\n|\n", "<br />");
//		}
//		return value;
//	}
	
	/**
	 * 判断是否为数字，包括小数、负数
	 * @param value
	 * @return
	 * @author:rock
	 * @time:2020年4月15日 上午10:46:15
	 */
	public static boolean isNumber(Object value) {
		if(isEmpty(value)){
			return  false;
		}
		if(value instanceof  Number){
			return true;
		}
		String pattern = "^[+-]?\\d+(\\.\\d+)?$";
		Pattern r = Pattern.compile(pattern);
		Matcher m = r.matcher(String.valueOf(value));
		return m.matches();
	}
	/**
	 * @Description
	 * @Param [obj] 对象转成map集合
	 * @return java.util.Map<java.lang.String,java.lang.Object>
	 * @Author yangyj
	 * @Date 2021.05.27 14:33
	 **/
	public static Map<String, Object> objectToMap(Object obj)  {
		Map<String, Object> map = new HashMap<String,Object>();
		try {
			Class<?> clazz = obj.getClass();
			for (Field field : clazz.getDeclaredFields()) {
				field.setAccessible(true);
				if(Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers())) {
					continue;
				}
				String fieldName = field.getName();
				Object data =field.get(obj);
				Object toStrValue = handleNull(data);
				if(isNotEmpty(toStrValue)){
					if(data.getClass().isArray()){
						if(ArrayUtils.isNotEmpty((String[])data)){
							map.put(fieldName,data);
						}
					}else {
						map.put(fieldName,data);
					}
				}

			}
		}catch (Exception e){
			e.printStackTrace();
		}
		return map;
	}

	/**
	 * @Description 包含空字段
	 * @Param [obj] 对象转成map集合
	 * @return java.util.Map<java.lang.String,java.lang.Object>
	 * @Author yangyj
	 * @Date 2021.05.27 14:33
	 **/
//	public static Map<String, Object> objectToMapNull(Object obj)  {
//		Map<String, Object> map = new HashMap<String,Object>();
//		try {
//			Class<?> clazz = obj.getClass();
//			for (Field field : clazz.getDeclaredFields()) {
//				field.setAccessible(true);
//				if(Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers())) {
//					continue;
//				}
//				String fieldName = field.getName();
//				Object data =field.get(obj);
//				Object toStrValue = handleNull(data);
//				if(isNotEmpty(toStrValue)&&data.getClass().isArray()){
//					if(ArrayUtils.isNotEmpty((String[])data)){
//						map.put(fieldName,data);
//					}
//				}else if(isNotEmpty(toStrValue)&&data instanceof Date){
//					map.put(fieldName, DateUtil.dateToStr((Date) data,"yyyy-MM-dd HH:mm:ss"));
//				}else {
//					map.put(fieldName,toStrValue);
//				}
//			}
//		}catch (Exception e){
//			e.printStackTrace();
//		}
//		return map;
//	}

	/**
	 * @Description 返回字符串后n个字符
	 * @Param [str, n]
	 * @return java.lang.String
	 * @Author yangyj
	 * @Date 2021.08.06 16:31
	 **/
    public static String tail(String str,int n){
		if(isNotEmpty(str)&&str.length()>=n){
			return  str.substring(str.length()-n);
		}else {
			return str;
		}
	}
	/**
	 * @Description list转字符串
	 * @Param [list, split：分隔符]
	 * @return java.lang.String
	 * @Author yangyj
	 * @Date 2021.08.06 17:11
	 **/
	public static String join(List<String>list,String split){
           StringBuilder sb = new StringBuilder("");
          if(ListUtils.isNotEmpty(list)){
          	  for(String str:list){
          	  	if(StringUtils.isNotEmpty(str)){
          	  		sb.append(str).append(split);
				}
			  }
          	  if(sb.length()>0&&isNotEmpty(split)){
          	  	sb.delete(sb.length()-split.length(),sb.length());
			  }
		  }
          return sb.toString();
	}

	public static String join(List<String>list){
	   return join(list,null);
	}
	public static String join(Object ...args){
		if(args!=null){
			 if(args.length>2){
			 	List<String> list =Arrays.stream(args).limit(args.length - 1).map(StringUtils::handleNull).collect(Collectors.toList());
			 	String split=handleNull(args[args.length-1]);
			 	return  join(list,split);
			 }else{
			 	return handleNull(args[0]);
			 }
		}else {
			return "";
		}
	}




	/**
	 * @Description 获取实体映射所有表字段名
	 * @Param [clazz]
	 * @return java.util.List<java.lang.String>
	 * @Author yangyj
	 * @Date 2021.08.18 11:05
	 **/
//	public static Map<String,String> getFiledAnnotate(Class<?> clazz) {
//		LinkedHashMap<String,String> names = new LinkedHashMap<>();
//		Field[] fields = clazz.getDeclaredFields();
//		Method[] methods=clazz.getMethods();
//		for (Field field:fields) {
//			field.setAccessible(true);
//			if(field.isAnnotationPresent(Column.class)) {
//				names.put(field.getDeclaredAnnotation(Column.class).name(),isEquals(field.getType().toString(),String.class)?"''":"null");
//			}
//		}
//		for (Method m:methods) {
//			m.setAccessible(true);
//			if(m.isAnnotationPresent(Column.class)) {
//				names.put(m.getDeclaredAnnotation(Column.class).name(),isEquals(m.getReturnType().toString(),String.class)?"''":"null");
//			}
//		}
//		return  names;
//	}

	/**
	 * @Description 只查询出指定字段内容
	 * @Param [clazz, fields]
	 * @return java.lang.String
	 * @Author yangyj
	 * @Date 2021.08.18 11:18
	 **/
//	public static String selectFieldsBuilder(Class<?>clazz,String ...fields){
//		StringBuilder sb = new StringBuilder();
//		Map<String,String> fieldsNames=getFiledAnnotate(clazz);
//		if(MapUtils.isNotEmpty(fieldsNames)){
//			if(ArrayUtils.isEmpty(fields)){
//				sb.append(" * ");
//			}else{
//				HashSet<String> keys = new HashSet<>(Arrays.asList(fields));
//				for(Map.Entry<String,String> entry:fieldsNames.entrySet()){
//					 if(!keys.contains(entry.getKey())){
//						 sb.append(entry.getValue()).append(" as ");
//					 }
//					sb.append(entry.getKey()).append(",");
//				}
//				if(sb.lastIndexOf(",")==sb.length()-1){
//					sb.deleteCharAt(sb.length()-1);
//				}
//			}
//		}
//		return sb.toString();
//	}
	public static String toString(byte[] bytes) {
		try {
			return new String(bytes, CHARSET_NAME);
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}
	

	/**
	 * @Description  返回保留指定小数位数字字符串
	 * @Param [number, scale]
	 * @return java.lang.String
	 * @Author yangyj
	 * @Date 2021.10.15 10:35
	 **/
   public static String number2String(Object number, Object scale){
		if(isNumber(number)){
			if(isEmpty(scale)){
				scale=0;
			}
			return  new BigDecimal(handleNull(number)).setScale(handleObj2Integer(scale),BigDecimal.ROUND_HALF_UP).toString();
		}
        return "";
   }

	/**
	 * @Description byte数组转Md5字符串
	 * @Param [bytes]
	 * @return java.lang.String
	 * @Author yangyj
	 * @Date 2021.12.20 17:10
	 **/
   public static  String bytes2Md5(byte[] bytes){

	   StringBuffer sb = new StringBuffer("");
	   byte b[] = Md5Util.md5(bytes);
	   int d;
	   for (int i = 0; i < b.length; i++) {
		   d = b[i];
		   if (d < 0) {
			   d = b[i] & 0xff;
			   // 与上一行效果等同
			   // i += 256;
		   }
		   if (d < 16)
			   sb.append("0");
		   sb.append(Integer.toHexString(d));
	   }
	   return sb.toString();
   }

	/**
	 * 转换为字节数组
	 * @param str
	 * @return
	 */
	public static byte[] getBytes(String str){
		if (str != null){
			try {
				return str.getBytes(CHARSET_NAME);
			} catch (UnsupportedEncodingException e) {
				return null;
			}
		}else{
			return null;
		}
	}



	/**
	 * @Description 获取最大小数位
	 * @Param [number]
	 * @return int
	 * @Author yangyj
	 * @Date 2021.12.23 15:08
	 **/
//	public  static Integer getScale(Object ...number){
//		int max=0;
//        for(Object n:number){
//        	if(StringUtils.isNotEmpty(n)){
//        		String[] sa = n.toString().split(",");
//                for(String s:sa){
//                	Matcher m = ReportUtils.matcher("(\\d)+.(\\d)+",s);
//                	if(m.find()){
//						max=Math.max(new StringBuilder(m.group()).reverse().toString().indexOf("."),max);
//					}
//				}
//			}
//		}
//        return max;
//	}

	/**
	 *
	 * @param name
	 * @param suffix
	 * @param splitStr
	 * @return
	 */
	public static String addSuffixInFirst(String name ,String suffix,String splitStr) {
		String newName = name;
		if (isEmpty(name)) {
			return newName;
		}

		int idx = name.indexOf(splitStr);
		if (idx > 0) {
			String templateName = name.substring(0,idx);
			String templateNameNew = templateName +  suffix;
			newName = templateNameNew + name.substring(idx);
		}
		return  newName;
	}

	public static String replaceSuffixInFirst(String name ,String suffix,String splitStr){
		String newName = name;
		if (isEmpty(name)) {
			return newName;
		}

		int idx = name.indexOf(splitStr);
		if (idx > 0) {
			String templateName = name.substring(0,idx);
			newName = newName.replace(templateName, suffix);
		}
		return  newName;
	}

	/**
	 * @Description 匹配度
	 * @Param [a, b]
	 * @return boolean
	 * @Author yangyj
	 * @Date 2022.03.24 17:40
	 **/
   public  static  boolean suitability(String a,String b){
		if(StringUtils.isNotEmpty(a,b)){
			char[] bA=b.toCharArray();
			if(a.length()>=bA.length){
				for (char c : bA) {
					if (!a.contains(String.valueOf(c))) {
						return false;
					}
				}
				return true;
			}
		}
		return false;
   }



	/*public static void main(String[] args) {
   	    Map<String,Object> map = new HashMap<>();
   	    map.put("yang",10);
		map.put("a",-10);
		List<String> list = Arrays.asList("1","12.6","856");
		System.out.println(Expression.parse("a+6*yang").calculate(map).toString());

	}*/



}
