干燥机配套车间生产管理系统/云平台服务端
baoshiwei
2024-10-25 9af47b4c0c25c5c2159ac6ceefced88dec72a2f9
Merge branch 'master' into herb-new
已添加9个文件
已修改10个文件
62452 ■■■■■ 文件已修改
.gitignore 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LICENSE 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
db/herb-20240318.sql 59951 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-boot-base-core/pom.xml 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/MqttConstant.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java 1484 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/service/BaseCommonService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/service/impl/BaseCommonServiceImpl.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/api/EmqxApi.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/api/EmqxApi.txt 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/vo/MoEquVo.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/MobileController.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/mqtt/MqttConfig.java 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/mqtt/MqttSampleCallback.java 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/mqtt/MqttUtil.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/jimureport/JimuReportTokenService.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -9,3 +9,8 @@
## front
**/*.lock
/target/
**/target
**/logs
LICENSE
@@ -187,7 +187,7 @@
      identification within third-party archives.
   Copyright (c) 2019 <a href="http://www.jeecg.com">Jeecg Boot</a> All rights reserved.
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
@@ -199,15 +199,14 @@
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
   In any case, you must not make any such use of this software as to develop software which may be considered competitive with this software.
  å¼€æºåè®®è¡¥å……
    JeecgBoot æ˜¯ç”± åŒ—京国炬信息技术有限公司 å‘行的软件。 æ€»éƒ¨ä½äºŽåŒ—京,地址:中国·北京·朝阳区科荟前街1号院奥林佳泰大厦。邮箱:jeecgos@163.com
    æœ¬è½¯ä»¶å—适用的国家软件著作权法(包括国际条约)和双重保护许可。
   1.允许基于本平台软件开展业务系统开发。
   2.不得基于该平台软件的基础,修改包装成一个与JeecgBoot平台软件功能类似的产品进行发布、销售,或与JeecgBoot参与同类软件产品市场的竞争。
     è¿åæ­¤æ¡æ¬¾å±žäºŽä¾µæƒè¡Œä¸ºï¼Œé¡»èµ”偿侵权经济损失,同时立即停止著作权侵权行为。
     è§£é‡Šæƒå½’:http://www.jeecg.com
