From ab4ec5e468ed4e2d1eccddd1d06aba34b29b1289 Mon Sep 17 00:00:00 2001 From: hrz <1710360675@qq.com> Date: Sat, 29 Mar 2025 21:52:06 +0800 Subject: [PATCH] =?UTF-8?q?update=EF=BC=9A=E5=AE=8C=E6=88=90user=E3=80=81a?= =?UTF-8?q?gent=E3=80=81device=E4=B8=89=E4=B8=AA=E6=A8=A1=E5=9D=97?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/manager-api/pom.xml | 32 ++++++++++- .../xiaozhi/common/config/SwaggerConfig.java | 55 ++++++++++++++++++- .../agent/controller/AgentController.java | 20 ++++++- .../controller/AgentTemplateController.java | 37 ------------- .../modules/agent/dto/AgentCreateDTO.java | 30 ---------- .../modules/agent/dto/AgentUpdateDTO.java | 5 -- .../modules/agent/entity/AgentEntity.java | 4 ++ .../agent/entity/AgentTemplateEntity.java | 10 +--- .../device/controller/DeviceController.java | 22 +++----- .../modules/device/dto/DeviceBindDTO.java | 1 + .../modules/device/dto/DeviceUnBindDTO.java | 2 +- .../modules/device/entity/DeviceEntity.java | 22 +++++++- .../modules/device/service/DeviceService.java | 8 +-- .../service/impl/DeviceServiceImpl.java | 27 ++++++--- .../modules/model/dto/ModelProviderDTO.java | 17 ++++-- .../model/entity/ModelConfigEntity.java | 17 ++++-- .../modules/timbre/entity/TimbreEntity.java | 4 ++ .../src/main/resources/application-dev.yml | 7 +-- .../resources/db/changelog/202503241021.sql | 10 ++-- .../xiaozhi/modules/device/DeviceTest.java | 50 +++++++++++++++++ .../src/test/resources/application.yml | 22 ++++++++ 21 files changed, 266 insertions(+), 136 deletions(-) delete mode 100644 main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentTemplateController.java create mode 100644 main/manager-api/src/test/java/xiaozhi/modules/device/DeviceTest.java create mode 100644 main/manager-api/src/test/resources/application.yml diff --git a/main/manager-api/pom.xml b/main/manager-api/pom.xml index 7e0bf307..9ad38043 100644 --- a/main/manager-api/pom.xml +++ b/main/manager-api/pom.xml @@ -18,7 +18,7 @@ UTF-8 UTF-8 21 - 5.12.0 + 5.10.1 1.2.20 3.5.5 5.8.24 @@ -87,6 +87,36 @@ ${junit.version} test + + org.junit.jupiter + junit-jupiter-engine + ${junit.version} + test + + + org.junit.jupiter + junit-jupiter-params + ${junit.version} + test + + + org.junit.platform + junit-platform-launcher + 1.10.1 + test + + + org.junit.platform + junit-platform-commons + 1.10.1 + test + + + org.junit.platform + junit-platform-engine + 1.10.1 + test + org.springframework.boot spring-boot-starter-test diff --git a/main/manager-api/src/main/java/xiaozhi/common/config/SwaggerConfig.java b/main/manager-api/src/main/java/xiaozhi/common/config/SwaggerConfig.java index 36e33aa1..da23a233 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/config/SwaggerConfig.java +++ b/main/manager-api/src/main/java/xiaozhi/common/config/SwaggerConfig.java @@ -15,11 +15,60 @@ import io.swagger.v3.oas.models.info.Info; @Configuration public class SwaggerConfig { + @Bean + public GroupedOpenApi deviceApi() { + return GroupedOpenApi.builder() + .group("device") + .pathsToMatch("/device/**") + .build(); + } + + @Bean + public GroupedOpenApi agentApi() { + return GroupedOpenApi.builder() + .group("agent") + .pathsToMatch("/agent/**") + .build(); + } + + @Bean + public GroupedOpenApi modelApi() { + return GroupedOpenApi.builder() + .group("models") + .pathsToMatch("/models/**") + .build(); + } + + @Bean + public GroupedOpenApi oatApi() { + return GroupedOpenApi.builder() + .group("ota") + .pathsToMatch("/ota/**") + .build(); + } + + @Bean + public GroupedOpenApi timbreApi() { + return GroupedOpenApi.builder() + .group("timbre") + .pathsToMatch("/timbre/**") + .build(); + } + + @Bean + public GroupedOpenApi sysApi() { + return GroupedOpenApi.builder() + .group("admin") + .pathsToMatch("/admin/**") + .build(); + } + @Bean public GroupedOpenApi userApi() { - String[] paths = { "/**" }; - return GroupedOpenApi.builder().group("xiaozhi") - .pathsToMatch(paths).build(); + return GroupedOpenApi.builder() + .group("user") + .pathsToMatch("/user/**") + .build(); } @Bean diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentController.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentController.java index bb0bb52d..93a741df 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentController.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentController.java @@ -15,6 +15,8 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; @@ -29,7 +31,9 @@ import xiaozhi.common.utils.Result; import xiaozhi.modules.agent.dto.AgentCreateDTO; import xiaozhi.modules.agent.dto.AgentUpdateDTO; import xiaozhi.modules.agent.entity.AgentEntity; +import xiaozhi.modules.agent.entity.AgentTemplateEntity; import xiaozhi.modules.agent.service.AgentService; +import xiaozhi.modules.agent.service.AgentTemplateService; import xiaozhi.modules.security.user.SecurityUser; @Tag(name = "智能体管理") @@ -38,6 +42,7 @@ import xiaozhi.modules.security.user.SecurityUser; @RequestMapping("/agent") public class AgentController { private final AgentService agentService; + private final AgentTemplateService agentTemplateService; @GetMapping("/list") @Operation(summary = "获取用户智能体列表") @@ -87,12 +92,12 @@ public class AgentController { return new Result<>(); } - @PutMapping + @PutMapping("/{id}") @Operation(summary = "更新智能体") @RequiresPermissions("sys:role:normal") - public Result update(@RequestBody @Valid AgentUpdateDTO dto) { + public Result update(@PathVariable String id, @RequestBody @Valid AgentUpdateDTO dto) { // 先查询现有实体 - AgentEntity existingEntity = agentService.getAgentById(dto.getId()); + AgentEntity existingEntity = agentService.getAgentById(id); if (existingEntity == null) { return new Result().error("智能体不存在"); } @@ -155,4 +160,13 @@ public class AgentController { agentService.deleteById(id); return new Result<>(); } + + @GetMapping("/template") + @Operation(summary = "智能体模板模板列表") + @RequiresPermissions("sys:role:normal") + public Result> templateList() { + List list = agentTemplateService + .list(new QueryWrapper().orderByAsc("sort")); + return new Result>().ok(list); + } } \ No newline at end of file diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentTemplateController.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentTemplateController.java deleted file mode 100644 index cd88a4c8..00000000 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentTemplateController.java +++ /dev/null @@ -1,37 +0,0 @@ -package xiaozhi.modules.agent.controller; - -import java.util.List; - -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; - -import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.tags.Tag; -import lombok.AllArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import xiaozhi.common.utils.Result; -import xiaozhi.modules.agent.entity.AgentTemplateEntity; -import xiaozhi.modules.agent.service.AgentTemplateService; - -@Slf4j -@Tag(name = "智能体模板管理") -@AllArgsConstructor -@RestController -@RequestMapping("/user/agent/template") -public class AgentTemplateController { - private final AgentTemplateService agentTemplateService; - - @GetMapping - @Operation(summary = "智能体模板模板列表") - @RequiresPermissions("sys:role:normal") - public Result> templateList() { - List list = agentTemplateService - .list(new QueryWrapper().orderByAsc("sort")); - return new Result>().ok(list); - } - -} \ No newline at end of file diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentCreateDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentCreateDTO.java index 13b56b73..59e77007 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentCreateDTO.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentCreateDTO.java @@ -18,34 +18,4 @@ public class AgentCreateDTO implements Serializable { @Schema(description = "智能体名称", example = "客服助手") @NotBlank(message = "智能体名称不能为空") private String agentName; - - @Schema(description = "语音识别模型标识", example = "asr_model_01") - private String asrModelId; - - @Schema(description = "语音活动检测标识", example = "vad_model_01") - private String vadModelId; - - @Schema(description = "大语言模型标识", example = "llm_model_01") - private String llmModelId; - - @Schema(description = "语音合成模型标识", example = "tts_model_01") - private String ttsModelId; - - @Schema(description = "音色标识", example = "voice_01") - private String ttsVoiceId; - - @Schema(description = "记忆模型标识", example = "mem_model_01") - private String memModelId; - - @Schema(description = "意图模型标识", example = "intent_model_01") - private String intentModelId; - - @Schema(description = "角色设定参数", example = "你是一个专业的客服助手,负责回答用户问题") - private String systemPrompt; - - @Schema(description = "语言编码", example = "zh_CN") - private String langCode; - - @Schema(description = "交互语种", example = "中文") - private String language; } \ No newline at end of file diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentUpdateDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentUpdateDTO.java index c0da024d..d54685d8 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentUpdateDTO.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/dto/AgentUpdateDTO.java @@ -3,7 +3,6 @@ package xiaozhi.modules.agent.dto; import java.io.Serializable; import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotBlank; import lombok.Data; /** @@ -16,10 +15,6 @@ import lombok.Data; public class AgentUpdateDTO implements Serializable { private static final long serialVersionUID = 1L; - @Schema(description = "智能体唯一标识", example = "a1b2c3d4e5f6", required = true) - @NotBlank(message = "智能体ID不能为空") - private String id; - @Schema(description = "智能体编码", example = "AGT_1234567890", required = false) private String agentCode; diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentEntity.java index 17daf2f7..917fe6d2 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentEntity.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentEntity.java @@ -2,6 +2,8 @@ package xiaozhi.modules.agent.entity; import java.util.Date; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.v3.oas.annotations.media.Schema; @@ -11,6 +13,8 @@ import lombok.Data; @TableName("ai_agent") @Schema(description = "智能体信息") public class AgentEntity { + + @TableId(type = IdType.ASSIGN_UUID) @Schema(description = "智能体唯一标识") private String id; diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentTemplateEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentTemplateEntity.java index 8a661209..6d83e4fe 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentTemplateEntity.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentTemplateEntity.java @@ -3,6 +3,7 @@ package xiaozhi.modules.agent.entity; import java.io.Serializable; import java.util.Date; +import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; @@ -20,7 +21,7 @@ public class AgentTemplateEntity implements Serializable { /** * 智能体唯一标识 */ - @TableId + @TableId(type = IdType.ASSIGN_UUID) private String id; /** @@ -61,7 +62,7 @@ public class AgentTemplateEntity implements Serializable { /** * 记忆模型标识 */ - private String memoryModelId; + private String memModelId; /** * 意图模型标识 @@ -88,11 +89,6 @@ public class AgentTemplateEntity implements Serializable { */ private Integer sort; - /** - * 是否默认模板:1:是,0:不是 - */ - private Integer isDefault; - /** * 创建者 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 index 3f18f619..2ae9e023 100644 --- 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 @@ -1,7 +1,6 @@ package xiaozhi.modules.device.controller; import java.util.List; -import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.apache.shiro.authz.annotation.RequiresPermissions; @@ -10,15 +9,11 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import io.swagger.v3.oas.annotations.Operation; 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.exception.ErrorCode; import xiaozhi.common.redis.RedisKeys; import xiaozhi.common.redis.RedisUtils; @@ -30,8 +25,6 @@ import xiaozhi.modules.device.entity.DeviceEntity; import xiaozhi.modules.device.service.DeviceService; import xiaozhi.modules.security.user.SecurityUser; -import java.util.List; - @Tag(name = "设备管理") @AllArgsConstructor @RestController @@ -41,26 +34,26 @@ public class DeviceController { private final RedisUtils redisUtils; - @PostMapping("/bind/{deviceCode}") + @PostMapping("/bind/{agentId}/{deviceCode}") @Operation(summary = "绑定设备") @RequiresPermissions("sys:role:normal") - public Result bindDevice(@PathVariable String agentId,@RequestBody String code) { - String macAddress = (String) redisUtils.get(RedisKeys.getDeviceCaptchaKey(code)); + public Result bindDevice(@PathVariable String agentId, @PathVariable String deviceCode) { + String macAddress = (String) redisUtils.get(RedisKeys.getDeviceCaptchaKey(deviceCode)); if (StringUtils.isBlank(macAddress)) { return new Result().error(ErrorCode.DEVICE_CAPTCHA_ERROR); } Long user = SecurityUser.getUser().getId(); - DeviceBindDTO deviceBindDTO = new DeviceBindDTO(macAddress,user,agentId); + DeviceBindDTO deviceBindDTO = new DeviceBindDTO(macAddress, user, agentId); deviceService.bindDevice(deviceBindDTO); return new Result<>(); } - @GetMapping("/bind") + @GetMapping("/bind/{agentId}") @Operation(summary = "获取已绑定设备") @RequiresPermissions("sys:role:normal") - public Result> getUserDevices() { + public Result> getUserDevices(@PathVariable String agentId) { UserDetail user = SecurityUser.getUser(); - List devices = deviceService.getUserDevices(user.getId()); + List devices = deviceService.getUserDevices(user.getId(), agentId); return new Result>().ok(devices); } @@ -73,5 +66,4 @@ public class DeviceController { return new Result(); } - } \ No newline at end of file diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceBindDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceBindDTO.java index 58fee01d..3413c31b 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceBindDTO.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/device/dto/DeviceBindDTO.java @@ -6,6 +6,7 @@ import lombok.Data; /** * 设备绑定的DTO + * * @author zjy * @since 2025-3-28 */ 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 index a2d02164..f18df5d4 100644 --- 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 @@ -15,6 +15,6 @@ public class DeviceUnBindDTO implements Serializable { @Schema(description = "设备ID") @NotBlank(message = "设备ID不能为空") - private Long deviceId; + private String 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 index 3e4ed0c4..8ebdf934 100644 --- 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 @@ -2,18 +2,26 @@ package xiaozhi.modules.device.entity; import java.util.Date; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import lombok.EqualsAndHashCode; -import xiaozhi.common.entity.BaseEntity; @Data @EqualsAndHashCode(callSuper = false) @TableName("ai_device") @Schema(description = "设备信息") -public class DeviceEntity extends BaseEntity { +public class DeviceEntity { + + @TableId(type = IdType.ASSIGN_UUID) + @Schema(description = "ID") + private String id; + @Schema(description = "关联用户ID") private Long userId; @@ -42,8 +50,18 @@ public class DeviceEntity extends BaseEntity { private Integer sort; @Schema(description = "更新者") + @TableField(fill = FieldFill.UPDATE) private Long updater; @Schema(description = "更新时间") + @TableField(fill = FieldFill.UPDATE) private Date updateDate; + + @Schema(description = "创建者") + @TableField(fill = FieldFill.INSERT) + private Long creator; + + @Schema(description = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createDate; } \ 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 index a02c6ee9..1a33ecb1 100644 --- 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 @@ -4,7 +4,7 @@ import java.util.List; import java.util.Map; import xiaozhi.common.page.PageData; -import xiaozhi.modules.device.dto.DeviceHeaderDTO; +import xiaozhi.modules.device.dto.DeviceBindDTO; import xiaozhi.modules.device.dto.DeviceReportReqDTO; import xiaozhi.modules.device.dto.DeviceReportRespDTO; import xiaozhi.modules.device.entity.DeviceEntity; @@ -25,17 +25,17 @@ public interface DeviceService { /** * 绑定设备 */ - DeviceEntity bindDevice(Long userId, DeviceHeaderDTO deviceHeader); + DeviceEntity bindDevice(DeviceBindDTO deviceHeader); /** * 获取用户设备列表 */ - List getUserDevices(Long userId); + List getUserDevices(Long userId, String agentId); /** * 解绑设备 */ - void unbindDevice(Long userId, Long deviceId); + void unbindDevice(Long userId, String deviceId); /** * 管理员设备列表 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 index d32bcbe9..3f7fb922 100644 --- 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 @@ -15,6 +15,7 @@ import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import cn.hutool.core.util.RandomUtil; @@ -22,8 +23,9 @@ import xiaozhi.common.exception.RenException; import xiaozhi.common.page.PageData; import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.user.UserDetail; +import xiaozhi.common.utils.ConvertUtils; import xiaozhi.modules.device.dao.DeviceDao; -import xiaozhi.modules.device.dto.DeviceHeaderDTO; +import xiaozhi.modules.device.dto.DeviceBindDTO; import xiaozhi.modules.device.dto.DeviceReportReqDTO; import xiaozhi.modules.device.dto.DeviceReportRespDTO; import xiaozhi.modules.device.entity.DeviceEntity; @@ -167,23 +169,34 @@ public class DeviceServiceImpl extends BaseServiceImpl return response; } - + @Override - public void bindDevice(DeviceBindDTO dto) { - DeviceEntity deviceEntity = ConvertUtils.sourceToTarget(dto, DeviceEntity.class); + public DeviceEntity bindDevice(DeviceBindDTO dto) { + // 查看是否已经被绑定 + DeviceEntity deviceEntity = baseDao + .selectOne(new LambdaQueryWrapper().eq(DeviceEntity::getMacAddress, dto.getMacAddress())); + if (deviceEntity != null) { + throw new RenException("设备已绑定"); + } + deviceEntity = ConvertUtils.sourceToTarget(dto, DeviceEntity.class); baseDao.insert(deviceEntity); + return deviceEntity; } @Override - public List getUserDevices(Long userId) { + public List getUserDevices(Long userId, String agentId) { QueryWrapper wrapper = new QueryWrapper<>(); wrapper.eq("user_id", userId); + wrapper.eq("agent_id", agentId); return baseDao.selectList(wrapper); } @Override - public void unbindDevice(Long userId, Long deviceId) { - baseDao.deleteById(deviceId); + public void unbindDevice(Long userId, String deviceId) { + UpdateWrapper wrapper = new UpdateWrapper<>(); + wrapper.eq("user_id", userId); + wrapper.eq("id", deviceId); + baseDao.delete(wrapper); } @Override diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelProviderDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelProviderDTO.java index 5dbdda31..605ed13a 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelProviderDTO.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelProviderDTO.java @@ -3,6 +3,7 @@ package xiaozhi.modules.model.dto; import java.io.Serializable; import java.util.Date; +import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; @@ -32,15 +33,19 @@ public class ModelProviderDTO implements Serializable { @Schema(description = "排序") private Integer sort; - @Schema(description = "创建者") - private Long creator; - - @Schema(description = "创建时间") - private Date createDate; - @Schema(description = "更新者") + @TableField(fill = FieldFill.UPDATE) private Long updater; @Schema(description = "更新时间") + @TableField(fill = FieldFill.UPDATE) private Date updateDate; + + @Schema(description = "创建者") + @TableField(fill = FieldFill.INSERT) + private Long creator; + + @Schema(description = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createDate; } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelConfigEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelConfigEntity.java index e15acaa8..0111ea96 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelConfigEntity.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelConfigEntity.java @@ -2,6 +2,7 @@ package xiaozhi.modules.model.entity; import java.util.Date; +import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -48,15 +49,19 @@ public class ModelConfigEntity { @Schema(description = "排序") private Integer sort; - @Schema(description = "创建者") - private Long creator; - - @Schema(description = "创建时间") - private Date createDate; - @Schema(description = "更新者") + @TableField(fill = FieldFill.UPDATE) private Long updater; @Schema(description = "更新时间") + @TableField(fill = FieldFill.UPDATE) private Date updateDate; + + @Schema(description = "创建者") + @TableField(fill = FieldFill.INSERT) + private Long creator; + + @Schema(description = "创建时间") + @TableField(fill = FieldFill.INSERT) + private Date createDate; } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/timbre/entity/TimbreEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/entity/TimbreEntity.java index 44ca195b..811969af 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/timbre/entity/TimbreEntity.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/entity/TimbreEntity.java @@ -2,6 +2,8 @@ package xiaozhi.modules.timbre.entity; import java.util.Date; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.v3.oas.annotations.media.Schema; @@ -43,8 +45,10 @@ public class TimbreEntity extends BaseEntity { private String voiceDemo; @Schema(description = "更新者") + @TableField(fill = FieldFill.UPDATE) private Long updater; @Schema(description = "更新时间") + @TableField(fill = FieldFill.UPDATE) private Date updateDate; } \ No newline at end of file diff --git a/main/manager-api/src/main/resources/application-dev.yml b/main/manager-api/src/main/resources/application-dev.yml index 753cca9a..24fe2113 100644 --- a/main/manager-api/src/main/resources/application-dev.yml +++ b/main/manager-api/src/main/resources/application-dev.yml @@ -7,9 +7,6 @@ knife4j: password: 2ZABCDEUgF setting: enableFooter: false -jasypt: - encryptor: - password: P9Hx718z8L spring: datasource: druid: @@ -54,4 +51,6 @@ spring: max-active: 8 # 连接池最大连接数(使用负值表示没有限制) max-idle: 8 # 连接池中的最大空闲连接 min-idle: 0 # 连接池中的最小空闲连接 - shutdown-timeout: 100ms # 客户端优雅关闭的等待时间 \ No newline at end of file + shutdown-timeout: 100ms # 客户端优雅关闭的等待时间 + liquibase: + enabled: false # 开发环境禁用Liquibase自动检查 \ No newline at end of file diff --git a/main/manager-api/src/main/resources/db/changelog/202503241021.sql b/main/manager-api/src/main/resources/db/changelog/202503241021.sql index e9aca210..39c1794a 100644 --- a/main/manager-api/src/main/resources/db/changelog/202503241021.sql +++ b/main/manager-api/src/main/resources/db/changelog/202503241021.sql @@ -1,10 +1,10 @@ -- 初始化智能体模板数据 DELETE FROM `ai_agent_template`; -INSERT INTO `ai_agent_template` VALUES ('9406648b5cc5fde1b8aa335b6f8b4f76', '小智', '湾湾小何', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', 'd50b06e9b8104d0d9c0f7316d258abcb', 'fcac83266edadd5a3125f06cfee1906b', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的台湾女孩,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 1, 1, NULL, NULL, NULL, NULL); -INSERT INTO `ai_agent_template` VALUES ('0ca32eb728c949e58b1000b2e401f90c', '小智', '通用男声', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '1f2e3d4c5b6a7f8e9d0c1b2a3f4e5bx2', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的男生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 2, 0, NULL, NULL, NULL, NULL); -INSERT INTO `ai_agent_template` VALUES ('6c7d8e9f0a1b2c3d4e5f6a7b8c9d0s24', '小智', '通用女声', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '9e8f7a6b5c4d3e2f1a0b9c8d7e6f5ad3', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的女生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 3, 0, NULL, NULL, NULL, NULL); -INSERT INTO `ai_agent_template` VALUES ('e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b1', '小智', '阳光男生', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '2b3c4d5e6f7a8b9c0d1e2f3a4b5c62a2', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的男生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 4, 0, NULL, NULL, NULL, NULL); -INSERT INTO `ai_agent_template` VALUES ('a45b6c7d8e9f0a1b2c3d4e5f6a7b8c92', '小智', '奶气萌娃', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', 'f7a38c03d5644e22b6d84f8923a74c51', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的萌娃,声音可爱,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 5, 0, NULL, NULL, NULL, NULL); +INSERT INTO `ai_agent_template` VALUES ('9406648b5cc5fde1b8aa335b6f8b4f76', '小智', '湾湾小何', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', 'd50b06e9b8104d0d9c0f7316d258abcb', 'fcac83266edadd5a3125f06cfee1906b', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的台湾女孩,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 1, NULL, NULL, NULL, NULL); +INSERT INTO `ai_agent_template` VALUES ('0ca32eb728c949e58b1000b2e401f90c', '小智', '通用男声', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '1f2e3d4c5b6a7f8e9d0c1b2a3f4e5bx2', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的男生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 2, NULL, NULL, NULL, NULL); +INSERT INTO `ai_agent_template` VALUES ('6c7d8e9f0a1b2c3d4e5f6a7b8c9d0s24', '小智', '通用女声', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '9e8f7a6b5c4d3e2f1a0b9c8d7e6f5ad3', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的女生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 3, NULL, NULL, NULL, NULL); +INSERT INTO `ai_agent_template` VALUES ('e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b1', '小智', '阳光男生', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', '2b3c4d5e6f7a8b9c0d1e2f3a4b5c62a2', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的男生,说话机车,声音好听,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 4, NULL, NULL, NULL, NULL); +INSERT INTO `ai_agent_template` VALUES ('a45b6c7d8e9f0a1b2c3d4e5f6a7b8c92', '小智', '奶气萌娃', '45f8b0d6dd3d4bfa8a28e6e0f5912d45', '23e7c9d090ea4d1e9b25f4c8d732a3a1', 'e9f2d891afbe4632b13a47c7a8c6e03d', '896db62c9dd74976ab0e8c14bf924d9d', 'f7a38c03d5644e22b6d84f8923a74c51', 'e2274b90e89ddda85207f55484d8b528', 'c4e12f874a3f4aa99f5b2c18e15d407b', '你是一个叫{{assistant_name}}的萌娃,声音可爱,习惯简短表达,爱用网络梗。\n请注意,要像一个人一样说话,请不要回复表情符号、代码、和xml标签。\n现在我正在和你进行语音聊天,我们开始吧。\n如果用户希望结束对话,请在最后说“拜拜”或“再见”。', 'zh', '中文', 5, NULL, NULL, NULL, NULL); -- 初始化模型配置数据 DELETE FROM `ai_model_config`; diff --git a/main/manager-api/src/test/java/xiaozhi/modules/device/DeviceTest.java b/main/manager-api/src/test/java/xiaozhi/modules/device/DeviceTest.java new file mode 100644 index 00000000..8647692c --- /dev/null +++ b/main/manager-api/src/test/java/xiaozhi/modules/device/DeviceTest.java @@ -0,0 +1,50 @@ +package xiaozhi.modules.device; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import lombok.extern.slf4j.Slf4j; +import xiaozhi.common.redis.RedisKeys; +import xiaozhi.common.redis.RedisUtils; + +@Slf4j +@SpringBootTest +@ActiveProfiles("dev") +@DisplayName("设备测试") +public class DeviceTest { + + @Autowired + private RedisUtils redisUtils; + + @Test + @DisplayName("测试写入设备信息") + public void testWriteDeviceInfo() { + log.info("开始测试写入设备信息..."); + + // 模拟设备MAC地址 + String macAddress = "00:11:22:33:44:55"; + // 模拟设备验证码 + String deviceCode = "123456"; + + String redisKey = RedisKeys.getDeviceCaptchaKey(deviceCode); + log.info("Redis Key: {}", redisKey); + + // 将设备信息写入Redis + redisUtils.set(redisKey, macAddress, 300); + log.info("设备信息已写入Redis"); + + // 验证是否写入成功 + String savedMacAddress = (String) redisUtils.get(redisKey); + log.info("从Redis读取的MAC地址: {}", savedMacAddress); + + // 使用断言验证 + Assertions.assertNotNull(savedMacAddress, "从Redis读取的MAC地址不应为空"); + Assertions.assertEquals(macAddress, savedMacAddress, "保存的MAC地址与原始MAC地址不匹配"); + + log.info("测试完成"); + } +} \ No newline at end of file diff --git a/main/manager-api/src/test/resources/application.yml b/main/manager-api/src/test/resources/application.yml new file mode 100644 index 00000000..099e8194 --- /dev/null +++ b/main/manager-api/src/test/resources/application.yml @@ -0,0 +1,22 @@ +spring: + data: + redis: + host: localhost + port: 6379 + database: 0 + timeout: 10s + lettuce: + pool: + min-idle: 0 + max-idle: 8 + max-active: 8 + max-wait: -1ms + +renren: + redis: + open: true + +logging: + level: + xiaozhi.modules.device: DEBUG + org.springframework.data.redis: DEBUG \ No newline at end of file