mirror of
https://github.com/xinnan-tech/xiaozhi-esp32-server.git
synced 2026-07-21 22:53:56 +08:00
Merge pull request #3195 from xinnan-tech/fix-timezone-unify
fix:修复时区导致的设备状态不同步的问题
This commit is contained in:
+4
-3
@@ -29,6 +29,7 @@ import xiaozhi.modules.device.dto.DeviceUnBindDTO;
|
|||||||
import xiaozhi.modules.device.dto.DeviceUpdateDTO;
|
import xiaozhi.modules.device.dto.DeviceUpdateDTO;
|
||||||
import xiaozhi.modules.device.entity.DeviceEntity;
|
import xiaozhi.modules.device.entity.DeviceEntity;
|
||||||
import xiaozhi.modules.device.service.DeviceService;
|
import xiaozhi.modules.device.service.DeviceService;
|
||||||
|
import xiaozhi.modules.device.vo.UserShowDeviceListVO;
|
||||||
import xiaozhi.modules.security.user.SecurityUser;
|
import xiaozhi.modules.security.user.SecurityUser;
|
||||||
import xiaozhi.modules.sys.service.SysParamsService;
|
import xiaozhi.modules.sys.service.SysParamsService;
|
||||||
|
|
||||||
@@ -78,10 +79,10 @@ public class DeviceController {
|
|||||||
@GetMapping("/bind/{agentId}")
|
@GetMapping("/bind/{agentId}")
|
||||||
@Operation(summary = "获取已绑定设备")
|
@Operation(summary = "获取已绑定设备")
|
||||||
@RequiresPermissions("sys:role:normal")
|
@RequiresPermissions("sys:role:normal")
|
||||||
public Result<List<DeviceEntity>> getUserDevices(@PathVariable String agentId) {
|
public Result<List<UserShowDeviceListVO>> getUserDevices(@PathVariable String agentId) {
|
||||||
UserDetail user = SecurityUser.getUser();
|
UserDetail user = SecurityUser.getUser();
|
||||||
List<DeviceEntity> devices = deviceService.getUserDevices(user.getId(), agentId);
|
List<UserShowDeviceListVO> devices = deviceService.getUserDeviceList(user.getId(), agentId);
|
||||||
return new Result<List<DeviceEntity>>().ok(devices);
|
return new Result<List<UserShowDeviceListVO>>().ok(devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping("/bind/{agentId}")
|
@PostMapping("/bind/{agentId}")
|
||||||
|
|||||||
@@ -30,6 +30,11 @@ public interface DeviceService extends BaseService<DeviceEntity> {
|
|||||||
*/
|
*/
|
||||||
List<DeviceEntity> getUserDevices(Long userId, String agentId);
|
List<DeviceEntity> getUserDevices(Long userId, String agentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户指定智能体的设备列表(带时区处理),
|
||||||
|
*/
|
||||||
|
List<UserShowDeviceListVO> getUserDeviceList(Long userId, String agentId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解绑设备
|
* 解绑设备
|
||||||
*/
|
*/
|
||||||
|
|||||||
+20
@@ -298,6 +298,21 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
|
|||||||
return baseDao.selectList(wrapper);
|
return baseDao.selectList(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<UserShowDeviceListVO> getUserDeviceList(Long userId, String agentId) {
|
||||||
|
List<DeviceEntity> devices = getUserDevices(userId, agentId);
|
||||||
|
return devices.stream().map(device -> {
|
||||||
|
UserShowDeviceListVO vo = ConvertUtils.sourceToTarget(device, UserShowDeviceListVO.class);
|
||||||
|
vo.setDeviceType(device.getBoard());
|
||||||
|
vo.setBoard(device.getBoard());
|
||||||
|
// 设置UTC时间戳供前端使用时区转换
|
||||||
|
if (device.getLastConnectedAt() != null) {
|
||||||
|
vo.setLastConnectedAtTimestamp(device.getLastConnectedAt().getTime());
|
||||||
|
}
|
||||||
|
return vo;
|
||||||
|
}).toList();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unbindDevice(Long userId, String deviceId) {
|
public void unbindDevice(Long userId, String deviceId) {
|
||||||
// 先查询设备信息,获取agentId
|
// 先查询设备信息,获取agentId
|
||||||
@@ -356,6 +371,11 @@ public class DeviceServiceImpl extends BaseServiceImpl<DeviceDao, DeviceEntity>
|
|||||||
sysUserUtilService.assignUsername(device.getUserId(),
|
sysUserUtilService.assignUsername(device.getUserId(),
|
||||||
vo::setBindUserName);
|
vo::setBindUserName);
|
||||||
vo.setDeviceType(device.getBoard());
|
vo.setDeviceType(device.getBoard());
|
||||||
|
vo.setBoard(device.getBoard());
|
||||||
|
// 设置UTC时间戳供前端使用时区转换
|
||||||
|
if (device.getLastConnectedAt() != null) {
|
||||||
|
vo.setLastConnectedAtTimestamp(device.getLastConnectedAt().getTime());
|
||||||
|
}
|
||||||
return vo;
|
return vo;
|
||||||
}).toList();
|
}).toList();
|
||||||
// 计算页数
|
// 计算页数
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package xiaozhi.modules.device.vo;
|
package xiaozhi.modules.device.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Schema(description = "用户显示设备列表VO")
|
@Schema(description = "用户显示设备列表VO")
|
||||||
public class UserShowDeviceListVO {
|
public class UserShowDeviceListVO {
|
||||||
@@ -16,6 +19,9 @@ public class UserShowDeviceListVO {
|
|||||||
@Schema(description = "设备型号")
|
@Schema(description = "设备型号")
|
||||||
private String deviceType;
|
private String deviceType;
|
||||||
|
|
||||||
|
@Schema(description = "设备型号(board)")
|
||||||
|
private String board;
|
||||||
|
|
||||||
@Schema(description = "设备唯一标识符")
|
@Schema(description = "设备唯一标识符")
|
||||||
private String id;
|
private String id;
|
||||||
|
|
||||||
@@ -28,4 +34,11 @@ public class UserShowDeviceListVO {
|
|||||||
@Schema(description = "最近对话时间")
|
@Schema(description = "最近对话时间")
|
||||||
private String recentChatTime;
|
private String recentChatTime;
|
||||||
|
|
||||||
|
@Schema(description = "最后连接时间(UTC毫秒)")
|
||||||
|
private Long lastConnectedAtTimestamp;
|
||||||
|
|
||||||
|
@Schema(description = "绑定时间")
|
||||||
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC")
|
||||||
|
private Date createDate;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
#MySQL
|
#MySQL
|
||||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
url: jdbc:mysql://127.0.0.1:3306/xiaozhi_esp32_server?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true
|
url: jdbc:mysql://127.0.0.1:3306/xiaozhi_esp32_server?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC&nullCatalogMeansCurrent=true
|
||||||
username: root
|
username: root
|
||||||
password: 123456
|
password: 123456
|
||||||
initial-size: 10
|
initial-size: 10
|
||||||
|
|||||||
@@ -373,7 +373,9 @@ export default {
|
|||||||
firmwareVersion: device.appVersion,
|
firmwareVersion: device.appVersion,
|
||||||
macAddress: device.macAddress,
|
macAddress: device.macAddress,
|
||||||
bindTime: device.createDate,
|
bindTime: device.createDate,
|
||||||
lastConversation: device.lastConnectedAt,
|
lastConversation: device.lastConnectedAtTimestamp
|
||||||
|
? this.formatRelativeTime(device.lastConnectedAtTimestamp)
|
||||||
|
: '-',
|
||||||
remark: device.alias,
|
remark: device.alias,
|
||||||
_originalRemark: device.alias,
|
_originalRemark: device.alias,
|
||||||
isEdit: false,
|
isEdit: false,
|
||||||
@@ -489,6 +491,14 @@ export default {
|
|||||||
const version = row.firmwareVersion.replace(/\./g, '');
|
const version = row.firmwareVersion.replace(/\./g, '');
|
||||||
return Number(version) >= 200;
|
return Number(version) >= 200;
|
||||||
},
|
},
|
||||||
|
formatRelativeTime(timestamp) {
|
||||||
|
if (!timestamp) return '-';
|
||||||
|
const ts = Number(timestamp);
|
||||||
|
if (isNaN(ts)) return '-';
|
||||||
|
const date = new Date(ts);
|
||||||
|
if (isNaN(date.getTime())) return '-';
|
||||||
|
return date.toLocaleString(); // 自动适配本地时区
|
||||||
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ services:
|
|||||||
security_opt:
|
security_opt:
|
||||||
- seccomp:unconfined
|
- seccomp:unconfined
|
||||||
environment:
|
environment:
|
||||||
- TZ=Asia/Shanghai
|
- TZ=UTC
|
||||||
ports:
|
ports:
|
||||||
# ws服务端
|
# ws服务端
|
||||||
- "8000:8000"
|
- "8000:8000"
|
||||||
|
|||||||
Reference in New Issue
Block a user