README.md
@@ -514,4 +514,4 @@
如果觉得还不错,请作者喝杯咖啡吧 â˜º
![](https://static.oschina.net/uploads/img/201903/08155608_0EFX.png)
![](https://static.oschina.net/uploads/img/201903/08155608_0EFX.png)
db/herb-20240318.sql
¶Ô±ÈÐÂÎļþ
ÎļþÌ«´ó
jeecg-boot-base-core/pom.xml
@@ -252,6 +252,13 @@
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
        </dependency>
    </dependencies>
    <!--MQTT client -->
    <dependency>
      <groupId>org.eclipse.paho</groupId>
      <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
      <version>1.2.5</version>
    </dependency>
</project>
  </dependencies>
</project>
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/CommonConstant.java
@@ -35,6 +35,10 @@
     * ç³»ç»Ÿæ—¥å¿—类型: æ“ä½œ
     */
    int LOG_TYPE_2 = 2;
  /**
   * MQTT日志
   */
  int LOG_TYPE_MQTT = 100;
    /**
     * æ“ä½œæ—¥å¿—类型: æŸ¥è¯¢
@@ -65,7 +69,16 @@
     * æ“ä½œæ—¥å¿—类型: å¯¼å‡º
     */
    int OPERATE_TYPE_6 = 6;
  /**
   * MQTT日志
   * 100-订阅
   * 200-发布
   */
  int OPERATE_MQTT_1 = 100;
  int OPERATE_MQTT_2 = 200;
    
    /** {@code 500 Server Error} (HTTP/1.0 - RFC 1945) */
    Integer SC_INTERNAL_SERVER_ERROR_500 = 500;
jeecg-boot-base-core/src/main/java/org/jeecg/common/constant/MqttConstant.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
package org.jeecg.common.constant;
/**
 * Mqtt指令常量
 */
public interface MqttConstant {
  /**************************系统订阅strat*******************************/
  //上线订阅
  String MQTT_TOPIC_ONLINE = "$SYS/brokers/+/clients/+/connected";
  //下线订阅
  String MQTT_TOPIC_OFFLINE = "$SYS/brokers/+/clients/+/disconnected";
  /**************************系统订阅end*******************************/
  /**************************移动端向服务端请求指令start*******************************/
  //移动端相关
  String MOBILE_UP = "mobile/up/#";
  //查询设备状态
  //移动端上行指令前缀(移动端请求)
  String MOBILE_UP_PREFIX = "mobile/up";
  //请求查询设备状态
  String MOBILE_QUERY_EQU_STATU = MOBILE_UP_PREFIX + "/query/equ/statu";
  //移动端远程请求指令
  String MOBILE_REQ_EQU_CMD = MOBILE_UP_PREFIX + "/req/equ/cmd";
  /**************************移动端向服务端请求指令end*******************************/
  /**************************服务端向移动端响应指令start*******************************/
  //返回数据仅返回给请求的客户端 %s发起请求客户端id
  //服务端下行指令前缀(返回给移动端)
  String SERVICE_DOWN_PREFIX = "service/down/res";
  //返回移动端查询设备状态
  String SERVICE_RES_EQU_STATU = SERVICE_DOWN_PREFIX + "/%s/statu";
  //返回移动端远程请求指令
  String SERVICE_RES_EQU_CMD = SERVICE_DOWN_PREFIX + "/%s/cmd";
  /**************************服务端向移动端响应指令end*******************************/
  //redis缓存
  String MQTT_ONLINE_CLIENT = "mqtt:online:client::";
}
jeecg-boot-base-core/src/main/java/org/jeecg/common/util/DateUtils.java
@@ -8,6 +8,8 @@
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
@@ -21,743 +23,777 @@
 */
public class DateUtils extends PropertyEditorSupport {
    public static ThreadLocal<SimpleDateFormat> date_sdf = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd");
        }
    };
    public static ThreadLocal<SimpleDateFormat> yyyyMMdd = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyyMMdd");
        }
    };
    public static ThreadLocal<SimpleDateFormat> date_sdf_wz = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyyå¹´MM月dd日");
        }
    };
    public static ThreadLocal<SimpleDateFormat> time_sdf = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm");
        }
    };
    public static ThreadLocal<SimpleDateFormat> yyyymmddhhmmss = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyyMMddHHmmss");
        }
    };
    public static ThreadLocal<SimpleDateFormat> short_time_sdf = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("HH:mm");
        }
    };
    public static ThreadLocal<SimpleDateFormat> datetimeFormat = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        }
    };
    /**
     * ä»¥æ¯«ç§’表示的时间
     */
    private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
    private static final long HOUR_IN_MILLIS = 3600 * 1000;
    private static final long MINUTE_IN_MILLIS = 60 * 1000;
    private static final long SECOND_IN_MILLIS = 1000;
    /**
     * æŒ‡å®šæ¨¡å¼çš„æ—¶é—´æ ¼å¼
     * @param pattern
     * @return
     */
    private static SimpleDateFormat getSdFormat(String pattern) {
        return new SimpleDateFormat(pattern);
    }
    /**
     * å½“前日历,这里用中国时间表示
     *
     * @return ä»¥å½“地时区表示的系统当前日历
     */
    public static Calendar getCalendar() {
        return Calendar.getInstance();
    }
    /**
     * æŒ‡å®šæ¯«ç§’数表示的日历
     *
     * @param millis æ¯«ç§’æ•°
     * @return æŒ‡å®šæ¯«ç§’数表示的日历
     */
    public static Calendar getCalendar(long millis) {
        Calendar cal = Calendar.getInstance();
        // --------------------cal.setTimeInMillis(millis);
        cal.setTime(new Date(millis));
        return cal;
    }
    // ////////////////////////////////////////////////////////////////////////////
    // getDate
    // å„种方式获取的Date
    // ////////////////////////////////////////////////////////////////////////////
    /**
     * å½“前日期
     *
     * @return ç³»ç»Ÿå½“前时间
     */
    public static Date getDate() {
        return new Date();
    }
    /**
     * æŒ‡å®šæ¯«ç§’数表示的日期
     *
     * @param millis æ¯«ç§’æ•°
     * @return æŒ‡å®šæ¯«ç§’数表示的日期
     */
    public static Date getDate(long millis) {
        return new Date(millis);
    }
    /**
     * æ—¶é—´æˆ³è½¬æ¢ä¸ºå­—符串
     *
     * @param time
     * @return
     */
    public static String timestamptoStr(Timestamp time) {
        Date date = null;
        if (null != time) {
            date = new Date(time.getTime());
        }
        return date2Str(date_sdf.get());
    }
    /**
     * å­—符串转换时间戳
     *
     * @param str
     * @return
     */
    public static Timestamp str2Timestamp(String str) {
        Date date = str2Date(str, date_sdf.get());
        return new Timestamp(date.getTime());
    }
    /**
     * å­—符串转换成日期
     *
     * @param str
     * @param sdf
     * @return
     */
    public static Date str2Date(String str, SimpleDateFormat sdf) {
        if (null == str || "".equals(str)) {
            return null;
        }
        Date date = null;
        try {
            date = sdf.parse(str);
            return date;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * æ—¥æœŸè½¬æ¢ä¸ºå­—符串
     *
     * @param dateSdf æ—¥æœŸæ ¼å¼
     * @return å­—符串
     */
    public static String date2Str(SimpleDateFormat dateSdf) {
        synchronized (dateSdf) {
            Date date = getDate();
            if (null == date) {
                return null;
            }
            return dateSdf.format(date);
        }
    }
    /**
     * æ ¼å¼åŒ–æ—¶é—´
     *
     * @param date
     * @param format
     * @return
     */
    public static String dateformat(String date, String format) {
        SimpleDateFormat sformat = new SimpleDateFormat(format);
        Date nowDate = null;
        try {
            nowDate = sformat.parse(date);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return sformat.format(nowDate);
    }
    /**
     * æ—¥æœŸè½¬æ¢ä¸ºå­—符串
     *
     * @param date     æ—¥æœŸ
     * @param dateSdf æ—¥æœŸæ ¼å¼
     * @return å­—符串
     */
    public static String date2Str(Date date, SimpleDateFormat dateSdf) {
        synchronized (dateSdf) {
            if (null == date) {
                return null;
            }
            return dateSdf.format(date);
        }
    }
    /**
     * æ—¥æœŸè½¬æ¢ä¸ºå­—符串
     *
     * @param format æ—¥æœŸæ ¼å¼
     * @return å­—符串
     */
    public static String getDate(String format) {
        Date date = new Date();
        if (null == date) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }
    /**
     * æŒ‡å®šæ¯«ç§’数的时间戳
     *
     * @param millis æ¯«ç§’æ•°
     * @return æŒ‡å®šæ¯«ç§’数的时间戳
     */
    public static Timestamp getTimestamp(long millis) {
        return new Timestamp(millis);
    }
    /**
     * ä»¥å­—符形式表示的时间戳
     *
     * @param time æ¯«ç§’æ•°
     * @return ä»¥å­—符形式表示的时间戳
     */
    public static Timestamp getTimestamp(String time) {
        return new Timestamp(Long.parseLong(time));
    }
    /**
     * ç³»ç»Ÿå½“前的时间戳
     *
     * @return ç³»ç»Ÿå½“前的时间戳
     */
    public static Timestamp getTimestamp() {
        return new Timestamp(System.currentTimeMillis());
    }
    /**
     * å½“前时间,格式 yyyy-MM-dd HH:mm:ss
     *
     * @return å½“前时间的标准形式字符串
     */
    public static String now() {
        return datetimeFormat.get().format(getCalendar().getTime());
    }
    /**
     * æŒ‡å®šæ—¥æœŸçš„æ—¶é—´æˆ³
     *
     * @param date æŒ‡å®šæ—¥æœŸ
     * @return æŒ‡å®šæ—¥æœŸçš„æ—¶é—´æˆ³
     */
    public static Timestamp getTimestamp(Date date) {
        return new Timestamp(date.getTime());
    }
    /**
     * æŒ‡å®šæ—¥åŽ†çš„æ—¶é—´æˆ³
     *
     * @param cal æŒ‡å®šæ—¥åކ
     * @return æŒ‡å®šæ—¥åŽ†çš„æ—¶é—´æˆ³
     */
    public static Timestamp getCalendarTimestamp(Calendar cal) {
        // ---------------------return new Timestamp(cal.getTimeInMillis());
        return new Timestamp(cal.getTime().getTime());
    }
    public static Timestamp gettimestamp() {
        Date dt = new Date();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowTime = df.format(dt);
        java.sql.Timestamp buydate = java.sql.Timestamp.valueOf(nowTime);
        return buydate;
    }
    // ////////////////////////////////////////////////////////////////////////////
    // getMillis
    // å„种方式获取的Millis
    // ////////////////////////////////////////////////////////////////////////////
    /**
     * ç³»ç»Ÿæ—¶é—´çš„æ¯«ç§’æ•°
     *
     * @return ç³»ç»Ÿæ—¶é—´çš„æ¯«ç§’æ•°
     */
    public static long getMillis() {
        return System.currentTimeMillis();
    }
    /**
     * æŒ‡å®šæ—¥åŽ†çš„æ¯«ç§’æ•°
     *
     * @param cal æŒ‡å®šæ—¥åކ
     * @return æŒ‡å®šæ—¥åŽ†çš„æ¯«ç§’æ•°
     */
    public static long getMillis(Calendar cal) {
        // --------------------return cal.getTimeInMillis();
        return cal.getTime().getTime();
    }
    /**
     * æŒ‡å®šæ—¥æœŸçš„æ¯«ç§’æ•°
     *
     * @param date æŒ‡å®šæ—¥æœŸ
     * @return æŒ‡å®šæ—¥æœŸçš„æ¯«ç§’æ•°
     */
    public static long getMillis(Date date) {
        return date.getTime();
    }
    /**
     * æŒ‡å®šæ—¶é—´æˆ³çš„æ¯«ç§’æ•°
     *
     * @param ts æŒ‡å®šæ—¶é—´æˆ³
     * @return æŒ‡å®šæ—¶é—´æˆ³çš„æ¯«ç§’æ•°
     */
    public static long getMillis(Timestamp ts) {
        return ts.getTime();
    }
    // ////////////////////////////////////////////////////////////////////////////
    // formatDate
    // å°†æ—¥æœŸæŒ‰ç…§ä¸€å®šçš„æ ¼å¼è½¬åŒ–为字符串
    // ////////////////////////////////////////////////////////////////////////////
    /**
     * é»˜è®¤æ–¹å¼è¡¨ç¤ºçš„系统当前日期,具体格式:年-月-日
     *
     * @return é»˜è®¤æ—¥æœŸæŒ‰â€œå¹´-月-日“格式显示
     */
    public static String formatDate() {
        return date_sdf.get().format(getCalendar().getTime());
    }
    /**
     * é»˜è®¤æ–¹å¼è¡¨ç¤ºçš„系统当前日期,具体格式:yyyy-MM-dd HH:mm:ss
     *
     * @return é»˜è®¤æ—¥æœŸæŒ‰â€œyyyy-MM-dd HH:mm:ss“格式显示
     */
    public static String formatDateTime() {
        return datetimeFormat.get().format(getCalendar().getTime());
    }
    /**
     * èŽ·å–æ—¶é—´å­—ç¬¦ä¸²
     */
    public static String getDataString(SimpleDateFormat formatstr) {
        synchronized (formatstr) {
            return formatstr.format(getCalendar().getTime());
        }
    }
    /**
     * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:年-月-日
     *
     * @param cal æŒ‡å®šçš„æ—¥æœŸ
     * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œå¹´-月-日“格式显示
     */
    public static String formatDate(Calendar cal) {
        return date_sdf.get().format(cal.getTime());
    }
    /**
     * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:年-月-日
     *
     * @param date æŒ‡å®šçš„æ—¥æœŸ
     * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œå¹´-月-日“格式显示
     */
    public static String formatDate(Date date) {
        return date_sdf.get().format(date);
    }
    /**
     * æŒ‡å®šæ¯«ç§’数表示日期的默认显示,具体格式:年-月-日
     *
     * @param millis æŒ‡å®šçš„æ¯«ç§’æ•°
     * @return æŒ‡å®šæ¯«ç§’数表示日期按“年-月-日“格式显示
     */
    public static String formatDate(long millis) {
        return date_sdf.get().format(new Date(millis));
    }
    /**
     * é»˜è®¤æ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
     *
     * @param pattern æŒ‡å®šçš„æ ¼å¼
     * @return é»˜è®¤æ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
     */
    public static String formatDate(String pattern) {
        return getSdFormat(pattern).format(getCalendar().getTime());
    }
    /**
     * æŒ‡å®šæ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
     *
     * @param cal     æŒ‡å®šçš„æ—¥æœŸ
     * @param pattern æŒ‡å®šçš„æ ¼å¼
     * @return æŒ‡å®šæ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
     */
    public static String formatDate(Calendar cal, String pattern) {
        return getSdFormat(pattern).format(cal.getTime());
    }
    /**
     * æŒ‡å®šæ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
     *
     * @param date    æŒ‡å®šçš„æ—¥æœŸ
     * @param pattern æŒ‡å®šçš„æ ¼å¼
     * @return æŒ‡å®šæ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
     */
    public static String formatDate(Date date, String pattern) {
        return getSdFormat(pattern).format(date);
    }
    // ////////////////////////////////////////////////////////////////////////////
    // formatTime
    // å°†æ—¥æœŸæŒ‰ç…§ä¸€å®šçš„æ ¼å¼è½¬åŒ–为字符串
    // ////////////////////////////////////////////////////////////////////////////
    /**
     * é»˜è®¤æ–¹å¼è¡¨ç¤ºçš„系统当前日期,具体格式:年-月-日 æ—¶ï¼šåˆ†
     *
     * @return é»˜è®¤æ—¥æœŸæŒ‰â€œå¹´-月-日 æ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
     */
    public static String formatTime() {
        return time_sdf.get().format(getCalendar().getTime());
    }
    /**
     * æŒ‡å®šæ¯«ç§’数表示日期的默认显示,具体格式:年-月-日 æ—¶ï¼šåˆ†
     *
     * @param millis æŒ‡å®šçš„æ¯«ç§’æ•°
     * @return æŒ‡å®šæ¯«ç§’数表示日期按“年-月-日 æ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
     */
    public static String formatTime(long millis) {
        return time_sdf.get().format(new Date(millis));
    }
    /**
     * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:年-月-日 æ—¶ï¼šåˆ†
     *
     * @param cal æŒ‡å®šçš„æ—¥æœŸ
     * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œå¹´-月-日 æ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
     */
    public static String formatTime(Calendar cal) {
        return time_sdf.get().format(cal.getTime());
    }
    /**
     * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:年-月-日 æ—¶ï¼šåˆ†
     *
     * @param date æŒ‡å®šçš„æ—¥æœŸ
     * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œå¹´-月-日 æ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
     */
    public static String formatTime(Date date) {
        return time_sdf.get().format(date);
    }
    // ////////////////////////////////////////////////////////////////////////////
    // formatShortTime
    // å°†æ—¥æœŸæŒ‰ç…§ä¸€å®šçš„æ ¼å¼è½¬åŒ–为字符串
    // ////////////////////////////////////////////////////////////////////////////
    /**
     * é»˜è®¤æ–¹å¼è¡¨ç¤ºçš„系统当前日期,具体格式:时:分
     *
     * @return é»˜è®¤æ—¥æœŸæŒ‰â€œæ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
     */
    public static String formatShortTime() {
        return short_time_sdf.get().format(getCalendar().getTime());
    }
    /**
     * æŒ‡å®šæ¯«ç§’数表示日期的默认显示,具体格式:时:分
     *
     * @param millis æŒ‡å®šçš„æ¯«ç§’æ•°
     * @return æŒ‡å®šæ¯«ç§’数表示日期按“时:分“格式显示
     */
    public static String formatShortTime(long millis) {
        return short_time_sdf.get().format(new Date(millis));
    }
    /**
     * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:时:分
     *
     * @param cal æŒ‡å®šçš„æ—¥æœŸ
     * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œæ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
     */
    public static String formatShortTime(Calendar cal) {
        return short_time_sdf.get().format(cal.getTime());
    }
    /**
     * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:时:分
     *
     * @param date æŒ‡å®šçš„æ—¥æœŸ
     * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œæ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
     */
    public static String formatShortTime(Date date) {
        return short_time_sdf.get().format(date);
    }
    // ////////////////////////////////////////////////////////////////////////////
    // parseDate
    // parseCalendar
    // parseTimestamp
    // å°†å­—符串按照一定的格式转化为日期或时间
    // ////////////////////////////////////////////////////////////////////////////
    /**
     * æ ¹æ®æŒ‡å®šçš„æ ¼å¼å°†å­—符串转换成Date å¦‚输入:2003-11-19 11:20:20将按照这个转成时间
     *
     * @param src     å°†è¦è½¬æ¢çš„原始字符窜
     * @param pattern è½¬æ¢çš„匹配格式
     * @return å¦‚果转换成功则返回转换后的日期
     * @throws ParseException
     */
    public static Date parseDate(String src, String pattern) throws ParseException {
        return getSdFormat(pattern).parse(src);
    }
    /**
     * æ ¹æ®æŒ‡å®šçš„æ ¼å¼å°†å­—符串转换成Date å¦‚输入:2003-11-19 11:20:20将按照这个转成时间
     *
     * @param src     å°†è¦è½¬æ¢çš„原始字符窜
     * @param pattern è½¬æ¢çš„匹配格式
     * @return å¦‚果转换成功则返回转换后的日期
     * @throws ParseException
     */
    public static Calendar parseCalendar(String src, String pattern) throws ParseException {
        Date date = parseDate(src, pattern);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        return cal;
    }
    public static String formatAddDate(String src, String pattern, int amount) throws ParseException {
        Calendar cal;
        cal = parseCalendar(src, pattern);
        cal.add(Calendar.DATE, amount);
        return formatDate(cal);
    }
    /**
     * æ ¹æ®æŒ‡å®šçš„æ ¼å¼å°†å­—符串转换成Date å¦‚输入:2003-11-19 11:20:20将按照这个转成时间
     *
     * @param src     å°†è¦è½¬æ¢çš„原始字符窜
     * @param pattern è½¬æ¢çš„匹配格式
     * @return å¦‚果转换成功则返回转换后的时间戳
     * @throws ParseException
     */
    public static Timestamp parseTimestamp(String src, String pattern) throws ParseException {
        Date date = parseDate(src, pattern);
        return new Timestamp(date.getTime());
    }
    // ////////////////////////////////////////////////////////////////////////////
    // dateDiff
    // è®¡ç®—两个日期之间的差值
    // ////////////////////////////////////////////////////////////////////////////
    /**
     * è®¡ç®—两个时间之间的差值,根据标志的不同而不同
     *
     * @param flag   è®¡ç®—标志,表示按照年/月/日/时/分/秒等计算
     * @param calSrc å‡æ•°
     * @param calDes è¢«å‡æ•°
     * @return ä¸¤ä¸ªæ—¥æœŸä¹‹é—´çš„差值
     */
    public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) {
        long millisDiff = getMillis(calSrc) - getMillis(calDes);
        char year = 'y';
        char day = 'd';
        char hour = 'h';
        char minute = 'm';
        char second = 's';
        if (flag == year) {
            return (calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR));
        }
        if (flag == day) {
            return (int) (millisDiff / DAY_IN_MILLIS);
        }
        if (flag == hour) {
            return (int) (millisDiff / HOUR_IN_MILLIS);
        }
        if (flag == minute) {
            return (int) (millisDiff / MINUTE_IN_MILLIS);
        }
        if (flag == second) {
            return (int) (millisDiff / SECOND_IN_MILLIS);
        }
        return 0;
    }
    public static Long getCurrentTimestamp() {
        return Long.valueOf(DateUtils.yyyymmddhhmmss.get().format(new Date()));
    }
    /**
     * String类型 è½¬æ¢ä¸ºDate, å¦‚果参数长度为10 è½¬æ¢æ ¼å¼â€yyyy-MM-dd“ å¦‚果参数长度为19 è½¬æ¢æ ¼å¼â€yyyy-MM-dd
     * HH:mm:ss“ * @param text String类型的时间值
     */
  public static ThreadLocal<SimpleDateFormat> date_sdf = new ThreadLocal<SimpleDateFormat>() {
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        if (StringUtils.hasText(text)) {
            try {
                int length10 = 10;
                int length19 = 19;
                if (text.indexOf(SymbolConstant.COLON) == -1 && text.length() == length10) {
                    setValue(DateUtils.date_sdf.get().parse(text));
                } else if (text.indexOf(SymbolConstant.COLON) > 0 && text.length() == length19) {
                    setValue(DateUtils.datetimeFormat.get().parse(text));
                } else {
                    throw new IllegalArgumentException("Could not parse date, date format is error ");
                }
            } catch (ParseException ex) {
                IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage());
                iae.initCause(ex);
                throw iae;
            }
        } else {
            setValue(null);
        }
    protected SimpleDateFormat initialValue() {
      return new SimpleDateFormat("yyyy-MM-dd");
    }
    public static int getYear() {
        GregorianCalendar calendar = new GregorianCalendar();
        calendar.setTime(getDate());
        return calendar.get(Calendar.YEAR);
  };
  public static ThreadLocal<SimpleDateFormat> yyyyMMdd = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
      return new SimpleDateFormat("yyyyMMdd");
    }
  };
  public static ThreadLocal<SimpleDateFormat> date_sdf_wz = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
      return new SimpleDateFormat("yyyyå¹´MM月dd日");
    }
  };
  public static ThreadLocal<SimpleDateFormat> time_sdf = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
      return new SimpleDateFormat("yyyy-MM-dd HH:mm");
    }
  };
  public static ThreadLocal<SimpleDateFormat> yyyymmddhhmmss = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
      return new SimpleDateFormat("yyyyMMddHHmmss");
    }
  };
  public static ThreadLocal<SimpleDateFormat> short_time_sdf = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
      return new SimpleDateFormat("HH:mm");
    }
  };
  public static ThreadLocal<SimpleDateFormat> datetimeFormat = new ThreadLocal<SimpleDateFormat>() {
    @Override
    protected SimpleDateFormat initialValue() {
      return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }
  };
    /**
     * å°†å­—符串转成时间
     * @param str
     * @return
     */
    public static Date parseDatetime(String str){
        try {
            return datetimeFormat.get().parse(str);
        }catch (Exception e){
        }
  /**
   * ä»¥æ¯«ç§’表示的时间
   */
  private static final long DAY_IN_MILLIS = 24 * 3600 * 1000;
  private static final long HOUR_IN_MILLIS = 3600 * 1000;
  private static final long MINUTE_IN_MILLIS = 60 * 1000;
  private static final long SECOND_IN_MILLIS = 1000;
  /**
   * æŒ‡å®šæ¨¡å¼çš„æ—¶é—´æ ¼å¼
   *
   * @param pattern
   * @return
   */
  private static SimpleDateFormat getSdFormat(String pattern) {
    return new SimpleDateFormat(pattern);
  }
  /**
   * å½“前日历,这里用中国时间表示
   *
   * @return ä»¥å½“地时区表示的系统当前日历
   */
  public static Calendar getCalendar() {
    return Calendar.getInstance();
  }
  /**
   * æŒ‡å®šæ¯«ç§’数表示的日历
   *
   * @param millis æ¯«ç§’æ•°
   * @return æŒ‡å®šæ¯«ç§’数表示的日历
   */
  public static Calendar getCalendar(long millis) {
    Calendar cal = Calendar.getInstance();
    // --------------------cal.setTimeInMillis(millis);
    cal.setTime(new Date(millis));
    return cal;
  }
  // ////////////////////////////////////////////////////////////////////////////
  // getDate
  // å„种方式获取的Date
  // ////////////////////////////////////////////////////////////////////////////
  /**
   * å½“前日期
   *
   * @return ç³»ç»Ÿå½“前时间
   */
  public static Date getDate() {
    return new Date();
  }
  /**
   * æŒ‡å®šæ¯«ç§’数表示的日期
   *
   * @param millis æ¯«ç§’æ•°
   * @return æŒ‡å®šæ¯«ç§’数表示的日期
   */
  public static Date getDate(long millis) {
    return new Date(millis);
  }
  /**
   * æ—¶é—´æˆ³è½¬æ¢ä¸ºå­—符串
   *
   * @param time
   * @return
   */
  public static String timestamptoStr(Timestamp time) {
    Date date = null;
    if (null != time) {
      date = new Date(time.getTime());
    }
    return date2Str(date_sdf.get());
  }
  /**
   * æ—¶é—´æˆ³è½¬æ¢ä¸ºå­—符串
   *
   * @param time
   * @return
   */
  public static String timestamptoStr(Long time, SimpleDateFormat sdf) {
    Date date = null;
    if (null != time) {
      date = new Date(time);
    }
    return date2Str(date, sdf);
  }
  /**
   * å­—符串转换时间戳
   *
   * @param str
   * @return
   */
  public static Timestamp str2Timestamp(String str) {
    Date date = str2Date(str, date_sdf.get());
    return new Timestamp(date.getTime());
  }
  /**
   * å­—符串转换成日期
   *
   * @param str
   * @param sdf
   * @return
   */
  public static Date str2Date(String str, SimpleDateFormat sdf) {
    if (null == str || "".equals(str)) {
      return null;
    }
    Date date = null;
    try {
      date = sdf.parse(str);
      return date;
    } catch (ParseException e) {
      e.printStackTrace();
    }
    return null;
  }
  /**
   * æ—¥æœŸè½¬æ¢ä¸ºå­—符串
   *
   * @param dateSdf æ—¥æœŸæ ¼å¼
   * @return å­—符串
   */
  public static String date2Str(SimpleDateFormat dateSdf) {
    synchronized (dateSdf) {
      Date date = getDate();
      if (null == date) {
        return null;
      }
      return dateSdf.format(date);
    }
  }
  /**
   * æ ¼å¼åŒ–æ—¶é—´
   *
   * @param date
   * @param format
   * @return
   */
  public static String dateformat(String date, String format) {
    SimpleDateFormat sformat = new SimpleDateFormat(format);
    Date nowDate = null;
    try {
      nowDate = sformat.parse(date);
    } catch (ParseException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return sformat.format(nowDate);
  }
  /**
   * æ—¥æœŸè½¬æ¢ä¸ºå­—符串
   *
   * @param date    æ—¥æœŸ
   * @param dateSdf æ—¥æœŸæ ¼å¼
   * @return å­—符串
   */
  public static String date2Str(Date date, SimpleDateFormat dateSdf) {
    synchronized (dateSdf) {
      if (null == date) {
        return null;
      }
      return dateSdf.format(date);
    }
  }
  /**
   * æ—¥æœŸè½¬æ¢ä¸ºå­—符串
   *
   * @param format æ—¥æœŸæ ¼å¼
   * @return å­—符串
   */
  public static String getDate(String format) {
    Date date = new Date();
    if (null == date) {
      return null;
    }
    SimpleDateFormat sdf = new SimpleDateFormat(format);
    return sdf.format(date);
  }
  /**
   * æŒ‡å®šæ¯«ç§’数的时间戳
   *
   * @param millis æ¯«ç§’æ•°
   * @return æŒ‡å®šæ¯«ç§’数的时间戳
   */
  public static Timestamp getTimestamp(long millis) {
    return new Timestamp(millis);
  }
  /**
   * ä»¥å­—符形式表示的时间戳
   *
   * @param time æ¯«ç§’æ•°
   * @return ä»¥å­—符形式表示的时间戳
   */
  public static Timestamp getTimestamp(String time) {
    return new Timestamp(Long.parseLong(time));
  }
  /**
   * ç³»ç»Ÿå½“前的时间戳
   *
   * @return ç³»ç»Ÿå½“前的时间戳
   */
  public static Timestamp getTimestamp() {
    return new Timestamp(System.currentTimeMillis());
  }
  /**
   * å½“前时间,格式 yyyy-MM-dd HH:mm:ss
   *
   * @return å½“前时间的标准形式字符串
   */
  public static String now() {
    return datetimeFormat.get().format(getCalendar().getTime());
  }
  /**
   * æŒ‡å®šæ—¥æœŸçš„æ—¶é—´æˆ³
   *
   * @param date æŒ‡å®šæ—¥æœŸ
   * @return æŒ‡å®šæ—¥æœŸçš„æ—¶é—´æˆ³
   */
  public static Timestamp getTimestamp(Date date) {
    return new Timestamp(date.getTime());
  }
  /**
   * æŒ‡å®šæ—¥åŽ†çš„æ—¶é—´æˆ³
   *
   * @param cal æŒ‡å®šæ—¥åކ
   * @return æŒ‡å®šæ—¥åŽ†çš„æ—¶é—´æˆ³
   */
  public static Timestamp getCalendarTimestamp(Calendar cal) {
    // ---------------------return new Timestamp(cal.getTimeInMillis());
    return new Timestamp(cal.getTime().getTime());
  }
  public static Timestamp gettimestamp() {
    Date dt = new Date();
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String nowTime = df.format(dt);
    java.sql.Timestamp buydate = java.sql.Timestamp.valueOf(nowTime);
    return buydate;
  }
  // ////////////////////////////////////////////////////////////////////////////
  // getMillis
  // å„种方式获取的Millis
  // ////////////////////////////////////////////////////////////////////////////
  /**
   * ç³»ç»Ÿæ—¶é—´çš„æ¯«ç§’æ•°
   *
   * @return ç³»ç»Ÿæ—¶é—´çš„æ¯«ç§’æ•°
   */
  public static long getMillis() {
    return System.currentTimeMillis();
  }
  /**
   * æŒ‡å®šæ—¥åŽ†çš„æ¯«ç§’æ•°
   *
   * @param cal æŒ‡å®šæ—¥åކ
   * @return æŒ‡å®šæ—¥åŽ†çš„æ¯«ç§’æ•°
   */
  public static long getMillis(Calendar cal) {
    // --------------------return cal.getTimeInMillis();
    return cal.getTime().getTime();
  }
  /**
   * æŒ‡å®šæ—¥æœŸçš„æ¯«ç§’æ•°
   *
   * @param date æŒ‡å®šæ—¥æœŸ
   * @return æŒ‡å®šæ—¥æœŸçš„æ¯«ç§’æ•°
   */
  public static long getMillis(Date date) {
    return date.getTime();
  }
  /**
   * æŒ‡å®šæ—¶é—´æˆ³çš„æ¯«ç§’æ•°
   *
   * @param ts æŒ‡å®šæ—¶é—´æˆ³
   * @return æŒ‡å®šæ—¶é—´æˆ³çš„æ¯«ç§’æ•°
   */
  public static long getMillis(Timestamp ts) {
    return ts.getTime();
  }
  // ////////////////////////////////////////////////////////////////////////////
  // formatDate
  // å°†æ—¥æœŸæŒ‰ç…§ä¸€å®šçš„æ ¼å¼è½¬åŒ–为字符串
  // ////////////////////////////////////////////////////////////////////////////
  /**
   * é»˜è®¤æ–¹å¼è¡¨ç¤ºçš„系统当前日期,具体格式:年-月-日
   *
   * @return é»˜è®¤æ—¥æœŸæŒ‰â€œå¹´-月-日“格式显示
   */
  public static String formatDate() {
    return date_sdf.get().format(getCalendar().getTime());
  }
  /**
   * é»˜è®¤æ–¹å¼è¡¨ç¤ºçš„系统当前日期,具体格式:yyyy-MM-dd HH:mm:ss
   *
   * @return é»˜è®¤æ—¥æœŸæŒ‰â€œyyyy-MM-dd HH:mm:ss“格式显示
   */
  public static String formatDateTime() {
    return datetimeFormat.get().format(getCalendar().getTime());
  }
  /**
   * èŽ·å–æ—¶é—´å­—ç¬¦ä¸²
   */
  public static String getDataString(SimpleDateFormat formatstr) {
    synchronized (formatstr) {
      return formatstr.format(getCalendar().getTime());
    }
  }
  /**
   * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:年-月-日
   *
   * @param cal æŒ‡å®šçš„æ—¥æœŸ
   * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œå¹´-月-日“格式显示
   */
  public static String formatDate(Calendar cal) {
    return date_sdf.get().format(cal.getTime());
  }
  /**
   * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:年-月-日
   *
   * @param date æŒ‡å®šçš„æ—¥æœŸ
   * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œå¹´-月-日“格式显示
   */
  public static String formatDate(Date date) {
    return date_sdf.get().format(date);
  }
  /**
   * æŒ‡å®šæ¯«ç§’数表示日期的默认显示,具体格式:年-月-日
   *
   * @param millis æŒ‡å®šçš„æ¯«ç§’æ•°
   * @return æŒ‡å®šæ¯«ç§’数表示日期按“年-月-日“格式显示
   */
  public static String formatDate(long millis) {
    return date_sdf.get().format(new Date(millis));
  }
  /**
   * é»˜è®¤æ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
   *
   * @param pattern æŒ‡å®šçš„æ ¼å¼
   * @return é»˜è®¤æ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
   */
  public static String formatDate(String pattern) {
    return getSdFormat(pattern).format(getCalendar().getTime());
  }
  /**
   * æŒ‡å®šæ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
   *
   * @param cal     æŒ‡å®šçš„æ—¥æœŸ
   * @param pattern æŒ‡å®šçš„æ ¼å¼
   * @return æŒ‡å®šæ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
   */
  public static String formatDate(Calendar cal, String pattern) {
    return getSdFormat(pattern).format(cal.getTime());
  }
  /**
   * æŒ‡å®šæ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
   *
   * @param date    æŒ‡å®šçš„æ—¥æœŸ
   * @param pattern æŒ‡å®šçš„æ ¼å¼
   * @return æŒ‡å®šæ—¥æœŸæŒ‰æŒ‡å®šæ ¼å¼æ˜¾ç¤º
   */
  public static String formatDate(Date date, String pattern) {
    return getSdFormat(pattern).format(date);
  }
  // ////////////////////////////////////////////////////////////////////////////
  // formatTime
  // å°†æ—¥æœŸæŒ‰ç…§ä¸€å®šçš„æ ¼å¼è½¬åŒ–为字符串
  // ////////////////////////////////////////////////////////////////////////////
  /**
   * é»˜è®¤æ–¹å¼è¡¨ç¤ºçš„系统当前日期,具体格式:年-月-日 æ—¶ï¼šåˆ†
   *
   * @return é»˜è®¤æ—¥æœŸæŒ‰â€œå¹´-月-日 æ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
   */
  public static String formatTime() {
    return time_sdf.get().format(getCalendar().getTime());
  }
  /**
   * æŒ‡å®šæ¯«ç§’数表示日期的默认显示,具体格式:年-月-日 æ—¶ï¼šåˆ†
   *
   * @param millis æŒ‡å®šçš„æ¯«ç§’æ•°
   * @return æŒ‡å®šæ¯«ç§’数表示日期按“年-月-日 æ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
   */
  public static String formatTime(long millis) {
    return time_sdf.get().format(new Date(millis));
  }
  /**
   * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:年-月-日 æ—¶ï¼šåˆ†
   *
   * @param cal æŒ‡å®šçš„æ—¥æœŸ
   * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œå¹´-月-日 æ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
   */
  public static String formatTime(Calendar cal) {
    return time_sdf.get().format(cal.getTime());
  }
  /**
   * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:年-月-日 æ—¶ï¼šåˆ†
   *
   * @param date æŒ‡å®šçš„æ—¥æœŸ
   * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œå¹´-月-日 æ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
   */
  public static String formatTime(Date date) {
    return time_sdf.get().format(date);
  }
  // ////////////////////////////////////////////////////////////////////////////
  // formatShortTime
  // å°†æ—¥æœŸæŒ‰ç…§ä¸€å®šçš„æ ¼å¼è½¬åŒ–为字符串
  // ////////////////////////////////////////////////////////////////////////////
  /**
   * é»˜è®¤æ–¹å¼è¡¨ç¤ºçš„系统当前日期,具体格式:时:分
   *
   * @return é»˜è®¤æ—¥æœŸæŒ‰â€œæ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
   */
  public static String formatShortTime() {
    return short_time_sdf.get().format(getCalendar().getTime());
  }
  /**
   * æŒ‡å®šæ¯«ç§’数表示日期的默认显示,具体格式:时:分
   *
   * @param millis æŒ‡å®šçš„æ¯«ç§’æ•°
   * @return æŒ‡å®šæ¯«ç§’数表示日期按“时:分“格式显示
   */
  public static String formatShortTime(long millis) {
    return short_time_sdf.get().format(new Date(millis));
  }
  /**
   * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:时:分
   *
   * @param cal æŒ‡å®šçš„æ—¥æœŸ
   * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œæ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
   */
  public static String formatShortTime(Calendar cal) {
    return short_time_sdf.get().format(cal.getTime());
  }
  /**
   * æŒ‡å®šæ—¥æœŸçš„默认显示,具体格式:时:分
   *
   * @param date æŒ‡å®šçš„æ—¥æœŸ
   * @return æŒ‡å®šæ—¥æœŸæŒ‰â€œæ—¶ï¼šåˆ†â€œæ ¼å¼æ˜¾ç¤º
   */
  public static String formatShortTime(Date date) {
    return short_time_sdf.get().format(date);
  }
  // ////////////////////////////////////////////////////////////////////////////
  // parseDate
  // parseCalendar
  // parseTimestamp
  // å°†å­—符串按照一定的格式转化为日期或时间
  // ////////////////////////////////////////////////////////////////////////////
  /**
   * æ ¹æ®æŒ‡å®šçš„æ ¼å¼å°†å­—符串转换成Date å¦‚输入:2003-11-19 11:20:20将按照这个转成时间
   *
   * @param src     å°†è¦è½¬æ¢çš„原始字符窜
   * @param pattern è½¬æ¢çš„匹配格式
   * @return å¦‚果转换成功则返回转换后的日期
   * @throws ParseException
   */
  public static Date parseDate(String src, String pattern) throws ParseException {
    return getSdFormat(pattern).parse(src);
  }
  /**
   * æ ¹æ®æŒ‡å®šçš„æ ¼å¼å°†å­—符串转换成Date å¦‚输入:2003-11-19 11:20:20将按照这个转成时间
   *
   * @param src     å°†è¦è½¬æ¢çš„原始字符窜
   * @param pattern è½¬æ¢çš„匹配格式
   * @return å¦‚果转换成功则返回转换后的日期
   * @throws ParseException
   */
  public static Calendar parseCalendar(String src, String pattern) throws ParseException {
    Date date = parseDate(src, pattern);
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    return cal;
  }
  public static String formatAddDate(String src, String pattern, int amount) throws ParseException {
    Calendar cal;
    cal = parseCalendar(src, pattern);
    cal.add(Calendar.DATE, amount);
    return formatDate(cal);
  }
  /**
   * æ ¹æ®æŒ‡å®šçš„æ ¼å¼å°†å­—符串转换成Date å¦‚输入:2003-11-19 11:20:20将按照这个转成时间
   *
   * @param src     å°†è¦è½¬æ¢çš„原始字符窜
   * @param pattern è½¬æ¢çš„匹配格式
   * @return å¦‚果转换成功则返回转换后的时间戳
   * @throws ParseException
   */
  public static Timestamp parseTimestamp(String src, String pattern) throws ParseException {
    Date date = parseDate(src, pattern);
    return new Timestamp(date.getTime());
  }
  // ////////////////////////////////////////////////////////////////////////////
  // dateDiff
  // è®¡ç®—两个日期之间的差值
  // ////////////////////////////////////////////////////////////////////////////
  /**
   * è®¡ç®—两个时间之间的差值,根据标志的不同而不同
   *
   * @param flag   è®¡ç®—标志,表示按照年/月/日/时/分/秒等计算
   * @param calSrc å‡æ•°
   * @param calDes è¢«å‡æ•°
   * @return ä¸¤ä¸ªæ—¥æœŸä¹‹é—´çš„差值
   */
  public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) {
    long millisDiff = getMillis(calSrc) - getMillis(calDes);
    char year = 'y';
    char day = 'd';
    char hour = 'h';
    char minute = 'm';
    char second = 's';
    if (flag == year) {
      return (calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR));
    }
    /**
     * åˆ¤æ–­ä¸¤ä¸ªæ—¶é—´æ˜¯å¦æ˜¯åŒä¸€å¤©
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameDay(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return false;
    if (flag == day) {
      return (int) (millisDiff / DAY_IN_MILLIS);
    }
    if (flag == hour) {
      return (int) (millisDiff / HOUR_IN_MILLIS);
    }
    if (flag == minute) {
      return (int) (millisDiff / MINUTE_IN_MILLIS);
    }
    if (flag == second) {
      return (int) (millisDiff / SECOND_IN_MILLIS);
    }
    return 0;
  }
  public static Long getCurrentTimestamp() {
    return Long.valueOf(DateUtils.yyyymmddhhmmss.get().format(new Date()));
  }
  /**
   * String类型 è½¬æ¢ä¸ºDate, å¦‚果参数长度为10 è½¬æ¢æ ¼å¼â€yyyy-MM-dd“ å¦‚果参数长度为19 è½¬æ¢æ ¼å¼â€yyyy-MM-dd
   * HH:mm:ss“ * @param text String类型的时间值
   */
  @Override
  public void setAsText(String text) throws IllegalArgumentException {
    if (StringUtils.hasText(text)) {
      try {
        int length10 = 10;
        int length19 = 19;
        if (text.indexOf(SymbolConstant.COLON) == -1 && text.length() == length10) {
          setValue(DateUtils.date_sdf.get().parse(text));
        } else if (text.indexOf(SymbolConstant.COLON) > 0 && text.length() == length19) {
          setValue(DateUtils.datetimeFormat.get().parse(text));
        } else {
          throw new IllegalArgumentException("Could not parse date, date format is error ");
        }
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);
        boolean isSameYear = calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
        boolean isSameMonth = isSameYear && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
        return isSameMonth && calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
      } catch (ParseException ex) {
        IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage());
        iae.initCause(ex);
        throw iae;
      }
    } else {
      setValue(null);
    }
  }
    /**
     * åˆ¤æ–­ä¸¤ä¸ªæ—¶é—´æ˜¯å¦æ˜¯åŒä¸€å‘¨
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameWeek(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return false;
        }
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);
        boolean isSameYear = calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
        return isSameYear && calendar1.get(Calendar.WEEK_OF_YEAR) == calendar2.get(Calendar.WEEK_OF_YEAR);
  public static int getYear() {
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTime(getDate());
    return calendar.get(Calendar.YEAR);
  }
  /**
   * å°†å­—符串转成时间
   *
   * @param str
   * @return
   */
  public static Date parseDatetime(String str) {
    try {
      return datetimeFormat.get().parse(str);
    } catch (Exception e) {
    }
    return null;
  }
    /**
     * åˆ¤æ–­ä¸¤ä¸ªæ—¶é—´æ˜¯å¦æ˜¯åŒä¸€æœˆ
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameMonth(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return false;
        }
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);
        boolean isSameYear = calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
        return isSameYear && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
  /**
   * åˆ¤æ–­ä¸¤ä¸ªæ—¶é—´æ˜¯å¦æ˜¯åŒä¸€å¤©
   *
   * @param date1
   * @param date2
   * @return
   */
  public static boolean isSameDay(Date date1, Date date2) {
    if (date1 == null || date2 == null) {
      return false;
    }
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(date1);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(date2);
    boolean isSameYear = calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
    boolean isSameMonth = isSameYear && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
    return isSameMonth && calendar1.get(Calendar.DAY_OF_MONTH) == calendar2.get(Calendar.DAY_OF_MONTH);
  }
    /**
     * åˆ¤æ–­ä¸¤ä¸ªæ—¶é—´æ˜¯å¦æ˜¯åŒä¸€å¹´
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isSameYear(Date date1, Date date2) {
        if (date1 == null || date2 == null) {
            return false;
        }
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date1);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(date2);
        return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
  /**
   * åˆ¤æ–­ä¸¤ä¸ªæ—¶é—´æ˜¯å¦æ˜¯åŒä¸€å‘¨
   *
   * @param date1
   * @param date2
   * @return
   */
  public static boolean isSameWeek(Date date1, Date date2) {
    if (date1 == null || date2 == null) {
      return false;
    }
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(date1);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(date2);
    boolean isSameYear = calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
    return isSameYear && calendar1.get(Calendar.WEEK_OF_YEAR) == calendar2.get(Calendar.WEEK_OF_YEAR);
  }
}
  /**
   * åˆ¤æ–­ä¸¤ä¸ªæ—¶é—´æ˜¯å¦æ˜¯åŒä¸€æœˆ
   *
   * @param date1
   * @param date2
   * @return
   */
  public static boolean isSameMonth(Date date1, Date date2) {
    if (date1 == null || date2 == null) {
      return false;
    }
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(date1);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(date2);
    boolean isSameYear = calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
    return isSameYear && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH);
  }
  /**
   * ç‰¹æ®Šæ—¶é—´str转正常str
   *
   * @param st 2024-08-14T01:07:36.761+00:00
   * @return
   */
  public static String zone2Str(String st) {
    // è§£æžå­—符串为ZonedDateTime对象
    ZonedDateTime zonedDateTime = ZonedDateTime.parse(st);
    // è½¬æ¢ä¸ºä¸­å›½æ ‡å‡†æ—¶é—´ï¼ˆUTC+8)
    ZonedDateTime cstDateTime = zonedDateTime.withZoneSameInstant(java.time.ZoneOffset.ofHours(8));
    // å®šä¹‰æƒ³è¦çš„输出格式
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    // æ ¼å¼åŒ–为想要的字符串
    String str = cstDateTime.format(formatter);
    return str;
  }
  /**
   * åˆ¤æ–­ä¸¤ä¸ªæ—¶é—´æ˜¯å¦æ˜¯åŒä¸€å¹´
   *
   * @param date1
   * @param date2
   * @return
   */
  public static boolean isSameYear(Date date1, Date date2) {
    if (date1 == null || date2 == null) {
      return false;
    }
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(date1);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(date2);
    return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR);
  }
}
jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/service/BaseCommonService.java
@@ -32,4 +32,12 @@
     */
    void addLog(String logContent, Integer logType, Integer operateType);
  /**
   * ä¿å­˜æ—¥å¿—
   * @param logContent
   * @param logType
   * @param operateType
   */
  void addLog(String logContent, Integer logType, Integer operateType,Integer tenantId,String methods);
}
jeecg-boot-base-core/src/main/java/org/jeecg/modules/base/service/impl/BaseCommonServiceImpl.java
@@ -24,67 +24,95 @@
@Slf4j
public class BaseCommonServiceImpl implements BaseCommonService {
    @Resource
    private BaseCommonMapper baseCommonMapper;
  @Resource
  private BaseCommonMapper baseCommonMapper;
    @Override
    public void addLog(LogDTO logDTO) {
        if(oConvertUtils.isEmpty(logDTO.getId())){
            logDTO.setId(String.valueOf(IdWorker.getId()));
        }
        //保存日志(异常捕获处理,防止数据太大存储失败,导致业务失败)JT-238
        try {
            logDTO.setCreateTime(new Date());
            baseCommonMapper.saveLog(logDTO);
        } catch (Exception e) {
            log.warn(" LogContent length : "+logDTO.getLogContent().length());
            log.warn(e.getMessage());
        }
  @Override
  public void addLog(LogDTO logDTO) {
    if (oConvertUtils.isEmpty(logDTO.getId())) {
      logDTO.setId(String.valueOf(IdWorker.getId()));
    }
    //保存日志(异常捕获处理,防止数据太大存储失败,导致业务失败)JT-238
    try {
      logDTO.setCreateTime(new Date());
      baseCommonMapper.saveLog(logDTO);
    } catch (Exception e) {
      log.warn(" LogContent length : " + logDTO.getLogContent().length());
      log.warn(e.getMessage());
    }
  }
  @Override
  public void addLog(String logContent, Integer logType, Integer operatetype, LoginUser user) {
    LogDTO sysLog = new LogDTO();
    sysLog.setId(String.valueOf(IdWorker.getId()));
    //注解上的描述,操作日志内容
    sysLog.setLogContent(logContent);
    sysLog.setLogType(logType);
    sysLog.setOperateType(operatetype);
    try {
      //获取request
      HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
      //设置IP地址
      sysLog.setIp(IpUtils.getIpAddr(request));
    } catch (Exception e) {
      sysLog.setIp("127.0.0.1");
    }
    //获取登录用户信息
    if (user == null) {
      try {
        user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
      } catch (Exception e) {
        //e.printStackTrace();
      }
    }
    if (user != null) {
      sysLog.setUserid(user.getUsername());
      sysLog.setUsername(user.getRealname());
    }
    sysLog.setCreateTime(new Date());
    //保存日志(异常捕获处理,防止数据太大存储失败,导致业务失败)JT-238
    try {
      baseCommonMapper.saveLog(sysLog);
    } catch (Exception e) {
      log.warn(" LogContent length : " + sysLog.getLogContent().length());
      log.warn(e.getMessage());
    }
  }
  @Override
  public void addLog(String logContent, Integer logType, Integer operateType) {
    addLog(logContent, logType, operateType, null);
  }
  @Override
  public void addLog(String logContent, Integer logType, Integer operatetype, Integer tenantId, String methods) {
    LogDTO sysLog = new LogDTO();
    sysLog.setId(String.valueOf(IdWorker.getId()));
    //注解上的描述,操作日志内容
    sysLog.setLogContent(logContent);
    sysLog.setLogType(logType);
    sysLog.setOperateType(operatetype);
    sysLog.setMethod(methods);
    sysLog.setTenantId(tenantId);
    try {
      //获取request
      HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
      //设置IP地址
      sysLog.setIp(IpUtils.getIpAddr(request));
    } catch (Exception e) {
      sysLog.setIp("127.0.0.1");
    }
    @Override
    public void addLog(String logContent, Integer logType, Integer operatetype, LoginUser user) {
        LogDTO sysLog = new LogDTO();
        sysLog.setId(String.valueOf(IdWorker.getId()));
        //注解上的描述,操作日志内容
        sysLog.setLogContent(logContent);
        sysLog.setLogType(logType);
        sysLog.setOperateType(operatetype);
        try {
            //获取request
            HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
            //设置IP地址
            sysLog.setIp(IpUtils.getIpAddr(request));
        } catch (Exception e) {
            sysLog.setIp("127.0.0.1");
        }
        //获取登录用户信息
        if(user==null){
            try {
                user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
            } catch (Exception e) {
                //e.printStackTrace();
            }
        }
        if(user!=null){
            sysLog.setUserid(user.getUsername());
            sysLog.setUsername(user.getRealname());
        }
        sysLog.setCreateTime(new Date());
        //保存日志(异常捕获处理,防止数据太大存储失败,导致业务失败)JT-238
        try {
            baseCommonMapper.saveLog(sysLog);
        } catch (Exception e) {
            log.warn(" LogContent length : "+sysLog.getLogContent().length());
            log.warn(e.getMessage());
        }
    sysLog.setCreateTime(new Date());
    //保存日志(异常捕获处理,防止数据太大存储失败,导致业务失败)JT-238
    try {
      baseCommonMapper.saveLog(sysLog);
    } catch (Exception e) {
      log.warn(" LogContent length : " + sysLog.getLogContent().length());
      log.warn(e.getMessage());
    }
    @Override
    public void addLog(String logContent, Integer logType, Integer operateType) {
        addLog(logContent, logType, operateType, null);
    }
  }
}
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/api/EmqxApi.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
package org.jeecg.modules.dry.api;
import com.alibaba.fastjson.JSONObject;
import okhttp3.Credentials;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
 * emqx rest api
 * å…¥å‚出参参考:https://docs.emqx.com/zh/emqx/v5.7/admin/api-docs.html
 */
@Component
public class EmqxApi {
  @Value(value = "${jeecg.mqtt.emqx_api_key}")
  private String emqxApiKey;
  @Value(value = "${jeecg.mqtt.emqx_secret_key}")
  private String emqxSecretKey;
  @Value(value = "${jeecg.mqtt.emqx_base}")
  private String emqxBaseUrl;
  //所有客户端
  public static final String CMD_CLIENTS = "/clients";
  //查询一个客户端状态
  public static final String CMD_CLIENTS_CLIENT = "/clients/%s";
  /**
   * EMQX接口
   *
   * @return
   */
  public JSONObject queryEmqx(String cmd) {
    try {
      OkHttpClient client = new OkHttpClient();
      Request request = new Request.Builder()
        .url(emqxBaseUrl + cmd)
        .header("Content-Type", "application/json")
        .header("Authorization", Credentials.basic(emqxApiKey, emqxSecretKey))
        .build();
      Response response = client.newCall(request).execute();
      String res = response.body().string();
      return JSONObject.parseObject(res);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
}
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/api/EmqxApi.txt
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,180 @@
//接口返回数据示例
1.clients:
{
    "data": [
        {
            "recv_msg.qos0": 0,
            "recv_oct": 603,
            "recv_msg.qos2": 0,
            "clean_start": true,
            "enable_authn": true,
            "send_msg.dropped.queue_full": 0,
            "proto_name": "MQTT",
            "listener": "tcp:default",
            "send_msg.qos0": 28,
            "user_property": {},
            "keepalive": 60,
            "username": "tongjitang",
            "proto_ver": 5,
            "node": "emqx@172.17.0.2",
            "mqueue_dropped": 0,
            "send_cnt": 243,
            "ip_address": "172.17.0.1",
            "created_at": "2024-08-07T01:23:29.226+00:00",
            "auth_expire_at": null,
            "recv_msg.qos1": 0,
            "durable": false,
            "is_bridge": false,
            "recv_msg.dropped": 0,
            "subscriptions_cnt": 5,
            "send_oct": 5886,
            "expiry_interval": 0,
            "heap_size": 610,
            "awaiting_rel_cnt": 0,
            "connected_at": "2024-08-07T01:23:29.226+00:00",
            "clientid": "1000_GM003",
            "inflight_cnt": 0,
            "port": 38422,
            "send_msg.dropped.expired": 0,
            "send_msg": 28,
            "mailbox_len": 0,
            "mountpoint": null,
            "send_msg.qos2": 0,
            "recv_msg.dropped.await_pubrel_timeout": 0,
            "recv_msg": 0,
            "send_msg.qos1": 0,
            "send_msg.dropped.too_large": 0,
            "send_msg.dropped": 0,
            "subscriptions_max": "infinity",
            "send_pkt": 243,
            "inflight_max": 32,
            "recv_pkt": 215,
            "client_attrs": {},
            "connected": true,
            "reductions": 204416,
            "awaiting_rel_max": 100,
            "is_persistent": false,
            "mqueue_max": 1000,
            "mqueue_len": 0,
            "recv_cnt": 215,
            "is_expired": false
        },
        {
            "recv_msg.qos0": 0,
            "recv_oct": 468,
            "recv_msg.qos2": 0,
            "clean_start": true,
            "enable_authn": true,
            "send_msg.dropped.queue_full": 0,
            "proto_name": "MQTT",
            "listener": "tcp:default",
            "send_msg.qos0": 0,
            "user_property": {},
            "keepalive": 60,
            "username": "tongjitang",
            "proto_ver": 5,
            "node": "emqx@172.17.0.2",
            "mqueue_dropped": 0,
            "send_cnt": 210,
            "ip_address": "172.17.0.1",
            "created_at": "2024-08-07T01:23:50.589+00:00",
            "auth_expire_at": null,
            "recv_msg.qos1": 0,
            "durable": false,
            "is_bridge": false,
            "recv_msg.dropped": 0,
            "subscriptions_cnt": 0,
            "send_oct": 442,
            "expiry_interval": 0,
            "heap_size": 610,
            "awaiting_rel_cnt": 0,
            "connected_at": "2024-08-07T01:23:50.589+00:00",
            "clientid": "1000_GM002",
            "inflight_cnt": 0,
            "port": 38424,
            "send_msg.dropped.expired": 0,
            "send_msg": 0,
            "mailbox_len": 0,
            "mountpoint": null,
            "send_msg.qos2": 0,
            "recv_msg.dropped.await_pubrel_timeout": 0,
            "recv_msg": 0,
            "send_msg.qos1": 0,
            "send_msg.dropped.too_large": 0,
            "send_msg.dropped": 0,
            "subscriptions_max": "infinity",
            "send_pkt": 210,
            "inflight_max": 32,
            "recv_pkt": 210,
            "client_attrs": {},
            "connected": true,
            "reductions": 171935,
            "awaiting_rel_max": 100,
            "is_persistent": false,
            "mqueue_max": 1000,
            "mqueue_len": 0,
            "recv_cnt": 210,
            "is_expired": false
        },
        {
            "recv_msg.qos0": 1,
            "recv_msg.qos2": 0,
            "clean_start": false,
            "enable_authn": true,
            "send_msg.dropped.queue_full": 0,
            "proto_name": "MQTT",
            "listener": "tcp:default",
            "send_msg.qos0": 0,
            "user_property": {},
            "keepalive": 10,
            "username": "tongjitang",
            "proto_ver": 4,
            "node": "emqx@172.17.0.2",
            "mqueue_dropped": 0,
            "ip_address": "172.17.0.1",
            "created_at": "2024-08-07T01:23:13.724+00:00",
            "auth_expire_at": null,
            "recv_msg.qos1": 0,
            "durable": false,
            "is_bridge": false,
            "recv_msg.dropped": 0,
            "subscriptions_cnt": 1,
            "disconnected_at": "2024-08-07T04:52:44.267+00:00",
            "expiry_interval": 7200,
            "heap_size": 610,
            "awaiting_rel_cnt": 0,
            "connected_at": "2024-08-07T02:41:51.865+00:00",
            "clientid": "1000_GM001",
            "inflight_cnt": 0,
            "port": 38454,
            "send_msg.dropped.expired": 0,
            "send_msg": 0,
            "mailbox_len": 0,
            "mountpoint": null,
            "send_msg.qos2": 0,
            "recv_msg.dropped.await_pubrel_timeout": 0,
            "recv_msg": 1,
            "send_msg.qos1": 0,
            "send_msg.dropped.too_large": 0,
            "send_msg.dropped": 0,
            "subscriptions_max": "infinity",
            "send_pkt": 786,
            "inflight_max": 32,
            "recv_pkt": 787,
            "client_attrs": {},
            "connected": false,
            "reductions": 386694,
            "awaiting_rel_max": 100,
            "is_persistent": true,
            "mqueue_max": 1000,
            "mqueue_len": 0,
            "is_expired": false
        }
    ],
    "meta": {
        "count": 3,
        "limit": 100,
        "page": 1,
        "hasnext": false
    }
}
jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/vo/MoEquVo.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,24 @@
package org.jeecg.modules.dry.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.jeecg.modules.dry.entity.DryEquipment;
import org.springframework.beans.BeanUtils;
/**
 * ç§»åŠ¨ç«¯-干燥机
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class MoEquVo extends DryEquipment {
  //设备是否在线
  private Boolean online;
  //设备工作状态
  private Integer statu;
  //开机时间
  private String upTime;
  //MQTT客户端id
  private String clientId;
}
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/MobileController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,97 @@
package org.jeecg.modules.dry.controller;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.MqttConstant;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.mybatis.MybatisPlusSaasConfig;
import org.jeecg.modules.dry.api.EmqxApi;
import org.jeecg.modules.dry.entity.DryEquipment;
import org.jeecg.modules.dry.service.IDryEquipmentService;
import org.jeecg.modules.dry.vo.MoEquVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@Api(tags = "移动端")
@RestController
@RequestMapping("/mobile")
@Slf4j
public class MobileController {
  @Autowired
  private IDryEquipmentService dryEquipmentService;
  @Autowired
  private RedisUtil redisUtil;
  @ApiOperation(value = "设备列表查询", notes = "设备列表查询")
  @GetMapping(value = "/equ/list")
  public Result<IPage<MoEquVo>> queryPageList(DryEquipment dryEquipment, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) {
    //------------------------------------------------------------------------------------------------
    //是否开启系统管理模块的多租户数据隔离【SAAS多租户模式】
    if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
      dryEquipment.setTenantId(oConvertUtils.getInt(TenantContext.getTenant(), 0));
    }
    //------------------------------------------------------------------------------------------------
    QueryWrapper<DryEquipment> queryWrapper = QueryGenerator.initQueryWrapper(dryEquipment, req.getParameterMap());
    Page<DryEquipment> page = new Page<DryEquipment>(pageNo, pageSize);
    Page<MoEquVo> voPage = new Page<MoEquVo>(pageNo, pageSize);
    IPage<DryEquipment> pageList = dryEquipmentService.page(page, queryWrapper);
    comp(pageList, voPage);
    return Result.OK(voPage);
  }
  private void comp(IPage<DryEquipment> pageList, Page<MoEquVo> page) {
    //当前租户id
    int tenantId = oConvertUtils.getInt(TenantContext.getTenant(), 0);
    List<MoEquVo> collect = pageList.getRecords().stream().map(item -> {
      MoEquVo vo = new MoEquVo();
      BeanUtils.copyProperties(item, vo);
      String clientid = "client-" + tenantId + "-" + item.getCode();
      JSONObject client = (JSONObject) redisUtil.get(MqttConstant.MQTT_ONLINE_CLIENT + clientid);
      //组装状态数据
      if (client != null) {
        vo.setOnline(true);
        //连接时间
        String st = client.getString("connectedAt");
        vo.setUpTime(st);
        vo.setClientId(clientid);
      }
      return vo;
    }).collect(Collectors.toList());
    //排序
    collect.sort(Comparator.comparing(obj -> obj.getCode(), Comparator.nullsLast(Comparator.naturalOrder())));
    collect.sort(Comparator.comparing(obj -> obj.getOnline(), Comparator.nullsLast(Comparator.naturalOrder())));
    BeanUtils.copyProperties(pageList, page);
    page.setRecords(collect);
  }
}
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/mqtt/MqttConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,182 @@
package org.jeecg.modules.dry.mqtt;
import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.jeecg.common.constant.MqttConstant;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.dry.api.EmqxApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.*;
/**
 * mqtt
 */
@Slf4j
@Configuration
public class MqttConfig {
  @Value(value = "${jeecg.mqtt.broker}")
  private String broker;
  @Value(value = "${jeecg.mqtt.mqtt_name}")
  private String mqttName;
  @Value(value = "${jeecg.mqtt.mqtt_pass}")
  private String mqttPass;
  @Value(value = "${jeecg.mqtt.mqtt_client_id}")
  private String mqttClientId;
  @Value(value = "${jeecg.mqtt.role}")
  private String role;
  @Autowired
  private MqttSampleCallback mqttSampleCallback;
  @Autowired
  private MqttUtil mqttUtil;
  @Autowired
  private RedisUtil redisUtil;
  @Autowired
  private EmqxApi emqxApi;
  @Bean
  public void initMqtt() {
    conn();
    reconn();
  }
  /**
   * mqtt连接配置
   */
  private void conn() {
    MemoryPersistence persistence = new MemoryPersistence();
    MqttConnectOptions mqttConnOpt = new MqttConnectOptions();
    mqttConnOpt.setUserName(mqttName);
    mqttConnOpt.setPassword(mqttPass.toCharArray());
    mqttConnOpt.setKeepAliveInterval(10);//设置心跳间隔
    mqttConnOpt.setConnectionTimeout(10);//设置连接超时时间
    mqttConnOpt.setCleanSession(false);//设置是否清除会话
    mqttConnOpt.setAutomaticReconnect(false);//设置是否自动重连
    //遗嘱消息 TODO qos2需要在设备上线时做清除消息操作
    mqttConnOpt.setWill("downline", ("我是" + mqttName + "_" + mqttClientId + ",我下线了").getBytes(), 2, false);
    try {
      MqttClient mqttClient = new MqttClient(broker, mqttClientId, persistence);
      mqttClient.connect(mqttConnOpt);
      if (mqttClient.isConnected()) {
        System.err.println("连接成功");
        // åˆ›å»ºæ¶ˆæ¯å¹¶è®¾ç½® QoS
        String content = "我是" + mqttName + "_" + mqttClientId + ",我上线了";
        MqttMessage message = new MqttMessage(content.getBytes());
        message.setQos(0);
        // æµ‹è¯•发布消息
        mqttClient.publish("topline", message);
        mqttClient.subscribe("message", 0);
        mqttClient.setCallback(mqttSampleCallback);
        mqttUtil.setMqttClient(mqttClient);
        //不同的角色需要不同的订阅
        switch (role) {
          //管理员
          case "admin":
            //订阅系统级设备上下线通知
            mqttClient.subscribe(MqttConstant.MQTT_TOPIC_ONLINE);
            mqttClient.subscribe(MqttConstant.MQTT_TOPIC_OFFLINE);
            //订阅移动端上行指令
            mqttClient.subscribe(MqttConstant.MOBILE_UP);
            System.err.println("admin订阅" + MqttConstant.MOBILE_UP);
            initClients();
            break;
          //普通用户
          case "user":
            //普通客户端只需订阅自身相关消息
            mqttClient.subscribe(MqttConstant.SERVICE_DOWN_PREFIX + "/" + mqttClientId + "/#");
            System.err.println("user订阅" + MqttConstant.SERVICE_DOWN_PREFIX + "/" + mqttClientId + "/#");
            break;
        }
      } else {
        System.err.println("连接失败");
      }
    } catch (MqttException e) {
      e.printStackTrace();
    }
  }
  //重连
  private void reconn() {
    Timer timer = new Timer();
    TimerTask task = new TimerTask() {
      @Override
      public void run() {
        // åœ¨è¿™é‡Œç¼–写定时执行的任务逻辑
        System.out.println("定时任务执行:" + new java.util.Date());
        if (mqttUtil.getMqttClient() == null || !mqttUtil.getMqttClient().isConnected()) {
          try {
            conn();
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    };
    // è®¾å®šå®šæ—¶ä»»åŠ¡ï¼Œå»¶è¿Ÿ0毫秒后开始执行,每隔1000毫秒(1秒)执行一次
    timer.schedule(task, 0, 10000);
  }
  /**
   * æœåŠ¡ç«¯ï¼ˆadmin角色)启动时查询所有设备并缓存到redis
   */
  private void initClients() {
    redisUtil.del(MqttConstant.MQTT_ONLINE_CLIENT);
    JSONObject clients = emqxApi.queryEmqx(EmqxApi.CMD_CLIENTS);
    //TODO æ ¹æ®emqx返回编写实体类
    if (clients != null && clients.containsKey("data")) {
      JSONArray data = clients.getJSONArray("data");
      for (int i = 0; i < data.size(); i++) {
        JSONObject obj = data.getJSONObject(i);
        JSONObject item = new JSONObject();
        //username
        item.put("username", obj.get("username"));
        //连接时间
        String st = obj.getString("connected_at");
        String upTime = DateUtils.zone2Str(st);
        item.put("connectedAt", upTime);
        //clientid
        String clientid = obj.getString("clientid");
        item.put("clientid", clientid);
        //是否连接
        Boolean connected = obj.getBoolean("connected");
        item.put("connected", connected);
        //
        String[] info = clientid.split("-");
        item.put("type", info[0]);
        item.put("tenantId", info[1]);
        item.put("code", info[2]);
        if (connected) {
          redisUtil.set(MqttConstant.MQTT_ONLINE_CLIENT + clientid, item);
        }
      }
    }
  }
}
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/mqtt/MqttSampleCallback.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,199 @@
package org.jeecg.modules.dry.mqtt;
import cn.hutool.core.thread.ThreadUtil;
import com.alibaba.fastjson.JSONObject;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.MqttConstant;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.base.service.BaseCommonService;
import org.jeecg.modules.dry.api.EmqxApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
@Scope("prototype")
public class MqttSampleCallback implements MqttCallback {
  @Value(value = "${jeecg.mqtt.role}")
  private String role;
  @Autowired
  private MqttUtil mqttUtil;
  @Autowired
  private EmqxApi emqxApi;
  @Autowired
  private BaseCommonService baseCommonService;
  @Autowired
  private RedisUtil redisUtil;
  @Override
  public void connectionLost(Throwable throwable) {
    System.err.println("连接断开::掉线");
  }
  @Override
  public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
    System.out.println("收到消息: \n  topic:" + topic + "\n  Qos:" + mqttMessage.getQos() + "\n  payload:"
      + new String(mqttMessage.getPayload()));
    switch (role) {
      // ç®¡ç†å‘˜
      case "admin":
        String message = new String(mqttMessage.getPayload());
        JSONObject messageJson = JSONObject.parseObject(message);
        if (topic.startsWith("$SYS/brokers/") && topic.endsWith("connected")) {
          JSONObject client = (JSONObject) redisUtil.get(MqttConstant.MQTT_ONLINE_CLIENT + messageJson.get("clientid"));
          if (client == null) {
            JSONObject item = new JSONObject();
            //username
            item.put("username", messageJson.get("username"));
            //连接时间
            Long st = messageJson.getLong("connected_at");
            String upTime = DateUtils.timestamptoStr(st, DateUtils.datetimeFormat.get());
            item.put("connectedAt", upTime);
            //clientid
            String clientid = messageJson.getString("clientid");
            item.put("clientid", clientid);
            //是否连接
            item.put("connected", true);
            //
            String[] info = clientid.split("-");
            item.put("type", info[0]);
            item.put("tenantId", info[1]);
            item.put("code", info[2]);
            redisUtil.set(MqttConstant.MQTT_ONLINE_CLIENT + clientid, item);
            System.err.println(String.format("设备: %s上线", clientid));
          }
        }
        if (topic.startsWith("$SYS/brokers/") && topic.endsWith("disconnected")) {
          String clientid = messageJson.getString("clientid");
          redisUtil.del(MqttConstant.MQTT_ONLINE_CLIENT + clientid);
          System.err.println(String.format("设备: %s下线", clientid));
        }
        parseAdminCommand(topic, mqttMessage);
        break;
      // æ™®é€šç”¨æˆ·
      case "user":
        System.err.println("user");
        parseUserCommand(topic, mqttMessage);
        break;
    }
  }
  @Override
  public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
    System.err.println("消息传递成功");
  }
  // è§£æžadmin角色指令
  private void parseAdminCommand(String topic, MqttMessage mqttMessage) {
    String message = new String(mqttMessage.getPayload());
    JSONObject messageJson = JSONObject.parseObject(message);
    //请求的客户端(服务端只推送数据到请求的客户端)
    StringBuilder req = new StringBuilder();
    if (messageJson.containsKey("req")) {
      req.append(messageJson.get("req"));
    }
    //前端传参时间戳转换
    if (messageJson.containsKey("timestamp")) {
      messageJson.put("timestamp", DateUtils.zone2Str(messageJson.get("timestamp").toString()));
    }
    baseCommonService.addLog(message, CommonConstant.LOG_TYPE_MQTT, CommonConstant.OPERATE_MQTT_1);
    switch (topic) {
      // æŸ¥è¯¢è®¾å¤‡åœ¨çº¿
      case MqttConstant.MOBILE_QUERY_EQU_STATU:
        System.err.println("admin收到" + topic);
        // æ ¹æ®è®¾å¤‡id查询设备mqtt在线状态
        String clientId = messageJson.getString("clientId");
        JSONObject client = (JSONObject) redisUtil.get(MqttConstant.MQTT_ONLINE_CLIENT + clientId);
        ThreadUtil.execute(() -> {
          if (client == null || client.isEmpty()) {
            JSONObject res = new JSONObject();
            res.put("success", false);
            res.put("msg", "查询失败");
            try {
              MqttMessage sendMessage = new MqttMessage(res.toJSONString().getBytes());
              sendMessage.setQos(0);
              mqttUtil.getMqttClient().publish(String.format(MqttConstant.SERVICE_RES_EQU_STATU, req), sendMessage);
            } catch (Exception e) {
              e.printStackTrace();
            }
            return;
          }
          client.put("success", true);
          client.put("msg", "查询成功");
          try {
            MqttMessage sendMessage = new MqttMessage(client.toJSONString().getBytes());
            sendMessage.setQos(0);
            mqttUtil.getMqttClient().publish(String.format(MqttConstant.SERVICE_RES_EQU_STATU, req), sendMessage);
            baseCommonService.addLog(client.toString(), CommonConstant.LOG_TYPE_MQTT, CommonConstant.OPERATE_MQTT_2);
          } catch (Exception e) {
            e.printStackTrace();
          }
        });
        break;
    }
  }
  // è§£æžuser角色指令
  private void parseUserCommand(String topic, MqttMessage mqttMessage) {
    String message = new String(mqttMessage.getPayload());
    JSONObject messageJson = JSONObject.parseObject(message);
    //请求的客户端(服务端只推送数据到请求的客户端)
    StringBuilder req = new StringBuilder();
    if (messageJson.containsKey("req")) {
      req.append(messageJson.get("req"));
    }
    //前端传参时间戳转换
    if (messageJson.containsKey("timestamp")) {
      messageJson.put("timestamp", DateUtils.zone2Str(messageJson.get("timestamp").toString()));
    }
    switch (topic) {
      case MqttConstant.MOBILE_REQ_EQU_CMD:
        System.err.println("user收到" + topic);
        System.err.println(message);
        ThreadUtil.execute(() -> {
          //TODO å‘PLC发送开关机操作,并返回信息
          JSONObject res = new JSONObject();
          res.put("success", true);
          res.put("msg", "操作成功");
          try {
            MqttMessage sendMessage = new MqttMessage(JSONObject.toJSONString(res).getBytes());
            sendMessage.setQos(0);
            mqttUtil.getMqttClient().publish(String.format(MqttConstant.SERVICE_RES_EQU_CMD, req), sendMessage);
            baseCommonService.addLog(res.toString(), CommonConstant.LOG_TYPE_MQTT, CommonConstant.OPERATE_MQTT_2);
          } catch (Exception e) {
            e.printStackTrace();
          }
        });
        break;
    }
  }
}
jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/mqtt/MqttUtil.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package org.jeecg.modules.dry.mqtt;
import lombok.Data;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.springframework.stereotype.Component;
@Component
@Data
public class MqttUtil {
  public   MqttClient mqttClient;
}
jeecg-module-system/jeecg-system-biz/src/main/java/org/jeecg/config/jimureport/JimuReportTokenService.java
@@ -1,19 +1,23 @@
package org.jeecg.config.jimureport;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.system.vo.SysUserCacheInfo;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.modules.jmreport.api.JmReportTokenServiceI;
import org.jeecg.modules.system.service.impl.SysBaseApiImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
 * è‡ªå®šä¹‰ç§¯æœ¨æŠ¥è¡¨é‰´æƒ(如果不进行自定义,则所有请求不做权限控制)
@@ -48,6 +52,16 @@
    }
    @Override
    public String[] getRoles(String token) {
        String username = JwtUtil.getUsername(token);
        Set roles = sysBaseApi.getUserRoleSet(username);
        if(CollectionUtils.isEmpty(roles)){
            return null;
        }
        return (String[]) roles.toArray(new String[roles.size()]);
    }
    @Override
    public Map<String, Object> getUserInfo(String token) {
        Map<String, Object> map = new HashMap(5);
        String username = JwtUtil.getUsername(token);
@@ -66,4 +80,21 @@
        // å°†æ‰€æœ‰ä¿¡æ¯å­˜æ”¾è‡³map è§£æžsql/api会根据map的键值解析
        return map;
    }
    /**
     * èŽ·å–å¤šç§Ÿæˆ·id
     * @return tenantId
     */
    public String getTenantId() {
        HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
        String tenantId = request.getHeader("tenantId");
        if(StringUtils.isNotEmpty(tenantId)){
            return tenantId;
        }
        tenantId = request.getParameter("tenantId");
        if (StringUtils.isNotEmpty(tenantId)) {
            return tenantId;
        }
        return "";
    }
}
pom.xml
@@ -56,7 +56,7 @@
        <minidao.version>1.9.0</minidao.version>
        <!-- ç§¯æœ¨æŠ¥è¡¨-->
        <jimureport-spring-boot-starter.version>1.5.8</jimureport-spring-boot-starter.version>
        <jimureport-spring-boot-starter.version>1.7.2-beta</jimureport-spring-boot-starter.version>
        <commons.version>2.6</commons.version>
        <aliyun-java-sdk-dysmsapi.version>2.1.0</aliyun-java-sdk-dysmsapi.version>
        <aliyun.oss.version>3.11.2</aliyun.oss.version>
@@ -347,7 +347,7 @@
            <dependency>
                <groupId>org.jeecgframework.jimureport</groupId>
                <artifactId>jimureport-nosql-starter</artifactId>
                <version>1.5.6</version>
                <version>1.6.0</version>
            </dependency>
        </dependencies>
    </dependencyManagement>