Browse Source

Merge branch 'master' of http://web.jzdsh.com:3000/jzdsh/auto

EDZ 4 years ago
parent
commit
07d2b3c395

+ 78 - 0
code/auto/model/src/main/java/com/jzdsh/util/Api.java

@@ -0,0 +1,78 @@
+package com.jzdsh.util;
+
+/**
+ * @author hugeng
+ * @date 2018/12/5 13:50
+ */
+public class Api< T > {
+
+    private static final String CODE_OK = "200";
+    private static final String CODE_FAIL = "400";
+
+    /**
+     * 提示信息
+     */
+    private String code;
+    /**
+     * 提示信息
+     */
+    private String msg;
+    /**
+     * 返回的数据
+     */
+    private T data;
+    /**
+     * 是否成功
+     */
+    private Boolean is;
+
+    public Api( ) {
+    }
+    public Api(boolean is, String code, String msg, T data) {
+        this.msg = msg;
+        this.code = code;
+        this.data = data;
+        this.is = is;
+    }
+
+    public static Api ok(Object data) {
+        return new Api(true, Api.CODE_OK,"server access successful",data);
+    }
+
+    public static Api fail(Object data) {
+        return new Api(false, Api.CODE_FAIL,"server access failed",data);
+    }
+
+
+    public String getMsg( ) {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public T getData( ) {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    public Boolean getIs( ) {
+        return is;
+    }
+
+    public void setIs(Boolean is) {
+        this.is = is;
+    }
+
+    public String getCode( ) {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+}

+ 237 - 0
code/auto/model/src/main/java/com/jzdsh/util/CommonCons.java

@@ -0,0 +1,237 @@
+package com.jzdsh.util;
+
+/**
+ * @description: 基本数据常量工具常
+ * @author: lc
+ * @create 2019-08-14  13:58
+ */
+public class CommonCons {
+
+
+    private static String project_name = "/nvrnetwork";
+
+
+    public static final String ZERO = "0";
+    public static final String ONE = "1";
+    public static final String TWO = "2";
+    public static final String BRACKETS = "[]";
+    public static final String UNDEFINED = "undefined";
+
+    public static final String SYSTEM_MESSAGE = "系统消息";
+    public static final String SYSTEM_MESSAGE_PAY_SUCCESS = "恭喜您,付款成功!";
+    public static final String SYSTEM_MESSAGE_RENEW_SUCCESS = "恭喜您,续费成功!";
+    public static final String SYSTEM_MESSAGE_NEW_USER = "恭喜您成为我们平台的新用户!";
+
+
+    public static final String SYSTEM_EXCEPTION = "系统异常!";
+
+
+    public static final String PICTURE_UPLOAD_SUCCESS = "图片上传成功!";
+
+
+    //项目名
+    public static final String ADMIN_PROJECT_NAME = project_name;
+    public static final String PROJECT_NAME = project_name;
+
+
+    //默认角色 车主
+    public static final Integer ROLE_ZERO = 0;
+    //商家类型 1服务商 2经销商
+    public static final Integer ROLE_ONE = 1;
+    public static final Integer ROLE_TWO = 2;
+
+    //serviceCategory 层级
+    public static final Integer LEVEL_ONE = 1;
+    public static final Integer LEVEL_TWO = 2;
+    public static final Integer LEVEL_THREE = 3;
+
+    //用户状态 0 未认证
+    public static final String USER_INFO_STATUS_ZERO = "0";
+    public static final String USER_INFO_STATUS_ONE = "1";
+
+
+    //---------------------------------------provider--------------------------------------
+
+    //服务类型
+    public static final String SERVICE_CATEGORY_STATUS_ONE = "1";  //一级类
+    public static final String SERVICE_CATEGORY_STATUS_TWO = "2";  // 二级分类
+    public static final String SERVICE_CATEGORY_STATUS_THREE = "3";  //    三级分类
+
+    //服务商 认证状态 0 未认证 1已认证(店铺认证)
+    public static final String PROVIDER_STATUS_ZERO = "0";
+    public static final String PROVIDER_STATUS_ONE = "1";
+
+    //该店铺是否在使用 0 未认领 1已认领(认领店铺)
+    public static final String PROVIDER_IS_USE_ZERO = "0";
+    public static final String PROVIDER_IS_USE_ONE = "1";
+
+    //该店铺是否推荐 0否  1推荐
+    public static final String PROVIDER_IS_HOT_ZERO = "0";
+    public static final String PROVIDER_IS_HOT_ONE = "1";
+    /**
+     * 服务类型
+     * 1:大类,2:二类,3:小类
+     */
+    public static final String CATEGORY_TPYE_ONE = "1";
+    public static final String CATEGORY_TPYE_TWO = "2";
+    public static final String CATEGORY_TPYE_THREE = "3";
+
+    //界面服务项目显示9条信息
+    public static final String CATEGORY_PAGE_NUMBER_ZERO = "0";
+    public static final String CATEGORY_PAGE_SIZE_NINE = "9";
+
+    //搜索默认 页码  显示 数量
+    public static final Integer PAGE_NUMBER = 1;
+    public static final Integer PAGE_SIZE = 15;
+
+
+    //服务商入住图片上传路径
+    public static final String PICTURE_AUTHENTICATION = "picture/authentication";
+    //服务项目 封面图片上传
+    public static final String PICTURE_SERVICE_ITEM = "picture/service_item";
+
+    //log图上传路径
+    public static final String LOG_PICTURE = "picture/log";
+    //banner图片上传路径
+    public static final String BANNER_PICTURE = "picture/banner";
+    //photos图册上传路径
+    public static final String PHOTOS_PICTURE = "picture/photos";
+
+    //采购单 图片上传路径
+    public static final String DEMAND_PICTURE = "picture/demand";
+
+
+    //vin 码 图
+    public static final String PICTURE_VIN = "picture/vin";
+
+
+    /**
+     * banner 图片显示位置
+     * 1 顶部,2腰部 ,3尾部(类详情)
+     */
+    public static final String BANNER_POSITION_ONE = "1";
+    public static final String BANNER_POSITION_TWO = "2";
+    public static final String BANNER_POSITION_THREE = "3";
+
+    /**
+     * 车系 series
+     */
+    // 1 车系/欧系.. ,2 品牌
+    public static final String SERIES_STATUS_ONE = "1";
+    public static final String SERIES_STATUS_TWO = "2";
+
+    /**
+     * authentication
+     * 认证 状态  0 审核中 1 未通过 2通过
+     */
+    public static final String AUTHENTICATION_STATUS_ZERO = "0";
+    public static final String AUTHENTICATION_STATUS_ONE = "1";
+    public static final String AUTHENTICATION_STATUS_TWO = "2";
+
+    //authentication 是否付款  0否 1是
+    public static final String AUTHENTICATION_ISPAY_ZERO = "0";
+    public static final String AUTHENTICATION_ISPAY_ONE = "1";
+    //authentication 是否处理  0未 1是
+    public static final String AUTHENTICATION_DEAL_ZERO = "0";
+    public static final String AUTHENTICATION_DEAL_ONE = "1";
+
+    /**
+     * mall 商城管理
+     */
+    // 0 未审核  1 已审核
+    public static final String MALL_STATUS_ZERO = "0";
+    public static final String MALL_STATUS_ONE = "1";
+
+    //order 订单状态 0 未支付,1已支付
+    public static final String ORDER_STATUS_ZERO = "0";
+    public static final String ORDER_STATUS_ONE = "1";
+
+    /**
+     * 商家
+     * 默认 logo
+     * 默认 banner
+     */
+    public static final String DEFAULT_STORE_LOGO = "/nvrnetwork/static/imgs/logo_store.jpg";
+    public static final String DEFAULT_STORE_BANNER = "/nvrnetwork/static/imgs/banner_store.jpg";
+
+    /**
+     * 地址纠错
+     */
+    //地址纠错上传图片
+    public static final String ADDRESS_CORRECTION_PICTURE = "picture/address_correction";
+    //状态 0 未解决 1 已解决
+    public static final String ADDRESS_CORRECTION_STATUS_ZERO = "0";
+    public static final String ADDRESS_CORRECTION_STATUS_ONE = "1";
+
+    /**
+     * 车主服务
+     */
+    //是否推荐 推荐首页展示  0否 1是
+    public static final String OWNER_SERVICE_RECOMMENDATION_ZERO = "0";
+    public static final String OWNER_SERVICE_RECOMMENDATION_ONE = "1";
+
+    /**
+     * 消息中心 是否已读
+     */
+    public static String MESSAGE_IS_READ_ZERO = "0";
+    public static String MESSAGE_IS_READ_ONE = "1";
+
+    /**
+     * 留言反馈
+     */
+    public static String FEEDBACK_IS_REPLY_ZERO = "0";
+    public static String FEEDBACK_IS_REPLY_ONE = "1";
+
+
+    /**
+     * 优惠券 类型 设置
+     */
+    public static final String COUPON_SET_TYPE_ZERO = "0"; //默认 优惠券 与 商家入驻
+    public static final String COUPON_SET_TYPE_ONE = "1";
+
+    //----------------------------------------------------------------------------------------
+    //-----------------------------------------dealer-----------------------------------------------
+
+    public static final int DISTANCE = 5001; // 默认5公里 显示范围  最近商家
+
+    /**
+     * AuthCoupon 认证优惠券
+     * is_use  该优惠券 是否已使用
+     */
+    public static final String AUTHCOUPON_IS_USE_ZERO = "0";
+    public static final String AUTHCOUPON_IS_USE_ONE = "1";
+
+    /**
+     * 优惠券   来源
+     * source 0 正常入驻 ,1 分享入驻
+     */
+    public static final String AUTHCOUPON_SOURCE_ZERO = "0";
+    public static final String AUTHCOUPON_SOURCE_ONE = "1";
+    // 优惠金额  默认 60元
+    public static final Integer AUTHCOUPON_MONEY = 60;
+
+    //经销商图册名称
+    public static final String DEALER_PICTURE_IMG = "dealerPictureImg";
+
+
+    // 优势产品 图
+    public static final String PRODUCT_PICTURE_IMG = "product_img";
+
+    //----------------------------------------------------------------------------------------
+
+    /**
+     * sm4 加密 key
+     */
+    public static final String SM4KEY = "nvrnetwork#";
+
+
+    /**
+     * 26个大写英文字母 根据字母索引使用   wzq
+     */
+    public static final String CAPITAL_ENGLISH_LETTER = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
+    /**
+     * 商家导出字段数组   wzq
+     */
+    public static final String[] BUSINESS_EXPORT_FIELD = {"店铺名称", "用户昵称", "企业名称", "省", "市", "区", "服务类别", "用户电话", "店铺电话", "入驻时间", "最后登录时间", "认证状态", "认证时间", "推荐人姓名", "推荐人手机号", "推荐人城市", "录入人姓名", "浏览量"};
+
+}

+ 190 - 0
code/auto/model/src/main/java/com/jzdsh/util/CommonUtil.java

@@ -0,0 +1,190 @@
+package com.jzdsh.util;
+
+import com.jfinal.kit.PathKit;
+import lombok.extern.log4j.Log4j2;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.*;
+import java.net.URL;
+import java.text.Collator;
+import java.util.*;
+
+/**
+ * 发送请求帮助类
+ *
+ * @author YaoShiHang
+ */
+public class CommonUtil {
+
+    public static Map< String, Object > cache = new HashMap<>( );
+
+    //用来产生随机验证码的
+    private static Random rand = new Random( );
+    private static String[] str = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
+
+    /**
+     * 获取几位随机数
+     *
+     * @param num 位数
+     * @return
+     */
+    public static String getRandom(int num) {
+        //存放产生的随机数
+        String sms;
+        //生成六位数的随机数
+        StringBuffer buf = new StringBuffer( );
+        for (int i = 0; i < num; i++) {
+            buf.append(str[rand.nextInt(10)]);
+        }
+        sms = buf.toString( );
+        return sms;
+    }
+
+    /**
+     * 获取uuid
+     *
+     * @return
+     */
+    public static String getUUID( ) {
+        return UUID.randomUUID( ).toString( ).trim( ).replace("-", "").toLowerCase( );
+    }
+
+    /**
+     * list集合按字典顺序排序
+     *
+     * @param list
+     * @return
+     */
+    public static List chineseSort(List< String > list) {
+        if (list == null || list.isEmpty( )) {
+            return list;
+        }
+        Collections.sort(list, (o1, o2) -> {
+            Comparator< Object > com = Collator.getInstance(Locale.CHINA);
+            return com.compare(o1, o2);
+        });
+        return list;
+    }
+
+    public static String[] splitIgnoreCase(String str) {
+        return str.split("[,,]+");
+    }
+
+    /**
+     * 对象序列化成字节码数据
+     *
+     * @param obj
+     * @return
+     */
+    public static byte[] setSerialize(Object obj) {
+        ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream( );
+        ObjectOutputStream oos = null;
+        try {
+            oos = new ObjectOutputStream(byteOutStream);
+            oos.writeObject(obj);
+            oos.close( );
+            return byteOutStream.toByteArray( );
+        } catch (Exception e) {
+            e.printStackTrace( );
+        } finally {
+            try {
+                oos.close( );
+            } catch (IOException e) {
+                e.printStackTrace( );
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 反序列化  字节码文件转对象
+     *
+     * @param bytes
+     * @return
+     */
+    public static Object getSerialize(byte[] bytes) {
+        ByteArrayInputStream byteInStream = new ByteArrayInputStream(bytes);
+        ObjectInputStream ois = null;
+        try {
+            ois = new ObjectInputStream(byteInStream);
+            return ois.readObject( );
+        } catch (Exception e) {
+            e.printStackTrace( );
+        } finally {
+            try {
+                ois.close( );
+            } catch (IOException e) {
+                e.printStackTrace( );
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 添加到缓存中
+     *
+     * @param key
+     * @param value
+     */
+    public static void setCache(String key, Object value) {
+        cache.put(key, value);
+    }
+
+    /**
+     * 从缓存中取出
+     *
+     * @param key
+     * @return
+     */
+    public static Object getCache(String key) {
+        return cache.get(key);
+    }
+
+
+
+    public static String wxImgSave(String img) {
+        if (StringUtils.isBlank(img)) {return "";}
+        String uuidJpg = null;
+        InputStream is = null;
+        OutputStream out = null;
+        try {
+            URL url = new URL(img);
+            is = url.openStream( );
+
+            File file = new File(PathKit.getWebRootPath()+"/upload/logo");
+            if (!file.exists( )) {
+                file.mkdirs( );
+            }
+            uuidJpg = CommonUtil.getUUID( ) + ".jpg";
+            out = new FileOutputStream(file + "/" + uuidJpg);
+
+            byte[] bytes = new byte[1024];
+            int l = 0;
+            while ((l = is.read(bytes)) > 0) {
+                out.write(bytes, 0, l);
+                out.flush( );
+            }
+
+        } catch (IOException e) {
+            System.out.println("微信头像 保存失败!" + e);
+        } finally {
+            if (out != null) {
+                try {
+                    out.close( );
+                } catch (IOException e) {
+                    e.printStackTrace( );
+                }
+            }
+            if (is != null) {
+                try {
+                    is.close( );
+                } catch (IOException e) {
+                    e.printStackTrace( );
+                }
+            }
+        }
+        return CommonCons.PROJECT_NAME + "/" + CommonCons.LOG_PICTURE + "/" + uuidJpg;
+    }
+
+
+}

+ 244 - 0
code/auto/model/src/main/java/com/jzdsh/util/MapUtils.java

@@ -0,0 +1,244 @@
+package com.jzdsh.util;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.jfinal.kit.HttpKit;
+import com.jfinal.kit.PropKit;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * @description: 高德地图工具类
+ * @author: lc
+ * @create 2019-08-22  17:08
+ */
+public class MapUtils {
+
+
+    /**
+     * 地球半径,单位 km
+     */
+    private static final double EARTH_RADIUS = 6378.137;
+
+
+    /**
+     * 地理编码url
+     *
+     * @param address 输入位置信息  "上海市静安区上海火车站"
+     * @return url
+     */
+    public static String getGeoUrl(String address) {
+        return "https://restapi.amap.com/v3/geocode/geo?key=" + PropKit.get("key") + "&address=" + address;
+    }
+
+    /**
+     * 逆地理编码url
+     *
+     * @param location 经纬度  "121.455625,31.250202"
+     * @return url
+     */
+    public static String getRegeoUrl(String location) {
+        return "https://restapi.amap.com/v3/geocode/regeo?key=" + PropKit.get("key") + "&location=" + location;
+    }
+
+    /**
+     * 向指定URL发送GET方法的请求
+     *
+     * @param url 发送请求的URL
+     * @return 远程资源的响应结果
+     */
+    public static String sendGet(String url) {
+
+        String result = "";
+        BufferedReader in = null;
+        try {
+            String urlNameString = url;
+            URL realUrl = new URL(urlNameString);
+            // 打开和URL之间的连接
+            URLConnection connection = realUrl.openConnection( );
+            // 设置通用的请求属性
+            connection.setRequestProperty("accept", "*/*");
+            connection.setRequestProperty("connection", "Keep-Alive");
+            connection.setRequestProperty("user-agent",
+                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
+            // 建立实际的连接
+            connection.connect( );
+            // 定义 BufferedReader输入流来读取URL的响应
+            in = new BufferedReader(new InputStreamReader(
+                    connection.getInputStream( ), "UTF-8"));
+            String line;
+            while ((line = in.readLine( )) != null) {
+                result += line;
+            }
+        } catch (Exception e) {
+            return null;
+        } finally { // 使用finally块来关闭输入流
+            try {
+                if (in != null) {
+                    in.close( );
+                }
+            } catch (Exception e2) {
+                e2.printStackTrace( );
+            }
+        }
+        return result;
+    }
+
+    /**
+     * 输入地址 返回信息 (已转码)
+     *
+     * @param address
+     * @return jsonStr
+     */
+    public static String sendAddress(String address) {
+        //net.sf.json.JSONObject get = HttpRequestUtil.httpRequest("https://restapi.amap.com/v3/geocode/geo", "GET", "address=" + address + "&key=" + WxConfig.MAP_KEY + "");
+        //return get.toString( );
+        return HttpKit.get("https://restapi.amap.com/v3/geocode/geo?address=" + address + "&key=" + PropKit.get("key"));
+    }
+
+    public static String getProvince(String jsonStr) {
+        String addressComponent = JSONObject.parseObject(jsonStr).getJSONObject("regeocode").getString("addressComponent");
+        String province = JSONObject.parseObject(addressComponent).getString("province");
+        return province;
+    }
+
+    public static String getCity(String jsonStr) {
+        String addressComponent = JSONObject.parseObject(jsonStr).getJSONObject("regeocode").getString("addressComponent");
+        String city = JSONObject.parseObject(addressComponent).getString("city");
+        return city;
+    }
+
+    /**
+     * 获取区域名称
+     *
+     * @param jsonStr 远程资源响应结果
+     * @return 列: "静安区"
+     */
+    public static String getDistrict(String jsonStr) {
+        String addressComponent = JSONObject.parseObject(jsonStr).getJSONObject("regeocode").getString("addressComponent");
+        String district = JSONObject.parseObject(addressComponent).getString("district");
+        return district;
+    }
+
+    /**
+     * 区域code
+     *
+     * @param jsonStr
+     * @return
+     */
+    public static String getAdcode(String jsonStr) {
+        String addressComponent = JSONObject.parseObject(jsonStr).getJSONObject("regeocode").getString("addressComponent");
+        String adcode = JSONObject.parseObject(addressComponent).getString("adcode");
+        return adcode;
+    }
+
+    /**
+     * 获取全地理位置名称
+     *
+     * @param jsonStr 远程资源响应结果
+     * @return 列: "上海市静安区上海火车站"
+     */
+    public static String getAddressNameByGeocoder(String jsonStr) {
+        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
+        String addressName = jsonObject.getJSONObject("regeocode").getString("formatted_address");
+        if ("[]".equals(addressName)) {
+            return "";
+        }
+        return addressName;
+    }
+
+    /**
+     * 获取经纬度
+     *
+     * @param jsonStr 远程资源响应结果
+     * @return 列: "121.455625,31.250202"
+     */
+    public static String getLongitudeAndLatitude(String jsonStr) {
+        String location = ""; //经纬度
+        JSONArray geocodes = JSONObject.parseObject(jsonStr).getJSONArray("geocodes");
+        if (geocodes != null && geocodes.size( ) != 0) {
+            for (Object geocode : JSONObject.parseObject(jsonStr).getJSONArray("geocodes")) {
+                location = JSONObject.parseObject(geocode.toString( )).get("location").toString( );
+            }
+        }
+        return location;
+    }
+
+    public static String getLongitudeLatitude(String address) {
+        return getLongitudeAndLatitude(sendAddress(address));
+    }
+
+
+    /**
+     * 根据经纬度,计算两点间的距离
+     *
+     * @param longitude1 第一个点的经度
+     * @param latitude1  第一个点的纬度
+     * @param longitude2 第二个点的经度
+     * @param latitude2  第二个点的纬度
+     * @return 返回距离 单位千米
+     */
+    public static double getDistance(double longitude1, double latitude1, double longitude2, double latitude2) {
+        // 纬度
+        double lat1 = Math.toRadians(latitude1);
+        double lat2 = Math.toRadians(latitude2);
+        // 经度
+        double lng1 = Math.toRadians(longitude1);
+        double lng2 = Math.toRadians(longitude2);
+        // 纬度之差
+        double a = lat1 - lat2;
+        // 经度之差
+        double b = lng1 - lng2;
+        // 计算两点距离的公式
+        double s = 2 * Math.asin(Math
+                .sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(b / 2), 2)));
+        // 弧长乘地球半径, 返回单位: 千米
+        s = s * EARTH_RADIUS;
+        return s;
+    }
+
+    /**
+     * 根据经纬度返回 省市县 地区
+     *
+     * @param longitude 经度
+     * @param latitude  维度
+     * @return map
+     */
+    public static Map< String, String > getMap(String longitude, String latitude) {
+        HashMap< String, String > map = new HashMap<>( );
+        if (StringUtils.isBlank(longitude) || Objects.equals("undefined", longitude)) {
+            map.put("province", "");
+            map.put("city", "");
+            map.put("district", "");
+            return map;
+        }
+        //-- 获取当前地理信息 区域
+        String url = getRegeoUrl(longitude + "," + latitude);
+        String jsonStr = MapUtils.sendGet(url);
+        String province = MapUtils.getProvince(jsonStr);
+        String city = MapUtils.getCity(jsonStr);
+        String district = MapUtils.getDistrict(jsonStr);
+        if (CommonCons.BRACKETS.equals(city)) {
+            city = province;
+        }
+        map.put("province", province);
+        map.put("city", city);
+        map.put("district", district);
+        return map;
+    }
+
+    public static void main(String[] args) {
+        getLongitudeLatitude("上海市上海市普陀区祁连山南路588弄1号");
+
+
+    }
+
+
+}

+ 243 - 0
code/auto/model/src/main/java/com/jzdsh/util/SM4.java

@@ -0,0 +1,243 @@
+package com.jzdsh.util;
+
+import org.apache.commons.lang3.ArrayUtils;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+
+/**
+ *
+ * @author Mr.Xiao
+ * @company GDT-ZWZX-DEV-PT
+ * @date 2017-08
+ * @since 1.6
+ */
+public class SM4 {
+
+    public static final int ROUND = 32;
+    private static final int ENCRYPT = 1;
+    private static final int DECRYPT = 0;
+    private static final int BLOCK = 16;
+
+    private byte[] Sbox = {
+            (byte) 0xd6, (byte) 0x90, (byte) 0xe9, (byte) 0xfe, (byte) 0xcc, (byte) 0xe1, 0x3d, (byte) 0xb7, 0x16, (byte) 0xb6, 0x14, (byte) 0xc2, 0x28, (byte) 0xfb, 0x2c, 0x05,
+            0x2b, 0x67, (byte) 0x9a, 0x76, 0x2a, (byte) 0xbe, 0x04, (byte) 0xc3, (byte) 0xaa, 0x44, 0x13, 0x26, 0x49, (byte) 0x86, 0x06, (byte) 0x99,
+            (byte) 0x9c, 0x42, 0x50, (byte) 0xf4, (byte) 0x91, (byte) 0xef, (byte) 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, (byte) 0xed, (byte) 0xcf, (byte) 0xac, 0x62,
+            (byte) 0xe4, (byte) 0xb3, 0x1c, (byte) 0xa9, (byte) 0xc9, 0x08, (byte) 0xe8, (byte) 0x95, (byte) 0x80, (byte) 0xdf, (byte) 0x94, (byte) 0xfa, 0x75, (byte) 0x8f, 0x3f, (byte) 0xa6,
+            0x47, 0x07, (byte) 0xa7, (byte) 0xfc, (byte) 0xf3, 0x73, 0x17, (byte) 0xba, (byte) 0x83, 0x59, 0x3c, 0x19, (byte) 0xe6, (byte) 0x85, 0x4f, (byte) 0xa8,
+            0x68, 0x6b, (byte) 0x81, (byte) 0xb2, 0x71, 0x64, (byte) 0xda, (byte) 0x8b, (byte) 0xf8, (byte) 0xeb, 0x0f, 0x4b, 0x70, 0x56, (byte) 0x9d, 0x35,
+            0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, (byte) 0xd1, (byte) 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, (byte) 0x87,
+            (byte) 0xd4, 0x00, 0x46, 0x57, (byte) 0x9f, (byte) 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, (byte) 0xe7, (byte) 0xa0, (byte) 0xc4, (byte) 0xc8, (byte) 0x9e,
+            (byte) 0xea, (byte) 0xbf, (byte) 0x8a, (byte) 0xd2, 0x40, (byte) 0xc7, 0x38, (byte) 0xb5, (byte) 0xa3, (byte) 0xf7, (byte) 0xf2, (byte) 0xce, (byte) 0xf9, 0x61, 0x15, (byte) 0xa1,
+            (byte) 0xe0, (byte) 0xae, 0x5d, (byte) 0xa4, (byte) 0x9b, 0x34, 0x1a, 0x55, (byte) 0xad, (byte) 0x93, 0x32, 0x30, (byte) 0xf5, (byte) 0x8c, (byte) 0xb1, (byte) 0xe3,
+            0x1d, (byte) 0xf6, (byte) 0xe2, 0x2e, (byte) 0x82, 0x66, (byte) 0xca, 0x60, (byte) 0xc0, 0x29, 0x23, (byte) 0xab, 0x0d, 0x53, 0x4e, 0x6f,
+            (byte) 0xd5, (byte) 0xdb, 0x37, 0x45, (byte) 0xde, (byte) 0xfd, (byte) 0x8e, 0x2f, 0x03, (byte) 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51,
+            (byte) 0x8d, 0x1b, (byte) 0xaf, (byte) 0x92, (byte) 0xbb, (byte) 0xdd, (byte) 0xbc, 0x7f, 0x11, (byte) 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, (byte) 0xd8,
+            0x0a, (byte) 0xc1, 0x31, (byte) 0x88, (byte) 0xa5, (byte) 0xcd, 0x7b, (byte) 0xbd, 0x2d, 0x74, (byte) 0xd0, 0x12, (byte) 0xb8, (byte) 0xe5, (byte) 0xb4, (byte) 0xb0,
+            (byte) 0x89, 0x69, (byte) 0x97, 0x4a, 0x0c, (byte) 0x96, 0x77, 0x7e, 0x65, (byte) 0xb9, (byte) 0xf1, 0x09, (byte) 0xc5, 0x6e, (byte) 0xc6, (byte) 0x84,
+            0x18, (byte) 0xf0, 0x7d, (byte) 0xec, 0x3a, (byte) 0xdc, 0x4d, 0x20, 0x79, (byte) 0xee, 0x5f, 0x3e, (byte) 0xd7, (byte) 0xcb, 0x39, 0x48
+    };
+
+    private int[] CK = {
+            0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269,
+            0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9,
+            0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249,
+            0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9,
+            0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229,
+            0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299,
+            0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209,
+            0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279
+    };
+
+    public static void main(String[] args) throws IOException {
+        String s = new SM4().encode("carmsg207", "carmsg#");
+        System.out.println(s);
+        String j = new SM4().decode("HFXnIHAKDs7jsFTzBTycqQ==", "carmsg#");
+        System.out.println(j);
+
+    }
+
+    private int Rotl(int x, int y) {
+        return x << y | x >>> (32 - y);
+    }
+
+    private int ByteSub(int A) {
+        return (Sbox[A >>> 24 & 0xFF] & 0xFF) << 24 | (Sbox[A >>> 16 & 0xFF] & 0xFF) << 16 | (Sbox[A >>> 8 & 0xFF] & 0xFF) << 8 | (Sbox[A & 0xFF] & 0xFF);
+    }
+
+    private int L1(int B) {
+        return B ^ Rotl(B, 2) ^ Rotl(B, 10) ^ Rotl(B, 18) ^ Rotl(B, 24);
+    }
+
+    private int L2(int B) {
+        return B ^ Rotl(B, 13) ^ Rotl(B, 23);
+    }
+
+    void SMS4Crypt(byte[] Input, byte[] Output, int[] rk) {
+        int r, mid, x0, x1, x2, x3;
+        int[] x = new int[4];
+        int[] tmp = new int[4];
+        for (int i = 0; i < 4; i++) {
+            tmp[0] = Input[0 + 4 * i] & 0xff;
+            tmp[1] = Input[1 + 4 * i] & 0xff;
+            tmp[2] = Input[2 + 4 * i] & 0xff;
+            tmp[3] = Input[3 + 4 * i] & 0xff;
+            x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
+        }
+        for (r = 0; r < 32; r += 4) {
+            mid = x[1] ^ x[2] ^ x[3] ^ rk[r + 0];
+            mid = ByteSub(mid);
+            x[0] = x[0] ^ L1(mid);   //x4
+
+            mid = x[2] ^ x[3] ^ x[0] ^ rk[r + 1];
+            mid = ByteSub(mid);
+            x[1] = x[1] ^ L1(mid);    //x5
+
+            mid = x[3] ^ x[0] ^ x[1] ^ rk[r + 2];
+            mid = ByteSub(mid);
+            x[2] = x[2] ^ L1(mid);    //x6
+
+            mid = x[0] ^ x[1] ^ x[2] ^ rk[r + 3];
+            mid = ByteSub(mid);
+            x[3] = x[3] ^ L1(mid);    //x7
+
+        }
+
+        //Reverse
+
+        for (int j = 0; j < 16; j += 4) {
+            Output[j] = (byte) (x[3 - j / 4] >>> 24 & 0xFF);
+            Output[j + 1] = (byte) (x[3 - j / 4] >>> 16 & 0xFF);
+            Output[j + 2] = (byte) (x[3 - j / 4] >>> 8 & 0xFF);
+            Output[j + 3] = (byte) (x[3 - j / 4] & 0xFF);
+        }
+    }
+
+    private void SMS4KeyExt(byte[] Key, int[] rk, int CryptFlag) {
+        int r, mid;
+        int[] x = new int[4];
+        int[] tmp = new int[4];
+        for (int i = 0; i < 4; i++) {
+            tmp[0] = Key[0 + 4 * i] & 0xFF;
+            tmp[1] = Key[1 + 4 * i] & 0xff;
+            tmp[2] = Key[2 + 4 * i] & 0xff;
+            tmp[3] = Key[3 + 4 * i] & 0xff;
+            x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
+        }
+        x[0] ^= 0xa3b1bac6;
+        x[1] ^= 0x56aa3350;
+        x[2] ^= 0x677d9197;
+        x[3] ^= 0xb27022dc;
+        for (r = 0; r < 32; r += 4) {
+            mid = x[1] ^ x[2] ^ x[3] ^ CK[r + 0];
+            mid = ByteSub(mid);
+            rk[r + 0] = x[0] ^= L2(mid);        //rk0=K4
+
+            mid = x[2] ^ x[3] ^ x[0] ^ CK[r + 1];
+            mid = ByteSub(mid);
+            rk[r + 1] = x[1] ^= L2(mid);        //rk1=K5
+
+            mid = x[3] ^ x[0] ^ x[1] ^ CK[r + 2];
+            mid = ByteSub(mid);
+            rk[r + 2] = x[2] ^= L2(mid);        //rk2=K6
+
+            mid = x[0] ^ x[1] ^ x[2] ^ CK[r + 3];
+            mid = ByteSub(mid);
+            rk[r + 3] = x[3] ^= L2(mid);        //rk3=K7
+
+        }
+
+        if (CryptFlag == DECRYPT) {
+            for (r = 0; r < 16; r++) {
+                mid = rk[r];
+                rk[r] = rk[31 - r];
+                rk[31 - r] = mid;
+            }
+        }
+    }
+
+    public byte[] sms4(byte[] in, int inLen, byte[] key, int CryptFlag) {
+        int point = 0;
+        int[] round_key = new int[ROUND];
+        //int[] round_key={0};
+
+        SMS4KeyExt(key, round_key, CryptFlag);
+        byte[] input = new byte[16];
+        byte[] output = new byte[16];
+        byte[] out = new byte[16];
+        while (inLen >= BLOCK) {
+            input = Arrays.copyOfRange(in, point, point + 16);
+            SMS4Crypt(input, output, round_key);
+            System.arraycopy(output, 0, out, point, BLOCK);
+            inLen -= BLOCK;
+            point += BLOCK;
+        }
+
+        return out;
+    }
+
+    /**
+     * 加密
+     *
+     * @param input
+     * @param key
+     * @return
+     * @throws IOException
+     */
+    public String encode(String input, String key)  {
+        try {
+            byte[] b_input = input.getBytes("utf-8");
+            byte[] b_key = new byte[16];
+            byte[] bbs = key.getBytes("utf-8");
+            if (bbs.length < 16) {
+                for (int i = 0; i < bbs.length; i++) {
+                    b_key[i] = bbs[i];
+                }
+            } else {
+                b_key = bbs;
+            }
+
+            byte[] o = new byte[0];
+            for (int i = 0; i < b_input.length; i += 16) {
+                byte[] t = ArrayUtils.subarray(b_input, i, i + 16);
+                o = ArrayUtils.addAll(o, sms4(t, 16, b_key, 1));
+            }
+            return new sun.misc.BASE64Encoder().encode(o);
+        } catch (UnsupportedEncodingException e) {
+            e.printStackTrace( );
+        }
+        return "";
+    }
+
+    /**
+     * 解密
+     *
+     * @param input
+     * @param key
+     * @return
+     * @throws IOException
+     */
+    public String decode(String input, String key) throws IOException {
+        byte[] b_input = new sun.misc.BASE64Decoder().decodeBuffer(input);
+        byte[] b_key = new byte[16];
+        byte[] bbs = key.getBytes("utf-8");
+
+        if (bbs.length < 16) {
+            for (int i = 0; i < bbs.length; i++) {
+                b_key[i] = bbs[i];
+            }
+        } else {
+            b_key = bbs;
+        }
+
+        byte[] o = new byte[0];
+        for (int i = 0; i < b_input.length; i += 16) {
+            byte[] t = ArrayUtils.subarray(b_input, i, i + 16);
+            byte[] t1 = sms4(t, 16, b_key, 0);
+            o = ArrayUtils.addAll(o, t1);
+        }
+
+        return new String(o, "utf-8").trim();
+    }
+}