diff --git a/README.md b/README.md
index 57c8241a..652b97bd 100644
--- a/README.md
+++ b/README.md
@@ -232,14 +232,9 @@ server:
本项目支持以下三种部署方式,您可根据实际需求选择。
-本项目的文档主要是`文字版本`的教程,如果你想要`视频版本`
-的教程,您可以学习一下[这个大佬的手把手教程](https://www.bilibili.com/video/BV1gePuejEvT)。
-
-如果你能把`文字版本的教程`和`视频版本的教程`结合起来一起看,可以让你更快上手。
-
1. [Docker 快速部署](./docs/Deployment.md)
-适合快速体验的普通用户,不需过多环境配置。缺点是,拉取镜像有点慢。
+适合快速体验的普通用户,不需过多环境配置。缺点是,拉取镜像有点慢。视频教程可参考[美女大佬教你Docker部署](https://www.bilibili.com/video/BV1RNQnYDE5t)
2. [借助 Docker 环境运行部署](./docs/Deployment.md#%E6%96%B9%E5%BC%8F%E4%BA%8C%E5%80%9F%E5%8A%A9docker%E7%8E%AF%E5%A2%83%E8%BF%90%E8%A1%8C%E9%83%A8%E7%BD%B2)
@@ -249,7 +244,7 @@ server:
适合熟悉`Conda` 环境或希望从零搭建运行环境的用户。
-对于对响应速度要求较高的场景,推荐使用本地源码运行方式以降低额外开销。
+对于对响应速度要求较高的场景,推荐使用本地源码运行方式以降低额外开销。视频教程可参考[帅哥大佬教你源码部署](https://www.bilibili.com/video/BV1GvQWYZEd2)
### 二、[固件编译](./docs/firmware-build.md)
@@ -378,4 +373,4 @@ VAD:
-
\ No newline at end of file
+
diff --git a/docs/contributor_open_letter.md b/docs/contributor_open_letter.md
index 1be3da28..1a46adbd 100644
--- a/docs/contributor_open_letter.md
+++ b/docs/contributor_open_letter.md
@@ -14,11 +14,11 @@
## 加入我们
-我们热忱欢迎志同道合的朋友加入,共同为项目贡献力量。参与方式如下:
+我们热忱欢迎志同道合的朋友加入,共同为项目贡献力量。您可在[这个链接](https://github.com/users/xinnan-tech/projects/3)查看我们近期要实现的功能,功能列表中还没指派相关人员处理的,正是急需您的参与。参与方式如下:
### 1、成为普通贡献者
-Fork 项目,提交 PR,由开发者审核后合入主分支。
+Fork 项目,,提交 PR,由开发者审核后合入主分支。
### 2、成为开发者
@@ -32,20 +32,9 @@ Fork 项目,提交 PR,由开发者审核后合入主分支。
2. **提交 PR 审核**
功能开发完成后,请在 GitHub 上提交 PR,由其他开发者审核,审核通过后合并入主分支。
-## 功能点的来源
-
-- **创新的点子与功能**
- 你的每一个灵感都可能成为项目的突破点,欢迎大胆提出前沿的创意与功能建议。
-
-- **代码优化**
- 如果你发现代码中存在改进的空间,欢迎提交优化方案,让我们的代码更加高效、易读。
-
-- **解决 Issues 问题**
- Issues 中有很多问题需要解决,我们一同完善、打造产品。
-
亲爱的开发者们,
每一次提交、每一份建议,都是对我们共同梦想的加持。每一代人有每一代人的使命,让我们共同书写智能生活的新篇章!
期待与你携手前行,共创未来。
-John,2025.3.11,广州
\ No newline at end of file
+John,2025.3.11,广州
diff --git a/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java b/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java
index e2e5de5d..e5365b3c 100644
--- a/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java
+++ b/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java
@@ -42,4 +42,5 @@ public interface ErrorCode {
int PASSWORD_LENGTH_ERROR = 10030;
int PASSWORD_WEAK_ERROR = 10031;
int DEL_MYSELF_ERROR = 10032;
+ int DEVICE_CAPTCHA_ERROR = 10033;
}
diff --git a/main/manager-api/src/main/java/xiaozhi/common/redis/RedisKeys.java b/main/manager-api/src/main/java/xiaozhi/common/redis/RedisKeys.java
index 0c594059..21121fd7 100644
--- a/main/manager-api/src/main/java/xiaozhi/common/redis/RedisKeys.java
+++ b/main/manager-api/src/main/java/xiaozhi/common/redis/RedisKeys.java
@@ -21,60 +21,9 @@ public class RedisKeys {
}
/**
- * 登录用户Key
+ * 未注册设备验证码Key
*/
- public static String getSecurityUserKey(Long id) {
- return "sys:security:user:" + id;
+ public static String getDeviceCaptchaKey(String captcha) {
+ return "sys:device:captcha:" + captcha;
}
-
- /**
- * 系统日志Key
- */
- public static String getSysLogKey() {
- return "sys:log";
- }
-
- /**
- * 系统资源Key
- */
- public static String getSysResourceKey() {
- return "sys:resource";
- }
-
- /**
- * 用户菜单导航Key
- */
- public static String getUserMenuNavKey(Long userId) {
- return "sys:user:nav:" + userId;
- }
-
- /**
- * 用户权限标识Key
- */
- public static String getUserPermissionsKey(Long userId) {
- return "sys:user:permissions:" + userId;
- }
-
- /**
- * 用户登陆错误次数
- *
- * @param username
- * @return
- */
- public static String getUserLoginErrorCountKey(String username) {
- return "sys:user:login:error:" + username;
- }
-
- public static String getUserInfoKey(Long userId) {
- return "sys:user:" + userId;
- }
-
- public static String getDataScopeListKey(Long userId) {
- return "sys:user:data:scope:" + userId;
- }
-
- public static String getSysUserName(Long id) {
- return "sys:user:name" + id;
- }
-
}
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/controller/DeviceController.java b/main/manager-api/src/main/java/xiaozhi/modules/device/controller/DeviceController.java
new file mode 100644
index 00000000..1974689c
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/device/controller/DeviceController.java
@@ -0,0 +1,83 @@
+package xiaozhi.modules.device.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.AllArgsConstructor;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.web.bind.annotation.*;
+import xiaozhi.common.constant.Constant;
+import xiaozhi.common.exception.ErrorCode;
+import xiaozhi.common.page.PageData;
+import xiaozhi.common.redis.RedisKeys;
+import xiaozhi.common.redis.RedisUtils;
+import xiaozhi.common.user.UserDetail;
+import xiaozhi.common.utils.JsonUtils;
+import xiaozhi.common.utils.Result;
+import xiaozhi.modules.device.dto.DeviceHeaderDTO;
+import xiaozhi.modules.device.dto.DeviceUnBindDTO;
+import xiaozhi.modules.device.entity.DeviceEntity;
+import xiaozhi.modules.device.service.DeviceService;
+import xiaozhi.modules.security.user.SecurityUser;
+
+import java.util.List;
+import java.util.Map;
+
+@AllArgsConstructor
+@RestController
+@RequestMapping("/device")
+@Tag(name = "设备管理")
+
+public class DeviceController {
+ private final DeviceService deviceService;
+ private final RedisUtils redisUtils;
+
+
+ @PostMapping("/bind/{deviceCode}")
+ @Operation(summary = "绑定设备")
+ @RequiresPermissions("sys:role:normal")
+ public Result bindDevice(@PathVariable String deviceCode) {
+ UserDetail user = SecurityUser.getUser();
+
+ String deviceHeaders = (String) redisUtils.get(RedisKeys.getDeviceCaptchaKey(deviceCode));
+ if (StringUtils.isBlank(deviceHeaders)) {
+ return new Result().error(ErrorCode.DEVICE_CAPTCHA_ERROR);
+ }
+ DeviceHeaderDTO deviceHeader = JsonUtils.parseObject(deviceHeaders.getBytes(), DeviceHeaderDTO.class);
+ DeviceEntity device = deviceService.bindDevice(user.getId(), deviceHeader);
+ return new Result().ok(device);
+ }
+
+ @GetMapping("/bind")
+ @Operation(summary = "获取已绑定设备")
+ @RequiresPermissions("sys:role:normal")
+ public Result> getUserDevices() {
+ UserDetail user = SecurityUser.getUser();
+ List devices = deviceService.getUserDevices(user.getId());
+ return new Result>().ok(devices);
+ }
+
+ @PostMapping("/unbind")
+ @Operation(summary = "解绑设备")
+ @RequiresPermissions("sys:role:normal")
+ public Result unbindDevice(@RequestBody DeviceUnBindDTO unDeviveBind) {
+ UserDetail user = SecurityUser.getUser();
+ deviceService.unbindDevice(user.getId(), unDeviveBind.getDeviceId());
+ return new Result();
+ }
+
+ @GetMapping("/all")
+ @Operation(summary = "设备列表(管理员)")
+ @RequiresPermissions("sys:role:superAdmin")
+ @Parameters({
+ @Parameter(name = Constant.PAGE, description = "当前页码,从1开始", required = true),
+ @Parameter(name = Constant.LIMIT, description = "每页显示记录数", required = true),
+ })
+ public Result> adminDeviceList(
+ @Parameter(hidden = true) @RequestParam Map params) {
+ PageData page = deviceService.adminDeviceList(params);
+ return new Result>().ok(page);
+ }
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/dao/DeviceDao.java b/main/manager-api/src/main/java/xiaozhi/modules/device/dao/DeviceDao.java
new file mode 100644
index 00000000..9e4a8cd4
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/device/dao/DeviceDao.java
@@ -0,0 +1,9 @@
+package xiaozhi.modules.device.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import xiaozhi.modules.device.entity.DeviceEntity;
+
+@Mapper
+public interface DeviceDao extends BaseMapper {
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceHeaderDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceHeaderDTO.java
new file mode 100644
index 00000000..83327fef
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceHeaderDTO.java
@@ -0,0 +1,19 @@
+package xiaozhi.modules.device.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Data
+@Schema(description = "设备连接头信息")
+public class DeviceHeaderDTO {
+
+ @Schema(description = "设备ID")
+ private String deviceId;
+
+ @Schema(description = "协议版本号")
+ private Long protocolVersion;
+
+ @Schema(description = "认证信息")
+ private String authorization;
+
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceUnBindDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceUnBindDTO.java
new file mode 100644
index 00000000..830a51ae
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceUnBindDTO.java
@@ -0,0 +1,19 @@
+package xiaozhi.modules.device.dto;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 设备解绑表单
+ */
+@Data
+@Schema(description = "设备解绑表单")
+public class DeviceUnBindDTO implements Serializable {
+
+ @Schema(description = "设备ID")
+ @NotBlank(message = "设备ID不能为空")
+ private Long deviceId;
+
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/entity/DeviceEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/device/entity/DeviceEntity.java
new file mode 100644
index 00000000..bc1a7e88
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/device/entity/DeviceEntity.java
@@ -0,0 +1,57 @@
+package xiaozhi.modules.device.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+@TableName("ai_device")
+@Schema(description = "设备信息")
+public class DeviceEntity {
+ @Schema(description = "设备ID")
+ private Long id;
+
+ @Schema(description = "关联用户ID")
+ private Long userId;
+
+ @Schema(description = "MAC地址")
+ private String macAddress;
+
+ @Schema(description = "最后连接时间")
+ private Date lastConnectedAt;
+
+ @Schema(description = "自动更新开关(0关闭/1开启)")
+ private Integer autoUpdate;
+
+ @Schema(description = "设备硬件型号")
+ private String board;
+
+ @Schema(description = "设备别名")
+ private String alias;
+
+ @Schema(description = "智能体编码")
+ private String agentCode;
+
+ @Schema(description = "智能体ID")
+ private Long agentId;
+
+ @Schema(description = "固件版本号")
+ private String appVersion;
+
+ @Schema(description = "排序")
+ private Integer sort;
+
+ @Schema(description = "创建者")
+ private Long creator;
+
+ @Schema(description = "创建时间")
+ private Date createDate;
+
+ @Schema(description = "更新者")
+ private Long updater;
+
+ @Schema(description = "更新时间")
+ private Date updateDate;
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/service/DeviceService.java b/main/manager-api/src/main/java/xiaozhi/modules/device/service/DeviceService.java
new file mode 100644
index 00000000..16ad44fe
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/device/service/DeviceService.java
@@ -0,0 +1,18 @@
+package xiaozhi.modules.device.service;
+
+import xiaozhi.common.page.PageData;
+import xiaozhi.modules.device.dto.DeviceHeaderDTO;
+import xiaozhi.modules.device.entity.DeviceEntity;
+
+import java.util.List;
+import java.util.Map;
+
+public interface DeviceService {
+ DeviceEntity bindDevice(Long userId, DeviceHeaderDTO deviceHeader);
+
+ List getUserDevices(Long userId);
+
+ void unbindDevice(Long userId, Long deviceId);
+
+ PageData adminDeviceList(Map params);
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java
new file mode 100644
index 00000000..279a9f2e
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/device/service/impl/DeviceServiceImpl.java
@@ -0,0 +1,57 @@
+package xiaozhi.modules.device.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.springframework.stereotype.Service;
+import xiaozhi.common.page.PageData;
+import xiaozhi.common.service.impl.BaseServiceImpl;
+import xiaozhi.modules.device.dao.DeviceDao;
+import xiaozhi.modules.device.dto.DeviceHeaderDTO;
+import xiaozhi.modules.device.entity.DeviceEntity;
+import xiaozhi.modules.device.service.DeviceService;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+@Service
+public class DeviceServiceImpl extends BaseServiceImpl implements DeviceService {
+ private final DeviceDao deviceDao;
+
+ // 添加构造函数来初始化 deviceMapper
+ public DeviceServiceImpl(DeviceDao deviceDao) {
+ this.deviceDao = deviceDao;
+ }
+
+ @Override
+ public DeviceEntity bindDevice(Long userId, DeviceHeaderDTO deviceHeader) {
+ DeviceEntity device = new DeviceEntity();
+ device.setUserId(userId);
+ device.setMacAddress(deviceHeader.getDeviceId());
+ device.setCreateDate(new Date());
+ deviceDao.insert(device);
+ return device;
+ }
+
+ @Override
+ public List getUserDevices(Long userId) {
+ QueryWrapper wrapper = new QueryWrapper<>();
+ wrapper.eq("user_id", userId);
+ return deviceDao.selectList(wrapper);
+ }
+
+ @Override
+ public void unbindDevice(Long userId, Long deviceId) {
+ deviceDao.deleteById(deviceId);
+ }
+
+ @Override
+ public PageData adminDeviceList(Map params) {
+ IPage page = deviceDao.selectPage(
+ getPage(params, "sort", true),
+ new QueryWrapper<>()
+ );
+ return new PageData<>(page.getRecords(), page.getTotal());
+ }
+
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/config/ShiroConfig.java b/main/manager-api/src/main/java/xiaozhi/modules/security/config/ShiroConfig.java
index 29f6b706..f770c79f 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/security/config/ShiroConfig.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/security/config/ShiroConfig.java
@@ -61,14 +61,9 @@ public class ShiroConfig {
Map filterMap = new LinkedHashMap<>();
filterMap.put("/webjars/**", "anon");
filterMap.put("/druid/**", "anon");
- filterMap.put("/login", "anon");
- filterMap.put("/publicKey", "anon");
filterMap.put("/v3/api-docs/**", "anon");
filterMap.put("/doc.html", "anon");
- filterMap.put("/sys/oss/download/**", "anon");
- filterMap.put("/captcha", "anon");
filterMap.put("/favicon.ico", "anon");
- filterMap.put("/mobile/**", "anon");
filterMap.put("/user/**", "anon");
filterMap.put("/**", "oauth2");
shiroFilter.setFilterChainDefinitionMap(filterMap);
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Realm.java b/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Realm.java
index 933724a1..3f8a3eeb 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Realm.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Realm.java
@@ -1,12 +1,5 @@
package xiaozhi.modules.security.oauth2;
-import xiaozhi.common.exception.ErrorCode;
-import xiaozhi.common.user.UserDetail;
-import xiaozhi.common.utils.ConvertUtils;
-import xiaozhi.common.utils.MessageUtils;
-import xiaozhi.modules.security.entity.SysUserTokenEntity;
-import xiaozhi.modules.security.service.ShiroService;
-import xiaozhi.modules.sys.entity.SysUserEntity;
import jakarta.annotation.Resource;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
@@ -15,8 +8,15 @@ import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
+import xiaozhi.common.exception.ErrorCode;
+import xiaozhi.common.user.UserDetail;
+import xiaozhi.common.utils.ConvertUtils;
+import xiaozhi.common.utils.MessageUtils;
+import xiaozhi.modules.security.entity.SysUserTokenEntity;
+import xiaozhi.modules.security.service.ShiroService;
+import xiaozhi.modules.sys.entity.SysUserEntity;
+import xiaozhi.modules.sys.enums.SuperAdminEnum;
-import java.util.List;
import java.util.Set;
/**
@@ -45,6 +45,13 @@ public class Oauth2Realm extends AuthorizingRealm {
//用户权限列表
Set permsSet = shiroService.getUserPermissions(user);
+ if (user.getSuperAdmin() == SuperAdminEnum.YES.value()) {
+ permsSet.add("sys:role:superAdmin");
+ permsSet.add("sys:role:normal");
+ } else {
+ permsSet.add("sys:role:normal");
+ }
+
SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
info.setStringPermissions(permsSet);
return info;
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sys/controller/SysUserController.java b/main/manager-api/src/main/java/xiaozhi/modules/sys/controller/SysUserController.java
index 2f030fff..9da7c62b 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/sys/controller/SysUserController.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/sys/controller/SysUserController.java
@@ -1,34 +1,9 @@
package xiaozhi.modules.sys.controller;
-import xiaozhi.common.annotation.LogOperation;
-import xiaozhi.common.constant.Constant;
-import xiaozhi.common.exception.ErrorCode;
-import xiaozhi.common.exception.RenException;
-import xiaozhi.common.page.PageData;
-import xiaozhi.common.user.UserDetail;
-import xiaozhi.common.utils.ConvertUtils;
-import xiaozhi.common.utils.Result;
-import xiaozhi.common.validator.AssertUtils;
-import xiaozhi.common.validator.ValidatorUtils;
-import xiaozhi.common.validator.group.AddGroup;
-import xiaozhi.common.validator.group.DefaultGroup;
-import xiaozhi.common.validator.group.UpdateGroup;
-import xiaozhi.modules.security.password.PasswordUtils;
-import xiaozhi.modules.security.user.SecurityUser;
-import xiaozhi.modules.sys.dto.PasswordDTO;
-import xiaozhi.modules.sys.dto.SysUserDTO;
-import xiaozhi.modules.sys.service.SysUserService;
-import io.swagger.v3.oas.annotations.Operation;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
-import org.apache.shiro.authz.annotation.RequiresPermissions;
-import org.springframework.web.bind.annotation.*;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
/**
* 用户管理
@@ -38,119 +13,5 @@ import java.util.Map;
@RequestMapping("/sys/user")
@Tag(name = "用户管理")
public class SysUserController {
- private final SysUserService sysUserService;
- @GetMapping("page")
- @Operation(summary = "分页")
- @Parameters({
- @Parameter(name = Constant.PAGE, description = "当前页码,从1开始", required = true),
- @Parameter(name = Constant.LIMIT, description = "每页显示记录数", required = true),
- @Parameter(name = Constant.ORDER_FIELD, description = "排序字段"),
- @Parameter(name = Constant.ORDER, description = "排序方式,可选值(asc、desc)"),
- @Parameter(name = "username", description = "用户名"),
- @Parameter(name = "gender", description = "性别"),
- @Parameter(name = "deptId", description = "部门ID")
- })
- @RequiresPermissions("sys:user:page")
- public Result> page(@Parameter(hidden = true) @RequestParam Map params) {
- PageData page = sysUserService.page(params);
-
- return new Result>().ok(page);
- }
-
- @GetMapping("{id}")
- @Operation(summary = "信息")
- @RequiresPermissions("sys:user:info")
- public Result get(@PathVariable("id") Long id) {
- SysUserDTO data = sysUserService.get(id);
- return new Result().ok(data);
- }
-
- @GetMapping("info")
- @Operation(summary = "登录用户信息")
- public Result info() {
- SysUserDTO data = ConvertUtils.sourceToTarget(SecurityUser.getUser(), SysUserDTO.class);
- return new Result().ok(data);
- }
-
- @PutMapping("password")
- @Operation(summary = "修改密码")
- @LogOperation("修改密码")
- public Result password(@RequestBody PasswordDTO dto) {
- //效验数据
- ValidatorUtils.validateEntity(dto);
- String newPassword = dto.getNewPassword();
- String password = dto.getPassword();
-
- //密码的强度
- if (newPassword == null || newPassword.length() < 8) {
- return new Result().error(ErrorCode.PASSWORD_LENGTH_ERROR);
- }
- if (!sysUserService.isStrongPassword(newPassword)) {
- return new Result().error(ErrorCode.PASSWORD_WEAK_ERROR);
- }
- UserDetail user = SecurityUser.getUser();
- //原密码不正确
- if (!PasswordUtils.matches(dto.getPassword(), user.getPassword())) {
- return new Result().error(ErrorCode.PASSWORD_ERROR);
- }
-
- sysUserService.updatePassword(user.getId(), dto.getNewPassword());
-
- return new Result();
- }
-
- @PostMapping
- @Operation(summary = "保存")
- @LogOperation("保存")
- @RequiresPermissions("sys:user:save")
- public Result save(@RequestBody SysUserDTO dto) {
- //效验数据
- ValidatorUtils.validateEntity(dto, AddGroup.class, DefaultGroup.class);
-
- sysUserService.save(dto);
-
- return new Result();
- }
-
- @PutMapping
- @Operation(summary = "修改")
- @LogOperation("修改")
- @RequiresPermissions("sys:user:update")
- public Result update(@RequestBody SysUserDTO dto) {
- //效验数据
- ValidatorUtils.validateEntity(dto, UpdateGroup.class, DefaultGroup.class);
-
- sysUserService.update(dto);
-
- return new Result();
- }
-
- @PutMapping("app")
- @Operation(summary = "修改")
- @LogOperation("修改")
- @RequiresPermissions("sys:user:update")
- public Result updateUserInfo(@RequestBody SysUserDTO dto) {
- sysUserService.updateUserInfo(dto);
-
- return new Result();
- }
-
- @DeleteMapping
- @Operation(summary = "删除")
- @LogOperation("删除")
- @RequiresPermissions("sys:user:delete")
- public Result delete(@RequestBody Long[] ids) {
- //效验数据
- AssertUtils.isArrayEmpty(ids, "id");
-
- List idList = Arrays.asList(ids);
- if (idList.contains(SecurityUser.getUserId())) {
- throw new RenException(ErrorCode.DEL_MYSELF_ERROR);
- }
-
- sysUserService.deleteBatchIds(idList);
-
- return new Result();
- }
}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sys/dao/SysUserDao.java b/main/manager-api/src/main/java/xiaozhi/modules/sys/dao/SysUserDao.java
index 08c48a4d..339e522a 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/sys/dao/SysUserDao.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/sys/dao/SysUserDao.java
@@ -1,12 +1,8 @@
package xiaozhi.modules.sys.dao;
+import org.apache.ibatis.annotations.Mapper;
import xiaozhi.common.dao.BaseDao;
import xiaozhi.modules.sys.entity.SysUserEntity;
-import org.apache.ibatis.annotations.Mapper;
-import org.apache.ibatis.annotations.Param;
-
-import java.util.List;
-import java.util.Map;
/**
* 系统用户
@@ -14,21 +10,4 @@ import java.util.Map;
@Mapper
public interface SysUserDao extends BaseDao {
- List getList(Map params);
-
- SysUserEntity getById(Long id);
-
- SysUserEntity getByUsername(String username);
-
- int updatePassword(@Param("id") Long id, @Param("newPassword") String newPassword);
-
- /**
- * 根据部门ID,查询用户数
- */
- int getCountByDeptId(Long deptId);
-
- /**
- * 根据部门ID,查询用户ID列表
- */
- List getUserIdListByDeptId(List deptIdList);
}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sys/entity/SysUserEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/sys/entity/SysUserEntity.java
index a5d14a71..764ee199 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/sys/entity/SysUserEntity.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/sys/entity/SysUserEntity.java
@@ -24,30 +24,6 @@ public class SysUserEntity extends BaseEntity {
* 密码
*/
private String password;
- /**
- * 姓名
- */
- private String realName;
- /**
- * 头像
- */
- private String headUrl;
- /**
- * 性别 0:男 1:女 2:保密
- */
- private Integer gender;
- /**
- * 邮箱
- */
- private String email;
- /**
- * 手机号
- */
- private String mobile;
- /**
- * 部门ID
- */
- private Long deptId;
/**
* 超级管理员 0:否 1:是
*/
@@ -56,6 +32,11 @@ public class SysUserEntity extends BaseEntity {
* 状态 0:停用 1:正常
*/
private Integer status;
+ /**
+ * 更新者
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private Long create_date;
/**
* 更新者
*/
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sys/service/SysUserService.java b/main/manager-api/src/main/java/xiaozhi/modules/sys/service/SysUserService.java
index 288c4cc0..f92de360 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/sys/service/SysUserService.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/sys/service/SysUserService.java
@@ -1,67 +1,19 @@
package xiaozhi.modules.sys.service;
-import xiaozhi.common.page.PageData;
import xiaozhi.common.service.BaseService;
import xiaozhi.modules.sys.dto.SysUserDTO;
import xiaozhi.modules.sys.entity.SysUserEntity;
-import java.util.List;
-import java.util.Map;
-
/**
* 系统用户
*/
public interface SysUserService extends BaseService {
- PageData page(Map params);
-
- List list(Map params);
-
- SysUserDTO get(Long id);
-
SysUserDTO getByUsername(String username);
void save(SysUserDTO dto);
- void update(SysUserDTO dto);
-
- void updateUserInfo(SysUserDTO dto);
-
void delete(Long[] ids);
- /**
- * 修改密码
- *
- * @param id 用户ID
- * @param newPassword 新密码
- */
- void updatePassword(Long id, String newPassword);
-
- /**
- * 根据部门ID,查询用户数
- */
- int getCountByDeptId(Long deptId);
-
- /**
- * 根据部门ID,查询用户Id列表
- */
- List getUserIdListByDeptId(List deptIdList);
-
- /**
- * 删除用户缓存
- *
- * @param userId
- */
- void deleteUserCache(Long userId);
-
- /**
- * 验证密码强度
- *
- * @param newPassword
- * @return
- */
- boolean isStrongPassword(String newPassword);
-
- String getName(Long creator);
}
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysUserServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysUserServiceImpl.java
index c9960b07..5c3a10c5 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysUserServiceImpl.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/sys/service/impl/SysUserServiceImpl.java
@@ -1,29 +1,22 @@
package xiaozhi.modules.sys.service.impl;
-import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
import xiaozhi.common.exception.ErrorCode;
import xiaozhi.common.exception.RenException;
-import xiaozhi.common.page.PageData;
-import xiaozhi.common.redis.RedisKeys;
-import xiaozhi.common.redis.RedisUtils;
import xiaozhi.common.service.impl.BaseServiceImpl;
-import xiaozhi.common.user.UserDetail;
import xiaozhi.common.utils.ConvertUtils;
import xiaozhi.modules.security.password.PasswordUtils;
-import xiaozhi.modules.security.user.SecurityUser;
import xiaozhi.modules.sys.dao.SysUserDao;
import xiaozhi.modules.sys.dto.SysUserDTO;
import xiaozhi.modules.sys.entity.SysUserEntity;
import xiaozhi.modules.sys.enums.SuperAdminEnum;
import xiaozhi.modules.sys.service.SysUserService;
-import lombok.AllArgsConstructor;
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.List;
-import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -34,40 +27,17 @@ import java.util.regex.Pattern;
@AllArgsConstructor
@Service
public class SysUserServiceImpl extends BaseServiceImpl implements SysUserService {
- private final RedisUtils redisUtils;
-
- @Override
- public PageData page(Map params) {
- //转换成like
- paramsToLike(params, "username");
-
- //分页
- IPage page = getPage(params, "t1.create_date", false);
-
- //查询
- List list = baseDao.getList(params);
-
- return getPageData(list, page.getTotal(), SysUserDTO.class);
- }
-
- @Override
- public List list(Map params) {
-
- List entityList = baseDao.getList(params);
-
- return ConvertUtils.sourceToTarget(entityList, SysUserDTO.class);
- }
-
- @Override
- public SysUserDTO get(Long id) {
- SysUserEntity entity = baseDao.getById(id);
-
- return ConvertUtils.sourceToTarget(entity, SysUserDTO.class);
- }
+ private final SysUserDao sysUserDao;
@Override
public SysUserDTO getByUsername(String username) {
- SysUserEntity entity = baseDao.getByUsername(username);
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("username", username);
+ List users = sysUserDao.selectList(queryWrapper);
+ if (users == null || users.isEmpty()) {
+ return null;
+ }
+ SysUserEntity entity = users.getFirst();
return ConvertUtils.sourceToTarget(entity, SysUserDTO.class);
}
@@ -86,42 +56,15 @@ public class SysUserServiceImpl extends BaseServiceImpl queryWrapper = new QueryWrapper<>();
+ return baseDao.selectCount(queryWrapper);
}
- @Override
- public int getCountByDeptId(Long deptId) {
- return baseDao.getCountByDeptId(deptId);
- }
- @Override
- public List getUserIdListByDeptId(List deptIdList) {
- return baseDao.getUserIdListByDeptId(deptIdList);
- }
-
- @Override
- public void deleteUserCache(Long userId) {
- // 删除缓存
- redisUtils.delete(RedisKeys.getUserInfoKey(userId));
- redisUtils.delete(RedisKeys.getDataScopeListKey(userId));
- redisUtils.delete(RedisKeys.getSysUserName(userId));
- }
-
- @Override
- public boolean isStrongPassword(String password) {
+ private boolean isStrongPassword(String password) {
// 弱密码的正则表达式
String weakPasswordRegex = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).+$";
Pattern pattern = Pattern.compile(weakPasswordRegex);
Matcher matcher = pattern.matcher(password);
return matcher.matches();
}
-
- @Override
- public String getName(Long id) {
- String name = (String) redisUtils.get(RedisKeys.getSysUserName(id));
- if (StringUtils.isBlank(name)) {
- SysUserEntity sysUserEntity = selectById(id);
- if (sysUserEntity != null) {
- redisUtils.set(RedisKeys.getSysUserName(id), sysUserEntity.getUsername());
- return sysUserEntity.getUsername();
- }
- }
- return name;
- }
}
diff --git a/main/manager-api/src/main/resources/db/changelog/202503131429.sql b/main/manager-api/src/main/resources/db/changelog/202503131429.sql
new file mode 100644
index 00000000..e939b7fe
--- /dev/null
+++ b/main/manager-api/src/main/resources/db/changelog/202503131429.sql
@@ -0,0 +1,167 @@
+-- 模型配置表
+DROP TABLE IF EXISTS `ai_model_config`;
+CREATE TABLE `ai_model_config` (
+ `id` BIGINT NOT NULL COMMENT '主键',
+ `model_type` VARCHAR(20) COMMENT '模型类型(Memory/ASR/VAD/LLM/TTS)',
+ `model_code` VARCHAR(50) COMMENT '模型编码(如AliLLM、DoubaoTTS)',
+ `model_name` VARCHAR(50) COMMENT '模型名称',
+ `is_default` TINYINT(1) DEFAULT 0 COMMENT '是否默认配置(0否 1是)',
+ `is_enabled` TINYINT(1) DEFAULT 0 COMMENT '是否启用(原注释有误,应为是否启用而非是否默认配置)',
+ `config_json` JSON COMMENT '模型配置(JSON格式)',
+ `doc_link` VARCHAR(200) COMMENT '官方文档链接',
+ `remark` VARCHAR(255) COMMENT '备注',
+ `sort` INT UNSIGNED DEFAULT 0 COMMENT '排序',
+ `creator` BIGINT COMMENT '创建者',
+ `create_date` DATETIME COMMENT '创建时间',
+ `updater` BIGINT COMMENT '更新者',
+ `update_date` DATETIME COMMENT '更新时间',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='模型配置表';
+
+-- TTS 音色表
+DROP TABLE IF EXISTS `ai_tts_voice`;
+CREATE TABLE `ai_tts_voice` (
+ `id` BIGINT NOT NULL COMMENT '主键',
+ `tts_model_id` BIGINT COMMENT '对应 TTS 模型主键',
+ `name` VARCHAR(20) COMMENT '音色名称',
+ `tts_voice` VARCHAR(50) COMMENT '音色编码',
+ `languages` VARCHAR(50) COMMENT '语言',
+ `voice_demo` VARCHAR(500) DEFAULT NULL COMMENT '音色 Demo',
+ `remark` VARCHAR(255) COMMENT '备注',
+ `sort` INT UNSIGNED DEFAULT 0 COMMENT '排序',
+ `creator` BIGINT COMMENT '创建者',
+ `create_date` DATETIME COMMENT '创建时间',
+ `updater` BIGINT COMMENT '更新者',
+ `update_date` DATETIME COMMENT '更新时间',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='TTS 音色表';
+
+-- 对话历史表
+DROP TABLE IF EXISTS `ai_chat_history`;
+CREATE TABLE `ai_chat_history` (
+ `id` BIGINT NOT NULL COMMENT '对话编号',
+ `user_id` BIGINT COMMENT '用户编号',
+ `agent_id` BIGINT DEFAULT NULL COMMENT '聊天角色',
+ `device_id` BIGINT DEFAULT NULL COMMENT '设备编号(原注释有误,应为设备编号)',
+ `message_count` INT COMMENT '信息汇总',
+ `sort` INT UNSIGNED DEFAULT 0 COMMENT '排序',
+ `creator` BIGINT COMMENT '创建者',
+ `create_date` DATETIME COMMENT '创建时间',
+ `updater` BIGINT COMMENT '更新者',
+ `update_date` DATETIME COMMENT '更新时间',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='对话历史表';
+
+-- 对话信息表
+DROP TABLE IF EXISTS `ai_chat_message`;
+CREATE TABLE `ai_chat_message` (
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '对话记录唯一标识',
+ `user_id` BIGINT COMMENT '用户唯一标识',
+ `chat_id` VARCHAR(64) COMMENT '对话历史 ID',
+ `agent_name` VARCHAR(64) COMMENT '智能体名称',
+ `role` ENUM('user', 'assistant') COMMENT '角色(用户或助理)',
+ `content` TEXT COMMENT '对话内容',
+ `embedding` TEXT COMMENT '对话内容的嵌入向量(可选)',
+ `url` VARCHAR(255) COMMENT '相关音频文件的 URL(可选)',
+ `prompt_tokens` INT UNSIGNED DEFAULT 0 COMMENT '提示令牌数',
+ `total_tokens` INT UNSIGNED DEFAULT 0 COMMENT '总令牌数',
+ `completion_tokens` INT UNSIGNED DEFAULT 0 COMMENT '完成令牌数',
+ `prompt_ms` INT UNSIGNED DEFAULT 0 COMMENT '提示耗时(毫秒)',
+ `total_ms` INT UNSIGNED DEFAULT 0 COMMENT '总耗时(毫秒)',
+ `completion_ms` INT UNSIGNED DEFAULT 0 COMMENT '完成耗时(毫秒)',
+ `sort` INT UNSIGNED DEFAULT 0 COMMENT '排序',
+ `creator` BIGINT COMMENT '创建者',
+ `create_date` DATETIME COMMENT '创建时间',
+ `updater` BIGINT COMMENT '更新者',
+ `update_date` DATETIME COMMENT '更新时间',
+ PRIMARY KEY (`id`),
+ INDEX `idx_user_id_chat_id_role` (`user_id`, `chat_id`) COMMENT '用户 ID、聊天会话 ID 和角色的联合索引,用于快速检索对话记录',
+ INDEX `idx_created_at` (`create_date`) COMMENT '创建时间的索引,用于按时间排序或检索对话记录'
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='对话信息表';
+
+-- 设备信息表
+DROP TABLE IF EXISTS `ai_device`;
+CREATE TABLE `ai_device` (
+ `id` BIGINT NOT NULL COMMENT '设备唯一标识',
+ `user_id` BIGINT COMMENT '关联用户 ID',
+ `mac_address` VARCHAR(50) COMMENT 'MAC 地址',
+ `last_connected_at` DATETIME COMMENT '最后连接时间',
+ `auto_update` TINYINT UNSIGNED DEFAULT 0 COMMENT '自动更新开关(0 关闭/1 开启)',
+ `board` VARCHAR(50) COMMENT '设备硬件型号',
+ `alias` VARCHAR(64) DEFAULT NULL COMMENT '设备别名',
+ `agent_code` VARCHAR(36) COMMENT '智能体编码',
+ `agent_id` BIGINT COMMENT '智能体 ID',
+ `app_version` VARCHAR(20) COMMENT '固件版本号',
+ `sort` INT UNSIGNED DEFAULT 0 COMMENT '排序',
+ `creator` BIGINT COMMENT '创建者',
+ `create_date` DATETIME COMMENT '创建时间',
+ `updater` BIGINT COMMENT '更新者',
+ `update_date` DATETIME COMMENT '更新时间',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='设备信息表';
+
+-- 智能体配置表
+DROP TABLE IF EXISTS `ai_agent`;
+CREATE TABLE `ai_agent` (
+ `id` BIGINT NOT NULL COMMENT '智能体唯一标识',
+ `user_id` BIGINT COMMENT '所属用户 ID',
+ `agent_code` VARCHAR(36) COMMENT '智能体唯一凭证',
+ `agent_name` VARCHAR(64) COMMENT '智能体名称',
+ `tts_voice` VARCHAR(64) COMMENT '语音合成标识',
+ `llm_model` VARCHAR(32) COMMENT '大语言模型标识',
+ `memory` TEXT COMMENT '历史记忆数据',
+ `character` TEXT COMMENT '角色设定参数',
+ `long_memory_switch` TINYINT UNSIGNED DEFAULT 0 COMMENT '长期记忆开关',
+ `lang_code` VARCHAR(10) COMMENT '语言编码',
+ `language` VARCHAR(10) COMMENT '交互语种',
+ `sort` INT UNSIGNED DEFAULT 0 COMMENT '排序权重',
+ `creator` BIGINT COMMENT '创建者 ID',
+ `created_at` DATETIME COMMENT '创建时间',
+ `updater` BIGINT COMMENT '更新者 ID',
+ `updated_at` DATETIME COMMENT '更新时间',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='智能体配置表';
+
+-- 智能体配置模板表
+DROP TABLE IF EXISTS `ai_agent_template`;
+CREATE TABLE `ai_agent_template` (
+ `id` BIGINT NOT NULL COMMENT '智能体唯一标识',
+ `agent_code` VARCHAR(36) COMMENT '智能体编码',
+ `agent_name` VARCHAR(64) COMMENT '智能体名称',
+ `asr_model_id` VARCHAR(32) COMMENT '语音识别模型标识',
+ `vad_model_id` VARCHAR(64) COMMENT '语音活动检测标识',
+ `llm_model_id` VARCHAR(32) COMMENT '大语言模型标识',
+ `tts_model_id` VARCHAR(32) COMMENT '语音合成模型标识',
+ `tts_voice_id` VARCHAR(32) COMMENT '音色标识',
+ `memory` TEXT COMMENT '历史记忆数据',
+ `character` TEXT COMMENT '角色设定参数',
+ `long_memory_switch` TINYINT UNSIGNED DEFAULT 0 COMMENT '长期记忆开关',
+ `lang_code` VARCHAR(10) COMMENT '语言编码',
+ `language` VARCHAR(10) COMMENT '交互语种',
+ `sort` INT UNSIGNED DEFAULT 0 COMMENT '排序权重',
+ `creator` BIGINT COMMENT '创建者 ID',
+ `created_at` DATETIME COMMENT '创建时间',
+ `updater` BIGINT COMMENT '更新者 ID',
+ `updated_at` DATETIME COMMENT '更新时间',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='智能体配置模板表';
+
+-- 声纹识别表
+DROP TABLE IF EXISTS `ai_voiceprint`;
+CREATE TABLE `ai_voiceprint` (
+ `id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '声纹唯一标识',
+ `name` VARCHAR(64) COMMENT '声纹名称',
+ `user_id` BIGINT COMMENT '用户 ID(关联用户表)',
+ `agent_id` BIGINT COMMENT '关联智能体 ID',
+ `agent_code` VARCHAR(36) COMMENT '关联智能体编码',
+ `agent_name` VARCHAR(36) COMMENT '关联智能体名称',
+ `description` VARCHAR(255) COMMENT '声纹描述',
+ `embedding` LONGTEXT COMMENT '声纹特征向量(JSON 数组格式)',
+ `memory` TEXT COMMENT '关联记忆数据',
+ `sort` INT UNSIGNED DEFAULT 0 COMMENT '排序权重',
+ `creator` BIGINT COMMENT '创建者 ID',
+ `created_at` DATETIME COMMENT '创建时间',
+ `updater` BIGINT COMMENT '更新者 ID',
+ `updated_at` DATETIME COMMENT '更新时间',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='声纹识别表';
\ No newline at end of file
diff --git a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml
index 563858cc..d1d7a557 100755
--- a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml
+++ b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml
@@ -16,3 +16,10 @@ databaseChangeLog:
- sqlFile:
encoding: utf8
path: classpath:db/changelog/202503101631.sql
+ - changeSet:
+ id: 202503131429
+ author: czc
+ changes:
+ - sqlFile:
+ encoding: utf8
+ path: classpath:db/changelog/202503131429.sql
\ No newline at end of file
diff --git a/main/manager-api/src/main/resources/i18n/messages.properties b/main/manager-api/src/main/resources/i18n/messages.properties
index 53851b2d..91e6a285 100644
--- a/main/manager-api/src/main/resources/i18n/messages.properties
+++ b/main/manager-api/src/main/resources/i18n/messages.properties
@@ -33,3 +33,4 @@
10030=\u5BC6\u7801\u957F\u5EA6\u4E0D\u8DB3{0}\u4F4D
10031=\u5F31\u5BC6\u7801
10032=\u5220\u9664\u672C\u6570\u636E\u5F02\u5E38
+10033=\u8BBE\u5907\u9A8C\u8BC1\u7801\u9519\u8BEF
diff --git a/main/manager-api/src/main/resources/i18n/messages_en_US.properties b/main/manager-api/src/main/resources/i18n/messages_en_US.properties
index 1c7208c0..515de18a 100644
--- a/main/manager-api/src/main/resources/i18n/messages_en_US.properties
+++ b/main/manager-api/src/main/resources/i18n/messages_en_US.properties
@@ -30,5 +30,6 @@
10029=Cannot contain illegal characters
10030=The password is less than {0} digits.
-10031=Weak password. The password must contain {0} of uppercase letters, lowercase letters, symbols and numbers.
+10031=The password must consist of numbers, uppercase and lowercase letters, and special characters at the same time
10032=Exception in deleting this data
+10033=Device verification code error
\ No newline at end of file
diff --git a/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties b/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties
index dde25078..23b9abfa 100644
--- a/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties
+++ b/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties
@@ -30,5 +30,6 @@
10028=\u5B9A\u65F6\u4EFB\u52A1\u5931\u8D25
10029=\u4E0D\u80FD\u5305\u542B\u975E\u6CD5\u5B57\u7B26
10030=\u5BC6\u7801\u957F\u5EA6\u4E0D\u8DB3{0}\u4F4D
-10031=\u5F31\u5BC6\u7801
-10032=\u5220\u9664\u672C\u6570\u636E\u5F02\u5E38\u5EA6\u4E0D\u591F\uFF0C\u9700\u8981\u540C\u65F6\u5305\u542B\u6570\u5B57,\u5C0F\u5199\u82F1\u6587,\u5927\u5199\u82F1\u6587
\ No newline at end of file
+10031=\u5BC6\u7801\u5FC5\u987B\u540C\u65F6\u5305\u542B\u6570\u5B57\u3001\u5927\u5C0F\u5B57\u6BCD\u548C\u7279\u6B8A\u5B57\u7B26\u7EC4\u6210
+10032=\u5220\u9664\u672C\u6570\u636E\u5F02\u5E38
+10033=\u8BBE\u5907\u9A8C\u8BC1\u7801\u9519\u8BEF
\ No newline at end of file
diff --git a/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties b/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties
index f8ee58cf..2a6bd8d0 100644
--- a/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties
+++ b/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties
@@ -30,5 +30,6 @@
10028=\u5B9A\u6642\u4EFB\u52D9\u5931\u6557
10029=\u4E0D\u80FD\u5305\u542B\u975E\u6CD5\u5B57\u7B26
10030=\u5BC6\u78BC\u9577\u5EA6\u4E0D\u8DB3{0}\u4F4D
-10031=\u5F31\u5BC6\u78BC\uFF0C\u5BC6\u78BC\u9700\u8981\u5305\u542B\u5927\u5BEB\u5B57\u6BCD\uFF0C\u5C0F\u5BEB\u5B57\u6BCD\uFF0C\u7B26\u865F\uFF0C\u6578\u5B57\u5176\u4E2D{0}\u7A2E
-10032=\u522A\u9664\u6B64\u6578\u64DA\u7570\u5E38
\ No newline at end of file
+10031=\u5BC6\u78BC\u5FC5\u9808\u540C\u6642\u5305\u542B\u6578\u5B57\u3001\u5927\u5C0F\u5B57\u6BCD\u548C\u7279\u6B8A\u5B57\u7B26\u7D44\u6210
+10032=\u522A\u9664\u6B64\u6578\u64DA\u7570\u5E38
+10033=\u8A2D\u5099\u9A57\u8B49\u78BC\u932F\u8AA4
\ No newline at end of file
diff --git a/main/manager-api/src/main/resources/mapper/sys/SysUserDao.xml b/main/manager-api/src/main/resources/mapper/sys/SysUserDao.xml
index dcbb3a26..007e91c4 100644
--- a/main/manager-api/src/main/resources/mapper/sys/SysUserDao.xml
+++ b/main/manager-api/src/main/resources/mapper/sys/SysUserDao.xml
@@ -3,48 +3,4 @@
-
-
-
-
-
-
-
- update sys_user set password = #{newPassword} where id = #{id}
-
-
-
-
-
-
\ No newline at end of file
diff --git a/main/manager-web/src/views/login.vue b/main/manager-web/src/views/login.vue
index 6c73f82f..d52d2c9b 100644
--- a/main/manager-web/src/views/login.vue
+++ b/main/manager-web/src/views/login.vue
@@ -25,7 +25,7 @@