设备心跳调整 app新增增设备时绑定联网设备
This commit is contained in:
36
.env.example
36
.env.example
@@ -1,36 +0,0 @@
|
||||
# ==========================================
|
||||
# Water 项目环境变量模板
|
||||
# 复制此文件为 .env 并填入真实值
|
||||
# .env 文件已加入 .gitignore,不会提交到仓库
|
||||
# ==========================================
|
||||
|
||||
# --- 数据库 ---
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=123456
|
||||
|
||||
# --- Redis ---
|
||||
REDIS_PASSWORD=
|
||||
|
||||
# --- Sa-Token JWT ---
|
||||
# 生产环境建议使用 openssl rand -base64 64 生成
|
||||
SA_TOKEN_JWT_SECRET_KEY=abcdefghijklmnopqrstuvwxyz
|
||||
|
||||
# --- MQTT Broker ---
|
||||
MQTT_ENABLED=true
|
||||
MQTT_BROKER_URL=ssl://service.reinkun.com:8883
|
||||
MQTT_USERNAME=admin
|
||||
MQTT_PASSWORD=yukun_mqtt
|
||||
|
||||
# --- 邮件 (SMTP) ---
|
||||
MAIL_PASSWORD=XZVDXjRdVrjiX8N3
|
||||
|
||||
# --- 短信 (阿里云 SMS) ---
|
||||
SMS_ACCESS_KEY_ID=LTAI5t7xHqxFKG9DwMgurvrn
|
||||
SMS_ACCESS_KEY_SECRET=nNFjR8YwNJUcMrrtdc4pkpPsHmYtfp
|
||||
|
||||
# --- SnailJob 调度中心 ---
|
||||
SNAIL_JOB_TOKEN=SJ_cKqBTPzCsWA3VyuCfFoccmuIEGXjr5KT
|
||||
|
||||
# --- 第三方登录 (JustAuth) ---
|
||||
# Gitee / QQ / 微信 等 OAuth 凭据请通过 application-*.yml 配置
|
||||
# 或使用 JUSTAUTH_ 前缀的环境变量覆盖
|
||||
12
.idea/compiler.xml
generated
12
.idea/compiler.xml
generated
@@ -25,18 +25,6 @@
|
||||
<entry name="$PROJECT_DIR$/../../repository/org/mapstruct/mapstruct-processor/1.6.3/mapstruct-processor-1.6.3.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/org/mapstruct/tools/gem/gem-api/1.0.0.Alpha3/gem-api-1.0.0.Alpha3.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/org/projectlombok/lombok-mapstruct-binding/0.2.0/lombok-mapstruct-binding-0.2.0.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/com/github/therapi/therapi-runtime-javadoc-scribe/0.15.0/therapi-runtime-javadoc-scribe-0.15.0.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/com/github/therapi/therapi-runtime-javadoc/0.15.0/therapi-runtime-javadoc-0.15.0.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/org/projectlombok/lombok/1.18.42/lombok-1.18.42.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/org/springframework/boot/spring-boot-configuration-processor/3.5.12/spring-boot-configuration-processor-3.5.12.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/io/github/linpeilie/mapstruct-plus-processor/1.5.0/mapstruct-plus-processor-1.5.0.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/io/github/linpeilie/mapstruct-plus/1.5.0/mapstruct-plus-1.5.0.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/org/mapstruct/mapstruct/1.6.3/mapstruct-1.6.3.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/io/github/linpeilie/mapstruct-plus-object-convert/1.5.0/mapstruct-plus-object-convert-1.5.0.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/cn/easii/tutelary-repackage-javapoet/1.0.5/tutelary-repackage-javapoet-1.0.5.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/org/mapstruct/mapstruct-processor/1.6.3/mapstruct-processor-1.6.3.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/org/mapstruct/tools/gem/gem-api/1.0.0.Alpha3/gem-api-1.0.0.Alpha3.jar" />
|
||||
<entry name="$PROJECT_DIR$/../../repository/org/projectlombok/lombok-mapstruct-binding/0.2.0/lombok-mapstruct-binding-0.2.0.jar" />
|
||||
</processorPath>
|
||||
<module name="water-app" />
|
||||
<module name="water-common-excel" />
|
||||
|
||||
17
.workbuddy/memory/2026-06-11.md
Normal file
17
.workbuddy/memory/2026-06-11.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# 2026-06-11 工作日志
|
||||
|
||||
### 14. DeviceDataHandler 和 DeviceRegisterHandler 补充设备在线状态刷新
|
||||
|
||||
**问题**:之前只有 ACK 应答会调用 `refreshDeviceOnline()` 续期 Redis 中的设备在线状态。但设备只要上报电量或注册就证明在线,这两个场景没刷新在线缓存。后果:设备只上报数据不发 ACK 时,5 分钟后重试逻辑误判它为离线。
|
||||
|
||||
**修复**:
|
||||
- `DeviceDataHandler.handle()` → 收到 `/publish/power` 后调用 `refreshDeviceOnline()`
|
||||
- `DeviceRegisterHandler.handle()` → 注册后调用 `refreshDeviceOnline()`
|
||||
- 两个 Handler 各自注入 `MqttProperties`,避免注入 `MqttCommandAckService` 引入新的循环依赖
|
||||
|
||||
**在线判定覆盖**(修复后):
|
||||
| 触发方式 | 是否刷新在线状态 |
|
||||
|---|---|
|
||||
| 设备上报电量 `/publish/power` | ✅ 新增 |
|
||||
| 设备注册 `/publish/register` | ✅ 新增 |
|
||||
| ACK 应答 `/publish/ack` | ✅ 原有 |
|
||||
23
.workbuddy/memory/2026-06-12.md
Normal file
23
.workbuddy/memory/2026-06-12.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# 2026-06-12 工作日志
|
||||
|
||||
### 15. 修复设备断电后数据库状态未更新为离线
|
||||
|
||||
**问题**:设备断电/断网后,Redis 中的在线 Key(`mqtt:device:status:{deviceNo}`)会在 TTL(默认 300s)到期后自动消失,但数据库 `app_device.status` 字段没有同步更新,始终显示在线。
|
||||
|
||||
**方案**:三层联动
|
||||
|
||||
1. **定时任务扫库(新增 `DeviceOfflineCheckTask`)**:每 90s 扫描 DB 中 `status=1` 的设备,检查 Redis Key 是否存在,不存在则批量更新 `status=0`(离线)。扫描间隔可通过 `mqtt.offline-check.interval-ms` 配置项覆盖。
|
||||
|
||||
2. **上线时同步写库**:
|
||||
- `DeviceDataHandler.handle()`:收到电量上报时,`AppDeviceBo.setStatus("1")` 写库 + 刷新 Redis Key
|
||||
- `DeviceRegisterHandler.buildRegisterDevice()`:注册时 `device.setStatus("1")`
|
||||
|
||||
3. **修复注册默认状态**:`registerByMqtt()` 中注册默认值从 `status=2` 改为 `status=1`(在线)
|
||||
|
||||
**状态值定义**(来自 `AppDeviceBo` 注释):
|
||||
- `0`:离线
|
||||
- `1`:在线
|
||||
- `2`:到期
|
||||
- `3`:故障
|
||||
|
||||
**新增文件**:`water-app/src/main/java/org/dromara/app/task/DeviceOfflineCheckTask.java`
|
||||
@@ -1,91 +1,327 @@
|
||||
2026-06-04 07:06:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-04 07:06:53 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:06:53 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[12]毫秒
|
||||
2026-06-04 07:06:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[36]毫秒
|
||||
2026-06-04 07:06:57 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2062185771665858562],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:06:57 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2062185771665858562],耗时:[13]毫秒
|
||||
2026-06-04 07:06:59 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2062185771665858562],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:06:59 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2062185771665858562],耗时:[5]毫秒
|
||||
2026-06-04 07:07:01 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[DELETE /app/v1/deleteDevice/2062185771665858562],参数类型[json],参数:[{"clientId":"32324a04c0175c8d61ac8a282553aea1"}]
|
||||
2026-06-04 07:07:01 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[DELETE /app/v1/deleteDevice/2062185771665858562],耗时:[10]毫秒
|
||||
2026-06-04 07:07:03 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:03 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-04 07:07:03 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[5]毫秒
|
||||
2026-06-04 07:07:03 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[22]毫秒
|
||||
2026-06-04 07:07:06 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/schedulelist],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-04 07:07:06 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/schedulelist],耗时:[12]毫秒
|
||||
2026-06-04 07:07:07 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/schedulelist],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["2"]}]
|
||||
2026-06-04 07:07:07 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/schedulelist],耗时:[15]毫秒
|
||||
2026-06-04 07:07:11 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:11 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[4]毫秒
|
||||
2026-06-04 07:07:13 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/dataStatistics],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:13 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/dataStatistics],耗时:[8]毫秒
|
||||
2026-06-04 07:07:14 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/waterLogList],参数类型[param],参数:[{"param[endTime]":[""],"param[beginTime]":[""],"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-04 07:07:14 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/waterLogList],耗时:[16]毫秒
|
||||
2026-06-04 07:07:16 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:16 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[4]毫秒
|
||||
2026-06-04 07:07:24 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:24 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[6]毫秒
|
||||
2026-06-04 07:07:33 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:33 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[6]毫秒
|
||||
2026-06-04 07:38:43 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:38:43 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-04 07:38:43 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[11]毫秒
|
||||
2026-06-04 07:38:43 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[28]毫秒
|
||||
2026-06-04 07:38:46 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2059509304398151682],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:38:46 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2059509304398151682],耗时:[7]毫秒
|
||||
2026-06-04 07:38:51 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:38:51 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[4]毫秒
|
||||
2026-06-04 08:11:28 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:11:28 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-04 08:11:32 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2060265891827957762],无参数
|
||||
2026-06-04 08:11:32 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2060265891827957762],耗时:[8]毫秒
|
||||
2026-06-04 08:11:33 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:11:34 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-04 08:11:35 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2060266873861324801],无参数
|
||||
2026-06-04 08:11:35 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2060266873861324801],耗时:[3]毫秒
|
||||
2026-06-04 08:11:37 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:11:37 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-04 08:11:38 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2060266816596492289],无参数
|
||||
2026-06-04 08:11:38 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2060266816596492289],耗时:[2]毫秒
|
||||
2026-06-04 08:11:51 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[PUT /app/v1/switchDevice],参数类型[json],参数:[{"id":"2060266816596492289","workStatus":"1","durationMin":"60"}]
|
||||
2026-06-04 08:11:51 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[PUT /app/v1/switchDevice],耗时:[13]毫秒
|
||||
2026-06-04 08:12:04 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:12:04 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-04 08:21:57 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:21:57 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-04 08:22:06 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:22:06 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-04 08:27:53 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:27:53 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[29]毫秒
|
||||
2026-06-04 09:53:05 [MQTT Rec: water-server] WARN org.dromara.mqtt.MqttClientManager - [MQTT] 连接断开: 已断开连接
|
||||
2026-06-04 10:08:12 [MQTT Rec: water-server] WARN org.dromara.mqtt.MqttClientManager - [MQTT] 连接断开: 已断开连接
|
||||
2026-06-04 10:13:27 [MQTT Rec: water-server] WARN org.dromara.mqtt.MqttClientManager - [MQTT] 连接断开: 已断开连接
|
||||
2026-06-04 10:28:49 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:28:49 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[49]毫秒
|
||||
2026-06-04 10:31:13 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:31:13 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[27]毫秒
|
||||
2026-06-04 10:44:03 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:44:03 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[23]毫秒
|
||||
2026-06-04 10:50:27 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:50:27 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-04 10:52:28 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:52:28 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[25]毫秒
|
||||
2026-06-04 10:52:47 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:52:47 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-04 10:53:33 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:53:33 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-04 11:05:23 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:05:23 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-04 11:08:20 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:08:20 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-04 11:17:17 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:17:17 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[21]毫秒
|
||||
2026-06-04 11:20:07 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:20:07 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-04 11:21:29 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:21:29 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-04 11:22:24 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:22:24 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-04 11:23:26 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:23:26 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 08:59:11 [master:housekeeper] WARN com.zaxxer.hikari.pool.HikariPool - master - Thread starvation or clock leap detected (housekeeper delta=14h57m13s457ms410µs100ns).
|
||||
2026-06-13 08:59:32 [MQTT Ping: water-server-8081] ERROR o.e.p.c.mqttv3.internal.ClientState - water-server-8081: Timed out as no write activity, keepAlive=60,000,000,000 lastOutboundActivity=150,167,329,517,400 lastInboundActivity=150,167,356,610,400 time=204,053,810,500,400 lastPing=150,167,329,537,400
|
||||
2026-06-13 08:59:32 [MQTT Ping: water-server-8081] WARN org.dromara.mqtt.MqttClientManager - [MQTT] 连接已断开:Timed out while waiting to write messages to the server
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已重新连接:ssl://service.reinkun.com:8883
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/finish/schedule 服务质量等级=1
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/register 服务质量等级=1
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/power 服务质量等级=1
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/ack 服务质量等级=1
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/finish/key 服务质量等级=1
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/error 服务质量等级=1
|
||||
2026-06-13 08:59:34 [mqtt-consumer-7] WARN o.d.a.handler.ScheduleFinishHandler - [MQTT] 排程完成上报未找到设备绑定的排程 时间=2026-06-13 08:59:34 设备编号=01
|
||||
2026-06-13 08:59:34 [mqtt-consumer-4] INFO o.d.app.handler.DeviceDataHandler - [MQTT] 设备电量更新 时间=2026-06-13 08:59:34 设备编号=01 消息体={
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 50,
|
||||
"charging": 0
|
||||
}
|
||||
2026-06-13 08:59:34 [mqtt-consumer-7] INFO o.d.a.handler.ScheduleFinishHandler - [MQTT] 浇水排程上报已保存 时间=2026-06-13 08:59:34 设备编号=01 消息体={
|
||||
"deviceNo": "01",
|
||||
"startWeek": 5,
|
||||
"startTime": "2026-06-11 8:20",
|
||||
"durationMin": 20,
|
||||
"triggerType": "mqtt on",
|
||||
"triggerON":"mqtt on",
|
||||
"triggerOFF":"mqtt off"
|
||||
}
|
||||
2026-06-13 08:59:34 [mqtt-consumer-8] INFO o.d.a.handler.DeviceRegisterHandler - [MQTT] 设备注册 时间=2026-06-13 08:59:34 设备编号=01 消息体={
|
||||
"deviceNo": "01",
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 63,
|
||||
"deviceEm": "11667796A-Y43-2606",
|
||||
"deviceSn": "260601",
|
||||
"deviceMac": "dc:da:0c:fa:28:9c",
|
||||
"version": "1.0"
|
||||
}
|
||||
2026-06-13 09:00:02 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:00:02 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[19]毫秒
|
||||
2026-06-13 09:00:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:00:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-13 09:00:52 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:00:52 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[9]毫秒
|
||||
2026-06-13 09:01:28 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:01:28 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:02:04 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:02:04 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:02:06 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:02:06 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 09:05:12 [schedule-pool-10] INFO o.d.app.task.DeviceOfflineCheckTask - [设备离线] 检测到 1 台设备离线,已更新数据库状态,设备编号:[01]
|
||||
2026-06-13 09:05:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"DC:DA:0C:FA:28:9E"}]
|
||||
2026-06-13 09:05:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[3]毫秒
|
||||
2026-06-13 09:05:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:05:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:06:56 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:06:56 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 09:07:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"DC:DA:0C:FA:28:9E"}]
|
||||
2026-06-13 09:07:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[8]毫秒
|
||||
2026-06-13 09:07:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:07:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-13 09:08:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:08:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"dc:da:0c:fa:28:9c"}]
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[2]毫秒
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:08:48 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:08:48 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:08:49 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:08:49 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:08:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:08:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 09:08:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:08:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[3]毫秒
|
||||
2026-06-13 09:08:54 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:08:54 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 09:09:18 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:09:18 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:09:19 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:09:19 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:11:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:11:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[11]毫秒
|
||||
2026-06-13 09:12:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:12:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:12:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:12:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[3]毫秒
|
||||
2026-06-13 09:13:56 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:13:56 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-13 09:15:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:15:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 09:15:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:15:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[5]毫秒
|
||||
2026-06-13 09:15:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/scheduleDeviceList/2062827585485807618],无参数
|
||||
2026-06-13 09:15:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/scheduleDeviceList/2062827585485807618],耗时:[7]毫秒
|
||||
2026-06-13 09:15:36 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/addScheduleDevice],参数类型[JSON],参数:[{"scheduleId":"2062827585485807618","deviceNos":["1779176626954"]}]
|
||||
2026-06-13 09:15:36 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/addScheduleDevice],耗时:[20]毫秒
|
||||
2026-06-13 09:15:37 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:15:37 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[11]毫秒
|
||||
2026-06-13 09:15:40 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:15:40 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[4]毫秒
|
||||
2026-06-13 09:15:46 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:15:46 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[6]毫秒
|
||||
2026-06-13 09:15:50 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:15:50 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[11]毫秒
|
||||
2026-06-13 09:15:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:15:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[6]毫秒
|
||||
2026-06-13 09:17:42 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:17:42 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 09:17:47 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:17:47 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[8]毫秒
|
||||
2026-06-13 09:17:48 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:17:48 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[9]毫秒
|
||||
2026-06-13 09:17:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:17:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[11]毫秒
|
||||
2026-06-13 09:24:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:24:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 09:24:17 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:24:17 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 09:26:05 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:26:05 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:26:07 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:26:07 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 09:27:39 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:27:39 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:27:40 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:27:40 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[22]毫秒
|
||||
2026-06-13 09:46:39 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:46:39 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[26]毫秒
|
||||
2026-06-13 09:46:42 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:46:42 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[16]毫秒
|
||||
2026-06-13 09:46:54 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":["fuck"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:46:54 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[20]毫秒
|
||||
2026-06-13 09:46:58 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:46:58 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 09:47:10 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":["fuck"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:47:10 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[11]毫秒
|
||||
2026-06-13 09:47:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:47:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 09:49:16 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:49:16 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 09:49:18 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:49:18 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 09:49:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":["666"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:49:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[12]毫秒
|
||||
2026-06-13 09:49:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:49:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 09:51:11 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/waterLogList],参数类型[表单参数],参数:[{"pageNum":["1"]}]
|
||||
2026-06-13 09:51:11 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/waterLogList],耗时:[34]毫秒
|
||||
2026-06-13 09:51:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:51:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 09:51:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:51:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[13]毫秒
|
||||
2026-06-13 09:51:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:51:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:51:33 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:51:33 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[7]毫秒
|
||||
2026-06-13 09:53:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:53:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 09:53:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:53:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:53:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"dc:da:0c:fa:28:9c"}]
|
||||
2026-06-13 09:53:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[4]毫秒
|
||||
2026-06-13 09:53:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:53:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[13]毫秒
|
||||
2026-06-13 09:54:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:54:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:54:21 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:54:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"dc:da:0c:fa:28:9e"}]
|
||||
2026-06-13 09:54:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[1]毫秒
|
||||
2026-06-13 09:54:21 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:54:46 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:54:46 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:54:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"DC:DA:0C:FA:28:9E"}]
|
||||
2026-06-13 09:54:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[4]毫秒
|
||||
2026-06-13 09:54:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:54:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 09:55:12 [mqtt-consumer-16] INFO o.d.a.handler.DeviceRegisterHandler - [MQTT] 设备注册 时间=2026-06-13 09:55:12 设备编号=01 消息体={
|
||||
"deviceNo": "01",
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"deviceEm": "11667796A-Y43-2606",
|
||||
"deviceSn": "260601",
|
||||
"deviceMac": "dc:da:0c:fa:28:9c",
|
||||
"version": "1.0"
|
||||
}
|
||||
2026-06-13 09:55:12 [mqtt-consumer-13] INFO o.d.app.handler.DeviceDataHandler - [MQTT] 设备电量更新 时间=2026-06-13 09:55:12 设备编号=01 消息体={
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"charging": 0
|
||||
}
|
||||
2026-06-13 09:55:12 [mqtt-consumer-14] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=2ab3a6e58d1b4a89919d218fda63b3f7 状态=null
|
||||
2026-06-13 09:55:38 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/addDevice],参数类型[JSON],参数:[{"deviceName":"浇水设备007","wifiName":"研发部","wifiPassword":"ckkj123456","macAddress":"DC:DA:0C:FA:28:9E","deviceNo":"01"}]
|
||||
2026-06-13 09:55:38 [XNIO-1 task-4] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 消息已发布 主题=/01/subscriber/cmd 消息体={"commandType":"bindDevice","deviceNo":"01","cmd":-1,"commandId":"73669072eb924e9f9772d80fb9be57f8","bindStatus":true}
|
||||
2026-06-13 09:55:38 [XNIO-1 task-4] INFO o.d.a.s.i.DeviceCommandServiceImpl - [命令] 命令已下发 设备编号=01 命令类型=bindDevice 命令编号=73669072eb924e9f9772d80fb9be57f8
|
||||
2026-06-13 09:55:38 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/addDevice],耗时:[39]毫秒
|
||||
2026-06-13 09:55:38 [mqtt-consumer-11] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=73669072eb924e9f9772d80fb9be57f8 状态=null
|
||||
2026-06-13 09:55:39 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:55:39 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:55:59 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:56:00 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:56:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"DC:DA:0C:FA:28:9E"}]
|
||||
2026-06-13 09:56:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[1]毫秒
|
||||
2026-06-13 09:56:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:56:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[13]毫秒
|
||||
2026-06-13 09:57:15 [mqtt-consumer-8] INFO o.d.a.handler.DeviceRegisterHandler - [MQTT] 设备注册 时间=2026-06-13 09:57:15 设备编号=01 消息体={
|
||||
"deviceNo": "01",
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"deviceEm": "11667796A-Y43-2606",
|
||||
"deviceSn": "260601",
|
||||
"deviceMac": "dc:da:0c:fa:28:9c",
|
||||
"version": "1.0"
|
||||
}
|
||||
2026-06-13 09:57:15 [mqtt-consumer-8] INFO o.d.app.handler.DeviceDataHandler - [MQTT] 设备电量更新 时间=2026-06-13 09:57:15 设备编号=01 消息体={
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"charging": 0
|
||||
}
|
||||
2026-06-13 09:57:15 [mqtt-consumer-12] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=2ab3a6e58d1b4a89919d218fda63b3f7 状态=null
|
||||
2026-06-13 09:57:39 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/addDevice],参数类型[JSON],参数:[{"deviceName":"智能浇水","wifiName":"测试机","wifiPassword":"66668888","macAddress":"DC:DA:0C:FA:28:9E","deviceNo":"01"}]
|
||||
2026-06-13 09:57:39 [XNIO-1 task-4] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 消息已发布 主题=/01/subscriber/cmd 消息体={"commandType":"bindDevice","deviceNo":"01","cmd":-1,"commandId":"a783262582fd41fcb09d59d55a07c9e3","bindStatus":true}
|
||||
2026-06-13 09:57:39 [XNIO-1 task-4] INFO o.d.a.s.i.DeviceCommandServiceImpl - [命令] 命令已下发 设备编号=01 命令类型=bindDevice 命令编号=a783262582fd41fcb09d59d55a07c9e3
|
||||
2026-06-13 09:57:39 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/addDevice],耗时:[35]毫秒
|
||||
2026-06-13 09:57:40 [mqtt-consumer-3] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=a783262582fd41fcb09d59d55a07c9e3 状态=null
|
||||
2026-06-13 09:57:40 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:57:40 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:59:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:59:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:59:57 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:59:58 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 10:02:09 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:02:09 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:02:11 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 10:02:11 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[3]毫秒
|
||||
2026-06-13 10:02:12 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:02:12 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-13 10:03:42 [schedule-pool-5] INFO o.d.app.task.DeviceOfflineCheckTask - [设备离线] 检测到 1 台设备离线,已更新数据库状态,设备编号:[01]
|
||||
2026-06-13 10:04:26 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:04:26 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:11:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 10:11:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 10:12:03 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:12:03 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[13]毫秒
|
||||
2026-06-13 10:12:20 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:20 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 10:12:23 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":["fuck"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:23 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[13]毫秒
|
||||
2026-06-13 10:12:28 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:28 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 10:12:36 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:36 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[7]毫秒
|
||||
2026-06-13 10:12:38 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":["66"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:38 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 10:12:42 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:42 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 10:16:20 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:16:20 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[7]毫秒
|
||||
2026-06-13 10:16:22 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:16:22 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 10:16:46 [mqtt-consumer-1] INFO o.d.a.handler.DeviceRegisterHandler - [MQTT] 设备注册 时间=2026-06-13 10:16:46 设备编号=01 消息体={
|
||||
"deviceNo": "01",
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"deviceEm": "11667796A-Y43-2606",
|
||||
"deviceSn": "260601",
|
||||
"deviceMac": "dc:da:0c:fa:28:9c",
|
||||
"version": "1.0"
|
||||
}
|
||||
2026-06-13 10:16:46 [mqtt-consumer-16] INFO o.d.app.handler.DeviceDataHandler - [MQTT] 设备电量更新 时间=2026-06-13 10:16:46 设备编号=01 消息体={
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"charging": 0
|
||||
}
|
||||
2026-06-13 10:16:47 [mqtt-consumer-16] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=2ab3a6e58d1b4a89919d218fda63b3f7 状态=null
|
||||
2026-06-13 10:16:57 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/addDevice],参数类型[JSON],参数:[{"deviceName":"还是浇水设备","wifiName":"研发部","wifiPassword":"ckkj123456","macAddress":"DC:DA:0C:FA:28:9E","deviceNo":"01"}]
|
||||
2026-06-13 10:16:57 [XNIO-1 task-4] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 消息已发布 主题=/01/subscriber/cmd 消息体={"commandType":"bindDevice","deviceNo":"01","cmd":-1,"commandId":"00119ae0fc844c1c88d61052e1ded66b","bindStatus":true}
|
||||
2026-06-13 10:16:57 [XNIO-1 task-4] INFO o.d.a.s.i.DeviceCommandServiceImpl - [命令] 命令已下发 设备编号=01 命令类型=bindDevice 命令编号=00119ae0fc844c1c88d61052e1ded66b
|
||||
2026-06-13 10:16:57 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/addDevice],耗时:[36]毫秒
|
||||
2026-06-13 10:16:57 [mqtt-consumer-6] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=00119ae0fc844c1c88d61052e1ded66b 状态=null
|
||||
2026-06-13 10:16:58 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 10:16:58 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[5]毫秒
|
||||
2026-06-13 10:17:04 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:17:04 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:18:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:18:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 10:23:12 [schedule-pool-4] INFO o.d.app.task.DeviceOfflineCheckTask - [设备离线] 检测到 1 台设备离线,已更新数据库状态,设备编号:[01]
|
||||
2026-06-13 10:34:56 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:34:56 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[22]毫秒
|
||||
2026-06-13 10:34:57 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:34:57 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 10:35:05 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:35:05 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:35:05 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:35:05 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:37:22 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:37:22 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:37:22 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-13 10:37:22 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 10:38:02 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/waterLogList],参数类型[表单参数],参数:[{"pageNum":["1"]}]
|
||||
2026-06-13 10:38:02 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/waterLogList],耗时:[14]毫秒
|
||||
2026-06-13 10:38:06 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:38:06 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 10:38:08 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/waterLogList],参数类型[表单参数],参数:[{"pageNum":["1"]}]
|
||||
2026-06-13 10:38:08 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/waterLogList],耗时:[12]毫秒
|
||||
2026-06-13 10:38:08 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:38:08 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 10:38:09 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:09 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:38:13 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/getUserInfo],无参数
|
||||
2026-06-13 10:38:13 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[9]毫秒
|
||||
2026-06-13 10:38:14 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:14 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 10:38:16 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/getUserInfo],无参数
|
||||
2026-06-13 10:38:16 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[6]毫秒
|
||||
2026-06-13 10:38:19 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:19 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/getUserInfo],无参数
|
||||
2026-06-13 10:38:19 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[5]毫秒
|
||||
2026-06-13 10:38:19 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 10:38:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 10:38:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 10:38:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[13]毫秒
|
||||
2026-06-13 10:38:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 10:38:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
|
||||
@@ -1,6 +1 @@
|
||||
2026-06-03 08:07:41 [MQTT Ping: water-server] ERROR o.e.p.c.mqttv3.internal.ClientState - water-server: Timed out as no write activity, keepAlive=60,000,000,000 lastOutboundActivity=1,242,491,392,259,400 lastInboundActivity=1,242,491,421,357,900 time=1,293,117,233,745,900 lastPing=1,242,491,392,263,200
|
||||
2026-06-03 11:22:23 [XNIO-1 task-2] ERROR o.d.c.s.h.SaTokenExceptionHandler - 请求地址'/app/v1/deviceList',认证失败'token 已被冻结:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJhcHBfdXNlcjoyMDU2NTQzNTA3NTE0MDk3NjY1Iiwicm5TdHIiOiI4QnM4c2RiWkdOMEFPRTVQUHZUeTFCYWtzV0ozQVVHaSIsImNsaWVudGlkIjoiNDI4YTgzMTBjZDQ0Mjc1N2FlNjk5ZGY1ZDg5NGYwNTEiLCJ0ZW5hbnRJZCI6IjAwMDAwMCIsInVzZXJJZCI6MjA1NjU0MzUwNzUxNDA5NzY2NX0.kKJvH80xg1I8iFL0-v4_aMCEGsuwYm87T19UQ7cu3l4',无法访问系统资源
|
||||
2026-06-03 11:23:01 [XNIO-1 task-2] ERROR o.d.c.w.h.GlobalExceptionHandler - 访问过于频繁,请稍候再试
|
||||
2026-06-03 11:45:09 [XNIO-1 task-2] ERROR o.d.c.s.h.SaTokenExceptionHandler - 请求地址'/app/v1/deviceList',认证失败'token 已被冻结:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJhcHBfdXNlcjoyMDU2NTQzNTA3NTE0MDk3NjY1Iiwicm5TdHIiOiJ2alU3OVV0dWhsYjc4azhhUDNRazM4YnJ3QVJ4MGt6MCIsImNsaWVudGlkIjoiNDI4YTgzMTBjZDQ0Mjc1N2FlNjk5ZGY1ZDg5NGYwNTEiLCJ0ZW5hbnRJZCI6IjAwMDAwMCIsInVzZXJJZCI6MjA1NjU0MzUwNzUxNDA5NzY2NSwidXNlck5hbWUiOiIxMzMwNTM3NjA1NCJ9.WkM2XneftUNQbnIm69pDDEAzocsvHZlkv6e5SRS4_48',无法访问系统资源
|
||||
2026-06-03 17:44:04 [XNIO-1 task-3] ERROR o.d.c.w.h.GlobalExceptionHandler - 参数校验异常
|
||||
2026-06-03 22:52:30 [XNIO-1 task-2] ERROR o.d.c.w.h.GlobalExceptionHandler - 密码输入错误1次
|
||||
2026-06-13 08:59:32 [MQTT Ping: water-server-8081] ERROR o.e.p.c.mqttv3.internal.ClientState - water-server-8081: Timed out as no write activity, keepAlive=60,000,000,000 lastOutboundActivity=150,167,329,517,400 lastInboundActivity=150,167,356,610,400 time=204,053,810,500,400 lastPing=150,167,329,537,400
|
||||
|
||||
@@ -1,88 +1,323 @@
|
||||
2026-06-04 07:06:53 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:06:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-04 07:06:53 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[12]毫秒
|
||||
2026-06-04 07:06:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[36]毫秒
|
||||
2026-06-04 07:06:57 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2062185771665858562],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:06:57 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2062185771665858562],耗时:[13]毫秒
|
||||
2026-06-04 07:06:59 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2062185771665858562],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:06:59 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2062185771665858562],耗时:[5]毫秒
|
||||
2026-06-04 07:07:01 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[DELETE /app/v1/deleteDevice/2062185771665858562],参数类型[json],参数:[{"clientId":"32324a04c0175c8d61ac8a282553aea1"}]
|
||||
2026-06-04 07:07:01 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[DELETE /app/v1/deleteDevice/2062185771665858562],耗时:[10]毫秒
|
||||
2026-06-04 07:07:03 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:03 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-04 07:07:03 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[5]毫秒
|
||||
2026-06-04 07:07:03 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[22]毫秒
|
||||
2026-06-04 07:07:06 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/schedulelist],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-04 07:07:06 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/schedulelist],耗时:[12]毫秒
|
||||
2026-06-04 07:07:07 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/schedulelist],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["2"]}]
|
||||
2026-06-04 07:07:07 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/schedulelist],耗时:[15]毫秒
|
||||
2026-06-04 07:07:11 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:11 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[4]毫秒
|
||||
2026-06-04 07:07:13 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/dataStatistics],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:13 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/dataStatistics],耗时:[8]毫秒
|
||||
2026-06-04 07:07:14 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/waterLogList],参数类型[param],参数:[{"param[endTime]":[""],"param[beginTime]":[""],"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-04 07:07:14 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/waterLogList],耗时:[16]毫秒
|
||||
2026-06-04 07:07:16 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:16 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[4]毫秒
|
||||
2026-06-04 07:07:24 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:24 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[6]毫秒
|
||||
2026-06-04 07:07:33 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:07:33 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[6]毫秒
|
||||
2026-06-04 07:38:43 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:38:43 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-04 07:38:43 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[11]毫秒
|
||||
2026-06-04 07:38:43 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[28]毫秒
|
||||
2026-06-04 07:38:46 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2059509304398151682],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:38:46 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2059509304398151682],耗时:[7]毫秒
|
||||
2026-06-04 07:38:51 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/getUserInfo],参数类型[param],参数:[{"clientId":["32324a04c0175c8d61ac8a282553aea1"]}]
|
||||
2026-06-04 07:38:51 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[4]毫秒
|
||||
2026-06-04 08:11:28 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:11:28 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-04 08:11:32 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2060265891827957762],无参数
|
||||
2026-06-04 08:11:32 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2060265891827957762],耗时:[8]毫秒
|
||||
2026-06-04 08:11:33 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:11:34 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-04 08:11:35 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2060266873861324801],无参数
|
||||
2026-06-04 08:11:35 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2060266873861324801],耗时:[3]毫秒
|
||||
2026-06-04 08:11:37 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:11:37 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-04 08:11:38 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/device/2060266816596492289],无参数
|
||||
2026-06-04 08:11:38 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/device/2060266816596492289],耗时:[2]毫秒
|
||||
2026-06-04 08:11:51 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[PUT /app/v1/switchDevice],参数类型[json],参数:[{"id":"2060266816596492289","workStatus":"1","durationMin":"60"}]
|
||||
2026-06-04 08:11:51 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[PUT /app/v1/switchDevice],耗时:[13]毫秒
|
||||
2026-06-04 08:12:04 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:12:04 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-04 08:21:57 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:21:57 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-04 08:22:06 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:22:06 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-04 08:27:53 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 08:27:53 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[29]毫秒
|
||||
2026-06-04 10:28:49 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:28:49 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[49]毫秒
|
||||
2026-06-04 10:31:13 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:31:13 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[27]毫秒
|
||||
2026-06-04 10:44:03 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:44:03 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[23]毫秒
|
||||
2026-06-04 10:50:27 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:50:27 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-04 10:52:28 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:52:28 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[25]毫秒
|
||||
2026-06-04 10:52:47 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:52:47 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-04 10:53:33 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 10:53:33 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-04 11:05:23 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:05:23 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-04 11:08:20 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:08:20 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-04 11:17:17 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:17:17 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[21]毫秒
|
||||
2026-06-04 11:20:07 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:20:07 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-04 11:21:29 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:21:29 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-04 11:22:24 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:22:24 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-04 11:23:26 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-04 11:23:26 [XNIO-1 task-2] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [PLUS]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已重新连接:ssl://service.reinkun.com:8883
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/finish/schedule 服务质量等级=1
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/register 服务质量等级=1
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/power 服务质量等级=1
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/ack 服务质量等级=1
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/finish/key 服务质量等级=1
|
||||
2026-06-13 08:59:34 [MQTT Call: water-server-8081] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 已订阅 主题=/+/publish/error 服务质量等级=1
|
||||
2026-06-13 08:59:34 [mqtt-consumer-4] INFO o.d.app.handler.DeviceDataHandler - [MQTT] 设备电量更新 时间=2026-06-13 08:59:34 设备编号=01 消息体={
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 50,
|
||||
"charging": 0
|
||||
}
|
||||
2026-06-13 08:59:34 [mqtt-consumer-7] INFO o.d.a.handler.ScheduleFinishHandler - [MQTT] 浇水排程上报已保存 时间=2026-06-13 08:59:34 设备编号=01 消息体={
|
||||
"deviceNo": "01",
|
||||
"startWeek": 5,
|
||||
"startTime": "2026-06-11 8:20",
|
||||
"durationMin": 20,
|
||||
"triggerType": "mqtt on",
|
||||
"triggerON":"mqtt on",
|
||||
"triggerOFF":"mqtt off"
|
||||
}
|
||||
2026-06-13 08:59:34 [mqtt-consumer-8] INFO o.d.a.handler.DeviceRegisterHandler - [MQTT] 设备注册 时间=2026-06-13 08:59:34 设备编号=01 消息体={
|
||||
"deviceNo": "01",
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 63,
|
||||
"deviceEm": "11667796A-Y43-2606",
|
||||
"deviceSn": "260601",
|
||||
"deviceMac": "dc:da:0c:fa:28:9c",
|
||||
"version": "1.0"
|
||||
}
|
||||
2026-06-13 09:00:02 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:00:02 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[19]毫秒
|
||||
2026-06-13 09:00:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:00:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-13 09:00:52 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:00:52 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[9]毫秒
|
||||
2026-06-13 09:01:28 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:01:28 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:02:04 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:02:04 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:02:06 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:02:06 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 09:05:12 [schedule-pool-10] INFO o.d.app.task.DeviceOfflineCheckTask - [设备离线] 检测到 1 台设备离线,已更新数据库状态,设备编号:[01]
|
||||
2026-06-13 09:05:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"DC:DA:0C:FA:28:9E"}]
|
||||
2026-06-13 09:05:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[3]毫秒
|
||||
2026-06-13 09:05:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:05:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:06:56 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:06:56 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 09:07:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"DC:DA:0C:FA:28:9E"}]
|
||||
2026-06-13 09:07:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[8]毫秒
|
||||
2026-06-13 09:07:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:07:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-13 09:08:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:08:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"dc:da:0c:fa:28:9c"}]
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[2]毫秒
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:08:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:08:48 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:08:48 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:08:49 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:08:49 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:08:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:08:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 09:08:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:08:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[3]毫秒
|
||||
2026-06-13 09:08:54 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:08:54 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 09:09:18 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:09:18 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:09:19 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:09:19 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:11:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:11:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[11]毫秒
|
||||
2026-06-13 09:12:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:12:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:12:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:12:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[3]毫秒
|
||||
2026-06-13 09:13:56 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:13:56 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-13 09:15:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:15:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 09:15:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:15:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[5]毫秒
|
||||
2026-06-13 09:15:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/scheduleDeviceList/2062827585485807618],无参数
|
||||
2026-06-13 09:15:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/scheduleDeviceList/2062827585485807618],耗时:[7]毫秒
|
||||
2026-06-13 09:15:36 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/addScheduleDevice],参数类型[JSON],参数:[{"scheduleId":"2062827585485807618","deviceNos":["1779176626954"]}]
|
||||
2026-06-13 09:15:36 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/addScheduleDevice],耗时:[20]毫秒
|
||||
2026-06-13 09:15:37 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:15:37 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[11]毫秒
|
||||
2026-06-13 09:15:40 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:15:40 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[4]毫秒
|
||||
2026-06-13 09:15:46 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:15:46 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[6]毫秒
|
||||
2026-06-13 09:15:50 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:15:50 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[11]毫秒
|
||||
2026-06-13 09:15:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:15:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[6]毫秒
|
||||
2026-06-13 09:17:42 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:17:42 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 09:17:47 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:17:47 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[8]毫秒
|
||||
2026-06-13 09:17:48 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedule/2062827585485807618],无参数
|
||||
2026-06-13 09:17:48 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedule/2062827585485807618],耗时:[9]毫秒
|
||||
2026-06-13 09:17:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:17:51 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[11]毫秒
|
||||
2026-06-13 09:24:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:24:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 09:24:17 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:24:17 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 09:26:05 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:26:05 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:26:07 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:26:07 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 09:27:39 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:27:39 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:27:40 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:27:40 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[22]毫秒
|
||||
2026-06-13 09:46:39 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:46:39 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[26]毫秒
|
||||
2026-06-13 09:46:42 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:46:42 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[16]毫秒
|
||||
2026-06-13 09:46:54 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":["fuck"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:46:54 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[20]毫秒
|
||||
2026-06-13 09:46:58 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:46:58 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 09:47:10 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":["fuck"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:47:10 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[11]毫秒
|
||||
2026-06-13 09:47:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:47:14 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 09:49:16 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:49:16 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 09:49:18 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:49:18 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 09:49:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":["666"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:49:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[12]毫秒
|
||||
2026-06-13 09:49:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:49:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 09:51:11 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/waterLogList],参数类型[表单参数],参数:[{"pageNum":["1"]}]
|
||||
2026-06-13 09:51:11 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/waterLogList],耗时:[34]毫秒
|
||||
2026-06-13 09:51:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 09:51:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 09:51:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:51:24 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[13]毫秒
|
||||
2026-06-13 09:51:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:51:32 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:51:33 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:51:33 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[7]毫秒
|
||||
2026-06-13 09:53:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:53:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 09:53:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:53:23 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:53:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"dc:da:0c:fa:28:9c"}]
|
||||
2026-06-13 09:53:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[4]毫秒
|
||||
2026-06-13 09:53:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:53:53 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[13]毫秒
|
||||
2026-06-13 09:54:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:54:12 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:54:21 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:54:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"dc:da:0c:fa:28:9e"}]
|
||||
2026-06-13 09:54:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[1]毫秒
|
||||
2026-06-13 09:54:21 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:54:46 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:54:46 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:54:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"DC:DA:0C:FA:28:9E"}]
|
||||
2026-06-13 09:54:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[4]毫秒
|
||||
2026-06-13 09:54:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:54:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 09:55:12 [mqtt-consumer-16] INFO o.d.a.handler.DeviceRegisterHandler - [MQTT] 设备注册 时间=2026-06-13 09:55:12 设备编号=01 消息体={
|
||||
"deviceNo": "01",
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"deviceEm": "11667796A-Y43-2606",
|
||||
"deviceSn": "260601",
|
||||
"deviceMac": "dc:da:0c:fa:28:9c",
|
||||
"version": "1.0"
|
||||
}
|
||||
2026-06-13 09:55:12 [mqtt-consumer-13] INFO o.d.app.handler.DeviceDataHandler - [MQTT] 设备电量更新 时间=2026-06-13 09:55:12 设备编号=01 消息体={
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"charging": 0
|
||||
}
|
||||
2026-06-13 09:55:12 [mqtt-consumer-14] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=2ab3a6e58d1b4a89919d218fda63b3f7 状态=null
|
||||
2026-06-13 09:55:38 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/addDevice],参数类型[JSON],参数:[{"deviceName":"浇水设备007","wifiName":"研发部","wifiPassword":"ckkj123456","macAddress":"DC:DA:0C:FA:28:9E","deviceNo":"01"}]
|
||||
2026-06-13 09:55:38 [XNIO-1 task-4] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 消息已发布 主题=/01/subscriber/cmd 消息体={"commandType":"bindDevice","deviceNo":"01","cmd":-1,"commandId":"73669072eb924e9f9772d80fb9be57f8","bindStatus":true}
|
||||
2026-06-13 09:55:38 [XNIO-1 task-4] INFO o.d.a.s.i.DeviceCommandServiceImpl - [命令] 命令已下发 设备编号=01 命令类型=bindDevice 命令编号=73669072eb924e9f9772d80fb9be57f8
|
||||
2026-06-13 09:55:38 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/addDevice],耗时:[39]毫秒
|
||||
2026-06-13 09:55:38 [mqtt-consumer-11] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=73669072eb924e9f9772d80fb9be57f8 状态=null
|
||||
2026-06-13 09:55:39 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:55:39 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:55:59 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:56:00 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 09:56:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/bindDeviceStatus],参数类型[JSON],参数:[{"macAddress":"DC:DA:0C:FA:28:9E"}]
|
||||
2026-06-13 09:56:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/bindDeviceStatus],耗时:[1]毫秒
|
||||
2026-06-13 09:56:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:56:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[13]毫秒
|
||||
2026-06-13 09:57:15 [mqtt-consumer-8] INFO o.d.a.handler.DeviceRegisterHandler - [MQTT] 设备注册 时间=2026-06-13 09:57:15 设备编号=01 消息体={
|
||||
"deviceNo": "01",
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"deviceEm": "11667796A-Y43-2606",
|
||||
"deviceSn": "260601",
|
||||
"deviceMac": "dc:da:0c:fa:28:9c",
|
||||
"version": "1.0"
|
||||
}
|
||||
2026-06-13 09:57:15 [mqtt-consumer-8] INFO o.d.app.handler.DeviceDataHandler - [MQTT] 设备电量更新 时间=2026-06-13 09:57:15 设备编号=01 消息体={
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"charging": 0
|
||||
}
|
||||
2026-06-13 09:57:15 [mqtt-consumer-12] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=2ab3a6e58d1b4a89919d218fda63b3f7 状态=null
|
||||
2026-06-13 09:57:39 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/addDevice],参数类型[JSON],参数:[{"deviceName":"智能浇水","wifiName":"测试机","wifiPassword":"66668888","macAddress":"DC:DA:0C:FA:28:9E","deviceNo":"01"}]
|
||||
2026-06-13 09:57:39 [XNIO-1 task-4] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 消息已发布 主题=/01/subscriber/cmd 消息体={"commandType":"bindDevice","deviceNo":"01","cmd":-1,"commandId":"a783262582fd41fcb09d59d55a07c9e3","bindStatus":true}
|
||||
2026-06-13 09:57:39 [XNIO-1 task-4] INFO o.d.a.s.i.DeviceCommandServiceImpl - [命令] 命令已下发 设备编号=01 命令类型=bindDevice 命令编号=a783262582fd41fcb09d59d55a07c9e3
|
||||
2026-06-13 09:57:39 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/addDevice],耗时:[35]毫秒
|
||||
2026-06-13 09:57:40 [mqtt-consumer-3] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=a783262582fd41fcb09d59d55a07c9e3 状态=null
|
||||
2026-06-13 09:57:40 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 09:57:40 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 09:59:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:59:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 09:59:57 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 09:59:58 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 10:02:09 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:02:09 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:02:11 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 10:02:11 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[3]毫秒
|
||||
2026-06-13 10:02:12 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:02:12 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-13 10:03:42 [schedule-pool-5] INFO o.d.app.task.DeviceOfflineCheckTask - [设备离线] 检测到 1 台设备离线,已更新数据库状态,设备编号:[01]
|
||||
2026-06-13 10:04:26 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:04:26 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:11:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 10:11:55 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[2]毫秒
|
||||
2026-06-13 10:12:03 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:12:03 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[13]毫秒
|
||||
2026-06-13 10:12:20 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:20 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 10:12:23 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":["fuck"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:23 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[13]毫秒
|
||||
2026-06-13 10:12:28 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:28 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 10:12:36 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:36 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[7]毫秒
|
||||
2026-06-13 10:12:38 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":["66"],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:38 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[10]毫秒
|
||||
2026-06-13 10:12:42 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:12:42 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 10:16:20 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:16:20 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[7]毫秒
|
||||
2026-06-13 10:16:22 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:16:22 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 10:16:46 [mqtt-consumer-1] INFO o.d.a.handler.DeviceRegisterHandler - [MQTT] 设备注册 时间=2026-06-13 10:16:46 设备编号=01 消息体={
|
||||
"deviceNo": "01",
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"deviceEm": "11667796A-Y43-2606",
|
||||
"deviceSn": "260601",
|
||||
"deviceMac": "dc:da:0c:fa:28:9c",
|
||||
"version": "1.0"
|
||||
}
|
||||
2026-06-13 10:16:46 [mqtt-consumer-16] INFO o.d.app.handler.DeviceDataHandler - [MQTT] 设备电量更新 时间=2026-06-13 10:16:46 设备编号=01 消息体={
|
||||
"deviceName": "Waterer_01",
|
||||
"powerLevel": 48,
|
||||
"charging": 0
|
||||
}
|
||||
2026-06-13 10:16:47 [mqtt-consumer-16] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=2ab3a6e58d1b4a89919d218fda63b3f7 状态=null
|
||||
2026-06-13 10:16:57 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[POST /app/v1/addDevice],参数类型[JSON],参数:[{"deviceName":"还是浇水设备","wifiName":"研发部","wifiPassword":"ckkj123456","macAddress":"DC:DA:0C:FA:28:9E","deviceNo":"01"}]
|
||||
2026-06-13 10:16:57 [XNIO-1 task-4] INFO org.dromara.mqtt.MqttClientManager - [MQTT] 消息已发布 主题=/01/subscriber/cmd 消息体={"commandType":"bindDevice","deviceNo":"01","cmd":-1,"commandId":"00119ae0fc844c1c88d61052e1ded66b","bindStatus":true}
|
||||
2026-06-13 10:16:57 [XNIO-1 task-4] INFO o.d.a.s.i.DeviceCommandServiceImpl - [命令] 命令已下发 设备编号=01 命令类型=bindDevice 命令编号=00119ae0fc844c1c88d61052e1ded66b
|
||||
2026-06-13 10:16:57 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[POST /app/v1/addDevice],耗时:[36]毫秒
|
||||
2026-06-13 10:16:57 [mqtt-consumer-6] INFO o.dromara.mqtt.MqttCommandAckService - [MQTT] 收到命令确认 设备编号=01 命令编号=00119ae0fc844c1c88d61052e1ded66b 状态=null
|
||||
2026-06-13 10:16:58 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/device/01],无参数
|
||||
2026-06-13 10:16:58 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/device/01],耗时:[5]毫秒
|
||||
2026-06-13 10:17:04 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:17:04 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:18:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:18:48 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 10:23:12 [schedule-pool-4] INFO o.d.app.task.DeviceOfflineCheckTask - [设备离线] 检测到 1 台设备离线,已更新数据库状态,设备编号:[01]
|
||||
2026-06-13 10:34:56 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:34:56 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[22]毫秒
|
||||
2026-06-13 10:34:57 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:34:57 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 10:35:05 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:35:05 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:35:05 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:35:05 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:37:22 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:37:22 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:37:22 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[18]毫秒
|
||||
2026-06-13 10:37:22 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 10:38:02 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/waterLogList],参数类型[表单参数],参数:[{"pageNum":["1"]}]
|
||||
2026-06-13 10:38:02 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/waterLogList],耗时:[14]毫秒
|
||||
2026-06-13 10:38:06 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:38:06 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 10:38:08 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/waterLogList],参数类型[表单参数],参数:[{"pageNum":["1"]}]
|
||||
2026-06-13 10:38:08 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/waterLogList],耗时:[12]毫秒
|
||||
2026-06-13 10:38:08 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/schedulelist],参数类型[表单参数],参数:[{"name":[""],"pageSize":["10"],"pageNum":["1"]}]
|
||||
2026-06-13 10:38:08 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/schedulelist],耗时:[9]毫秒
|
||||
2026-06-13 10:38:09 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:09 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[15]毫秒
|
||||
2026-06-13 10:38:13 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/getUserInfo],无参数
|
||||
2026-06-13 10:38:13 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[9]毫秒
|
||||
2026-06-13 10:38:14 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:14 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 10:38:16 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/getUserInfo],无参数
|
||||
2026-06-13 10:38:16 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[6]毫秒
|
||||
2026-06-13 10:38:19 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:19 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/getUserInfo],无参数
|
||||
2026-06-13 10:38:19 [XNIO-1 task-4] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/getUserInfo],耗时:[5]毫秒
|
||||
2026-06-13 10:38:19 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[16]毫秒
|
||||
2026-06-13 10:38:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:21 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 10:38:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[17]毫秒
|
||||
2026-06-13 10:38:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:25 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[13]毫秒
|
||||
2026-06-13 10:38:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
2026-06-13 10:38:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]开始请求 => URL[GET /app/v1/deviceList],无参数
|
||||
2026-06-13 10:38:27 [XNIO-1 task-3] INFO o.d.c.w.i.PlusWebInvokeTimeInterceptor - [请求]结束请求 => URL[GET /app/v1/deviceList],耗时:[14]毫秒
|
||||
|
||||
@@ -18,7 +18,7 @@ public class DromaraApplication {
|
||||
SpringApplication application = new SpringApplication(DromaraApplication.class);
|
||||
application.setApplicationStartup(new BufferingApplicationStartup(2048));
|
||||
application.run(args);
|
||||
log.info("(♥◠‿◠)ノ゙ water-Vue-Plus启动成功 ლ(´ڡ`ლ)゙");
|
||||
log.info("(♥◠‿◠)ノ゙ 系统启动成功 ლ(´ڡ`ლ)゙");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class AuthController {
|
||||
SysClientVo client = clientService.queryByClientId(clientId);
|
||||
// 查询不到 client 或 client 内不包含 grantType
|
||||
if (ObjectUtil.isNull(client) || !StringUtils.contains(client.getGrantType(), grantType)) {
|
||||
log.info("客户端id: {} 认证类型:{} 异常!.", clientId, grantType);
|
||||
log.info("客户端ID:{} 认证类型:{} 异常!", clientId, grantType);
|
||||
return R.fail(MessageUtils.message("auth.grant.type.error"));
|
||||
} else if (!SystemConstants.NORMAL.equals(client.getStatus())) {
|
||||
return R.fail(MessageUtils.message("auth.grant.type.blocked"));
|
||||
|
||||
@@ -73,7 +73,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
SpringUtils.context().publishEvent(logininforEvent);
|
||||
// 更新登录信息
|
||||
loginService.recordLoginInfo((Long) loginParameter.getExtra(LoginHelper.USER_KEY), ip);
|
||||
log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
|
||||
log.info("用户登录,用户ID:{},令牌:{}", loginId, tokenValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,7 +85,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
TenantHelper.dynamic(tenantId, () -> {
|
||||
RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
|
||||
});
|
||||
log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue);
|
||||
log.info("用户注销,用户ID:{},令牌:{}", loginId, tokenValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,7 +97,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
TenantHelper.dynamic(tenantId, () -> {
|
||||
RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
|
||||
});
|
||||
log.info("user doKickout, userId:{}, token:{}", loginId, tokenValue);
|
||||
log.info("用户被踢下线,用户ID:{},令牌:{}", loginId, tokenValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +109,7 @@ public class UserActionListener implements SaTokenListener {
|
||||
TenantHelper.dynamic(tenantId, () -> {
|
||||
RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
|
||||
});
|
||||
log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue);
|
||||
log.info("用户被顶下线,用户ID:{},令牌:{}", loginId, tokenValue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -55,6 +55,9 @@ mqtt:
|
||||
pending-set-key: "mqtt:command:pending:ids"
|
||||
device-status-cache-prefix: "mqtt:device:status:"
|
||||
device-status-cache-ttl-seconds: 300
|
||||
offline-check:
|
||||
enabled: true
|
||||
interval-ms: 90000
|
||||
topics:
|
||||
subscribe:
|
||||
|
||||
|
||||
@@ -1 +1,78 @@
|
||||
#错误消息
|
||||
#错误消息
|
||||
operation.success=操作成功
|
||||
operation.fail=操作失败
|
||||
query.success=查询成功
|
||||
not.null=* 必须填写
|
||||
user.jcaptcha.error=验证码错误
|
||||
user.jcaptcha.expire=验证码已失效
|
||||
user.not.exists=对不起, 您的账号:{0} 不存在.
|
||||
user.password.not.match=用户不存在/密码错误
|
||||
user.password.retry.limit.count=密码输入错误{0}次
|
||||
user.password.retry.limit.exceed=密码输入错误{0}次,账户锁定{1}分钟
|
||||
user.password.delete=对不起,您的账号:{0} 已被删除
|
||||
user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
|
||||
role.blocked=角色已封禁,请联系管理员
|
||||
user.logout.success=退出成功
|
||||
length.not.valid=长度必须在{min}到{max}个字符之间
|
||||
user.username.not.blank=用户名不能为空
|
||||
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
|
||||
user.username.length.valid=账户长度必须在{min}到{max}个字符之间
|
||||
user.password.not.blank=用户密码不能为空
|
||||
user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
|
||||
user.password.not.valid=* 5-50个字符
|
||||
user.password.format.valid=密码必须包含大写字母、小写字母、数字和特殊字符
|
||||
user.email.not.valid=邮箱格式错误
|
||||
user.email.not.blank=邮箱不能为空
|
||||
user.email.not.username=邮箱号不一致
|
||||
user.phonenumber.not.blank=用户手机号不能为空
|
||||
user.mobile.phone.number.not.valid=手机号格式错误
|
||||
user.mobile.phone.number.not.username=手机号不一致
|
||||
user.login.success=登录成功
|
||||
user.register.success=注册成功
|
||||
user.register.save.error=保存用户 {0} 失败,注册账号已存在
|
||||
user.register.error=注册失败,请联系系统管理人员
|
||||
user.notfound=请重新登录
|
||||
user.forcelogout=管理员强制退出,请重新登录
|
||||
user.unknown.error=未知错误,请重新登录
|
||||
auth.grant.type.error=认证权限类型错误
|
||||
auth.grant.type.blocked=认证权限类型已禁用
|
||||
auth.grant.type.not.blank=认证权限类型不能为空
|
||||
auth.clientid.not.blank=认证客户端id不能为空
|
||||
##文件上传消息
|
||||
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
|
||||
upload.filename.exceed.length=上传的文件名最长{0}个字符
|
||||
##权限
|
||||
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
|
||||
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
|
||||
repeat.submit.message=不允许重复提交,请稍候再试
|
||||
rate.limiter.message=访问过于频繁,请稍候再试
|
||||
sms.code.not.blank=短信验证码不能为空
|
||||
sms.code.retry.limit.count=短信验证码输入错误{0}次
|
||||
sms.code.retry.limit.exceed=短信验证码输入错误{0}次,账户锁定{1}分钟
|
||||
email.code.not.blank=邮箱验证码不能为空
|
||||
email.code.retry.limit.count=邮箱验证码输入错误{0}次
|
||||
email.code.retry.limit.exceed=邮箱验证码输入错误{0}次,账户锁定{1}分钟
|
||||
xcx.code.not.blank=小程序[code]不能为空
|
||||
social.source.not.blank=第三方登录平台[source]不能为空
|
||||
social.code.not.blank=第三方登录平台[code]不能为空
|
||||
social.state.not.blank=第三方登录平台[state]不能为空
|
||||
##租户
|
||||
tenant.number.not.blank=租户编号不能为空
|
||||
tenant.not.exists=对不起, 您的租户不存在,请联系管理员
|
||||
tenant.blocked=对不起,您的租户已禁用,请联系管理员
|
||||
tenant.expired=对不起,您的租户已过期,请联系管理员
|
||||
##APP
|
||||
app.device.no.not.blank=设备编号不能为空
|
||||
app.device.not.exists.or.denied=设备不存在或无权访问
|
||||
app.schedule.id.not.blank=排程编号不能为空
|
||||
app.schedule.not.exists.or.denied=排程不存在或无权访问
|
||||
app.schedule.id.not.blank.request=scheduleId不能为空
|
||||
app.schedule.devices.not.blank=deviceNos不能为空
|
||||
app.watering.log.id.not.blank=浇水记录编号不能为空
|
||||
app.watering.log.not.exists.or.denied=浇水记录不存在或无权访问
|
||||
app.user.data.denied=没有权限访问用户数据!
|
||||
app.user.phone.exists=修改用户'{0}'失败,手机号码已存在
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#错误消息
|
||||
# error messages
|
||||
operation.success=Operation successful
|
||||
operation.fail=Operation failed
|
||||
query.success=Query successful
|
||||
not.null=* Required fill in
|
||||
user.jcaptcha.error=Captcha error
|
||||
user.jcaptcha.expire=Captcha invalid
|
||||
@@ -6,9 +9,9 @@ user.not.exists=Sorry, your account: {0} does not exist
|
||||
user.password.not.match=User does not exist/Password error
|
||||
user.password.retry.limit.count=Password input error {0} times
|
||||
user.password.retry.limit.exceed=Password input error {0} times, account locked for {1} minutes
|
||||
user.password.delete=Sorry, your account:{0} has been deleted
|
||||
user.password.delete=Sorry, your account: {0} has been deleted
|
||||
user.blocked=Sorry, your account: {0} has been disabled. Please contact the administrator
|
||||
role.blocked=Role disabled,please contact administrators
|
||||
role.blocked=Role disabled, please contact administrators
|
||||
user.logout.success=Exit successful
|
||||
length.not.valid=The length must be between {min} and {max} characters
|
||||
user.username.not.blank=Username cannot be blank
|
||||
@@ -20,29 +23,31 @@ user.password.not.valid=* 5-50 characters
|
||||
user.password.format.valid=Password must contain uppercase, lowercase, digit, and special character
|
||||
user.email.not.valid=Mailbox format error
|
||||
user.email.not.blank=Mailbox cannot be blank
|
||||
user.email.not.username=Email does not match the current user
|
||||
user.phonenumber.not.blank=Phone number cannot be blank
|
||||
user.mobile.phone.number.not.valid=Phone number format error
|
||||
user.mobile.phone.number.not.username=Phone number does not match the current user
|
||||
user.login.success=Login successful
|
||||
user.register.success=Register successful
|
||||
user.register.save.error=Failed to save user {0}, The registered account already exists
|
||||
user.register.error=Register failed, please contact system administrator
|
||||
user.notfound=Please login again
|
||||
user.forcelogout=The administrator is forced to exit,please login again
|
||||
user.forcelogout=The administrator is forced to exit, please login again
|
||||
user.unknown.error=Unknown error, please login again
|
||||
auth.grant.type.error=Auth grant type error
|
||||
auth.grant.type.blocked=Auth grant type disabled
|
||||
auth.grant.type.not.blank=Auth grant type cannot be blank
|
||||
auth.clientid.not.blank=Auth clientid cannot be blank
|
||||
##文件上传消息
|
||||
upload.exceed.maxSize=The uploaded file size exceeds the limit file size!<br/>the maximum allowed file size is:{0}MB!
|
||||
## upload messages
|
||||
upload.exceed.maxSize=The uploaded file size exceeds the limit file size!<br/>the maximum allowed file size is: {0}MB!
|
||||
upload.filename.exceed.length=The maximum length of uploaded file name is {0} characters
|
||||
##权限
|
||||
no.permission=You do not have permission to the data,please contact your administrator to add permissions [{0}]
|
||||
no.create.permission=You do not have permission to create data,please contact your administrator to add permissions [{0}]
|
||||
no.update.permission=You do not have permission to modify data,please contact your administrator to add permissions [{0}]
|
||||
no.delete.permission=You do not have permission to delete data,please contact your administrator to add permissions [{0}]
|
||||
no.export.permission=You do not have permission to export data,please contact your administrator to add permissions [{0}]
|
||||
no.view.permission=You do not have permission to view data,please contact your administrator to add permissions [{0}]
|
||||
## permissions
|
||||
no.permission=You do not have permission to the data, please contact your administrator to add permissions [{0}]
|
||||
no.create.permission=You do not have permission to create data, please contact your administrator to add permissions [{0}]
|
||||
no.update.permission=You do not have permission to modify data, please contact your administrator to add permissions [{0}]
|
||||
no.delete.permission=You do not have permission to delete data, please contact your administrator to add permissions [{0}]
|
||||
no.export.permission=You do not have permission to export data, please contact your administrator to add permissions [{0}]
|
||||
no.view.permission=You do not have permission to view data, please contact your administrator to add permissions [{0}]
|
||||
repeat.submit.message=Repeat submit is not allowed, please try again later
|
||||
rate.limiter.message=Visit too frequently, please try again later
|
||||
sms.code.not.blank=Sms code cannot be blank
|
||||
@@ -55,8 +60,19 @@ xcx.code.not.blank=Mini program [code] cannot be blank
|
||||
social.source.not.blank=Social login platform [source] cannot be blank
|
||||
social.code.not.blank=Social login platform [code] cannot be blank
|
||||
social.state.not.blank=Social login platform [state] cannot be blank
|
||||
##租户
|
||||
## tenant
|
||||
tenant.number.not.blank=Tenant number cannot be blank
|
||||
tenant.not.exists=Sorry, your tenant does not exist. Please contact the administrator
|
||||
tenant.blocked=Sorry, your tenant is disabled. Please contact the administrator
|
||||
tenant.expired=Sorry, your tenant has expired. Please contact the administrator.
|
||||
## APP
|
||||
app.device.no.not.blank=Device number cannot be blank
|
||||
app.device.not.exists.or.denied=Device does not exist or access is denied
|
||||
app.schedule.id.not.blank=Schedule ID cannot be blank
|
||||
app.schedule.not.exists.or.denied=Schedule does not exist or access is denied
|
||||
app.schedule.id.not.blank.request=scheduleId cannot be blank
|
||||
app.schedule.devices.not.blank=deviceNos cannot be blank
|
||||
app.watering.log.id.not.blank=Watering log ID cannot be blank
|
||||
app.watering.log.not.exists.or.denied=Watering log does not exist or access is denied
|
||||
app.user.data.denied=No permission to access user data
|
||||
app.user.phone.exists=Failed to update user ''{0}'': phone number already exists
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
#错误消息
|
||||
operation.success=操作成功
|
||||
operation.fail=操作失败
|
||||
query.success=查询成功
|
||||
not.null=* 必须填写
|
||||
user.jcaptcha.error=验证码错误
|
||||
user.jcaptcha.expire=验证码已失效
|
||||
@@ -20,8 +23,10 @@ user.password.not.valid=* 5-50个字符
|
||||
user.password.format.valid=密码必须包含大写字母、小写字母、数字和特殊字符
|
||||
user.email.not.valid=邮箱格式错误
|
||||
user.email.not.blank=邮箱不能为空
|
||||
user.email.not.username=邮箱号不一致
|
||||
user.phonenumber.not.blank=用户手机号不能为空
|
||||
user.mobile.phone.number.not.valid=手机号格式错误
|
||||
user.mobile.phone.number.not.username=手机号不一致
|
||||
user.login.success=登录成功
|
||||
user.register.success=注册成功
|
||||
user.register.save.error=保存用户 {0} 失败,注册账号已存在
|
||||
@@ -60,3 +65,14 @@ tenant.number.not.blank=租户编号不能为空
|
||||
tenant.not.exists=对不起, 您的租户不存在,请联系管理员
|
||||
tenant.blocked=对不起,您的租户已禁用,请联系管理员
|
||||
tenant.expired=对不起,您的租户已过期,请联系管理员
|
||||
##APP
|
||||
app.device.no.not.blank=设备编号不能为空
|
||||
app.device.not.exists.or.denied=设备不存在或无权访问
|
||||
app.schedule.id.not.blank=排程编号不能为空
|
||||
app.schedule.not.exists.or.denied=排程不存在或无权访问
|
||||
app.schedule.id.not.blank.request=scheduleId不能为空
|
||||
app.schedule.devices.not.blank=deviceNos不能为空
|
||||
app.watering.log.id.not.blank=浇水记录编号不能为空
|
||||
app.watering.log.not.exists.or.denied=浇水记录不存在或无权访问
|
||||
app.user.data.denied=没有权限访问用户数据!
|
||||
app.user.phone.exists=修改用户'{0}'失败,手机号码已存在
|
||||
|
||||
@@ -70,7 +70,7 @@ public class ThreadPoolConfig {
|
||||
if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
|
||||
pool.shutdownNow();
|
||||
if (!pool.awaitTermination(120, TimeUnit.SECONDS)) {
|
||||
log.info("Pool did not terminate");
|
||||
log.info("线程池未在指定时间内终止");
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ie) {
|
||||
@@ -87,9 +87,8 @@ public class ThreadPoolConfig {
|
||||
* 打印线程异常信息
|
||||
*/
|
||||
public static void printException(Runnable r, Throwable t) {
|
||||
if (t == null && r instanceof Future<?>) {
|
||||
if (t == null && r instanceof Future<?> future) {
|
||||
try {
|
||||
Future<?> future = (Future<?>) r;
|
||||
if (future.isDone()) {
|
||||
future.get();
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package org.dromara.common.core.domain;
|
||||
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.common.core.constant.HttpStatus;
|
||||
import org.dromara.common.core.utils.MessageUtils;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
@@ -36,11 +37,11 @@ public class R<T> implements Serializable {
|
||||
private T data;
|
||||
|
||||
public static <T> R<T> ok() {
|
||||
return restResult(null, SUCCESS, "操作成功");
|
||||
return restResult(null, SUCCESS, message("operation.success", "操作成功"));
|
||||
}
|
||||
|
||||
public static <T> R<T> ok(T data) {
|
||||
return restResult(data, SUCCESS, "操作成功");
|
||||
return restResult(data, SUCCESS, message("operation.success", "操作成功"));
|
||||
}
|
||||
|
||||
public static <T> R<T> ok(String msg) {
|
||||
@@ -52,7 +53,7 @@ public class R<T> implements Serializable {
|
||||
}
|
||||
|
||||
public static <T> R<T> fail() {
|
||||
return restResult(null, FAIL, "操作失败");
|
||||
return restResult(null, FAIL, message("operation.fail", "操作失败"));
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(String msg) {
|
||||
@@ -100,6 +101,15 @@ public class R<T> implements Serializable {
|
||||
return r;
|
||||
}
|
||||
|
||||
private static String message(String code, String defaultMessage) {
|
||||
try {
|
||||
String message = MessageUtils.message(code);
|
||||
return code.equals(message) ? defaultMessage : message;
|
||||
} catch (Exception e) {
|
||||
return defaultMessage;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Boolean isError(R<T> ret) {
|
||||
return !isSuccess(ret);
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class RegionUtils {
|
||||
Config v6Config = null;
|
||||
InputStream v6XdbInputStream = ResourceUtil.getStreamSafe(DEFAULT_IPV6_XDB_PATH);
|
||||
if (v6XdbInputStream == null) {
|
||||
log.warn("未加载 IPv6 地址库:未在类路径下找到文件 {}。当前仅启用 IPv4 查询。如需启用 IPv6,请将 ip2region_v6.xdb 放置到 resources 目录", DEFAULT_IPV6_XDB_PATH);
|
||||
log.warn("未加载 IPv6 地址库:未在类路径下找到文件 {}。当前仅启用 IPv4 查询。如需启用 IPv6,请将 ip2region_v6.xdb 放置到资源目录", DEFAULT_IPV6_XDB_PATH);
|
||||
} else {
|
||||
v6Config = Config.custom()
|
||||
.setCachePolicy(Config.BufferCache)
|
||||
@@ -128,7 +128,7 @@ public class RegionUtils {
|
||||
try {
|
||||
ip2Region.close(10000);
|
||||
} catch (Exception e) {
|
||||
log.error("Ip2Region服务关闭异常", e);
|
||||
log.error("IP地址库服务关闭异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ public class RegionUtils {
|
||||
try {
|
||||
ip2Region.close(timeout.toMillis());
|
||||
} catch (Exception e) {
|
||||
log.error("Ip2Region服务关闭异常", e);
|
||||
log.error("IP地址库服务关闭异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ public class SaTokenAnnotationMetadataJavadocResolver extends AbstractMetadataJa
|
||||
SA_IGNORE_CLASS = (Class<? extends Annotation>) ClassLoaderUtil.loadClass(SA_IGNORE_CLASS_NAME, false);
|
||||
SA_CHECK_LOGIN_CLASS = (Class<? extends Annotation>) ClassLoaderUtil.loadClass(SA_CHECK_LOGIN_NAME, false);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("SaTokenAnnotationJavadocResolver init success, load annotation class: {}", List.of(SA_CHECK_ROLE_CLASS, SA_CHECK_PERMISSION_CLASS, SA_IGNORE_CLASS, SA_CHECK_LOGIN_CLASS));
|
||||
log.debug("SaToken 注解 Javadoc 解析器初始化成功,已加载注解类:{}", List.of(SA_CHECK_ROLE_CLASS, SA_CHECK_PERMISSION_CLASS, SA_IGNORE_CLASS, SA_CHECK_LOGIN_CLASS));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ public class JacksonConfig {
|
||||
public Jackson2ObjectMapperBuilderCustomizer customizer() {
|
||||
return builder -> {
|
||||
builder.timeZone(TimeZone.getDefault());
|
||||
log.info("初始化 jackson 配置");
|
||||
log.info("初始化JSON序列化配置");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>water-common-json</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>water-common-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dromara</groupId>
|
||||
<artifactId>water-app</artifactId>
|
||||
|
||||
@@ -34,7 +34,12 @@ public class DeviceMqttCommandPublisher implements IDeviceCommandPublisher {
|
||||
command.getPayload().put("commandType", command.getCommandType());
|
||||
|
||||
ackService.savePending(command);
|
||||
try {
|
||||
mqttClientManager.publish(command.getTopic(), JsonUtils.toJsonString(command.getPayload()));
|
||||
} catch (RuntimeException e) {
|
||||
ackService.removePending(command.getCommandId());
|
||||
throw e;
|
||||
}
|
||||
return command.getCommandId();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,10 @@ package org.dromara.mqtt;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.app.mqtt.MqttMessageDispatcher;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.mqtt.config.properties.MqttProperties;
|
||||
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
|
||||
import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
|
||||
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
|
||||
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
|
||||
import org.eclipse.paho.client.mqttv3.MqttException;
|
||||
import org.eclipse.paho.client.mqttv3.MqttMessage;
|
||||
import org.eclipse.paho.client.mqttv3.*;
|
||||
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
@@ -26,11 +23,7 @@ import java.security.GeneralSecurityException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@Slf4j
|
||||
@@ -50,6 +43,12 @@ public class MqttClientManager implements DisposableBean {
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "mqtt", name = "enabled", havingValue = "true")
|
||||
public MqttAsyncClient mqttConnect() throws MqttException {
|
||||
if (StringUtils.isBlank(props.getBrokerUrl())) {
|
||||
throw new ServiceException("启用 MQTT 时必须配置 broker-url");
|
||||
}
|
||||
if (StringUtils.isBlank(props.getClientId())) {
|
||||
throw new ServiceException("启用 MQTT 时必须配置 client-id");
|
||||
}
|
||||
messageQueue = new ArrayBlockingQueue<>(Math.max(1, props.getAsync().getQueueCapacity()));
|
||||
consumerExecutor = createConsumerExecutor();
|
||||
running = true;
|
||||
@@ -71,13 +70,13 @@ public class MqttClientManager implements DisposableBean {
|
||||
client.setCallback(new MqttCallbackExtended() {
|
||||
@Override
|
||||
public void connectionLost(Throwable cause) {
|
||||
log.warn("[MQTT] connection lost: {}", cause == null ? "" : cause.getMessage());
|
||||
log.warn("[MQTT] 连接已断开:{}", cause == null ? "" : cause.getMessage());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void connectComplete(boolean reconnect, String serverURI) {
|
||||
if (reconnect) {
|
||||
log.info("[MQTT] reconnected: {}", serverURI);
|
||||
log.info("[MQTT] 已重新连接:{}", serverURI);
|
||||
subscribeTopics();
|
||||
}
|
||||
}
|
||||
@@ -94,7 +93,7 @@ public class MqttClientManager implements DisposableBean {
|
||||
});
|
||||
|
||||
client.connect(options).waitForCompletion();
|
||||
log.info("[MQTT] connected: {}", props.getBrokerUrl());
|
||||
log.info("[MQTT] 已连接:{}", props.getBrokerUrl());
|
||||
subscribeTopics();
|
||||
return client;
|
||||
}
|
||||
@@ -183,11 +182,11 @@ public class MqttClientManager implements DisposableBean {
|
||||
InboundMessage inboundMessage = new InboundMessage(topic, payload);
|
||||
try {
|
||||
if (!messageQueue.offer(inboundMessage, props.getAsync().getOfferTimeoutMs(), TimeUnit.MILLISECONDS)) {
|
||||
log.warn("[MQTT] inbound queue full, dropped topic={}", topic);
|
||||
log.warn("[MQTT] 上行消息队列已满,丢弃 主题={}", topic);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
log.warn("[MQTT] enqueue interrupted topic={}", topic);
|
||||
log.warn("[MQTT] 上行消息入队被中断 主题={}", topic);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -221,7 +220,7 @@ public class MqttClientManager implements DisposableBean {
|
||||
try {
|
||||
dispatcher.dispatch(message.topic(), message.payload());
|
||||
} catch (Exception e) {
|
||||
log.error("[MQTT] dispatch failed topic={}", message.topic(), e);
|
||||
log.error("[MQTT] 消息分发失败 主题={}", message.topic(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,30 +231,31 @@ public class MqttClientManager implements DisposableBean {
|
||||
}
|
||||
List<String> topics = props.getTopics() == null ? List.of() : props.getTopics().getSubscribe();
|
||||
if (topics == null || topics.isEmpty()) {
|
||||
log.warn("[MQTT] no subscribe topics configured");
|
||||
log.warn("[MQTT] 未配置订阅主题");
|
||||
return;
|
||||
}
|
||||
int[] qos = topics.stream().mapToInt(topic -> props.getQos()).toArray();
|
||||
client.subscribe(topics.toArray(new String[0]), qos).waitForCompletion();
|
||||
topics.forEach(topic -> log.info("[MQTT] subscribed: {} qos={}", topic, props.getQos()));
|
||||
topics.forEach(topic -> log.info("[MQTT] 已订阅 主题={} 服务质量等级={}", topic, props.getQos()));
|
||||
} catch (MqttException e) {
|
||||
log.error("[MQTT] subscribe failed", e);
|
||||
log.error("[MQTT] 订阅失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void publish(String topic, String payload) {
|
||||
try {
|
||||
if (client == null || !client.isConnected()) {
|
||||
log.warn("[MQTT] publish skipped, client not connected topic={}", topic);
|
||||
return;
|
||||
throw new ServiceException("MQTT客户端未连接");
|
||||
}
|
||||
MqttMessage message = new MqttMessage(payload.getBytes(StandardCharsets.UTF_8));
|
||||
message.setQos(props.getQos());
|
||||
message.setRetained(false);
|
||||
client.publish(topic, message);
|
||||
log.info("[MQTT] published topic={} payload={}", topic, payload);
|
||||
IMqttDeliveryToken token = client.publish(topic, message);
|
||||
token.waitForCompletion(Math.max(1000L, props.getConnectionTimeout() * 1000L));
|
||||
log.info("[MQTT] 消息已发布 主题={} 消息体={}", topic, payload);
|
||||
} catch (MqttException e) {
|
||||
log.error("[MQTT] publish failed topic={}", topic, e);
|
||||
log.error("[MQTT] 消息发布失败 主题={}", topic, e);
|
||||
throw new ServiceException("MQTT 消息发布失败:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package org.dromara.mqtt;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.app.domain.AppDevice;
|
||||
import org.dromara.app.domain.mqtt.DeviceCommand;
|
||||
import org.dromara.app.domain.mqtt.DeviceCommandAck;
|
||||
import org.dromara.app.mapper.AppDeviceMapper;
|
||||
import org.dromara.app.service.IDeviceCommandAckHandler;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
@@ -17,11 +20,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@@ -36,16 +35,24 @@ public class MqttCommandAckService implements IDeviceCommandAckHandler {
|
||||
@Autowired
|
||||
private MqttClientManager mqttClientManager;
|
||||
private final MqttProperties mqttProperties;
|
||||
private final AppDeviceMapper appDeviceMapper;
|
||||
|
||||
public void savePending(DeviceCommand command) {
|
||||
RedisUtils.setCacheObject(pendingKey(command.getCommandId()), command, Duration.ofSeconds(mqttProperties.getCommandAck().getPendingTtlSeconds()));
|
||||
pendingIds().add(command.getCommandId());
|
||||
}
|
||||
|
||||
public void removePending(String commandId) {
|
||||
if (StringUtils.isBlank(commandId)) {
|
||||
return;
|
||||
}
|
||||
deletePending(commandId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAck(String deviceNo, String payload) {
|
||||
if (StringUtils.isBlank(payload)) {
|
||||
log.warn("[MQTT] 收到空 ACK deviceNo={}", deviceNo);
|
||||
log.warn("[MQTT] 收到空 ACK 设备编号={}", deviceNo);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -59,26 +66,25 @@ public class MqttCommandAckService implements IDeviceCommandAckHandler {
|
||||
try {
|
||||
ack = JsonUtils.parseObject(trimmedPayload, DeviceCommandAck.class);
|
||||
} catch (RuntimeException e) {
|
||||
log.warn("[MQTT] ACK JSON 格式错误 deviceNo={} payload={}", deviceNo, payload, e);
|
||||
log.warn("[MQTT] ACK JSON 格式错误 设备编号={} 消息体={}", deviceNo, payload, e);
|
||||
return;
|
||||
}
|
||||
if (ack == null || ack.getCommandId() == null) {
|
||||
log.warn("[MQTT] ACK 缺少 commandId deviceNo={} payload={}", deviceNo, payload);
|
||||
log.warn("[MQTT] ACK 缺少命令编号 设备编号={} 消息体={}", deviceNo, payload);
|
||||
return;
|
||||
}
|
||||
ack.setDeviceNo(deviceNo);
|
||||
RedisUtils.deleteObject(pendingKey(ack.getCommandId()));
|
||||
pendingIds().remove(ack.getCommandId());
|
||||
deletePending(ack.getCommandId());
|
||||
RedisUtils.setCacheObject(ackKey(ack.getCommandId()), ack, Duration.ofSeconds(mqttProperties.getCommandAck().getAckTtlSeconds()));
|
||||
refreshDeviceOnline(deviceNo);
|
||||
log.info("[MQTT] command ack received deviceNo={} commandId={} status={}", deviceNo, ack.getCommandId(), ack.getStatus());
|
||||
log.info("[MQTT] 收到命令确认 设备编号={} 命令编号={} 状态={}", deviceNo, ack.getCommandId(), ack.getStatus());
|
||||
}
|
||||
|
||||
private void handlePlainAck(String deviceNo, String payload) {
|
||||
List<DeviceCommand> pendingCommands = findPendingCommandsByDeviceNo(deviceNo);
|
||||
refreshDeviceOnline(deviceNo);
|
||||
if (pendingCommands.size() != 1) {
|
||||
log.warn("[MQTT] 非 JSON ACK 无法唯一匹配待确认命令 deviceNo={} pendingCount={} payload={}", deviceNo, pendingCommands.size(), payload);
|
||||
log.warn("[MQTT] 非 JSON ACK 无法唯一匹配待确认命令 设备编号={} 待确认数量={} 消息体={}", deviceNo, pendingCommands.size(), payload);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -90,10 +96,9 @@ public class MqttCommandAckService implements IDeviceCommandAckHandler {
|
||||
ack.setStatus("1");
|
||||
ack.setMessage(payload);
|
||||
|
||||
RedisUtils.deleteObject(pendingKey(commandId));
|
||||
pendingIds().remove(commandId);
|
||||
deletePending(commandId);
|
||||
RedisUtils.setCacheObject(ackKey(commandId), ack, Duration.ofSeconds(mqttProperties.getCommandAck().getAckTtlSeconds()));
|
||||
log.info("[MQTT] plain command ack received deviceNo={} commandId={} payload={}", deviceNo, commandId, payload);
|
||||
log.info("[MQTT] 收到非 JSON 命令确认 设备编号={} 命令编号={} 消息体={}", deviceNo, commandId, payload);
|
||||
}
|
||||
|
||||
private List<DeviceCommand> findPendingCommandsByDeviceNo(String deviceNo) {
|
||||
@@ -126,7 +131,9 @@ public class MqttCommandAckService implements IDeviceCommandAckHandler {
|
||||
retryCommand(commandId, now);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
log.warn("[MQTT] 命令重试锁等待被中断 commandId={}", commandId);
|
||||
log.warn("[MQTT] 命令重试锁等待被中断 命令编号={}", commandId);
|
||||
} catch (RuntimeException e) {
|
||||
log.error("[MQTT] 命令重试失败 命令编号={}", commandId, e);
|
||||
} finally {
|
||||
if (locked && lock.isHeldByCurrentThread()) {
|
||||
lock.unlock();
|
||||
@@ -144,15 +151,20 @@ public class MqttCommandAckService implements IDeviceCommandAckHandler {
|
||||
return;
|
||||
}
|
||||
if (command.getRetryCount() >= mqttProperties.getCommandAck().getMaxRetryCount()) {
|
||||
RedisUtils.deleteObject(pendingKey(commandId));
|
||||
pendingIds().remove(commandId);
|
||||
log.warn("[MQTT] 命令重试次数已达上限 deviceNo={} commandId={}", command.getDeviceNo(), commandId);
|
||||
deletePending(commandId);
|
||||
log.warn("[MQTT] 命令重试次数已达上限 设备编号={} 命令编号={}", command.getDeviceNo(), commandId);
|
||||
return;
|
||||
}
|
||||
if (!isDeviceOnline(command.getDeviceNo())) {
|
||||
command.setRetryCount(command.getRetryCount() + 1);
|
||||
if (command.getRetryCount() >= mqttProperties.getCommandAck().getMaxRetryCount()) {
|
||||
deletePending(commandId);
|
||||
log.warn("[MQTT] 设备离线,命令达到最大等待次数,已删除待确认命令 设备编号={} 命令编号={}", command.getDeviceNo(), commandId);
|
||||
return;
|
||||
}
|
||||
command.setNextRetryAt(now + mqttProperties.getCommandAck().getRetryIntervalMs());
|
||||
savePending(command);
|
||||
log.debug("[MQTT] command retry delayed, device offline deviceNo={} commandId={}", command.getDeviceNo(), commandId);
|
||||
log.debug("[MQTT] 设备离线,命令延后重试 设备编号={} 命令编号={} 等待次数={}", command.getDeviceNo(), commandId, command.getRetryCount());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -161,7 +173,7 @@ public class MqttCommandAckService implements IDeviceCommandAckHandler {
|
||||
command.setNextRetryAt(now + mqttProperties.getCommandAck().getRetryIntervalMs());
|
||||
mqttClientManager.publish(command.getTopic(), JsonUtils.toJsonString(command.getPayload()));
|
||||
savePending(command);
|
||||
log.info("[MQTT] command resent deviceNo={} commandId={} retry={}", command.getDeviceNo(), commandId, command.getRetryCount());
|
||||
log.info("[MQTT] 命令已重新下发 设备编号={} 命令编号={} 重试次数={}", command.getDeviceNo(), commandId, command.getRetryCount());
|
||||
}
|
||||
|
||||
private boolean isDeviceOnline(String deviceNo) {
|
||||
@@ -183,12 +195,22 @@ public class MqttCommandAckService implements IDeviceCommandAckHandler {
|
||||
statusCache,
|
||||
Duration.ofSeconds(mqttProperties.getCommandAck().getDeviceStatusCacheTtlSeconds())
|
||||
);
|
||||
appDeviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<AppDevice>()
|
||||
.set(AppDevice::getStatus, "1")
|
||||
.eq(AppDevice::getDeviceNo, deviceNo)
|
||||
);
|
||||
}
|
||||
|
||||
private RSet<String> pendingIds() {
|
||||
return RedisUtils.getClient().getSet(mqttProperties.getCommandAck().getPendingSetKey());
|
||||
}
|
||||
|
||||
private void deletePending(String commandId) {
|
||||
RedisUtils.deleteObject(pendingKey(commandId));
|
||||
pendingIds().remove(commandId);
|
||||
}
|
||||
|
||||
private String pendingKey(String commandId) {
|
||||
return mqttProperties.getCommandAck().getPendingKeyPrefix() + commandId;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package org.dromara.mqtt;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.mqtt.config.properties.MqttProperties;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MqttCommandRetryTask {
|
||||
@@ -15,6 +17,7 @@ public class MqttCommandRetryTask {
|
||||
@Scheduled(fixedDelayString = "${mqtt.command-ack.scan-interval-ms:5000}")
|
||||
public void retryExpiredCommands() {
|
||||
if (mqttProperties.getCommandAck().isEnabled()) {
|
||||
// log.info("[设备命令重新下发] 定时器调用成功 ");
|
||||
ackService.retryExpiredCommands();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import cn.hutool.http.HttpStatus;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.dromara.common.core.utils.MessageUtils;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
@@ -52,7 +53,7 @@ public class TableDataInfo<T> implements Serializable {
|
||||
this.rows = list;
|
||||
this.total = total;
|
||||
this.code = HttpStatus.HTTP_OK;
|
||||
this.msg = "查询成功";
|
||||
this.msg = message("query.success", "查询成功");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +62,7 @@ public class TableDataInfo<T> implements Serializable {
|
||||
public static <T> TableDataInfo<T> build(IPage<T> page) {
|
||||
TableDataInfo<T> rspData = new TableDataInfo<>();
|
||||
rspData.setCode(HttpStatus.HTTP_OK);
|
||||
rspData.setMsg("查询成功");
|
||||
rspData.setMsg(message("query.success", "查询成功"));
|
||||
rspData.setRows(page.getRecords());
|
||||
rspData.setTotal(page.getTotal());
|
||||
return rspData;
|
||||
@@ -73,7 +74,7 @@ public class TableDataInfo<T> implements Serializable {
|
||||
public static <T> TableDataInfo<T> build(List<T> list) {
|
||||
TableDataInfo<T> rspData = new TableDataInfo<>();
|
||||
rspData.setCode(HttpStatus.HTTP_OK);
|
||||
rspData.setMsg("查询成功");
|
||||
rspData.setMsg(message("query.success", "查询成功"));
|
||||
rspData.setRows(list);
|
||||
rspData.setTotal(list.size());
|
||||
return rspData;
|
||||
@@ -85,7 +86,7 @@ public class TableDataInfo<T> implements Serializable {
|
||||
public static <T> TableDataInfo<T> build() {
|
||||
TableDataInfo<T> rspData = new TableDataInfo<>();
|
||||
rspData.setCode(HttpStatus.HTTP_OK);
|
||||
rspData.setMsg("查询成功");
|
||||
rspData.setMsg(message("query.success", "查询成功"));
|
||||
return rspData;
|
||||
}
|
||||
|
||||
@@ -104,4 +105,13 @@ public class TableDataInfo<T> implements Serializable {
|
||||
return new TableDataInfo<>(pageList, list.size());
|
||||
}
|
||||
|
||||
private static String message(String code, String defaultMessage) {
|
||||
try {
|
||||
String message = MessageUtils.message(code);
|
||||
return code.equals(message) ? defaultMessage : message;
|
||||
} catch (Exception e) {
|
||||
return defaultMessage;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class MybatisExceptionHandler {
|
||||
log.error("请求地址'{}', 未找到数据源", requestURI);
|
||||
return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, "未找到数据源,请联系管理员确认");
|
||||
}
|
||||
log.error("请求地址'{}', Mybatis系统异常", requestURI, e);
|
||||
log.error("请求地址'{}', MyBatis系统异常", requestURI, e);
|
||||
return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public class OssFactory {
|
||||
client = CLIENT_CACHE.get(key);
|
||||
if (client == null || !client.checkPropertiesSame(properties)) {
|
||||
CLIENT_CACHE.put(key, new OssClient(configKey, properties));
|
||||
log.info("创建OSS实例 key => {}", configKey);
|
||||
log.info("创建OSS实例 配置键 => {}", configKey);
|
||||
return CLIENT_CACHE.get(key);
|
||||
}
|
||||
} finally {
|
||||
|
||||
@@ -69,7 +69,7 @@ public class RateLimiterAspect {
|
||||
}
|
||||
throw new ServiceException(message);
|
||||
}
|
||||
log.info("限制令牌 => {}, 剩余令牌 => {}, 缓存key => '{}'", count, number, combineKey);
|
||||
log.info("限制令牌 => {}, 剩余令牌 => {}, 缓存键 => '{}'", count, number, combineKey);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof ServiceException) {
|
||||
throw e;
|
||||
|
||||
@@ -98,7 +98,7 @@ public class RedisConfig {
|
||||
.setReadMode(clusterServersConfig.getReadMode())
|
||||
.setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
|
||||
}
|
||||
log.info("初始化 redis 配置");
|
||||
log.info("初始化 Redis 配置");
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ public class SmsExceptionHandler {
|
||||
@ExceptionHandler(SmsBlendException.class)
|
||||
public R<Void> handleSmsBlendException(SmsBlendException e, HttpServletRequest request) {
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生sms短信异常.", requestURI, e);
|
||||
log.error("请求地址'{}',发生短信异常.", requestURI, e);
|
||||
return R.fail(HttpStatus.HTTP_INTERNAL_ERROR, "短信发送失败,请稍后再试...");
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -210,7 +209,7 @@ public class SseEmitterManager {
|
||||
broadcastMessage.setMessage(sseMessageDto.getMessage());
|
||||
broadcastMessage.setUserIds(sseMessageDto.getUserIds());
|
||||
RedisUtils.publish(SSE_TOPIC, broadcastMessage, consumer -> {
|
||||
log.info("SSE发送主题订阅消息topic:{} session keys:{} message:{}",
|
||||
log.info("SSE发送主题订阅消息 主题={} 用户ID={} 消息={}",
|
||||
SSE_TOPIC, sseMessageDto.getUserIds(), sseMessageDto.getMessage());
|
||||
});
|
||||
}
|
||||
@@ -224,7 +223,7 @@ public class SseEmitterManager {
|
||||
SseMessageDto broadcastMessage = new SseMessageDto();
|
||||
broadcastMessage.setMessage(message);
|
||||
RedisUtils.publish(SSE_TOPIC, broadcastMessage, consumer -> {
|
||||
log.info("SSE发送主题订阅消息topic:{} message:{}", SSE_TOPIC, message);
|
||||
log.info("SSE发送主题订阅消息 主题={} 消息={}", SSE_TOPIC, message);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ public class SseTopicListener implements ApplicationRunner, Ordered {
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
sseEmitterManager.subscribeMessage((message) -> {
|
||||
log.info("SSE主题订阅收到消息session keys={} message={}", message.getUserIds(), message.getMessage());
|
||||
log.info("SSE主题订阅收到消息 用户ID={} 消息={}", message.getUserIds(), message.getMessage());
|
||||
// 如果key不为空就按照key发消息 如果为空就群发
|
||||
if (CollUtil.isNotEmpty(message.getUserIds())) {
|
||||
message.getUserIds().forEach(key -> {
|
||||
|
||||
@@ -28,7 +28,7 @@ public class PlusTenantLineHandler implements TenantLineHandler {
|
||||
public Expression getTenantId() {
|
||||
String tenantId = TenantHelper.getTenantId();
|
||||
if (StringUtils.isBlank(tenantId)) {
|
||||
log.error("无法获取有效的租户id -> Null");
|
||||
log.error("无法获取有效的租户ID -> 空");
|
||||
return new NullValue();
|
||||
}
|
||||
// 返回固定租户
|
||||
|
||||
@@ -39,10 +39,10 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
||||
}
|
||||
String tenantId = TenantHelper.getTenantId();
|
||||
if (StringUtils.isBlank(tenantId)) {
|
||||
log.debug("无法获取有效的租户id -> Null");
|
||||
log.debug("无法获取有效的租户ID -> 空");
|
||||
return super.map(name);
|
||||
}
|
||||
if (StringUtils.startsWith(name, tenantId + "")) {
|
||||
if (StringUtils.startsWith(name, tenantId)) {
|
||||
// 如果存在则直接返回
|
||||
return super.map(name);
|
||||
}
|
||||
@@ -70,10 +70,10 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
|
||||
}
|
||||
String tenantId = TenantHelper.getTenantId();
|
||||
if (StringUtils.isBlank(tenantId)) {
|
||||
log.debug("无法获取有效的租户id -> Null");
|
||||
log.debug("无法获取有效的租户ID -> 空");
|
||||
return unmap;
|
||||
}
|
||||
if (StringUtils.startsWith(unmap, tenantId + "")) {
|
||||
if (StringUtils.startsWith(unmap, tenantId)) {
|
||||
// 如果存在则删除
|
||||
return unmap.substring((tenantId + ":").length());
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class TenantSpringCacheManager extends PlusSpringCacheManager {
|
||||
}
|
||||
String tenantId = TenantHelper.getTenantId();
|
||||
if (StringUtils.isBlank(tenantId)) {
|
||||
log.error("无法获取有效的租户id -> Null");
|
||||
log.error("无法获取有效的租户ID -> 空");
|
||||
}
|
||||
if (StringUtils.startsWith(name, tenantId)) {
|
||||
// 如果存在则直接返回
|
||||
|
||||
@@ -7,11 +7,11 @@ import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.core.utils.reflect.ReflectUtils;
|
||||
import org.dromara.common.translation.annotation.Translation;
|
||||
import org.dromara.common.translation.core.TranslationInterface;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
@@ -61,7 +61,7 @@ public class TranslationHandler extends JsonSerializer<Object> implements Contex
|
||||
Object result = trans.translation(value, translation.other());
|
||||
gen.writeObject(result);
|
||||
} catch (Exception e) {
|
||||
log.error("翻译处理异常,type: {}, value: {}", translation.type(), value, e);
|
||||
log.error("翻译处理异常,类型:{},值:{}", translation.type(), value, e);
|
||||
// 出现异常时输出原始值而不是中断序列化
|
||||
gen.writeObject(value);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package org.dromara.common.web.core;
|
||||
|
||||
import org.springframework.web.servlet.LocaleResolver;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.springframework.web.servlet.LocaleResolver;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
@@ -16,12 +17,24 @@ public class I18nLocaleResolver implements LocaleResolver {
|
||||
@Override
|
||||
public Locale resolveLocale(HttpServletRequest httpServletRequest) {
|
||||
String language = httpServletRequest.getHeader("content-language");
|
||||
Locale locale = Locale.getDefault();
|
||||
if (language != null && language.length() > 0) {
|
||||
String[] split = language.split("_");
|
||||
locale = new Locale(split[0], split[1]);
|
||||
if (StringUtils.isBlank(language)) {
|
||||
language = httpServletRequest.getParameter("lang");
|
||||
}
|
||||
return locale;
|
||||
if (StringUtils.isBlank(language)) {
|
||||
language = httpServletRequest.getHeader("Accept-Language");
|
||||
}
|
||||
if (StringUtils.isBlank(language)) {
|
||||
return Locale.SIMPLIFIED_CHINESE;
|
||||
}
|
||||
String languageTag = language.split(",")[0].trim().replace('_', '-');
|
||||
if ("zh".equalsIgnoreCase(languageTag)) {
|
||||
return Locale.SIMPLIFIED_CHINESE;
|
||||
}
|
||||
if ("en".equalsIgnoreCase(languageTag)) {
|
||||
return Locale.US;
|
||||
}
|
||||
Locale locale = Locale.forLanguageTag(languageTag);
|
||||
return StringUtils.isBlank(locale.getLanguage()) ? Locale.SIMPLIFIED_CHINESE : locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,16 +51,16 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
|
||||
jsonParam = rootNode.toString();
|
||||
}
|
||||
}
|
||||
log.info("[PLUS]开始请求 => URL[{}],参数类型[json],参数:[{}]", url, jsonParam);
|
||||
log.info("[请求]开始请求 => URL[{}],参数类型[JSON],参数:[{}]", url, jsonParam);
|
||||
} else {
|
||||
Map<String, String[]> parameterMap = request.getParameterMap();
|
||||
if (MapUtil.isNotEmpty(parameterMap)) {
|
||||
Map<String, String[]> map = new LinkedHashMap<>(parameterMap);
|
||||
MapUtil.removeAny(map, SystemConstants.EXCLUDE_PROPERTIES);
|
||||
String parameters = JsonUtils.toJsonString(map);
|
||||
log.info("[PLUS]开始请求 => URL[{}],参数类型[param],参数:[{}]", url, parameters);
|
||||
log.info("[请求]开始请求 => URL[{}],参数类型[表单参数],参数:[{}]", url, parameters);
|
||||
} else {
|
||||
log.info("[PLUS]开始请求 => URL[{}],无参数", url);
|
||||
log.info("[请求]开始请求 => URL[{}],无参数", url);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
|
||||
StopWatch stopWatch = KEY_CACHE.get();
|
||||
if (ObjectUtil.isNotNull(stopWatch)) {
|
||||
stopWatch.stop();
|
||||
log.info("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getDuration().toMillis());
|
||||
log.info("[请求]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getDuration().toMillis());
|
||||
KEY_CACHE.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,11 +31,11 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
|
||||
LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
|
||||
if (ObjectUtil.isNull(loginUser)) {
|
||||
session.close(CloseStatus.BAD_DATA);
|
||||
log.info("[connect] invalid token received. sessionId: {}", session.getId());
|
||||
log.info("[连接] 收到无效令牌,会话ID={}", session.getId());
|
||||
return;
|
||||
}
|
||||
WebSocketSessionHolder.addSession(loginUser.getUserId(), new ConcurrentWebSocketSessionDecorator(session, 10 * 1000, 64000));
|
||||
log.info("[connect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
|
||||
log.info("[连接] 会话ID={},用户ID={},用户类型={}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +90,7 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
|
||||
*/
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
|
||||
log.error("[transport error] sessionId: {} , exception:{}", session.getId(), exception.getMessage());
|
||||
log.error("[传输错误] 会话ID={},异常={}", session.getId(), exception.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,11 +103,11 @@ public class PlusWebSocketHandler extends AbstractWebSocketHandler {
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
|
||||
LoginUser loginUser = (LoginUser) session.getAttributes().get(LOGIN_USER_KEY);
|
||||
if (ObjectUtil.isNull(loginUser)) {
|
||||
log.info("[disconnect] invalid token received. sessionId: {}", session.getId());
|
||||
log.info("[断开连接] 收到无效令牌,会话ID={}", session.getId());
|
||||
return;
|
||||
}
|
||||
WebSocketSessionHolder.removeSession(loginUser.getUserId());
|
||||
log.info("[disconnect] sessionId: {},userId:{},userType:{}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
|
||||
log.info("[断开连接] 会话ID={},用户ID={},用户类型={}", session.getId(), loginUser.getUserId(), loginUser.getUserType());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -54,7 +54,7 @@ public class PlusWebSocketInterceptor implements HandshakeInterceptor {
|
||||
attributes.put(LOGIN_USER_KEY, loginUser);
|
||||
return true;
|
||||
} catch (NotLoginException e) {
|
||||
log.error("WebSocket 认证失败'{}',无法访问系统资源", e.getMessage());
|
||||
log.error("网络套接字认证失败'{}',无法访问系统资源", e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ public class WebSocketTopicListener implements ApplicationRunner, Ordered {
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
// 订阅WebSocket消息
|
||||
WebSocketUtils.subscribeMessage((message) -> {
|
||||
log.info("WebSocket主题订阅收到消息session keys={} message={}", message.getSessionKeys(), message.getMessage());
|
||||
log.info("网络套接字主题订阅收到消息 会话标识={} 消息={}", message.getSessionKeys(), message.getMessage());
|
||||
// 如果key不为空就按照key发消息 如果为空就群发
|
||||
if (CollUtil.isNotEmpty(message.getSessionKeys())) {
|
||||
message.getSessionKeys().forEach(key -> {
|
||||
@@ -40,7 +40,7 @@ public class WebSocketTopicListener implements ApplicationRunner, Ordered {
|
||||
});
|
||||
}
|
||||
});
|
||||
log.info("初始化WebSocket主题订阅监听器成功");
|
||||
log.info("初始化网络套接字主题订阅监听器成功");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -69,7 +69,7 @@ public class WebSocketUtils {
|
||||
broadcastMessage.setMessage(webSocketMessage.getMessage());
|
||||
broadcastMessage.setSessionKeys(unsentSessionKeys);
|
||||
RedisUtils.publish(WEB_SOCKET_TOPIC, broadcastMessage, consumer -> {
|
||||
log.info(" WebSocket发送主题订阅消息topic:{} session keys:{} message:{}",
|
||||
log.info("网络套接字发送主题订阅消息 主题={} 会话标识={} 消息={}",
|
||||
WEB_SOCKET_TOPIC, unsentSessionKeys, webSocketMessage.getMessage());
|
||||
});
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class WebSocketUtils {
|
||||
WebSocketMessageDto broadcastMessage = new WebSocketMessageDto();
|
||||
broadcastMessage.setMessage(message);
|
||||
RedisUtils.publish(WEB_SOCKET_TOPIC, broadcastMessage, consumer -> {
|
||||
log.info("WebSocket发送主题订阅消息topic:{} message:{}", WEB_SOCKET_TOPIC, message);
|
||||
log.info("网络套接字发送主题订阅消息 主题={} 消息={}", WEB_SOCKET_TOPIC, message);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -115,12 +115,12 @@ public class WebSocketUtils {
|
||||
*/
|
||||
private static void sendMessage(WebSocketSession session, WebSocketMessage<?> message) {
|
||||
if (session == null || !session.isOpen()) {
|
||||
log.warn("[send] session会话已经关闭");
|
||||
log.warn("[发送] 会话已经关闭");
|
||||
} else {
|
||||
try {
|
||||
session.sendMessage(message);
|
||||
} catch (IOException e) {
|
||||
log.error("[send] session({}) 发送消息({}) 异常", session, message, e);
|
||||
log.error("[发送] 会话({}) 发送消息({}) 异常", session, message, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ public class CustomNotifier extends AbstractEventNotifier {
|
||||
case STATUS_UNKNOWN -> "服务未知异常"; //监控系统无法确定实例的当前状态
|
||||
default -> "未知状态"; //没有匹配的状态
|
||||
};
|
||||
log.info("Instance Status Change: 状态名称【{}】, 注册名称【{}】, 实例ID【{}】, 状态【{}】, 服务URL【{}】",
|
||||
log.info("实例状态变更:状态名称【{}】, 注册名称【{}】, 实例ID【{}】, 状态【{}】, 服务URL【{}】",
|
||||
statusName, registName, instanceId, status, serviceUrl);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -10,15 +10,19 @@ import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.app.domain.bo.*;
|
||||
import org.dromara.app.domain.bo.AppDeviceBo;
|
||||
import org.dromara.app.domain.bo.AppScheduleBo;
|
||||
import org.dromara.app.domain.bo.AppSchedulingDeviceBo;
|
||||
import org.dromara.app.domain.bo.AppWateringLogBo;
|
||||
import org.dromara.app.domain.mqtt.DeviceCommand;
|
||||
import org.dromara.app.domain.vo.*;
|
||||
import org.dromara.app.service.*;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.app.service.impl.AppScheduleServiceImpl;
|
||||
import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.domain.model.LoginUser;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.exception.user.UserException;
|
||||
import org.dromara.common.core.utils.MessageUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
@@ -77,16 +81,15 @@ public class AppController extends BaseController {
|
||||
*
|
||||
*/
|
||||
@ApiEncrypt
|
||||
@PostMapping("/addDevice")
|
||||
public R<Void> addDevice(@RequestBody String body) {
|
||||
AppDeviceBo appDevic = JsonUtils.parseObject(body, AppDeviceBo.class);
|
||||
appDevic.setUserId(LoginHelper.getUserId());
|
||||
Boolean b = appDeviceService.insertByBo(appDevic);
|
||||
if (b){
|
||||
return R.ok();
|
||||
}else {
|
||||
|
||||
return R.fail();
|
||||
@PostMapping("/bindDeviceStatus")
|
||||
public R<Map> bindDeviceStatus(@RequestBody String body) {
|
||||
try {
|
||||
AppDeviceBo appDevice = JsonUtils.parseObject(body, AppDeviceBo.class);
|
||||
appDevice.setUserId(LoginHelper.getUserId());
|
||||
Map<String, Object> map = appDeviceService.bindDeviceStatus(appDevice);
|
||||
return R.ok(map);
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,11 +97,15 @@ public class AppController extends BaseController {
|
||||
* 绑定已通过MQTT注册上线的设备
|
||||
*/
|
||||
@ApiEncrypt
|
||||
@PostMapping("/bindDevice")
|
||||
@PostMapping("/addDevice")
|
||||
public R<AppDeviceVo> bindDevice(@RequestBody String body) {
|
||||
try {
|
||||
AppDeviceBo appDevice = JsonUtils.parseObject(body, AppDeviceBo.class);
|
||||
appDevice.setUserId(LoginHelper.getUserId());
|
||||
return R.ok(appDeviceService.bindRegisteredDevice(appDevice));
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,7 +117,11 @@ public class AppController extends BaseController {
|
||||
@GetMapping("/device/{deviceNo}")
|
||||
public R<AppDeviceVo> getDeviceInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable String deviceNo) {
|
||||
return R.ok(appDeviceService.queryById(deviceNo));
|
||||
try {
|
||||
return R.ok(getOwnedDevice(deviceNo));
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -123,9 +134,11 @@ public class AppController extends BaseController {
|
||||
@PutMapping("/updateDeviceInfo")
|
||||
public R<Void> updateDeviceInfo(@Validated @RequestBody AppDeviceBo bo) {
|
||||
try {
|
||||
assertDeviceOwned(bo.getDeviceNo());
|
||||
bo.setUserId(LoginHelper.getUserId());
|
||||
return toAjax(appDeviceService.updateByBo(bo));
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
return fail(e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -137,7 +150,14 @@ public class AppController extends BaseController {
|
||||
@DeleteMapping("/deleteDevice/{deviceNos}")
|
||||
public R<Void> removeDevice(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable String[] deviceNos) {
|
||||
try {
|
||||
for (String deviceNo : deviceNos) {
|
||||
assertDeviceOwned(deviceNo);
|
||||
}
|
||||
return toAjax(appDeviceService.deleteWithValidByIds(List.of(deviceNos), true));
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -149,11 +169,11 @@ public class AppController extends BaseController {
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/switchDevice")
|
||||
public R<Void> switchDevice(@RequestBody String body) {
|
||||
Map<String,String> map = JsonUtils.parseObject(body, Map.class);
|
||||
try {
|
||||
Map<String,String> map = JsonUtils.parseObject(body, Map.class);
|
||||
String deviceNo = map.get("deviceNo");
|
||||
String status = map.get("workStatus");
|
||||
Date date = new Date();
|
||||
String startTime = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
||||
String durationMinValue = map.get("durationMin");
|
||||
Integer durationMin = StringUtils.isBlank(durationMinValue) ? null : Integer.valueOf(durationMinValue);
|
||||
//更新设备工作状态
|
||||
@@ -161,7 +181,7 @@ public class AppController extends BaseController {
|
||||
// 记录信息到历史表
|
||||
return toAjax(flag);
|
||||
} catch (Exception e) {
|
||||
return R.fail(e.getMessage());
|
||||
return fail(e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -173,6 +193,7 @@ public class AppController extends BaseController {
|
||||
*/
|
||||
@GetMapping("/scheduleDeviceList/{scheduleId}")
|
||||
public R<Map<String,Object>> scheduleDeviceList( @PathVariable Long scheduleId) {
|
||||
try {
|
||||
|
||||
Map retMap = new HashMap();
|
||||
//所有设备列表
|
||||
@@ -195,6 +216,9 @@ public class AppController extends BaseController {
|
||||
|
||||
|
||||
return R.ok(retMap);
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
*绑定排程跟设备
|
||||
@@ -202,26 +226,32 @@ public class AppController extends BaseController {
|
||||
@RepeatSubmit()
|
||||
@PostMapping("/addScheduleDevice")
|
||||
public R<Void> addScheduleDevice( @RequestBody String body) {
|
||||
try {
|
||||
Map<String, Object> map = JsonUtils.parseObject(body, Map.class);
|
||||
if (map == null || map.get("scheduleId") == null) {
|
||||
throw new ServiceException("scheduleId不能为空");
|
||||
throw new ServiceException("app.schedule.id.not.blank.request");
|
||||
}
|
||||
Long scheduleId = Long.valueOf(map.get("scheduleId").toString());
|
||||
assertScheduleOwned(scheduleId);
|
||||
List<String> deviceNos = parseDeviceNos(map);
|
||||
if (deviceNos.isEmpty()) {
|
||||
throw new ServiceException("deviceNos不能为空");
|
||||
throw new ServiceException("app.schedule.devices.not.blank");
|
||||
}
|
||||
|
||||
for (String deviceNo:deviceNos){
|
||||
if (StringUtils.isBlank(deviceNo)) {
|
||||
continue;
|
||||
}
|
||||
assertDeviceOwned(deviceNo);
|
||||
AppSchedulingDeviceBo schedulingDeviceBo = new AppSchedulingDeviceBo();
|
||||
schedulingDeviceBo.setDeviceNo(deviceNo);
|
||||
schedulingDeviceBo.setScheduleId(scheduleId);
|
||||
appSchedulingDeviceService.insertByBo(schedulingDeviceBo);
|
||||
}
|
||||
return R.ok();
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> parseDeviceNos(Map<String, Object> map) {
|
||||
@@ -255,9 +285,22 @@ public class AppController extends BaseController {
|
||||
|
||||
@Log(title = "排程与设备关联", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/deleteScheduleDevice")
|
||||
public R<Void> deleteScheduleDevice(@NotEmpty(message = "主键不能为空")
|
||||
@RequestParam String scheduleId, @RequestParam String deviceNo) {
|
||||
return toAjax(appSchedulingDeviceService.deleteWithValidByScheduleIdAndDeviceNo(Long.valueOf(scheduleId), deviceNo));
|
||||
public R<Void> deleteScheduleDevice(@RequestParam(required = false) String scheduleId,
|
||||
@RequestParam(required = false) String deviceNo) {
|
||||
try {
|
||||
if (StringUtils.isBlank(scheduleId)) {
|
||||
throw new ServiceException("app.schedule.id.not.blank.request");
|
||||
}
|
||||
if (StringUtils.isBlank(deviceNo)) {
|
||||
throw new ServiceException("app.device.no.not.blank");
|
||||
}
|
||||
Long scheduleIdValue = Long.valueOf(scheduleId);
|
||||
assertScheduleOwned(scheduleIdValue);
|
||||
assertDeviceOwned(deviceNo);
|
||||
return toAjax(appSchedulingDeviceService.deleteWithValidByScheduleIdAndDeviceNo(scheduleIdValue, deviceNo));
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -289,8 +332,8 @@ public class AppController extends BaseController {
|
||||
}
|
||||
return R.fail();
|
||||
// return toAjax(appScheduleService.insertByBo(bo));
|
||||
} catch (RuntimeException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,7 +346,8 @@ public class AppController extends BaseController {
|
||||
@GetMapping("/schedule/{id}")
|
||||
public R<AppScheduleVo> getScheduleInfo(@NotNull(message = "主键不能为空")
|
||||
@PathVariable Long id) {
|
||||
AppScheduleVo appScheduleVo = appScheduleService.queryById(id);
|
||||
try {
|
||||
AppScheduleVo appScheduleVo = getOwnedSchedule(id);
|
||||
if (ObjectUtil.isNotNull(appScheduleVo)){
|
||||
List<AppScheduleDetailVo> list = appScheduleDetailService.queryByScheduleIdByStatus(appScheduleVo.getId());
|
||||
|
||||
@@ -345,6 +389,9 @@ public class AppController extends BaseController {
|
||||
|
||||
|
||||
return R.fail(appScheduleVo);
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -356,8 +403,13 @@ public class AppController extends BaseController {
|
||||
@PutMapping("/editScheduleStatus")
|
||||
public R<Void> editScheduleStatus(@NotNull(message = "主键不能为空")
|
||||
@RequestBody AppScheduleBo bo) {
|
||||
|
||||
try {
|
||||
assertScheduleOwned(bo.getId());
|
||||
bo.setUserId(LoginHelper.getUserId());
|
||||
return toAjax(appScheduleService.updateStatusByBo(bo));
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -367,12 +419,18 @@ public class AppController extends BaseController {
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/updataschedule")
|
||||
public R<Object> editSchedule(@Validated(EditGroup.class) @RequestBody AppScheduleBo bo) {
|
||||
try {
|
||||
assertScheduleOwned(bo.getId());
|
||||
bo.setUserId(LoginHelper.getUserId());
|
||||
Map<String, Object> map = appScheduleService.updateByBo(bo);
|
||||
if (Boolean.valueOf(map.get("flag").toString())){
|
||||
return R.ok(map.get("appSchedule"));
|
||||
}else {
|
||||
return R.fail();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -386,7 +444,14 @@ public class AppController extends BaseController {
|
||||
@DeleteMapping("/deleteschedule/{ids}")
|
||||
public R<Void> removeSchedule(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
try {
|
||||
for (Long id : ids) {
|
||||
assertScheduleOwned(id);
|
||||
}
|
||||
return toAjax(appScheduleService.deleteWithValidByIds(List.of(ids), true));
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,7 +492,14 @@ public class AppController extends BaseController {
|
||||
@DeleteMapping("/waterLog/{ids}")
|
||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
||||
@PathVariable Long[] ids) {
|
||||
try {
|
||||
for (Long id : ids) {
|
||||
assertWateringLogOwned(id);
|
||||
}
|
||||
return toAjax(appWateringLogService.deleteWithValidByIds(List.of(ids), true));
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -463,7 +535,7 @@ public class AppController extends BaseController {
|
||||
map.put("averageTime",averageTime);
|
||||
return R.ok(map);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
return fail(e);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -475,16 +547,20 @@ public class AppController extends BaseController {
|
||||
*/
|
||||
@GetMapping("/getUserInfo")
|
||||
public R<UserInfoVo> getUserInfo() {
|
||||
try {
|
||||
UserInfoVo userInfoVo = new UserInfoVo();
|
||||
LoginUser loginUser = LoginHelper.getLoginUser();
|
||||
SysUserVo user = DataPermissionHelper.ignore(() -> userService.selectUserById(loginUser.getUserId()));
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
return R.fail("没有权限访问用户数据!");
|
||||
return R.fail(MessageUtils.message("app.user.data.denied"));
|
||||
}
|
||||
userInfoVo.setUser(user);
|
||||
userInfoVo.setPermissions(loginUser.getMenuPermission());
|
||||
userInfoVo.setRoles(loginUser.getRolePermission());
|
||||
return R.ok(userInfoVo);
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -495,13 +571,17 @@ public class AppController extends BaseController {
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/updataUser")
|
||||
public R<Void> editUser( @RequestBody SysUserBo user) {
|
||||
try {
|
||||
userService.checkUserAllowed(user.getUserId());
|
||||
userService.checkUserDataScope(user.getUserId());
|
||||
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
|
||||
return R.fail("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
|
||||
return R.fail(MessageUtils.message("app.user.phone.exists", user.getUserName()));
|
||||
}
|
||||
|
||||
return toAjax(userService.updateAppUser(user));
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -510,6 +590,7 @@ public class AppController extends BaseController {
|
||||
@RepeatSubmit()
|
||||
@PutMapping("/updataPassword")
|
||||
public R<Void> updataPassword(@RequestBody SysUserVo vo) {
|
||||
try {
|
||||
Long userId = LoginHelper.getUserId();
|
||||
SysUserVo sysUserVo = userService.selectUserById(userId);
|
||||
if (!BCrypt.checkpw(vo.getOldPassword(), sysUserVo.getPassword())){
|
||||
@@ -519,6 +600,9 @@ public class AppController extends BaseController {
|
||||
userBo.setUserId(userId);
|
||||
userBo.setPassword(vo.getPassword());
|
||||
return toAjax(userService.updateUserPas(userBo));
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -527,6 +611,7 @@ public class AppController extends BaseController {
|
||||
@ApiEncrypt
|
||||
@PostMapping("/retrievePassword")
|
||||
public R<Void> forgot(@RequestBody String body) {
|
||||
try {
|
||||
SysUserBo bo = JsonUtils.parseObject(body, SysUserBo.class);
|
||||
bo.setUserId(LoginHelper.getUserId());
|
||||
|
||||
@@ -543,12 +628,16 @@ public class AppController extends BaseController {
|
||||
}
|
||||
|
||||
return toAjax(userService.updateUserPas(bo));
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@GetMapping("/test")
|
||||
public R<Void> test (){
|
||||
try {
|
||||
|
||||
DeviceCommand deviceCommand = new DeviceCommand();
|
||||
|
||||
@@ -556,6 +645,65 @@ public class AppController extends BaseController {
|
||||
|
||||
// String s = deviceCommandService.sendSwitchCommand("01", "1", "2026-06-10 14:35:31", 20);
|
||||
return R.ok(bindDevice);
|
||||
} catch (Exception e) {
|
||||
return fail(e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> R<T> fail(Exception e) {
|
||||
return R.fail(toI18nErrorMessage(e));
|
||||
}
|
||||
|
||||
private String toI18nErrorMessage(Exception e) {
|
||||
String message = e.getMessage();
|
||||
if (StringUtils.isBlank(message)) {
|
||||
return MessageUtils.message("operation.fail");
|
||||
}
|
||||
String i18nMessage = MessageUtils.message(message);
|
||||
return message.equals(i18nMessage) ? message : i18nMessage;
|
||||
}
|
||||
|
||||
private AppDeviceVo getOwnedDevice(String deviceNo) {
|
||||
if (StringUtils.isBlank(deviceNo)) {
|
||||
throw new ServiceException("app.device.no.not.blank");
|
||||
}
|
||||
AppDeviceVo device = appDeviceService.queryById(deviceNo);
|
||||
Long userId = LoginHelper.getUserId();
|
||||
if (device == null || !Objects.equals(device.getUserId(), userId)) {
|
||||
throw new ServiceException("app.device.not.exists.or.denied");
|
||||
}
|
||||
return device;
|
||||
}
|
||||
|
||||
private void assertDeviceOwned(String deviceNo) {
|
||||
getOwnedDevice(deviceNo);
|
||||
}
|
||||
|
||||
private AppScheduleVo getOwnedSchedule(Long scheduleId) {
|
||||
if (scheduleId == null) {
|
||||
throw new ServiceException("app.schedule.id.not.blank");
|
||||
}
|
||||
AppScheduleVo schedule = appScheduleService.queryById(scheduleId);
|
||||
Long userId = LoginHelper.getUserId();
|
||||
if (schedule == null || !Objects.equals(schedule.getUserId(), userId)) {
|
||||
throw new ServiceException("app.schedule.not.exists.or.denied");
|
||||
}
|
||||
return schedule;
|
||||
}
|
||||
|
||||
private void assertScheduleOwned(Long scheduleId) {
|
||||
getOwnedSchedule(scheduleId);
|
||||
}
|
||||
|
||||
private void assertWateringLogOwned(Long id) {
|
||||
if (id == null) {
|
||||
throw new ServiceException("app.watering.log.id.not.blank");
|
||||
}
|
||||
AppWateringLogVo log = appWateringLogService.queryById(id);
|
||||
Long userId = LoginHelper.getUserId();
|
||||
if (log == null || !Objects.equals(log.getUserId(), userId)) {
|
||||
throw new ServiceException("app.watering.log.not.exists.or.denied");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,14 +1,22 @@
|
||||
package org.dromara.app.handler;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.app.domain.AppDevice;
|
||||
import org.dromara.app.domain.bo.AppDeviceBo;
|
||||
import org.dromara.app.mapper.AppDeviceMapper;
|
||||
import org.dromara.app.mqtt.MqttTopicHandler;
|
||||
import org.dromara.app.service.IAppDeviceService;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.redis.utils.RedisUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -22,6 +30,13 @@ public class DeviceDataHandler implements MqttTopicHandler {
|
||||
|
||||
private static final Pattern PATTERN = Pattern.compile("^/([^/]+)/publish/power$");
|
||||
private final IAppDeviceService appDeviceService;
|
||||
private final AppDeviceMapper appDeviceMapper;
|
||||
|
||||
@Value("${mqtt.command-ack.device-status-cache-prefix}")
|
||||
private String deviceStatusCachePrefix;
|
||||
|
||||
@Value("${mqtt.command-ack.device-status-cache-ttl-seconds}")
|
||||
private int deviceStatusCacheTtlSeconds;
|
||||
|
||||
@Override
|
||||
public Pattern topicPattern() {
|
||||
@@ -32,14 +47,44 @@ public class DeviceDataHandler implements MqttTopicHandler {
|
||||
public void handle(String deviceNo, String payload) {
|
||||
try {
|
||||
Map<String, Object> dto = JsonUtils.parseObject(payload, Map.class);
|
||||
if (dto == null || dto.get("powerLevel") == null) {
|
||||
log.warn("[MQTT] 设备电量上报缺少电量字段 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, payload);
|
||||
refreshDeviceOnline(deviceNo);
|
||||
return;
|
||||
}
|
||||
// 更新设备电量 + 同步在线状态到数据库
|
||||
AppDeviceBo appDeviceBo = new AppDeviceBo();
|
||||
appDeviceBo.setDeviceNo(deviceNo);
|
||||
appDeviceBo.setPowerLevel(dto.get("powerLevel").toString());
|
||||
appDeviceBo.setPowerLevelUpdatatime(new Date());
|
||||
appDeviceBo.setStatus("1"); // 收到数据 = 在线
|
||||
appDeviceService.updateByBo(appDeviceBo);
|
||||
log.info("[MQTT] 设备电量更新 deviceNo={} payload={}", deviceNo, payload);
|
||||
// 同步刷新 Redis 在线缓存(定时任务离线检测依赖此 Key)
|
||||
refreshDeviceOnline(deviceNo);
|
||||
log.info("[MQTT] 设备电量更新 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, payload);
|
||||
} catch (Exception e) {
|
||||
log.error("[MQTT] 设备电量更新失败 deviceNo={} payload={}", deviceNo, payload, e);
|
||||
log.error("[MQTT] 设备电量更新失败 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, payload, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新设备在线状态到 Redis(与 MqttCommandAckService 逻辑一致)
|
||||
* 写入 Redis 后 TTL 到期自动过期 = 离线
|
||||
*/
|
||||
private void refreshDeviceOnline(String deviceNo) {
|
||||
Map<String, Object> statusCache = new HashMap<>();
|
||||
statusCache.put("deviceNo", deviceNo);
|
||||
statusCache.put("status", "1");
|
||||
statusCache.put("lastReportTime", Instant.now().toString());
|
||||
RedisUtils.setCacheObject(
|
||||
deviceStatusCachePrefix + deviceNo,
|
||||
statusCache,
|
||||
Duration.ofSeconds(deviceStatusCacheTtlSeconds)
|
||||
);
|
||||
appDeviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<AppDevice>()
|
||||
.set(AppDevice::getStatus, "1")
|
||||
.eq(AppDevice::getDeviceNo, deviceNo)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
package org.dromara.app.handler;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.app.domain.AppDevice;
|
||||
import org.dromara.app.domain.bo.AppDeviceBo;
|
||||
import org.dromara.app.mapper.AppDeviceMapper;
|
||||
import org.dromara.app.mqtt.MqttTopicHandler;
|
||||
import org.dromara.app.service.IAppDeviceService;
|
||||
import org.dromara.common.json.utils.JsonUtils;
|
||||
import org.dromara.common.redis.utils.RedisUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -22,6 +30,13 @@ public class DeviceRegisterHandler implements MqttTopicHandler {
|
||||
private static final Pattern PATTERN = Pattern.compile("^/([^/]+)/publish/register$");
|
||||
|
||||
private final IAppDeviceService appDeviceService;
|
||||
private final AppDeviceMapper appDeviceMapper;
|
||||
|
||||
@Value("${mqtt.command-ack.device-status-cache-prefix}")
|
||||
private String deviceStatusCachePrefix;
|
||||
|
||||
@Value("${mqtt.command-ack.device-status-cache-ttl-seconds}")
|
||||
private int deviceStatusCacheTtlSeconds;
|
||||
|
||||
@Override
|
||||
public Pattern topicPattern() {
|
||||
@@ -34,15 +49,18 @@ public class DeviceRegisterHandler implements MqttTopicHandler {
|
||||
Map<String, Object> dto = JsonUtils.parseObject(payload, Map.class);
|
||||
AppDeviceBo device = buildRegisterDevice(deviceNo, dto);
|
||||
appDeviceService.registerByMqtt(device);
|
||||
log.info("[MQTT] 设备注册 deviceNo={} payload={}", deviceNo, payload);
|
||||
// 注册即在线
|
||||
refreshDeviceOnline(deviceNo);
|
||||
log.info("[MQTT] 设备注册 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, payload);
|
||||
} catch (Exception e) {
|
||||
log.error("[MQTT] 设备注册失败 deviceNo={} payload={}", deviceNo, payload, e);
|
||||
log.error("[MQTT] 设备注册失败 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, payload, e);
|
||||
}
|
||||
}
|
||||
|
||||
private AppDeviceBo buildRegisterDevice(String topicDeviceNo, Map<String, Object> dto) {
|
||||
AppDeviceBo device = new AppDeviceBo();
|
||||
device.setDeviceNo(topicDeviceNo);
|
||||
device.setStatus("1"); // 注册即在线
|
||||
if (dto == null) {
|
||||
return device;
|
||||
}
|
||||
@@ -67,4 +85,24 @@ public class DeviceRegisterHandler implements MqttTopicHandler {
|
||||
private String valueAsString(Object value) {
|
||||
return value == null ? null : String.valueOf(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新设备在线状态到 Redis
|
||||
*/
|
||||
private void refreshDeviceOnline(String deviceNo) {
|
||||
Map<String, Object> statusCache = new HashMap<>();
|
||||
statusCache.put("deviceNo", deviceNo);
|
||||
statusCache.put("status", "1");
|
||||
statusCache.put("lastReportTime", Instant.now().toString());
|
||||
RedisUtils.setCacheObject(
|
||||
deviceStatusCachePrefix + deviceNo,
|
||||
statusCache,
|
||||
Duration.ofSeconds(deviceStatusCacheTtlSeconds)
|
||||
);
|
||||
appDeviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<AppDevice>()
|
||||
.set(AppDevice::getStatus, "1")
|
||||
.eq(AppDevice::getDeviceNo, deviceNo)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ public class ErromesHandler implements MqttTopicHandler {
|
||||
public void handle(String deviceNo, String payload) {
|
||||
try {
|
||||
Map<String, Object> dto = JsonUtils.parseObject(payload, Map.class);
|
||||
log.info("[MQTT] 设备异常告警 deviceNo={} payload={}", deviceNo, dto);
|
||||
log.info("[MQTT] 设备异常告警 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, dto);
|
||||
} catch (Exception e) {
|
||||
log.error("[MQTT] 设备异常处理失败 deviceNo={}", deviceNo, e);
|
||||
log.error("[MQTT] 设备异常处理失败 时间={} 设备编号={}", HandlerLogTime.now(), deviceNo, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.dromara.app.handler;
|
||||
|
||||
import org.dromara.common.core.utils.DateUtils;
|
||||
|
||||
final class HandlerLogTime {
|
||||
|
||||
private HandlerLogTime() {
|
||||
}
|
||||
|
||||
static String now() {
|
||||
return DateUtils.getTime();
|
||||
}
|
||||
}
|
||||
@@ -41,16 +41,16 @@ public class KeyFinishHandler implements MqttTopicHandler {
|
||||
Map<String, Object> dto = JsonUtils.parseObject(payload, Map.class);
|
||||
AppWateringLogBo logBo = buildWateringLog(deviceNo, dto);
|
||||
appWateringLogService.insertByBo(logBo);
|
||||
log.info("[MQTT] 按键浇水完成上报已保存 deviceNo={} payload={}", deviceNo, payload);
|
||||
log.info("[MQTT] 按键浇水完成上报已保存 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, payload);
|
||||
} catch (Exception e) {
|
||||
log.error("[MQTT] 按键浇水完成上报处理失败 deviceNo={} payload={}", deviceNo, payload, e);
|
||||
log.error("[MQTT] 按键浇水完成上报处理失败 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, payload, e);
|
||||
}
|
||||
}
|
||||
|
||||
private AppWateringLogBo buildWateringLog(String topicDeviceNo, Map<String, Object> dto) {
|
||||
String payloadDeviceNo = valueAsString(dto.get("deviceNo"));
|
||||
if (StringUtils.isNotBlank(payloadDeviceNo) && !topicDeviceNo.equals(payloadDeviceNo)) {
|
||||
log.warn("[MQTT] 按键浇水完成上报设备编号不一致 topicDeviceNo={} payloadDeviceNo={}", topicDeviceNo, payloadDeviceNo);
|
||||
log.warn("[MQTT] 按键浇水完成上报设备编号不一致 时间={} 主题设备编号={} 消息体设备编号={}", HandlerLogTime.now(), topicDeviceNo, payloadDeviceNo);
|
||||
}
|
||||
|
||||
Date receivedAt = new Date();
|
||||
@@ -127,7 +127,7 @@ public class KeyFinishHandler implements MqttTopicHandler {
|
||||
}
|
||||
long diffMillis = endTime.getTime() - startTime.getTime();
|
||||
if (diffMillis < 0) {
|
||||
log.warn("[MQTT] 按键浇水完成上报结束时间早于开始时间 startTime={} endTime={}", startTime, endTime);
|
||||
log.warn("[MQTT] 按键浇水完成上报结束时间早于开始时间 时间={} 开始时间={} 结束时间={}", HandlerLogTime.now(), startTime, endTime);
|
||||
return 0;
|
||||
}
|
||||
return (int) (diffMillis / 60000L);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package org.dromara.app.handler;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import org.dromara.app.domain.AppSchedulingDevice;
|
||||
import org.dromara.app.domain.bo.AppWateringLogBo;
|
||||
import org.dromara.app.domain.vo.AppDeviceVo;
|
||||
@@ -46,16 +46,16 @@ public class ScheduleFinishHandler implements MqttTopicHandler {
|
||||
Map<String, Object> dto = JsonUtils.parseObject(payload, Map.class);
|
||||
AppWateringLogBo logBo = buildWateringLog(deviceNo, dto);
|
||||
appWateringLogService.insertByBo(logBo);
|
||||
log.info("[MQTT] 浇水排程上报 saved deviceNo={} payload={}", deviceNo, payload);
|
||||
log.info("[MQTT] 浇水排程上报已保存 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, payload);
|
||||
} catch (Exception e) {
|
||||
log.error("[MQTT] 浇水排程上报 failed deviceNo={} payload={}", deviceNo, payload, e);
|
||||
log.error("[MQTT] 浇水排程上报处理失败 时间={} 设备编号={} 消息体={}", HandlerLogTime.now(), deviceNo, payload, e);
|
||||
}
|
||||
}
|
||||
|
||||
private AppWateringLogBo buildWateringLog(String topicDeviceNo, Map<String, Object> dto) {
|
||||
String payloadDeviceNo = valueAsString(dto.get("deviceNo"));
|
||||
if (StringUtils.isNotBlank(payloadDeviceNo) && !topicDeviceNo.equals(payloadDeviceNo)) {
|
||||
log.warn("[MQTT] 排程完成上报设备编号不一致 topicDeviceNo={} payloadDeviceNo={}", topicDeviceNo, payloadDeviceNo);
|
||||
log.warn("[MQTT] 排程完成上报设备编号不一致 时间={} 主题设备编号={} 消息体设备编号={}", HandlerLogTime.now(), topicDeviceNo, payloadDeviceNo);
|
||||
}
|
||||
|
||||
|
||||
@@ -96,11 +96,11 @@ public class ScheduleFinishHandler implements MqttTopicHandler {
|
||||
.eq(AppSchedulingDevice::getDeviceNo, deviceNo)
|
||||
);
|
||||
if (schedulingDevices == null || schedulingDevices.isEmpty()) {
|
||||
log.warn("[MQTT] 排程完成上报未找到设备绑定的排程 deviceNo={}", deviceNo);
|
||||
log.warn("[MQTT] 排程完成上报未找到设备绑定的排程 时间={} 设备编号={}", HandlerLogTime.now(), deviceNo);
|
||||
return 0L;
|
||||
}
|
||||
if (schedulingDevices.size() > 1) {
|
||||
log.warn("[MQTT] 排程完成上报匹配到多个排程 deviceNo={} count={}", deviceNo, schedulingDevices.size());
|
||||
log.warn("[MQTT] 排程完成上报匹配到多个排程 时间={} 设备编号={} 数量={}", HandlerLogTime.now(), deviceNo, schedulingDevices.size());
|
||||
}
|
||||
return schedulingDevices.get(0).getScheduleId();
|
||||
}
|
||||
@@ -148,7 +148,7 @@ public class ScheduleFinishHandler implements MqttTopicHandler {
|
||||
}
|
||||
long diffMillis = endTime.getTime() - startTime.getTime();
|
||||
if (diffMillis < 0) {
|
||||
log.warn("[MQTT] 排程完成上报结束时间早于开始时间 startTime={} endTime={}", startTime, endTime);
|
||||
log.warn("[MQTT] 排程完成上报结束时间早于开始时间 时间={} 开始时间={} 结束时间={}", HandlerLogTime.now(), startTime, endTime);
|
||||
return 0;
|
||||
}
|
||||
return (int) (diffMillis / 60000L);
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
package org.dromara.app.mapper;
|
||||
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
import org.dromara.app.domain.AppDevice;
|
||||
import org.dromara.app.domain.vo.AppDeviceVo;
|
||||
import org.dromara.common.mybatis.annotation.DataColumn;
|
||||
import org.dromara.common.mybatis.annotation.DataPermission;
|
||||
import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Update;
|
||||
|
||||
/**
|
||||
* 设备信息
|
||||
@@ -29,6 +28,15 @@ public interface AppDeviceMapper extends BaseMapperPlus<AppDevice, AppDeviceVo>
|
||||
<if test="status != null and status != ''">
|
||||
status = #{status},
|
||||
</if>
|
||||
<if test="workStatus != null and workStatus != ''">
|
||||
work_status = #{workStatus},
|
||||
</if>
|
||||
<if test="wifiName != null and wifiName != ''">
|
||||
wifi_name = #{wifiName},
|
||||
</if>
|
||||
<if test="wifiPassword != null and wifiPassword != ''">
|
||||
wifi_password = #{wifiPassword},
|
||||
</if>
|
||||
</set>
|
||||
where device_no = #{deviceNo}
|
||||
and (user_id is null or user_id = #{userId})
|
||||
@@ -37,7 +45,10 @@ public interface AppDeviceMapper extends BaseMapperPlus<AppDevice, AppDeviceVo>
|
||||
int bindIfAvailable(@Param("deviceNo") String deviceNo,
|
||||
@Param("userId") Long userId,
|
||||
@Param("deviceName") String deviceName,
|
||||
@Param("status") String status);
|
||||
@Param("status") String status,
|
||||
@Param("workStatus") String workStatus,
|
||||
@Param("wifiName") String wifiName,
|
||||
@Param("wifiPassword") String wifiPassword);
|
||||
|
||||
@Update("""
|
||||
update app_device
|
||||
@@ -49,4 +60,11 @@ public interface AppDeviceMapper extends BaseMapperPlus<AppDevice, AppDeviceVo>
|
||||
@Param("userId") Long userId,
|
||||
@Param("workStatus") String workStatus);
|
||||
|
||||
@Select("""
|
||||
select *
|
||||
from app_device
|
||||
where mac_address = #{macAddress}
|
||||
""")
|
||||
AppDevice selectByMac(@Param("macAddress") String macAddress);
|
||||
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
|
||||
public interface AppWateringLogMapper extends BaseMapperPlus<AppWateringLog, AppWateringLogVo> {
|
||||
|
||||
@Select("SELECT count(id) FROM app_watering_log\n" +
|
||||
"WHERE user_id=${userId} AND YEAR(create_time) = YEAR(CURDATE()) AND MONTH(create_time) = MONTH(CURDATE());")
|
||||
"WHERE user_id=#{userId} AND YEAR(create_time) = YEAR(CURDATE()) AND MONTH(create_time) = MONTH(CURDATE());")
|
||||
Long selectByMonCout(@Param("userId") Long userId);
|
||||
|
||||
|
||||
@Select("SELECT COUNT(id) \n" +
|
||||
"FROM app_watering_log \n" +
|
||||
"WHERE user_id=${userId} AND WEEK(create_time) = WEEK(CURDATE());")
|
||||
"WHERE user_id=#{userId} AND WEEK(create_time) = WEEK(CURDATE());")
|
||||
Long selectByWeekCount(@Param("userId") Long userId);
|
||||
|
||||
|
||||
@@ -29,11 +29,11 @@ public interface AppWateringLogMapper extends BaseMapperPlus<AppWateringLog, App
|
||||
|
||||
@Select("SELECT COUNT(id) \n" +
|
||||
"FROM app_watering_log \n" +
|
||||
"WHERE user_id=${userId} AND trigger_type =${triggerType}")
|
||||
Long selectByTriggerTypeCount(Long userId, String triggerType);
|
||||
"WHERE user_id=#{userId} AND trigger_type =#{triggerType}")
|
||||
Long selectByTriggerTypeCount(@Param("userId") Long userId, @Param("triggerType") String triggerType);
|
||||
|
||||
@Select("SELECT SUM(duration_min)\n" +
|
||||
"FROM app_watering_log \n" +
|
||||
"WHERE user_id=${userId}")
|
||||
Long selectByTotalWateringTime(Long userId);
|
||||
"WHERE user_id=#{userId}")
|
||||
Long selectByTotalWateringTime(@Param("userId") Long userId);
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ public class MqttMessageDispatcher {
|
||||
|
||||
public MqttMessageDispatcher(List<MqttTopicHandler> handlers) {
|
||||
this.handlers = handlers;
|
||||
log.info("[MQTT] dispatcher initialized with {} handlers", handlers.size());
|
||||
log.info("[MQTT] 消息分发器初始化完成,处理器数量={}", handlers.size());
|
||||
for (MqttTopicHandler handler : handlers) {
|
||||
log.info("[MQTT] └ registered: {} -> {}", handler.getClass().getSimpleName(), handler.topicPattern());
|
||||
log.info("[MQTT] 已注册处理器:{} -> {}", handler.getClass().getSimpleName(), handler.topicPattern());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public class MqttMessageDispatcher {
|
||||
* @param payload 消息体
|
||||
*/
|
||||
public void dispatch(String topic, String payload) {
|
||||
log.debug("[MQTT] received topic={} payload={}", topic, payload);
|
||||
log.debug("[MQTT] 收到消息 主题={} 消息体={}", topic, payload);
|
||||
|
||||
for (MqttTopicHandler handler : handlers) {
|
||||
Matcher matcher = handler.topicPattern().matcher(topic);
|
||||
@@ -44,6 +44,6 @@ public class MqttMessageDispatcher {
|
||||
}
|
||||
}
|
||||
|
||||
log.warn("[MQTT] no handler for topic: {} payload={}", topic, payload);
|
||||
log.warn("[MQTT] 未找到匹配的处理器 主题={} 消息体={}", topic, payload);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
package org.dromara.app.service;
|
||||
|
||||
import org.dromara.app.domain.vo.AppDeviceVo;
|
||||
import org.dromara.app.domain.bo.AppDeviceBo;
|
||||
import org.dromara.common.mybatis.annotation.DataColumn;
|
||||
import org.dromara.common.mybatis.annotation.DataPermission;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.app.domain.vo.AppDeviceVo;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 设备信息
|
||||
@@ -97,4 +96,6 @@ public interface IAppDeviceService {
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteWithValidByIds(Collection<String> deviceNos, Boolean isValid);
|
||||
|
||||
Map<String, Object> bindDeviceStatus(AppDeviceBo appDevice);
|
||||
}
|
||||
|
||||
@@ -25,15 +25,12 @@ import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import org.dromara.common.mybatis.core.page.TableDataInfo;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@@ -116,7 +113,7 @@ public class AppDeviceServiceImpl implements IAppDeviceService {
|
||||
device.setPowerLevelUpdatatime(new Date());
|
||||
// applyRegisterBindToken(device, bo, exists);
|
||||
if (StringUtils.isBlank(device.getStatus())) {
|
||||
device.setStatus("2");
|
||||
device.setStatus("1"); // 注册默认在线
|
||||
device.setWorkStatus("2");
|
||||
}
|
||||
|
||||
@@ -131,6 +128,45 @@ public class AppDeviceServiceImpl implements IAppDeviceService {
|
||||
return baseMapper.updateById(device) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> bindDeviceStatus(AppDeviceBo bo) {
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("bindDeviceStatus", 200);
|
||||
params.put("bindDeviceStatusName", "");
|
||||
if (bo == null) {
|
||||
params.put("bindDeviceStatus", 300);
|
||||
params.put("bindDeviceStatusName", "设备信息不能为空");
|
||||
return params;
|
||||
}
|
||||
|
||||
if (StringUtils.isBlank(bo.getMacAddress())) {
|
||||
params.put("bindDeviceStatus", 301);
|
||||
params.put("bindDeviceStatusName", "MAC地址不能为空");
|
||||
return params;
|
||||
}
|
||||
params.put("bindDevice", null);
|
||||
Long userId = LoginHelper.getUserId();
|
||||
AppDevice exists = baseMapper.selectByMac(bo.getMacAddress());
|
||||
if (exists == null) {
|
||||
params.put("bindDeviceStatus", 302);
|
||||
params.put("bindDeviceStatusName", "设备未上线注册,请先完成配网");
|
||||
return params;
|
||||
}
|
||||
params.put("bindDevice", exists);
|
||||
if (exists.getUserId() != null && !exists.getUserId().equals(userId)) {
|
||||
params.put("bindDeviceStatus", 303);
|
||||
params.put("bindDeviceStatusName", "设备已被其他用户绑定");
|
||||
return params;
|
||||
}
|
||||
if (exists.getUserId() == null ) {
|
||||
params.put("bindDeviceStatus", 304);
|
||||
params.put("bindDeviceStatusName", "设备未绑定,请先绑定用户");
|
||||
return params;
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppDeviceVo bindRegisteredDevice(AppDeviceBo bo) {
|
||||
if (StringUtils.isBlank(bo.getDeviceNo())) {
|
||||
@@ -147,8 +183,10 @@ public class AppDeviceServiceImpl implements IAppDeviceService {
|
||||
// validBindToken(bo.getBindToken(), exists);
|
||||
|
||||
String status = StringUtils.isBlank(bo.getStatus()) ? exists.getStatus() : bo.getStatus();
|
||||
String wifiName = StringUtils.isBlank(bo.getWifiName()) ? exists.getWifiName() : bo.getWifiName();
|
||||
String wifiPassword = StringUtils.isBlank(bo.getWifiPassword()) ? exists.getWifiPassword() : bo.getWifiPassword();
|
||||
String deviceName = StringUtils.isBlank(bo.getDeviceName()) ? exists.getDeviceName() : bo.getDeviceName();
|
||||
int rows = baseMapper.bindIfAvailable(exists.getDeviceNo(), userId, deviceName, status);
|
||||
int rows = baseMapper.bindIfAvailable(exists.getDeviceNo(), userId, deviceName, status,"0",wifiName,wifiPassword);
|
||||
if (rows <= 0) {
|
||||
AppDevice current = baseMapper.selectById(bo.getDeviceNo());
|
||||
if (current == null) {
|
||||
@@ -188,7 +226,7 @@ public class AppDeviceServiceImpl implements IAppDeviceService {
|
||||
if (ObjectUtil.isNotNull(device) && StringUtils.isNotBlank(device.getDeviceNo())) {
|
||||
// 通过业务层统一下发命令(含浇水日志记录)
|
||||
String commandId = deviceCommandService.sendSwitchCommand(deviceNo, workStatus, startTime, durationMin);
|
||||
log.info("[DEVICE] switch command sent deviceNo={} commandId={}", deviceNo, commandId);
|
||||
log.info("[设备] 开关命令已下发 设备编号={} 命令编号={}", deviceNo, commandId);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -25,11 +25,7 @@ import org.dromara.common.satoken.utils.LoginHelper;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@@ -88,7 +84,13 @@ public class AppScheduleServiceImpl implements IAppScheduleService {
|
||||
@Override
|
||||
public Boolean updateStatusByBo(AppScheduleBo bo) {
|
||||
AppSchedule update = MapstructUtils.convert(bo, AppSchedule.class);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
Long userId = bo.getUserId() == null ? LoginHelper.getUserId() : bo.getUserId();
|
||||
return baseMapper.update(
|
||||
update,
|
||||
Wrappers.<AppSchedule>lambdaQuery()
|
||||
.eq(AppSchedule::getId, bo.getId())
|
||||
.eq(AppSchedule::getUserId, userId)
|
||||
) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -98,7 +100,13 @@ public class AppScheduleServiceImpl implements IAppScheduleService {
|
||||
validEntityBeforeSave(update);
|
||||
|
||||
Map<String, Object> repMap = new HashMap<>();
|
||||
Boolean flag = baseMapper.updateById(update) > 0;
|
||||
Long userId = bo.getUserId() == null ? LoginHelper.getUserId() : bo.getUserId();
|
||||
Boolean flag = baseMapper.update(
|
||||
update,
|
||||
Wrappers.<AppSchedule>lambdaQuery()
|
||||
.eq(AppSchedule::getId, bo.getId())
|
||||
.eq(AppSchedule::getUserId, userId)
|
||||
) > 0;
|
||||
repMap.put("flag", flag);
|
||||
repMap.put("list", new ArrayList<>());
|
||||
repMap.put("appSchedule", "");
|
||||
|
||||
@@ -3,13 +3,13 @@ package org.dromara.app.service.impl;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.app.domain.bo.AppWateringLogBo;
|
||||
import org.dromara.app.domain.mqtt.DeviceCommand;
|
||||
import org.dromara.app.domain.vo.AppDeviceVo;
|
||||
import org.dromara.app.service.IAppDeviceService;
|
||||
import org.dromara.app.service.IAppWateringLogService;
|
||||
import org.dromara.app.service.IDeviceCommandPublisher;
|
||||
import org.dromara.app.service.IDeviceCommandService;
|
||||
import org.dromara.app.domain.bo.AppWateringLogBo;
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.satoken.utils.LoginHelper;
|
||||
@@ -50,7 +50,7 @@ public class DeviceCommandServiceImpl implements IDeviceCommandService {
|
||||
public String sendCommand(DeviceCommand command) {
|
||||
validate(command);
|
||||
String commandId = commandPublisher.send(command);
|
||||
log.info("[CMD] command sent deviceNo={} commandType={} commandId={}",
|
||||
log.info("[命令] 命令已下发 设备编号={} 命令类型={} 命令编号={}",
|
||||
command.getDeviceNo(), command.getCommandType(), commandId);
|
||||
return commandId;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class DeviceCommandServiceImpl implements IDeviceCommandService {
|
||||
}
|
||||
|
||||
String commandId = commandPublisher.send(command);
|
||||
log.info("[CMD] switch command sent deviceNo={} workStatus={} durationMin={} commandId={}",
|
||||
log.info("[命令] 开关命令已下发 设备编号={} 工作状态={} 持续分钟数={} 命令编号={}",
|
||||
deviceNo, workStatus, durationMin, commandId);
|
||||
|
||||
Long userId = LoginHelper.getUserId();
|
||||
@@ -86,7 +86,7 @@ public class DeviceCommandServiceImpl implements IDeviceCommandService {
|
||||
} else {
|
||||
boolean updated = wateringLogService.finishManualLog(deviceNo, userId, new Date());
|
||||
if (!updated) {
|
||||
log.warn("[CMD] no active manual watering log found deviceNo={} userId={} stopCommandId={}",
|
||||
log.warn("[命令] 未找到进行中的手动浇水记录 设备编号={} 用户ID={} 停止命令编号={}",
|
||||
deviceNo, userId, commandId);
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ public class DeviceCommandServiceImpl implements IDeviceCommandService {
|
||||
command.setCommandType("bindDevice");
|
||||
Map<String, Object> objectObjectHashMap = new HashMap<>();
|
||||
objectObjectHashMap.put("bindStatus", true);
|
||||
objectObjectHashMap.put("deviceNo", "01");
|
||||
objectObjectHashMap.put("deviceNo", deviceNo);
|
||||
objectObjectHashMap.put("cmd", -1);
|
||||
command.getPayload().putAll(objectObjectHashMap);
|
||||
return sendCommand(command);
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package org.dromara.app.task;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.app.domain.AppDevice;
|
||||
import org.dromara.app.mapper.AppDeviceMapper;
|
||||
import org.dromara.common.redis.utils.RedisUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 设备离线检测定时任务
|
||||
* <p>
|
||||
* 逻辑:Redis 中 mqtt:device:status:{deviceNo} Key 的 TTL 由 device-status-cache-ttl-seconds 控制。
|
||||
* 设备断电/断网后不再上报数据,TTL 到期 Key 自动消失。
|
||||
* 本任务定期扫描数据库中非离线状态的设备,如果对应 Redis Key 已不存在,
|
||||
* 则将数据库 status 更新为 0(离线)。
|
||||
* </p>
|
||||
*
|
||||
* <p>扫描间隔通过 {@code mqtt.offline-check.interval-ms} 配置,建议小于设备在线 Key 的 TTL。</p>
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DeviceOfflineCheckTask {
|
||||
|
||||
private final AppDeviceMapper appDeviceMapper;
|
||||
|
||||
@Value("${mqtt.command-ack.device-status-cache-prefix}")
|
||||
private String deviceStatusCachePrefix;
|
||||
|
||||
@Value("${mqtt.offline-check.enabled:true}")
|
||||
private boolean enabled;
|
||||
|
||||
/**
|
||||
* 每 90 秒检查一次(Redis TTL 默认 300s,90s 间隔确保 1.5 个周期内同步)
|
||||
* 可通过 mqtt.offline-check.interval-ms 覆盖(单位 ms)
|
||||
*/
|
||||
@Scheduled(fixedDelayString = "${mqtt.offline-check.interval-ms:90000}")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void checkOfflineDevices() {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 查询数据库中所有非离线状态的设备,避免状态不是 1 但仍需离线修正的设备被漏掉
|
||||
List<AppDevice> onlineDevices = appDeviceMapper.selectList(
|
||||
new LambdaQueryWrapper<AppDevice>()
|
||||
.ne(AppDevice::getStatus, "0")
|
||||
.select(AppDevice::getDeviceNo)
|
||||
);
|
||||
|
||||
if (onlineDevices.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 过滤出 Redis Key 已过期(不存在)的设备
|
||||
List<String> offlineDeviceNos = onlineDevices.stream()
|
||||
.map(AppDevice::getDeviceNo)
|
||||
.filter(deviceNo -> !RedisUtils.hasKey(deviceStatusCachePrefix + deviceNo))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (offlineDeviceNos.isEmpty()) {
|
||||
log.debug("[设备离线] 本次检测未发现离线设备,扫描设备数:{}", onlineDevices.size());
|
||||
return;
|
||||
}
|
||||
|
||||
// 批量更新为离线
|
||||
int updated = appDeviceMapper.update(null,
|
||||
new LambdaUpdateWrapper<AppDevice>()
|
||||
.set(AppDevice::getStatus, "0")
|
||||
.ne(AppDevice::getStatus, "0")
|
||||
.in(AppDevice::getDeviceNo, offlineDeviceNos)
|
||||
);
|
||||
|
||||
log.info("[设备离线] 检测到 {} 台设备离线,已更新数据库状态,设备编号:{}",
|
||||
updated, offlineDeviceNos);
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ public class SaTokenTestController {
|
||||
@SaCheckRole("none_exist") // 该注解会被忽略
|
||||
@GetMapping("/basic/ignoreAll")
|
||||
public R<Void> ignoreAll() {
|
||||
log.info("【场景4】SaIgnore忽略所有权限校验");
|
||||
log.info("【场景4】忽略注解跳过所有权限校验");
|
||||
return R.ok("SaIgnore生效,所有权限校验被忽略");
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ public class SaTokenTestController {
|
||||
@SaCheckRole(value = {"admin", "operator"}, mode = SaMode.AND)
|
||||
@GetMapping("/advance/multiRoleAnd")
|
||||
public R<Void> multiRoleAnd() {
|
||||
log.info("【场景5】多角色AND模式(admin+operator)校验通过");
|
||||
log.info("【场景5】多角色且模式(admin+operator)校验通过");
|
||||
return R.ok("同时拥有admin和operator角色,校验通过");
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class SaTokenTestController {
|
||||
@SaCheckRole(value = {"admin", "test"}, mode = SaMode.OR)
|
||||
@GetMapping("/advance/multiRoleOr")
|
||||
public R<Void> multiRoleOr() {
|
||||
log.info("【场景6】多角色OR模式(admin|test)校验通过");
|
||||
log.info("【场景6】多角色或模式(admin|test)校验通过");
|
||||
return R.ok("拥有admin或test角色,校验通过");
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ public class SaTokenTestController {
|
||||
@SaCheckPermission(value = {"system:user:edit", "system:log:view"}, mode = SaMode.AND)
|
||||
@GetMapping("/advance/multiPermAnd")
|
||||
public R<Void> multiPermAnd() {
|
||||
log.info("【场景7】多权限AND模式(system:user:edit+system:log:view)校验通过");
|
||||
log.info("【场景7】多权限且模式(system:user:edit+system:log:view)校验通过");
|
||||
return R.ok("同时拥有system:user:edit和system:log:view权限,校验通过");
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ public class SaTokenTestController {
|
||||
@SaCheckPermission(value = {"system:user:add", "system:user:delete"}, mode = SaMode.OR)
|
||||
@GetMapping("/advance/multiPermOr")
|
||||
public R<Void> multiPermOr() {
|
||||
log.info("【场景8】多权限OR模式(system:user:add|system:user:delete)校验通过");
|
||||
log.info("【场景8】多权限或模式(system:user:add|system:user:delete)校验通过");
|
||||
return R.ok("拥有system:user:add或system:user:delete权限,校验通过");
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ public class SaTokenTestController {
|
||||
@SaCheckPermission("system:user:all")
|
||||
@GetMapping("/advanced/mixRolePermAnd")
|
||||
public R<Void> mixRolePermAnd() {
|
||||
log.info("【场景11】角色+权限混合AND(admin+system:user:all)校验通过");
|
||||
log.info("【场景11】角色+权限混合且模式(admin+system:user:all)校验通过");
|
||||
return R.ok("拥有admin角色且拥有system:user:all权限,校验通过");
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ public class SaTokenTestController {
|
||||
@SaCheckPermission(value = {"system:manage"}, mode = SaMode.OR)
|
||||
@GetMapping("/advanced/mixRolePermOr")
|
||||
public R<Void> mixRolePermOr() {
|
||||
log.info("【场景12】角色+权限混合OR(super_admin|system:manage)校验通过");
|
||||
log.info("【场景12】角色+权限混合或模式(super_admin|system:manage)校验通过");
|
||||
return R.ok("拥有super_admin角色或system:manage权限,校验通过");
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ public class SaTokenTestController {
|
||||
@SaCheckPermission(value = "system:user:export", orRole = {"admin", "operator"})
|
||||
@GetMapping("/advanced/permWithOrRole")
|
||||
public R<Void> permWithOrRole() {
|
||||
log.info("【场景13】权限+orRole兜底校验通过");
|
||||
log.info("【场景13】权限+角色兜底校验通过");
|
||||
return R.ok("拥有system:user:export权限,或拥有admin/operator角色,校验通过");
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ public class SaTokenTestController {
|
||||
@SaIgnore
|
||||
@GetMapping("/special/ignoreOverride")
|
||||
public R<Void> ignoreOverride() {
|
||||
log.info("【场景14】SaIgnore覆盖类级别权限注解");
|
||||
log.info("【场景14】忽略注解覆盖类级别权限注解");
|
||||
return R.ok("方法级SaIgnore覆盖类级别权限校验");
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ public class FlwCommonServiceImpl implements IFlwCommonService {
|
||||
// // 指定获取一个短信服务商 configKey
|
||||
// SmsBlend smsBlend = SmsFactory.getSmsBlend("config1");
|
||||
// SmsResponse smsResponse = smsBlend.sendMessage(phones, templateId, map);
|
||||
log.info("【短信发送 - TODO】用户数量={} 内容={}", userList.size(), message);
|
||||
log.info("【短信发送 - 待实现】用户数量={} 内容={}", userList.size(), message);
|
||||
}
|
||||
default -> log.warn("【消息发送】未处理的消息类型:{}", messageTypeEnum);
|
||||
}
|
||||
|
||||
@@ -194,8 +194,8 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
|
||||
try {
|
||||
defService.removeDef(ids);
|
||||
} catch (Exception e) {
|
||||
log.error("Error removing flow definitions: {}", e.getMessage(), e);
|
||||
throw new RuntimeException("Failed to remove flow definitions", e);
|
||||
log.error("删除流程定义失败:{}", e.getMessage(), e);
|
||||
throw new RuntimeException("删除流程定义失败", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
|
||||
flowInstances.forEach(instance -> {
|
||||
Definition definition = definitionMap.get(instance.getDefinitionId());
|
||||
if (ObjectUtil.isNull(definition)) {
|
||||
log.warn("实例 ID: {} 对应的流程定义信息未找到,跳过删除事件触发。", instance.getId());
|
||||
log.warn("实例ID:{} 对应的流程定义信息未找到,跳过删除事件触发。", instance.getId());
|
||||
return;
|
||||
}
|
||||
flowProcessEventHandler.processDeleteHandler(definition.getFlowCode(), instance.getBusinessId());
|
||||
|
||||
@@ -267,7 +267,7 @@ public class FlwNodeExtServiceImpl implements NodeExtService, IFlwNodeExtService
|
||||
nodeExtVo.setVariables(variables);
|
||||
} else {
|
||||
// 未知扩展类型,记录日志
|
||||
log.warn("未知扩展类型:code={}, value={}", code, value);
|
||||
log.warn("未知扩展类型:编码={},值={}", code, value);
|
||||
}
|
||||
}
|
||||
return nodeExtVo;
|
||||
|
||||
@@ -283,7 +283,7 @@ public class FlwTaskAssigneeServiceImpl implements IFlwTaskAssigneeService, Hand
|
||||
return Pair.of(type, parts[1]);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("解析 storageId 失败,格式非法:{},错误信息:{}", storageId, e.getMessage());
|
||||
log.warn("解析存储ID失败,格式非法:{},错误信息:{}", storageId, e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,8 +754,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
|
||||
public boolean taskOperation(TaskOperationBo bo, String taskOperation) {
|
||||
TaskOperationEnum op = TaskOperationEnum.getByCode(taskOperation);
|
||||
if (op == null) {
|
||||
log.error("Invalid operation type:{} ", taskOperation);
|
||||
throw new ServiceException("Invalid operation type " + taskOperation);
|
||||
log.error("无效的操作类型:{}", taskOperation);
|
||||
throw new ServiceException("无效的操作类型 " + taskOperation);
|
||||
}
|
||||
|
||||
FlowParams flowParams = FlowParams.build().message(bo.getMessage());
|
||||
|
||||
Reference in New Issue
Block a user