43 KiB
Water IoT APP 接口文档
业务接口 Base URL:
/app/v1认证接口前缀:/auth、/resource认证方式: Sa-Token;/app/v1/**业务接口需携带Authorization: Bearer <token>,登录/注册/普通验证码接口免登录 响应编码: UTF-8 最后更新: 2026-07-14
目录
通用说明
统一响应结构 R<T>
大多数接口返回统一的 R<T> 包装结构:
{
"code": 200,
"msg": "操作成功",
"data": { }
}
| 字段 | 类型 | 说明 |
|---|---|---|
code |
int |
200 表示成功,500 表示失败 |
msg |
string |
提示消息(支持 i18n 国际化) |
data |
T |
业务数据,类型视接口而定;无数据时为 null |
判断逻辑:code === 200 为成功,其余均为失败。
分页响应结构 TableDataInfo<T>
列表查询接口返回 TableDataInfo<T>:
{
"code": 200,
"msg": "查询成功",
"total": 100,
"rows": [ ]
}
| 字段 | 类型 | 说明 |
|---|---|---|
code |
int |
200 表示成功 |
msg |
string |
提示消息 |
total |
long |
总记录数 |
rows |
T[] |
当前页数据列表 |
分页请求参数
所有分页查询接口(GET 请求)支持以下 Query 参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNum |
int |
否 | 当前页码,默认 1 |
pageSize |
int |
否 | 每页条数,默认查全部 |
注意:设备列表、排程列表、浇水记录列表的排序方向固定为
createTime desc(服务端强制设置),前端无需传排序参数。
特殊标注说明
| 标注 | 说明 |
|---|---|
@ApiEncrypt |
启用 api-decrypt 后强制请求体加密;默认配置关闭时仍使用普通 JSON |
@RepeatSubmit |
防重复提交,相同请求在短时间内只能提交一次 |
@Log |
操作会被记录到系统日志 |
当前默认配置
api-decrypt.enabled=false,因此@ApiEncrypt接口可直接发送普通 JSON。 当部署环境启用接口加密后,标注@ApiEncrypt的 POST/PUT 接口必须携带encrypt-key请求头并发送加密后的 body;该标注不代表免登录。
零、登录、注册与验证码
本章节接口来自 AuthController 和 CaptchaController。两个控制器使用了 @SaIgnore,普通登录、注册和验证码接口免登录;退出登录、账号注销验证码和账号注销仍会在方法内部校验 Token。
默认 APP 客户端配置:
| 参数 | 默认值 | 说明 |
|---|---|---|
clientId |
428a8310cd442757ae699df5d894f051 |
APP 客户端 ID,来源于 sys_client 初始化数据 |
tenantId |
000000 |
默认租户 ID;关闭多租户时仍可沿用该值 |
userType |
app_user |
APP 注册用户类型 |
grantType |
password / sms |
默认 APP 客户端支持密码、短信和社交授权 |
0.1 获取图形验证码
GET /auth/code
认证:免登录。验证码开启时按 IP 限流,每 60 秒最多 10 次。
响应:R<CaptchaVo>
{
"code": 200,
"msg": "操作成功",
"data": {
"captchaEnabled": true,
"uuid": "54ef90b79e384d29a44d59f863f83a52",
"img": "data:image/png;base64,..."
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
captchaEnabled |
boolean |
是否启用图形验证码 |
uuid |
string |
验证码缓存标识 |
img |
string |
Base64 图片数据 |
当前密码登录和注册服务中的图形验证码校验代码已注释,APP 注册实际使用手机号/邮箱验证码。
0.2 获取通用手机号或邮箱验证码
根据 username 格式自动选择短信或邮件发送,主要用于注册和找回密码。
GET /resource/code?username={username}
认证:免登录。相同 username 每 60 秒最多请求 1 次。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
username |
string |
是 | 手机号或邮箱;手机号发送短信,其他值按邮箱发送 |
响应:R<Void>
{
"code": 200,
"msg": "123456",
"data": null
}
当前实现会把验证码同时放入响应
msg,生产环境存在验证码泄露风险,建议生产部署时改为固定提示文本。
0.3 获取短信验证码
用于短信验证码登录。
GET /resource/sms/code?phonenumber={phonenumber}
认证:免登录。相同手机号每 60 秒最多请求 1 次。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
phonenumber |
string |
是 | 接收验证码的手机号 |
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
0.4 获取邮箱验证码
GET /resource/email/code?email={email}
认证:免登录。相同邮箱每 60 秒最多请求 1 次。
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
email |
string |
是 | 接收验证码的邮箱地址 |
响应:R<Void>。未开启邮件功能时返回 当前系统没有开启邮箱功能!。
0.5 用户登录
POST /auth/login
认证:免登录。接口标注 @ApiEncrypt,加密规则参见通用说明。
密码登录请求体(grantType=password)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
clientId |
string |
是 | APP 客户端 ID |
grantType |
string |
是 | 固定为 password |
username |
string |
是 | 用户名、手机号或邮箱,长度 2~30 |
password |
string |
是 | 密码,长度 5~30 |
{
"clientId": "428a8310cd442757ae699df5d894f051",
"grantType": "password",
"username": "13800000000",
"password": "123456"
}
短信登录请求体(grantType=sms)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
clientId |
string |
是 | APP 客户端 ID |
grantType |
string |
是 | 固定为 sms |
phonenumber |
string |
是 | 手机号 |
smsCode |
string |
是 | /resource/sms/code 获取的验证码 |
{
"clientId": "428a8310cd442757ae699df5d894f051",
"grantType": "sms",
"phonenumber": "13800000000",
"smsCode": "123456"
}
响应:R<LoginVo>
{
"code": 200,
"msg": "操作成功",
"data": {
"access_token": "登录Token",
"refresh_token": null,
"expire_in": 1800,
"refresh_expire_in": null,
"client_id": "428a8310cd442757ae699df5d894f051",
"scope": null,
"openid": null
}
}
后续业务请求头:
Authorization: Bearer 登录Token
0.6 用户注册
POST /auth/register
认证:免登录。接口标注 @ApiEncrypt;系统配置必须允许注册。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
clientId |
string |
是 | APP 客户端 ID |
grantType |
string |
是 | 可传 password、sms,用于通过基础请求校验 |
username |
string |
是 | 手机号、邮箱或用户名,长度 2~30 |
password |
string |
是 | 密码,长度 5~30 |
userType |
string |
是 | APP 用户固定传 app_user |
code |
string |
是 | 调用 /resource/code?username=... 获取的验证码 |
{
"clientId": "428a8310cd442757ae699df5d894f051",
"grantType": "password",
"username": "13800000000",
"password": "123456",
"userType": "app_user",
"code": "123456"
}
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
注册验证码以
username为缓存键,因此获取验证码和注册时的username必须完全一致。
0.7 忘记密码
PUT /auth/forgot
认证:免登录。接口标注 @ApiEncrypt。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
username |
string |
是 | 已注册的用户名或手机号 |
smsCode |
string |
是 | 以 username 为缓存键的验证码,可通过 /resource/code 获取 |
password |
string |
是 | 新密码,长度 5~30 |
{
"username": "13800000000",
"smsCode": "123456",
"password": "NewPass456"
}
响应:R<Void>
当前实现限制:邮箱分支查询结果未赋值给用户对象,因此邮箱找回密码当前会被判定为“账号未注册”;建议修复后再开放邮箱找回。
0.8 退出登录
POST /auth/logout
认证:需要 Authorization: Bearer <token>。
响应:R<Void>,成功消息为 退出成功。
0.9 获取账号注销验证码
根据当前登录账号优先向已绑定手机号发送短信;没有有效手机号时发送到邮箱。
GET /resource/account/cancel/code
认证:需要 Authorization: Bearer <token>。每个用户每 60 秒最多请求 1 次。
响应:R<Void>
验证码以当前登录用户名为缓存键。账号未绑定手机号或邮箱时返回失败。
0.11 注销账号
DELETE /auth/account
认证:需要 Authorization: Bearer <token>。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
code |
string |
是 | /resource/account/cancel/code 获取的验证码 |
{
"code": "123456"
}
响应:R<Void>,成功消息为 注销成功。
注销成功后会解绑并初始化用户名下设备,删除排程、浇水记录及系统用户关联数据,并退出当前账号。该操作不可恢复,超级管理员账号不允许注销。
一、设备管理
1.1 查询设备列表(分页)
查询当前登录用户名下的设备列表。
GET /app/v1/deviceList
请求参数(Query)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNum |
int |
否 | 页码,默认 1 |
pageSize |
int |
否 | 每页条数 |
deviceNo |
string |
否 | 设备编号(精确查询) |
deviceName |
string |
否 | 设备名称(模糊查询) |
status |
string |
否 | 设备状态:1-在线 0-离线 2-到期 3-故障 |
wifiName |
string |
否 | WiFi 名称(模糊查询) |
deviceEm |
string |
否 | 设备型号(精确查询) |
deviceSn |
string |
否 | 设备序列号(精确查询) |
fwVer |
string |
否 | 固件版本(精确查询) |
macAddress |
string |
否 | MAC 地址(精确查询) |
响应:TableDataInfo<AppDeviceVo>
{
"code": 200,
"msg": "查询成功",
"total": 2,
"rows": [
{
"deviceNo": "D20260101001",
"userId": 1,
"deviceName": "前院浇灌器",
"deviceInitName": "智能浇灌器Pro",
"deviceImg": "https://oss.example.com/device/xxx.png",
"qrcode": "D20260101001",
"status": "1",
"workStatus": "0",
"powerLevel": "85",
"powerLevelUpdatatime": "2026-07-14 08:30:00",
"wifiName": "Home-WiFi",
"wifiPassword": "12345678",
"deviceEm": "WATER-PRO-1",
"deviceSn": "SN20260101001",
"fwVer": "1.0.3",
"macAddress": "AA:BB:CC:DD:EE:FF",
"nickName": "张三",
"expirationTime": "2027-01-01 00:00:00"
}
]
}
1.2 绑定设备状态检查
检查设备绑定状态(加密接口)。
POST /app/v1/bindDeviceStatus
请求头
Content-Type: application/json
请求体(JSON;启用接口加密时发送加密后的 JSON 字符串)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceNo |
string |
否 | 设备编号 |
macAddress |
string |
否 | MAC 地址 |
deviceInitName |
string |
否 | 设备初始名称 |
以上三个设备标识至少填写一个。查询顺序为 deviceNo、macAddress、deviceInitName。
响应:R<Map<String, Object>>
{
"code": 200,
"msg": "操作成功",
"data": {
"bindDeviceStatus": 304,
"bindDeviceStatusName": "设备未绑定,请先绑定用户",
"bindDevice": {
"deviceNo": "D20260101001",
"macAddress": "AA:BB:CC:DD:EE:FF",
"userId": null,
"status": "1",
"workStatus": "2"
}
}
}
bindDeviceStatus 业务状态码:
| 状态码 | 说明 |
|---|---|
200 |
设备已绑定当前用户,可正常使用 |
300 |
设备信息为空 |
301 |
未提供设备编号、MAC 地址或设备初始名称 |
302 |
设备未入库注册 |
303 |
设备已被其他用户绑定 |
304 |
设备存在但尚未绑定用户,可以继续调用 /addDevice |
305 |
设备尚未完成配网 |
这些是
data.bindDeviceStatus的业务状态码;接口外层code在正常处理时仍为200。
1.3 绑定已上线设备
绑定通过 MQTT 注册上线的设备到当前用户(加密接口)。
POST /app/v1/addDevice
请求头
Content-Type: application/json
请求体(JSON;启用接口加密时发送加密后的 JSON 字符串)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceNo |
string |
是 | MQTT 注册后服务端分配的设备编号 |
deviceName |
string |
否 | 设备名称 |
status |
string |
否 | 绑定后保留/设置的设备在线状态 |
wifiName |
string |
否 | WiFi 名称 |
wifiPassword |
string |
否 | WiFi 密码 |
响应:R<AppDeviceVo>
{
"code": 200,
"msg": "操作成功",
"data": {
"deviceNo": "D20260101001",
"userId": 1,
"deviceName": "前院浇灌器",
"deviceInitName": "智能浇灌器Pro",
"deviceImg": "https://oss.example.com/device/xxx.png",
"status": "1",
"workStatus": "0",
"macAddress": "AA:BB:CC:DD:EE:FF",
"expirationTime": "2027-01-01 00:00:00"
}
}
1.4 获取设备详情
GET /app/v1/device/{deviceNo}
路径参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceNo |
string |
是 | 设备编号 |
响应:R<AppDeviceVo>
{
"code": 200,
"msg": "操作成功",
"data": {
"deviceNo": "D20260101001",
"userId": 1,
"deviceName": "前院浇灌器",
"deviceInitName": "智能浇灌器Pro",
"deviceImg": "https://oss.example.com/device/xxx.png",
"qrcode": "D20260101001",
"status": "1",
"workStatus": "0",
"powerLevel": "85",
"powerLevelUpdatatime": "2026-07-14 08:30:00",
"wifiName": "Home-WiFi",
"wifiPassword": "12345678",
"deviceEm": "WATER-PRO-1",
"deviceSn": "SN20260101001",
"fwVer": "1.0.3",
"macAddress": "AA:BB:CC:DD:EE:FF",
"nickName": "张三",
"expirationTime": "2027-01-01 00:00:00"
}
}
权限:只能查询当前用户名下的设备,否则返回错误。
1.5 修改设备信息
PUT /app/v1/updateDeviceInfo
@RepeatSubmit— 防重复提交
请求头
Content-Type: application/json
请求体:AppDeviceBo(JSON)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceNo |
string |
是 | 设备编号(EditGroup 校验) |
deviceName |
string |
否 | 设备名称 |
deviceImg |
string |
否 | 设备图片 URL |
wifiName |
string |
否 | WiFi 名称 |
wifiPassword |
string |
否 | WiFi 密码 |
{
"deviceNo": "D20260101001",
"deviceName": "后院浇灌器",
"deviceImg": "https://oss.example.com/device/new.png"
}
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
权限:只能修改当前用户名下的设备。
1.6 删除设备(解绑)
解绑一个或多个设备。
DELETE /app/v1/deleteDevice/{deviceNos}
路径参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceNos |
string |
是 | 设备编号,多个用逗号分隔。例:D001,D002 |
示例
DELETE /app/v1/deleteDevice/D20260101001,D20260101002
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
权限:只能解绑当前用户名下的设备。
1.7 手动开关设备
手动开启或关闭设备工作状态,并可通过 MQTT 下发指令到设备。
PUT /app/v1/switchDevice
@RepeatSubmit— 防重复提交
请求头
Content-Type: application/json
请求体(JSON)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceNo |
string |
是 | 设备编号 |
workStatus |
string |
是 | 工作状态:1-开启 0-关闭 |
durationMin |
int |
条件必填 | 持续时长(分钟);workStatus=1 时必须大于 0,关闭时可不传 |
{
"deviceNo": "D20260101001",
"workStatus": "1",
"durationMin": 20
}
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
说明:开启时
startTime由服务端按当前时间生成,格式为yyyy-MM-dd HH:mm:ss。
二、排程管理
2.1 查询排程列表(分页)
GET /app/v1/schedulelist
请求参数(Query)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNum |
int |
否 | 页码 |
pageSize |
int |
否 | 每页条数 |
name |
string |
否 | 排程名称(模糊查询) |
status |
string |
否 | 状态:0-关闭 1-开启 |
响应:TableDataInfo<AppScheduleVo>
{
"code": 200,
"msg": "查询成功",
"total": 1,
"rows": [
{
"id": 1,
"userId": 1,
"name": "工作日早晨浇水",
"status": "1",
"details": null,
"deviceNos": null
}
]
}
注意:列表查询返回的
details和deviceNos为null,完整信息请通过 2.3 排程详情 获取。
2.2 新增排程
POST /app/v1/addschedule
@RepeatSubmit— 防重复提交
请求头
Content-Type: application/json
请求体:AppScheduleBo(JSON,AddGroup 校验)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
name |
string |
否 | 排程名称 |
status |
string |
否 | 状态:0-关闭 1-开启 |
details |
array |
是 | 排程详情列表(至少一天) |
details 数组元素结构(AppScheduleDetail)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
weekday |
int |
是 | 星期几:1-周一 ~ 7-周日 |
timeData |
array |
是 | 时间段列表 |
zones |
int |
否 | 浇水区域(位掩码) |
triggerType |
string |
否 | 触发类型:0-排程(默认) |
status |
string |
否 | 状态:0-关闭(默认) |
timeData 数组元素结构(TimeSlot)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
startTime |
string |
是 | 开始时间,格式 HH:mm |
durationMin |
int |
否 | 持续时长(分钟) |
{
"name": "工作日早晨浇水",
"status": "1",
"details": [
{
"weekday": 1,
"timeData": [
{ "startTime": "06:30", "durationMin": 15 },
{ "startTime": "18:00", "durationMin": 20 }
],
"triggerType": "0",
"status": "1"
},
{
"weekday": 2,
"timeData": [
{ "startTime": "06:30", "durationMin": 15 }
],
"triggerType": "0",
"status": "1"
}
]
}
响应:R<AppScheduleVo>
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 10,
"userId": 1,
"name": "工作日早晨浇水",
"status": "1",
"details": [
{
"id": 101,
"weekday": 1,
"timeData": [
{ "startTime": "06:30", "durationMin": 15 },
{ "startTime": "18:00", "durationMin": 20 }
],
"triggerType": "0",
"status": "1"
}
],
"deviceNos": null
}
}
2.3 排程详情
获取排程完整信息,包含排程详情列表和已绑定设备列表。
GET /app/v1/schedule/{id}
路径参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
long |
是 | 排程 ID |
响应:R<AppScheduleVo>
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 10,
"userId": 1,
"name": "工作日早晨浇水",
"status": "1",
"details": [
{
"id": 1,
"weekday": 1,
"timeData": [
{ "startTime": "06:30", "durationMin": 15 },
{ "startTime": "18:00", "durationMin": 20 }
],
"triggerType": "0",
"status": "1"
}
],
"deviceNos": [
{
"deviceNo": "D20260101001",
"userId": 1,
"deviceName": "前院浇灌器",
"status": "1",
"workStatus": "0"
}
]
}
}
说明:
details返回该排程当前查询到的全部明细,不在控制器中额外过滤状态。deviceNos为已绑定设备的完整AppDeviceVo列表。timeData已从 JSON 字符串解析为数组。
2.4 修改排程状态
开启或关闭排程,状态变更后通过 MQTT 通知所有已绑定设备。
PUT /app/v1/editScheduleStatus
请求头
Content-Type: application/json
请求体:AppScheduleBo(JSON)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
long |
是 | 排程 ID |
status |
string |
是 | 目标状态:0-关闭 1-开启 |
{
"id": 10,
"status": "0"
}
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
MQTT 通知:
- 关闭(
status=0):向绑定设备下发排程取消指令。- 开启(
status=1):向绑定设备重新下发完整排程信息。
2.5 修改排程
修改排程内容,更新后通过 MQTT 向所有绑定设备重新下发排程。
PUT /app/v1/updataschedule
@RepeatSubmit— 防重复提交
请求头
Content-Type: application/json
请求体:AppScheduleBo(JSON,EditGroup 校验)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id |
long |
是 | 排程 ID(EditGroup 校验) |
name |
string |
否 | 排程名称 |
status |
string |
否 | 状态:0-关闭 1-开启 |
details |
array |
否 | 排程详情列表(同 2.2 新增排程) |
{
"id": 10,
"name": "周末浇水计划",
"status": "1",
"details": [
{
"id": 101,
"weekday": 6,
"timeData": [
{ "startTime": "08:00", "durationMin": 30 }
],
"triggerType": "0",
"status": "1"
}
]
}
响应:R<Object>
{
"code": 200,
"msg": "操作成功",
"data": {
"id": 10,
"userId": 1,
"name": "周末浇水计划",
"status": "1",
"details": [ ]
}
}
说明:
data为更新后的AppScheduleVo对象。修改已有排程明细时应传明细id,否则服务端无法按主键更新该明细。
2.6 删除排程
删除一个或多个排程,并通知所有绑定设备解绑。
DELETE /app/v1/deleteschedule/{ids}
路径参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ids |
long |
是 | 排程 ID,多个用逗号分隔。例:10,11 |
示例
DELETE /app/v1/deleteschedule/10,11
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
MQTT 通知:删除成功后,向每个排程关联的所有设备下发解绑指令。
三、排程-设备关联
3.1 查询排程可关联的设备
查询当前用户名下未被其他排程关联的设备列表。
GET /app/v1/scheduleDeviceList/{scheduleId}
路径参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
scheduleId |
long |
是 | 排程 ID |
响应:R<Map<String, Object>>
{
"code": 200,
"msg": "操作成功",
"data": {
"deviceList": [
{
"deviceNo": "D20260101003",
"userId": 1,
"deviceName": "阳台浇灌器",
"status": "1",
"workStatus": "0"
}
]
}
}
说明:返回的设备列表为当前用户名下未与任何排程关联的设备。已关联其他排程的设备不会出现在列表中。
3.2 绑定排程与设备
将一个或多个设备绑定到指定排程,绑定后通过 MQTT 向设备下发排程信息。
POST /app/v1/addScheduleDevice
@RepeatSubmit— 防重复提交
请求头
Content-Type: application/json
请求体(JSON)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
scheduleId |
long |
是 | 排程 ID |
deviceNos |
array |
是 | 设备编号列表。也可用 deviceNo(逗号分隔字符串)或 deviceIds |
{
"scheduleId": 10,
"deviceNos": ["D20260101001", "D20260101003"]
}
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
说明:
deviceNos支持数组或逗号分隔字符串格式。- 已绑定该排程的设备会自动跳过(幂等)。
- 绑定后,服务端通过 MQTT 向设备下发排程详情。
3.3 删除排程与设备绑定
解除排程与设备的绑定关系,并通知设备取消排程。
DELETE /app/v1/deleteScheduleDevice
请求参数(Query)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
scheduleId |
string |
是 | 排程 ID |
deviceNo |
string |
是 | 设备编号 |
示例
DELETE /app/v1/deleteScheduleDevice?scheduleId=10&deviceNo=D20260101001
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
MQTT 通知:解绑成功后,向设备下发排程解绑指令。若 MQTT 下发失败,不影响接口返回成功(仅记录日志警告)。
四、浇水记录
4.1 查询浇水记录列表(分页)
GET /app/v1/waterLogList
请求参数(Query)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
pageNum |
int |
否 | 页码 |
pageSize |
int |
否 | 每页条数 |
deviceNo |
string |
否 | 设备编号 |
commandId |
string |
否 | MQTT 命令 ID |
scheduleId |
long |
否 | 关联排程 ID |
startTime |
date |
否 | 开始时间(精确匹配) |
endTime |
date |
否 | 结束时间(精确匹配) |
durationMin |
string |
否 | 持续时间(精确匹配) |
zones |
string |
否 | 浇水区域 |
triggerType |
string |
否 | 触发类型:0-排程 1-手动 |
remark |
string |
否 | 备注(模糊匹配) |
params[beginTime] |
date |
否 | 创建时间范围开始;需与 params[endTime] 同时传入 |
params[endTime] |
date |
否 | 创建时间范围结束;需与 params[beginTime] 同时传入 |
响应:TableDataInfo<AppWateringLogVo>
{
"code": 200,
"msg": "查询成功",
"total": 50,
"rows": [
{
"id": 1,
"userId": 1,
"deviceNo": "D20260101001",
"deviceName": "前院浇灌器",
"commandId": "CMD_20260714001",
"scheduleId": 10,
"startTime": "2026-07-14 06:30:00",
"endTime": "2026-07-14 06:45:00",
"durationMin": "15",
"zones": "1",
"triggerType": "0",
"remark": null,
"status": "0",
"createTime": "2026-07-14 06:30:00"
}
]
}
说明:响应中
deviceName由服务端关联查询后填充。
4.2 查询设备最新进行中的浇水记录
GET /app/v1/latestWaterLog
请求参数(Query)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
deviceNo |
string |
是 | 设备编号 |
响应:R<Map<String, Object>>
{
"code": 200,
"msg": "操作成功",
"data": {
"startTime": "2026-07-14 08:00:00",
"endTime": "2026-07-14 08:20:00"
}
}
说明:控制器按当前用户、设备编号和状态
1发起查询,并取 ID 最大的一条记录。若无进行中的记录,data为null。时间格式为yyyy-MM-dd HH:mm:ss。当前实现限制:
AppWateringLogServiceImpl.buildQueryWrapper尚未把status加入查询条件,因此现有代码实际可能取到该设备 ID 最大但已结束的记录。客户端依赖“进行中”语义前,应先修复该服务查询条件。
4.3 删除浇水记录
DELETE /app/v1/waterLog/{ids}
路径参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
ids |
long |
是 | 记录 ID,多个用逗号分隔。例:1,2,3 |
示例
DELETE /app/v1/waterLog/1,2,3
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
权限:只能删除当前用户的浇水记录。
五、数据统计
5.1 数据统计
获取当前用户的浇水数据统计汇总。
GET /app/v1/dataStatistics
请求参数:无
响应:R<Map<String, Object>>
{
"code": 200,
"msg": "操作成功",
"data": {
"count": 120,
"monCount": 15,
"weekCount": 4,
"schedule": 80,
"manualNum": 40,
"allTime": 3600,
"averageTime": 30
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
count |
long |
总浇水次数 |
monCount |
long |
本月浇水次数 |
weekCount |
long |
本周浇水次数 |
schedule |
long |
排程触发浇水次数 |
manualNum |
long |
手动触发浇水次数 |
allTime |
long |
总浇水时间(分钟) |
averageTime |
long |
平均每次浇水时间(分钟) |
六、用户管理
6.1 获取用户信息
GET /app/v1/getUserInfo
请求参数:无
响应:R<UserInfoVo>
{
"code": 200,
"msg": "操作成功",
"data": {
"user": {
"userId": 1,
"deptId": 100,
"userName": "admin",
"nickName": "管理员",
"email": "admin@example.com",
"phonenumber": "138****8888",
"sex": "0",
"avatar": "https://oss.example.com/avatar/xxx.png",
"status": "0",
"loginIp": "192.168.1.1",
"loginDate": "2026-07-14 09:00:00",
"remark": null,
"createTime": "2026-01-01 00:00:00"
},
"permissions": ["*:*:*"],
"roles": ["admin"]
}
}
说明:
phonenumber和system:user:edit权限才能看到完整内容)。
6.2 修改用户信息
PUT /app/v1/updataUser
@RepeatSubmit— 防重复提交
请求头
Content-Type: application/json
请求体:SysUserBo(JSON)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
userId |
long |
是 | 用户 ID |
nickName |
string |
否 | 用户昵称(最长 30 字符) |
email |
string |
否 | 邮箱(需符合邮箱格式,最长 50 字符) |
phonenumber |
string |
否 | 手机号(需唯一) |
code |
string |
条件必填 | 修改手机号时使用的短信验证码 |
sex |
string |
否 | 性别:0-男 1-女 2-未知 |
avatar |
string |
否 | 头像 URL |
{
"userId": 1,
"nickName": "新昵称",
"phonenumber": "13900001111",
"code": "123456",
"email": "new@example.com",
"sex": "0"
}
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
校验:手机号需全局唯一;请求中包含
phonenumber时,服务层会校验code短信验证码。
6.3 修改登录密码
PUT /app/v1/updataPassword
@RepeatSubmit— 防重复提交
请求头
Content-Type: application/json
请求体:SysUserVo(JSON)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
oldPassword |
string |
是 | 旧密码(明文,服务端 BCrypt 校验) |
password |
string |
是 | 新密码(明文) |
{
"oldPassword": "OldPass123",
"password": "NewPass456"
}
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
说明:旧密码使用 BCrypt 校验,不匹配则返回
user.password.not.match错误。
6.4 找回密码
通过手机号或邮箱找回密码(加密接口)。
POST /app/v1/retrievePassword
请求头
Content-Type: application/json
请求体(JSON;启用接口加密时发送加密后的 JSON 字符串)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
userName |
string |
是 | 用户名(手机号或邮箱) |
password |
string |
是 | 新密码 |
code |
string |
条件必填 | userName 为手机号时使用的短信验证码 |
{
"userName": "13900001111",
"password": "NewPass456",
"code": "123456"
}
响应:R<Void>
{
"code": 200,
"msg": "操作成功",
"data": null
}
校验逻辑:
- 若
userName为邮箱格式:校验邮箱是否已注册,未注册则报错user.email.not.username。- 若
userName为手机号格式:校验手机号是否已注册及短信验证码,未注册则报错user.mobile.phone.number.not.username。- 当前实现仍从登录 Token 获取
userId,因此该接口不是匿名接口,并且控制器内未校验短信/邮箱验证码。
七、文件上传
7.1 上传图片
上传图片到 OSS 对象存储,仅支持图片类型。
POST /app/v1/uploadImage
请求头
Content-Type: multipart/form-data
请求参数(FormData)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
file |
file |
是 | 图片文件(Content-Type 必须以 image/ 开头) |
当前 Spring Multipart 配置允许单文件最大 100MB、单次请求最大 100MB;实际部署还可能受网关和 OSS 配置限制。
响应:R<SysOssUploadVo>
{
"code": 200,
"msg": "操作成功",
"data": {
"url": "https://oss.example.com/2026/07/14/xxx.png",
"fileName": "screenshot.png",
"ossId": "123456"
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
url |
string |
文件访问 URL |
fileName |
string |
原始文件名 |
ossId |
string |
对象存储记录 ID |
八、版本检查
8.1 检查APP版本更新
GET /app/v1/checkVersion
请求参数(Query)
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
platform |
string |
否 | 平台类型:android(默认)或 ios |
currentVersion |
string |
是 | APP 当前版本号 |
示例
GET /app/v1/checkVersion?platform=android¤tVersion=1.0.2
响应:R<AppVersionCheckVo>
{
"code": 200,
"msg": "操作成功",
"data": {
"platform": "android",
"currentVersion": "1.0.2",
"latestVersion": "1.0.3",
"versionCode": 3,
"updateAvailable": true,
"forceUpdate": false,
"downloadUrl": "https://oss.example.com/app/water-1.0.3.apk",
"releaseNotes": "1. 修复设备绑定问题\n2. 优化排程功能"
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
platform |
string |
平台类型 |
currentVersion |
string |
客户端当前版本 |
latestVersion |
string |
服务端最新版本 |
versionCode |
int |
版本序号(用于排序) |
updateAvailable |
boolean |
是否有可更新版本 |
forceUpdate |
boolean |
是否强制更新 |
downloadUrl |
string |
安装包下载地址 |
releaseNotes |
string |
更新说明 |
当前版本判断采用版本字符串是否完全相等:
currentVersion与latestVersion不相等时,updateAvailable=true,未进行语义化版本大小比较。
九、内部调试接口
9.1 MQTT绑定命令测试
GET /app/v1/test
该接口会直接调用 sendBindDeviceCommand("01"),向固定设备编号 01 下发绑定命令,并返回生成的命令 ID。
响应:R<Void>(运行时实际将命令 ID 作为消息文本返回)
{
"code": 200,
"msg": "生成的命令ID",
"data": null
}
该路由仅用于后端联调,不属于 APP 正式业务接口。生产环境建议删除、关闭或增加管理员权限控制。
附录:数据模型
AppDeviceVo(设备信息)
| 字段 | 类型 | 说明 |
|---|---|---|
deviceNo |
string |
设备编号 |
userId |
long |
用户 ID |
deviceName |
string |
设备名称 |
deviceInitName |
string |
设备初始名称 |
deviceImg |
string |
设备图片 URL |
qrcode |
string |
二维码内容 |
status |
string |
设备状态:1-在线 0-离线 2-到期 3-故障 |
workStatus |
string |
工作状态:0-休息 1-工作 2-初始/未配网 |
powerLevel |
string |
电量百分比 |
powerLevelUpdatatime |
date |
电量更新时间 |
wifiName |
string |
WiFi 名称 |
wifiPassword |
string |
WiFi 密码 |
deviceEm |
string |
设备型号 |
deviceSn |
string |
设备序列号 |
fwVer |
string |
固件版本 |
macAddress |
string |
MAC 地址 |
nickName |
string |
用户昵称 |
expirationTime |
date |
到期时间 |
AppScheduleVo(排程信息)
| 字段 | 类型 | 说明 |
|---|---|---|
id |
long |
排程 ID |
userId |
long |
用户 ID |
name |
string |
排程名称 |
status |
string |
状态:0-关闭 1-开启 |
details |
array |
排程详情列表;新增和详情接口会返回,列表接口通常为空 |
deviceNos |
array |
已绑定设备列表(仅详情接口返回) |
AppScheduleDetail(排程详情)
| 字段 | 类型 | 说明 |
|---|---|---|
id |
long |
详情 ID |
weekday |
int |
星期几:1-周一 ~ 7-周日 |
timeData |
array |
时间段列表 |
triggerType |
string |
触发类型:0-排程 1-手动 |
status |
string |
状态:0-关闭 1-开启 |
TimeSlot(时间段)
| 字段 | 类型 | 说明 |
|---|---|---|
startTime |
string |
开始时间(格式 HH:mm) |
durationMin |
int |
持续时长(分钟) |
AppWateringLogVo(浇水记录)
| 字段 | 类型 | 说明 |
|---|---|---|
id |
long |
记录 ID |
userId |
long |
用户 ID |
deviceNo |
string |
设备编号 |
deviceName |
string |
设备名称 |
commandId |
string |
命令 ID |
scheduleId |
long |
关联排程 ID |
startTime |
date |
开始时间 |
endTime |
date |
结束时间 |
durationMin |
string |
持续时间(分钟) |
zones |
string |
浇水区域 |
triggerType |
string |
触发类型:0-排程 1-手动 |
remark |
string |
备注 |
status |
string |
状态:0-已结束 1-进行中 |
createTime |
date |
创建时间 |
枚举值速查
| 枚举 | 值 | 说明 |
|---|---|---|
设备状态 status |
1 |
在线 |
0 |
离线 | |
2 |
到期 | |
3 |
故障 | |
工作状态 workStatus |
0 |
休息 |
1 |
工作 | |
2 |
初始/未配网 | |
排程状态 status |
0 |
关闭 |
1 |
开启 | |
触发类型 triggerType |
0 |
排程触发 |
1 |
手动触发 | |
浇水记录状态 status |
0 |
已结束 |
1 |
进行中 | |
星期 weekday |
1~7 |
周一~周日 |
用户性别 sex |
0 |
男 |
1 |
女 | |
2 |
未知 | |
强制更新 forceUpdate |
0 |
否 |
1 |
是 |
联调提示:
/app/v1/**业务接口及明确标注“需要登录”的认证接口,请求头需携带Authorization: Bearer <token>;登录、注册、忘记密码、租户列表和普通验证码接口免登录。- 当前
api-decrypt.enabled=false时发送普通 JSON;启用后,标注@ApiEncrypt的接口(绑定设备状态检查、绑定设备、找回密码)需按约定加密请求体并携带encrypt-key。- 标注
@RepeatSubmit的接口,短时间内重复提交会被拦截,前端应在收到响应前禁用提交按钮。- 删除类接口的路径参数支持逗号分隔多个 ID。
- 分页接口排序固定为
createTime desc,前端无需传排序参数。- 时间字段统一使用
yyyy-MM-dd HH:mm:ss格式,时间段startTime使用HH:mm格式。