Merge branch 'master' into herb-new
| | |
| | | |
| | | ## front |
| | | **/*.lock |
| | | |
| | | |
| | | /target/ |
| | | **/target |
| | | **/logs |
| | |
| | | 2.ä¸å¾åºäºè¯¥å¹³å°è½¯ä»¶çåºç¡ï¼ä¿®æ¹å
è£
æä¸ä¸ªä¸JeecgBootå¹³å°è½¯ä»¶åè½ç±»ä¼¼ç产åè¿è¡åå¸ãéå®ï¼æä¸JeecgBootåä¸å类软件产åå¸åºçç«äºã |
| | | è¿åæ¤æ¡æ¬¾å±äºä¾µæè¡ä¸ºï¼é¡»èµå¿ä¾µæç»æµæå¤±ï¼åæ¶ç«å³åæ¢è使侵æè¡ä¸ºã |
| | | è§£éæå½ï¼http://www.jeecg.com |
| | | |
| | |
| | | <groupId>commons-fileupload</groupId> |
| | | <artifactId>commons-fileupload</artifactId> |
| | | </dependency> |
| | | <!--MQTT client --> |
| | | <dependency> |
| | | <groupId>org.eclipse.paho</groupId> |
| | | <artifactId>org.eclipse.paho.client.mqttv3</artifactId> |
| | | <version>1.2.5</version> |
| | | </dependency> |
| | | |
| | | </dependencies> |
| | | |
| | | </project> |
| | |
| | | * ç³»ç»æ¥å¿ç±»åï¼ æä½ |
| | | */ |
| | | int LOG_TYPE_2 = 2; |
| | | /** |
| | | * MQTTæ¥å¿ |
| | | */ |
| | | int LOG_TYPE_MQTT = 100; |
| | | |
| | | /** |
| | | * æä½æ¥å¿ç±»åï¼ æ¥è¯¢ |
| | |
| | | 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; |
| | | /** {@code 200 OK} (HTTP/1.0 - RFC 1945) */ |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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::"; |
| | | |
| | | |
| | | } |
| | |
| | | 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; |
| | |
| | | |
| | | /** |
| | | * æå®æ¨¡å¼çæ¶é´æ ¼å¼ |
| | | * |
| | | * @param pattern |
| | | * @return |
| | | */ |
| | |
| | | } |
| | | 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 |
| | | */ |
| | |
| | | } |
| | | |
| | | /** |
| | | * ç¹æ®æ¶é´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 |
| | |
| | | */ |
| | | 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); |
| | | |
| | | } |
| | |
| | | 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"); |
| | | } |
| | | |
| | | sysLog.setCreateTime(new Date()); |
| | | //ä¿åæ¥å¿ï¼å¼å¸¸æè·å¤çï¼é²æ¢æ°æ®å¤ªå¤§åå¨å¤±è´¥ï¼å¯¼è´ä¸å¡å¤±è´¥ï¼JT-238 |
| | | try { |
| | | baseCommonMapper.saveLog(sysLog); |
| | | } catch (Exception e) { |
| | | log.warn(" LogContent length : " + sysLog.getLogContent().length()); |
| | | log.warn(e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | //æ¥å£è¿åæ°æ®ç¤ºä¾ |
| | | 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 |
| | | } |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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); |
| | | } |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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); |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
¶Ô±ÈÐÂÎļþ |
| | |
| | | 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; |
| | | |
| | | } |
| | |
| | | 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; |
| | | |
| | | /** |
| | | * èªå®ä¹ç§¯æ¨æ¥è¡¨é´æ(妿ä¸è¿è¡èªå®ä¹ï¼åææè¯·æ±ä¸åæéæ§å¶) |
| | |
| | | } |
| | | |
| | | @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); |
| | |
| | | // å°ææä¿¡æ¯åæ¾è³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 ""; |
| | | } |
| | | } |
| | |
| | | <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> |
| | |
| | | <dependency> |
| | | <groupId>org.jeecgframework.jimureport</groupId> |
| | | <artifactId>jimureport-nosql-starter</artifactId> |
| | | <version>1.5.6</version> |
| | | <version>1.6.0</version> |
| | | </dependency> |
| | | </dependencies> |
| | | </dependencyManagement> |