diff --git a/.gitignore b/.gitignore index 675fb688..e4c2ac00 100644 --- a/.gitignore +++ b/.gitignore @@ -156,3 +156,4 @@ main/manager-web/node_modules main/xiaozhi-server/models/SenseVoiceSmall/model.pt main/xiaozhi-server/models/sherpa-onnx* my_wakeup_words.mp3 +main/manager-api/.vscode diff --git a/main/manager-api/README.md b/main/manager-api/README.md index 0435956e..5eb87ae8 100644 --- a/main/manager-api/README.md +++ b/main/manager-api/README.md @@ -11,6 +11,7 @@ manager-api 该项目基于SpringBoot框架开发。 JDK 21 Maven 3.8+ MySQL 8.0+ +Redis 5.0+ Vue 3.x # 创建数据库 @@ -43,6 +44,30 @@ spring: password: 123456 ``` + +# 连接Redis + +如果还没有Redis,你可以通过docker安装redis + +``` +docker run --name xiaozhi-esp32-server-redis -d -p 6379:6379 redis +``` + +# 确认项目Redis连接信息 + +在`src/main/resources/application-dev.yml`中配置Redis连接信息 + +``` +spring: + data: + redis: + host: localhost + port: 6379 + password: + database: 0 +``` + + # 测试启动 本项目为SpringBoot项目,启动方式为: diff --git a/main/manager-api/pom.xml b/main/manager-api/pom.xml index eacbdff9..441c09e6 100644 --- a/main/manager-api/pom.xml +++ b/main/manager-api/pom.xml @@ -27,7 +27,6 @@ 2.0.2 1.6.2 33.0.0-jre - 3.3.2 4.20.0 @@ -168,6 +167,12 @@ lombok true + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.20.0 + diff --git a/main/manager-api/src/main/java/xiaozhi/common/convert/DateConverter.java b/main/manager-api/src/main/java/xiaozhi/common/convert/DateConverter.java index a8439180..20c61be8 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/convert/DateConverter.java +++ b/main/manager-api/src/main/java/xiaozhi/common/convert/DateConverter.java @@ -1,17 +1,17 @@ package xiaozhi.common.convert; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.convert.converter.Converter; -import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; - import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + /** * 日期转换 * Copyright (c) 人人开源 All rights reserved. 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 9f2cb10d..bb0bb52d 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 @@ -1,13 +1,26 @@ package xiaozhi.modules.agent.controller; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +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.Parameter; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.AllArgsConstructor; -import org.apache.shiro.authz.annotation.RequiresPermissions; -import org.springframework.web.bind.annotation.*; import xiaozhi.common.constant.Constant; import xiaozhi.common.page.PageData; import xiaozhi.common.user.UserDetail; @@ -19,17 +32,13 @@ import xiaozhi.modules.agent.entity.AgentEntity; import xiaozhi.modules.agent.service.AgentService; import xiaozhi.modules.security.user.SecurityUser; -import java.util.Date; -import java.util.List; -import java.util.Map; - @Tag(name = "智能体管理") @AllArgsConstructor @RestController @RequestMapping("/agent") public class AgentController { private final AgentService agentService; - + @GetMapping("/list") @Operation(summary = "获取用户智能体列表") @RequiresPermissions("sys:role:normal") @@ -38,7 +47,7 @@ public class AgentController { List agents = agentService.getUserAgents(user.getId()); return new Result>().ok(agents); } - + @GetMapping("/all") @Operation(summary = "智能体列表(管理员)") @RequiresPermissions("sys:role:superAdmin") @@ -51,7 +60,7 @@ public class AgentController { PageData page = agentService.adminAgentList(params); return new Result>().ok(page); } - + @GetMapping("/{id}") @Operation(summary = "获取智能体详情") @RequiresPermissions("sys:role:normal") @@ -59,25 +68,25 @@ public class AgentController { AgentEntity agent = agentService.getAgentById(id); return new Result().ok(agent); } - + @PostMapping @Operation(summary = "创建智能体") @RequiresPermissions("sys:role:normal") public Result save(@RequestBody @Valid AgentCreateDTO dto) { AgentEntity entity = ConvertUtils.sourceToTarget(dto, AgentEntity.class); - + // 设置用户ID和创建者信息 UserDetail user = SecurityUser.getUser(); entity.setUserId(user.getId()); entity.setCreator(user.getId()); entity.setCreatedAt(new Date()); - + // ID、智能体编码和排序会在Service层自动生成 agentService.insert(entity); - + return new Result<>(); } - + @PutMapping @Operation(summary = "更新智能体") @RequiresPermissions("sys:role:normal") @@ -87,7 +96,7 @@ public class AgentController { if (existingEntity == null) { return new Result().error("智能体不存在"); } - + // 只更新提供的非空字段 if (dto.getAgentName() != null) { existingEntity.setAgentName(dto.getAgentName()); @@ -128,17 +137,17 @@ public class AgentController { if (dto.getSort() != null) { existingEntity.setSort(dto.getSort()); } - + // 设置更新者信息 UserDetail user = SecurityUser.getUser(); existingEntity.setUpdater(user.getId()); existingEntity.setUpdatedAt(new Date()); - + agentService.updateById(existingEntity); - + return new Result<>(); } - + @DeleteMapping("/{id}") @Operation(summary = "删除智能体") @RequiresPermissions("sys:role:normal") @@ -146,4 +155,4 @@ public class AgentController { agentService.deleteById(id); return new Result<>(); } -} \ No newline at end of file +} \ 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 new file mode 100644 index 00000000..cd88a4c8 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/controller/AgentTemplateController.java @@ -0,0 +1,37 @@ +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/dao/AgentTemplateDao.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentTemplateDao.java new file mode 100644 index 00000000..33871a63 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/dao/AgentTemplateDao.java @@ -0,0 +1,20 @@ +package xiaozhi.modules.agent.dao; + +import org.apache.ibatis.annotations.Mapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +import xiaozhi.modules.agent.entity.AgentTemplateEntity; + +/** +* @author chenerlei +* @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Mapper +* @createDate 2025-03-22 11:48:18 +*/ +@Mapper +public interface AgentTemplateDao extends BaseMapper { + +} + + + + 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 new file mode 100644 index 00000000..ca021242 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/entity/AgentTemplateEntity.java @@ -0,0 +1,115 @@ +package xiaozhi.modules.agent.entity; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * 智能体配置模板表 + * @TableName ai_agent_template + */ +@TableName(value ="ai_agent_template") +@Data +public class AgentTemplateEntity implements Serializable { + /** + * 智能体唯一标识 + */ + @TableId + private String id; + + /** + * 智能体编码 + */ + private String agentCode; + + /** + * 智能体名称 + */ + private String agentName; + + /** + * 语音识别模型标识 + */ + private String asrModelId; + + /** + * 语音活动检测标识 + */ + private String vadModelId; + + /** + * 大语言模型标识 + */ + private String llmModelId; + + /** + * 语音合成模型标识 + */ + private String ttsModelId; + + /** + * 音色标识 + */ + private String ttsVoiceId; + + /** + * 记忆模型标识 + */ + private String memoryModelId; + + /** + * 意图模型标识 + */ + private String intentModelId; + + /** + * 角色设定参数 + */ + private String systemPrompt; + + /** + * 语言编码 + */ + private String langCode; + + /** + * 交互语种 + */ + private String language; + + /** + * 排序权重 + */ + private Integer sort; + + /** + * 是否默认模板:1:是,0:不是 + */ + private Integer isDefault; + + /** + * 创建者 ID + */ + private Long creator; + + /** + * 创建时间 + */ + private Date createdAt; + + /** + * 更新者 ID + */ + private Long updater; + + /** + * 更新时间 + */ + private Date updatedAt; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentTemplateService.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentTemplateService.java new file mode 100644 index 00000000..01bb50d5 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/AgentTemplateService.java @@ -0,0 +1,14 @@ +package xiaozhi.modules.agent.service; + +import xiaozhi.modules.agent.entity.AgentTemplateEntity; + +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @author chenerlei + * @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Service + * @createDate 2025-03-22 11:48:18 + */ +public interface AgentTemplateService extends IService { + +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java index b41310ab..8e73c003 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentServiceImpl.java @@ -1,64 +1,65 @@ -package xiaozhi.modules.agent.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.agent.dao.AgentDao; -import xiaozhi.modules.agent.entity.AgentEntity; -import xiaozhi.modules.agent.service.AgentService; - -import java.util.List; -import java.util.Map; -import java.util.UUID; - -@Service -public class AgentServiceImpl extends BaseServiceImpl implements AgentService { - private final AgentDao agentDao; - - public AgentServiceImpl(AgentDao agentDao) { - this.agentDao = agentDao; - } - - @Override - public List getUserAgents(Long userId) { - QueryWrapper wrapper = new QueryWrapper<>(); - wrapper.eq("user_id", userId); - return agentDao.selectList(wrapper); - } - - @Override - public PageData adminAgentList(Map params) { - IPage page = agentDao.selectPage( - getPage(params, "sort", true), - new QueryWrapper<>() - ); - return new PageData<>(page.getRecords(), page.getTotal()); - } - - @Override - public AgentEntity getAgentById(String id) { - return agentDao.selectById(id); - } - - @Override - public boolean insert(AgentEntity entity) { - // 如果ID为空,自动生成一个UUID作为ID - if (entity.getId() == null || entity.getId().trim().isEmpty()) { - entity.setId(UUID.randomUUID().toString().replace("-", "")); - } - - // 如果智能体编码为空,自动生成一个带前缀的编码 - if (entity.getAgentCode() == null || entity.getAgentCode().trim().isEmpty()) { - entity.setAgentCode("AGT_" + System.currentTimeMillis()); - } - - // 如果排序字段为空,设置默认值0 - if (entity.getSort() == null) { - entity.setSort(0); - } - - return super.insert(entity); - } -} \ No newline at end of file +package xiaozhi.modules.agent.service.impl; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; + +import xiaozhi.common.page.PageData; +import xiaozhi.common.service.impl.BaseServiceImpl; +import xiaozhi.modules.agent.dao.AgentDao; +import xiaozhi.modules.agent.entity.AgentEntity; +import xiaozhi.modules.agent.service.AgentService; + +@Service +public class AgentServiceImpl extends BaseServiceImpl implements AgentService { + private final AgentDao agentDao; + + public AgentServiceImpl(AgentDao agentDao) { + this.agentDao = agentDao; + } + + @Override + public List getUserAgents(Long userId) { + QueryWrapper wrapper = new QueryWrapper<>(); + wrapper.eq("user_id", userId); + return agentDao.selectList(wrapper); + } + + @Override + public PageData adminAgentList(Map params) { + IPage page = agentDao.selectPage( + getPage(params, "sort", true), + new QueryWrapper<>()); + return new PageData<>(page.getRecords(), page.getTotal()); + } + + @Override + public AgentEntity getAgentById(String id) { + return agentDao.selectById(id); + } + + @Override + public boolean insert(AgentEntity entity) { + // 如果ID为空,自动生成一个UUID作为ID + if (entity.getId() == null || entity.getId().trim().isEmpty()) { + entity.setId(UUID.randomUUID().toString().replace("-", "")); + } + + // 如果智能体编码为空,自动生成一个带前缀的编码 + if (entity.getAgentCode() == null || entity.getAgentCode().trim().isEmpty()) { + entity.setAgentCode("AGT_" + System.currentTimeMillis()); + } + + // 如果排序字段为空,设置默认值0 + if (entity.getSort() == null) { + entity.setSort(0); + } + + return super.insert(entity); + } +} \ No newline at end of file diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentTemplateServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentTemplateServiceImpl.java new file mode 100644 index 00000000..02dafdec --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/service/impl/AgentTemplateServiceImpl.java @@ -0,0 +1,20 @@ +package xiaozhi.modules.agent.service.impl; + +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import xiaozhi.modules.agent.dao.AgentTemplateDao; +import xiaozhi.modules.agent.entity.AgentTemplateEntity; +import xiaozhi.modules.agent.service.AgentTemplateService; + +/** + * @author chenerlei + * @description 针对表【ai_agent_template(智能体配置模板表)】的数据库操作Service实现 + * @createDate 2025-03-22 11:48:18 + */ +@Service +public class AgentTemplateServiceImpl extends ServiceImpl + implements AgentTemplateService { + +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentTemplateVO.java b/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentTemplateVO.java new file mode 100644 index 00000000..20c0e144 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/agent/vo/AgentTemplateVO.java @@ -0,0 +1,13 @@ +package xiaozhi.modules.agent.vo; + +import lombok.Data; +import xiaozhi.modules.agent.entity.AgentTemplateEntity; + +@Data +public class AgentTemplateVO extends AgentTemplateEntity { + // 角色音色 + private String ttsModelName; + + // 角色模型 + private String llmModelName; +} 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 31b28ebb..4feb1024 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 @@ -1,6 +1,7 @@ package xiaozhi.modules.device.service; import xiaozhi.common.page.PageData; +import xiaozhi.common.service.BaseService; import xiaozhi.modules.device.dto.DeviceHeaderDTO; import xiaozhi.modules.device.dto.DeviceReportReqDTO; import xiaozhi.modules.device.dto.DeviceReportRespDTO; @@ -19,11 +20,11 @@ public interface DeviceService { DeviceReportRespDTO checkDeviceActive(String macAddress, String deviceId, String clientId, DeviceReportReqDTO deviceReport); DeviceEntity bindDevice(Long userId, DeviceHeaderDTO deviceHeader); - + List getUserDevices(Long userId); - + void unbindDevice(Long userId, Long deviceId); - + PageData adminDeviceList(Map params); Boolean deviceActivation(String activationCode); diff --git a/main/manager-api/src/main/java/xiaozhi/modules/device/vo/DeviceOtaVO.java b/main/manager-api/src/main/java/xiaozhi/modules/device/vo/DeviceOtaVO.java new file mode 100644 index 00000000..c5af75af --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/device/vo/DeviceOtaVO.java @@ -0,0 +1,55 @@ +package xiaozhi.modules.device.vo; + +import lombok.Data; + +@Data +public class DeviceOtaVO { + private Activation activation; + private Mqtt mqtt; + private ServerTime server_time; + private Firmware firmware; + private String error; + + @Data + public static class Activation { + private String code; + private String message; + + public Activation() { + } + public Activation(String code, String message) { + this.code = code; + this.message = message; + } + } + + @Data + public class Mqtt { + + } + + @Data + public static class ServerTime { + private Long timestamp; + private Integer timezone_offset; + + public ServerTime() { + } + public ServerTime(Long timestamp, Integer timezone_offset) { + this.timestamp = timestamp; + this.timezone_offset = timezone_offset; + } + } + + @Data + public static class Firmware { + private String version; + private String url; + public Firmware() { + } + public Firmware(String version, String url) { + this.version = version; + this.url = url; + } + } +} 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 1013c4b8..f5c00fe9 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 @@ -74,6 +74,7 @@ public class ShiroConfig { filterMap.put("/user/captcha", "anon"); filterMap.put("/user/login", "anon"); filterMap.put("/user/register", "anon"); + filterMap.put("/ota/**", "anon"); filterMap.put("/**", "oauth2"); shiroFilter.setFilterChainDefinitionMap(filterMap); diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java b/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java index 6ab9d1b9..657217ae 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java @@ -1,12 +1,18 @@ package xiaozhi.modules.security.controller; +import java.io.IOException; + +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletResponse; import lombok.AllArgsConstructor; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.*; import xiaozhi.common.exception.ErrorCode; import xiaozhi.common.exception.RenException; import xiaozhi.common.page.TokenDTO; @@ -22,8 +28,6 @@ import xiaozhi.modules.sys.dto.PasswordDTO; import xiaozhi.modules.sys.dto.SysUserDTO; import xiaozhi.modules.sys.service.SysUserService; -import java.io.IOException; - /** * 登录控制层 */ @@ -36,14 +40,13 @@ public class LoginController { private final SysUserTokenService sysUserTokenService; private final CaptchaService captchaService; - @GetMapping("/captcha") @Operation(summary = "验证码") public void captcha(HttpServletResponse response, String uuid) throws IOException { - //uuid不能为空 + // uuid不能为空 AssertUtils.isBlank(uuid, ErrorCode.IDENTIFIER_NOT_NULL); - //生成验证码 + // 生成验证码 captchaService.create(response, uuid); } diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Filter.java b/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Filter.java index 8f110941..1ca288fd 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Filter.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Filter.java @@ -55,11 +55,6 @@ public class Oauth2Filter extends AuthenticatingFilter { //获取请求token,如果token不存在,直接返回401 String token = getRequestToken((HttpServletRequest) request); - // TODO 调试接口,临时取消登录限制,需要 token 参数的除外 -// if (true) { -// return true; -// } - if (StringUtils.isBlank(token)) { logger.warn("onAccessDenied:token is empty"); diff --git a/main/manager-api/src/main/resources/application-dev.yml b/main/manager-api/src/main/resources/application-dev.yml index a8fdf21f..753cca9a 100644 --- a/main/manager-api/src/main/resources/application-dev.yml +++ b/main/manager-api/src/main/resources/application-dev.yml @@ -15,7 +15,7 @@ spring: druid: #MySQL driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://localhost: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=Asia/Shanghai&nullCatalogMeansCurrent=true username: root password: 123456 initial-size: 10 @@ -41,4 +41,17 @@ spring: merge-sql: false wall: config: - multi-statement-allow: true \ No newline at end of file + multi-statement-allow: true + data: + redis: + host: 127.0.0.1 # Redis服务器地址 + port: 6379 # Redis服务器连接端口 + password: # Redis服务器连接密码(默认为空) + database: 0 # Redis数据库索引(默认为0) + timeout: 10000ms # 连接超时时间(毫秒) + lettuce: + pool: + max-active: 8 # 连接池最大连接数(使用负值表示没有限制) + max-idle: 8 # 连接池中的最大空闲连接 + min-idle: 0 # 连接池中的最小空闲连接 + shutdown-timeout: 100ms # 客户端优雅关闭的等待时间 \ No newline at end of file diff --git a/main/manager-api/src/main/resources/application.yml b/main/manager-api/src/main/resources/application.yml index 282362d0..9c38b392 100644 --- a/main/manager-api/src/main/resources/application.yml +++ b/main/manager-api/src/main/resources/application.yml @@ -24,21 +24,9 @@ spring: max-file-size: 100MB max-request-size: 100MB enabled: true - data: - redis: - database: 0 - host: 127.0.0.1 - port: 6379 - password: # 密码(默认为空) - timeout: 6000ms # 连接超时时长(毫秒) - lettuce: - pool: - max-active: 1000 # 连接池最大连接数(使用负值表示没有限制) - max-wait: -1ms # 连接池最大阻塞等待时间(使用负值表示没有限制) - max-idle: 10 # 连接池中的最大空闲连接 - min-idle: 5 # 连接池中的最小空闲连接 main: allow-bean-definition-overriding: true + knife4j: enable: true basic: @@ -50,7 +38,7 @@ knife4j: renren: redis: - open: false + open: true xss: enabled: true exclude-urls: @@ -59,7 +47,7 @@ renren: mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml #实体扫描,多个package用逗号或者分号分隔 - typeAliasesPackage: xiaozhi.modules.*.entity + typeAliasesPackage: xiaozhi.modules.*.entity;xiaozhi.modules.*.domain global-config: #数据库相关配置 db-config: diff --git a/main/manager-api/src/main/resources/db/changelog/202503241020.sql b/main/manager-api/src/main/resources/db/changelog/202503241020.sql new file mode 100644 index 00000000..95e75a7b --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202503241020.sql @@ -0,0 +1,32 @@ +-- 修改字段名 +ALTER TABLE `ai_agent` RENAME COLUMN `mem_model_id` TO `memory_model_id`; +ALTER TABLE `ai_agent_template` RENAME COLUMN `mem_model_id` TO `memory_model_id`; +-- 添加字段 +ALTER TABLE `ai_agent_template` ADD COLUMN `is_default` tinyint(1) NULL DEFAULT 0 COMMENT '是否默认模板:1:是,0:不是' AFTER `sort`; + +-- 初始化智能体模板数据 +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_model_config` VALUES ('23e7c9d090ea4d1e9b25f4c8d732a3a1', 'VAD', 'SileroVAD', 'SileroVAD', 1, 1, '{\"SileroVAD\": {\"model_dir\": \"models/snakers4_silero-vad\", \"threshold\": 0.5, \"min_silence_duration_ms\": 700}}', NULL, NULL, 0, NULL, NULL, NULL, NULL); +INSERT INTO `ai_model_config` VALUES ('45f8b0d6dd3d4bfa8a28e6e0f5912d45', 'ASR', 'FunASR', 'FunASR', 1, 1, '{\"FunASR\": {\"type\": \"fun_local\", \"model_dir\": \"models/SenseVoiceSmall\", \"output_dir\": \"tmp/\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL); +INSERT INTO `ai_model_config` VALUES ('e2274b90e89ddda85207f55484d8b528', 'Memory', 'nomem', 'nomem', 1, 1, '{\"mem0ai\": {\"type\": \"nomem\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL); +INSERT INTO `ai_model_config` VALUES ('3930ac3448faf621f0a120bc829dfdfa', 'Memory', 'mem_local_short', 'mem_local_short', 1, 1, '{\"mem_local_short\": {\"type\": \"mem_local_short\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL); +INSERT INTO `ai_model_config` VALUES ('a07f3d25f52340b2b2a1e8d264079e1a', 'Memory', 'mem0ai', 'mem0ai', 1, 1, '{\"mem0ai\": {\"type\": \"mem0ai\", \"api_key\": \"你的mem0ai api key\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL); +INSERT INTO `ai_model_config` VALUES ('7a1c0a8e6d0e4035b982a4c07c3a5f76', 'LLM', 'AliLLM', 'AliLLM', 1, 1, '{\"AliLLM\": {\"type\": \"openai\", \"top_k\": 50, \"top_p\": 1, \"api_key\": \"你的ali api key\", \"base_url\": \"https://dashscope.aliyuncs.com/compatible-mode/v1\", \"max_tokens\": 500, \"model_name\": \"qwen-turbo\", \"temperature\": 0.7, \"frequency_penalty\": 0}}', NULL, NULL, 0, NULL, NULL, NULL, NULL); +INSERT INTO `ai_model_config` VALUES ('e9f2d891afbe4632b13a47c7a8c6e03d', 'LLM', 'ChatGLMLLM', 'ChatGLMLLM', 1, 1, '{\"ChatGLMLLM\": {\"url\": \"https://open.bigmodel.cn/api/paas/v4/\", \"type\": \"openai\", \"api_key\": \"0415dad4014847babc3e3f03024c50a3.qH7FgTy5Yawc85fl\", \"model_name\": \"glm-4-flash\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL); +INSERT INTO `ai_model_config` VALUES ('d50b06e9b8104d0d9c0f7316d258abcb', 'TTS', 'EdgeTTS', 'EdgeTTS', 1, 1, '{\"EdgeTTS\": {\"type\": \"edge\", \"voice\": \"zh-CN-XiaoxiaoNeural\", \"output_dir\": \"tmp/\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL); +INSERT INTO `ai_model_config` VALUES ('896db62c9dd74976ab0e8c14bf924d9d', 'TTS', 'DoubaoTTS', 'DoubaoTTS', 1, 1, '{\"DoubaoTTS\": {\"type\": \"doubao\", \"appid\": \"你的火山引擎语音合成服务appid\", \"voice\": \"BV034_streaming\", \"api_url\": \"https://openspeech.bytedance.com/api/v1/tts\", \"cluster\": \"volcano_tts\", \"output_dir\": \"tmp/\", \"access_token\": \"你的火山引擎语音合成服务access_token\", \"authorization\": \"Bearer;\"}}', NULL, NULL, 0, NULL, NULL, NULL, NULL); +INSERT INTO `ai_model_config` VALUES ('c4e12f874a3f4aa99f5b2c18e15d407b', 'Intent', 'function_call', 'function_call', 1, 1, '{\"function_call\": {\"type\": \"nointent\", \"functions\": [\"change_role\", \"get_weather\", \"get_news\", \"play_music\"]}}', NULL, NULL, 0, NULL, NULL, NULL, NULL); + +-- 初始化音色数据 +INSERT INTO `ai_tts_voice` VALUES ('fcac83266edadd5a3125f06cfee1906b', 'd50b06e9b8104d0d9c0f7316d258abcb', '湾湾小何', 'zh-CN-XiaoxiaoNeural', '中文', 'https://lf3-static.bytednsdoc.com/obj/eden-cn/lm_hz_ihsph/ljhwZthlaukjlkulzlp/portal/bigtts/湾湾小何.mp3', NULL, 1, NULL, NULL, NULL, NULL); +INSERT INTO `ai_tts_voice` VALUES ('1f2e3d4c5b6a7f8e9d0c1b2a3f4e5bx2', '896db62c9dd74976ab0e8c14bf924d9d', '通用男声', 'BV002_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV002.mp3', NULL, 2, NULL, NULL, NULL, NULL); +INSERT INTO `ai_tts_voice` VALUES ('9e8f7a6b5c4d3e2f1a0b9c8d7e6f5ad3', '896db62c9dd74976ab0e8c14bf924d9d', '通用女声', 'BV001_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV001.mp3', NULL, 3, NULL, NULL, NULL, NULL); +INSERT INTO `ai_tts_voice` VALUES ('2b3c4d5e6f7a8b9c0d1e2f3a4b5c62a2', '896db62c9dd74976ab0e8c14bf924d9d', '阳光男生', 'BV056_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV056.mp3', NULL, 4, NULL, NULL, NULL, NULL); +INSERT INTO `ai_tts_voice` VALUES ('f7a38c03d5644e22b6d84f8923a74c51', '896db62c9dd74976ab0e8c14bf924d9d', '奶气萌娃', 'BV051_streaming', '中文', 'https://lf3-speech.bytetos.com/obj/speech-tts-external/portal/Portal_Demo_BV051.mp3', NULL, 5, NULL, NULL, NULL, NULL); + 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 89ed7ff5..41d9f61a 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 @@ -15,4 +15,11 @@ databaseChangeLog: changes: - sqlFile: encoding: utf8 - path: classpath:db/changelog/202503141346.sql \ No newline at end of file + path: classpath:db/changelog/202503141346.sql + - changeSet: + id: 202503241020 + author: dreamchen + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202503241020.sql \ No newline at end of file diff --git a/main/manager-api/src/main/resources/mapper/agent/AgentTemplateMapper.xml b/main/manager-api/src/main/resources/mapper/agent/AgentTemplateMapper.xml new file mode 100644 index 00000000..bc372f8a --- /dev/null +++ b/main/manager-api/src/main/resources/mapper/agent/AgentTemplateMapper.xml @@ -0,0 +1,6 @@ + + + +