diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelConfigController.java~ b/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelConfigController.java~ new file mode 100644 index 00000000..d1693839 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelConfigController.java~ @@ -0,0 +1,2 @@ +package xiaozhi.modules.model.controller;public class ModelConfigController { +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelController.java b/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelController.java new file mode 100644 index 00000000..f743a795 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/controller/ModelController.java @@ -0,0 +1,106 @@ +package xiaozhi.modules.model.controller; + +import io.swagger.v3.oas.annotations.Operation; +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 xiaozhi.common.page.PageData; +import xiaozhi.common.utils.Result; +import xiaozhi.modules.model.dto.ModelConfigBodyDTO; +import xiaozhi.modules.model.dto.ModelConfigDTO; +import xiaozhi.modules.model.dto.ModelProviderDTO; +import xiaozhi.modules.model.service.ModelConfigService; +import xiaozhi.modules.model.service.ModelProviderService; + +import java.util.List; + +@AllArgsConstructor +@RestController +@RequestMapping("/models") +@Tag(name = "模型配置") +public class ModelController { + + private final ModelProviderService modelProviderService; + + private final ModelConfigService modelConfigService; + + @GetMapping("/models/names") + @Operation(summary = "获取所有模型名称") + @RequiresPermissions("sys:role:superAdmin") + public Result> getModelNames(@RequestParam String modelType, + @RequestParam(required = false) String modelName) { + List modelNameList = modelConfigService.getModelCodeList(modelType, modelName); + return new Result>().ok(modelNameList); + } + + @GetMapping("/{modelType}/provideTypes") + @Operation(summary = "获取模型供应器列表") + @RequiresPermissions("sys:role:superAdmin") + public Result> getModelProviderList(@PathVariable String modelType) { + List modelProviderDTOS = modelProviderService.getListByModelType(modelType); + return new Result>().ok(modelProviderDTOS); + } + + @GetMapping("/{modelType}/{provideCode}/fields") + @Operation(summary = "获取模型供应器字段") + @RequiresPermissions("sys:role:superAdmin") + public Result> getModelProviderFields(@PathVariable String modelType, @PathVariable String provideCode) { + List fieldList = modelProviderService.getFieldList(modelType, provideCode); + return new Result>().ok(fieldList); + } + + + @GetMapping("/models/list") + @Operation(summary = "获取模型配置列表") + @RequiresPermissions("sys:role:superAdmin") + public Result> getModelConfigList(@RequestParam String modelType, + @RequestParam(required = false) String modelName, + @RequestParam(required = false, defaultValue = "0") Integer page, + @RequestParam(required = false,defaultValue = "10") Integer limit) { + PageData pageList = modelConfigService.getPageList(modelType, modelName, page, limit); + return new Result>().ok(pageList); + } + + + @PostMapping("/models/{modelType}/{provideCode}") + @Operation(summary = "新增模型配置") + @RequiresPermissions("sys:role:superAdmin") + public Result addModelConfig(@PathVariable String modelType, + @PathVariable String provideCode, + @RequestBody ModelConfigBodyDTO modelConfigBodyDTO) { + ModelConfigDTO modelConfigDTO = modelConfigService.add(modelType, provideCode, modelConfigBodyDTO); + return new Result().ok(modelConfigDTO); + } + + + @PutMapping("/models/{modelType}/{provideCode}/{id}") + @Operation(summary = "编辑模型配置") + @RequiresPermissions("sys:role:superAdmin") + public Result editModelConfig(@PathVariable String modelType, + @PathVariable String provideCode, + @PathVariable String id, + @RequestBody ModelConfigBodyDTO modelConfigBodyDTO) { + ModelConfigDTO modelConfigDTO = modelConfigService.edit(modelType, provideCode, id, modelConfigBodyDTO); + return new Result().ok(modelConfigDTO); + } + + + @DeleteMapping("/models/{modelType}/{provideCode}/{id}") + @Operation(summary = "删除模型配置") + @RequiresPermissions("sys:role:superAdmin") + public Result deleteModelConfig(@PathVariable String modelType, @PathVariable String provideCode, @PathVariable String id) { + modelConfigService.delete(modelType, provideCode, id); + return new Result<>(); + } + + @GetMapping("/models/{modelName}/voices") + @Operation(summary = "获取模型音色") + @RequiresPermissions("sys:role:normal") + public Result> getVoiceList(@PathVariable String modelName, + @RequestParam(required = false) String voiceName) { + + List voiceList = modelConfigService.getVoiceList(modelName, voiceName); + return new Result>().ok(voiceList); + } +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/dao/ModelConfigDao.java b/main/manager-api/src/main/java/xiaozhi/modules/model/dao/ModelConfigDao.java new file mode 100644 index 00000000..a35967e4 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/dao/ModelConfigDao.java @@ -0,0 +1,17 @@ +package xiaozhi.modules.model.dao; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import xiaozhi.common.dao.BaseDao; +import xiaozhi.modules.model.entity.ModelConfigEntity; + +import java.util.List; + +@Mapper +public interface ModelConfigDao extends BaseDao { + + /** + * get model_code list + */ + List getModelCodeList(@Param("modelType") String modelType, @Param("modelName") String modelName); +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/dao/ModelProviderDao.java b/main/manager-api/src/main/java/xiaozhi/modules/model/dao/ModelProviderDao.java new file mode 100644 index 00000000..51042e8d --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/dao/ModelProviderDao.java @@ -0,0 +1,14 @@ +package xiaozhi.modules.model.dao; + +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import xiaozhi.common.dao.BaseDao; +import xiaozhi.modules.model.entity.ModelProviderEntity; + +import java.util.List; + +@Mapper +public interface ModelProviderDao extends BaseDao { + + List getFieldList(@Param("modelType") String modelType, @Param("provideCode") String provideCode); +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelConfigBodyDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelConfigBodyDTO.java new file mode 100644 index 00000000..639e19a2 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelConfigBodyDTO.java @@ -0,0 +1,41 @@ +package xiaozhi.modules.model.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; + +@Data +@Schema(description = "模型供应器/商") +public class ModelConfigBodyDTO { + + @Serial + private static final long serialVersionUID = 1L; + +// @Schema(description = "模型类型(Memory/ASR/VAD/LLM/TTS)") +// private String modelType; +// + @Schema(description = "模型编码(如AliLLM、DoubaoTTS)") + private String modelCode; + + @Schema(description = "模型名称") + private String modelName; + + @Schema(description = "是否默认配置(0否 1是)") + private Integer isDefault; + + @Schema(description = "是否启用") + private Integer isEnabled; + + @Schema(description = "模型配置(JSON格式)") + private String configJson; + + @Schema(description = "官方文档链接") + private String docLink; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "排序") + private Integer sort; +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelConfigDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelConfigDTO.java new file mode 100644 index 00000000..95a44921 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelConfigDTO.java @@ -0,0 +1,45 @@ +package xiaozhi.modules.model.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +@Data +@Schema(description = "模型供应器/商") +public class ModelConfigDTO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + @Schema(description = "主键") + private Long id; + + @Schema(description = "模型类型(Memory/ASR/VAD/LLM/TTS)") + private String modelType; + + @Schema(description = "模型编码(如AliLLM、DoubaoTTS)") + private String modelCode; + + @Schema(description = "模型名称") + private String modelName; + + @Schema(description = "是否默认配置(0否 1是)") + private Integer isDefault; + + @Schema(description = "是否启用") + private Integer isEnabled; + + @Schema(description = "模型配置(JSON格式)") + private String configJson; + + @Schema(description = "官方文档链接") + private String docLink; + + @Schema(description = "备注") + private String remark; + + @Schema(description = "排序") + private Integer sort; +} 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 new file mode 100644 index 00000000..acce3036 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/dto/ModelProviderDTO.java @@ -0,0 +1,45 @@ +package xiaozhi.modules.model.dto; + +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +@Data +@Schema(description = "模型供应器/商") +public class ModelProviderDTO implements Serializable { +// +// @Schema(description = "主键") +// private Long id; + + @Schema(description = "模型类型(Memory/ASR/VAD/LLM/TTS)") + private String modelType; + + @Schema(description = "供应器类型") + private String providerCode; + + @Schema(description = "供应器名称") + private String name; + + @Schema(description = "供应器字段列表(JSON格式)") + @TableField(typeHandler = JacksonTypeHandler.class) + private String fields; + + @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; +} 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 new file mode 100644 index 00000000..c98705f3 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelConfigEntity.java @@ -0,0 +1,62 @@ +package xiaozhi.modules.model.entity; + +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 com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + + +@Data +@TableName("ai_model_config") +@Schema(description = "模型配置表") +public class ModelConfigEntity { + + @TableId(type = IdType.ASSIGN_UUID) + @Schema(description = "主键") + private String id; + + @Schema(description = "模型类型(Memory/ASR/VAD/LLM/TTS)") + private String modelType; + + @Schema(description = "模型编码(如AliLLM、DoubaoTTS)") + private String modelCode; + + @Schema(description = "模型名称") + private String modelName; + + @Schema(description = "是否默认配置(0否 1是)") + private Integer isDefault; + + @Schema(description = "是否启用") + private Integer isEnabled; + + @TableField(typeHandler = JacksonTypeHandler.class) + @Schema(description = "模型配置(JSON格式)") + private String configJson; + + @Schema(description = "官方文档链接") + private String docLink; + + @Schema(description = "备注") + private String remark; + + @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; +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelProviderEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelProviderEntity.java new file mode 100644 index 00000000..0c526b88 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/entity/ModelProviderEntity.java @@ -0,0 +1,49 @@ +package xiaozhi.modules.model.entity; + +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 com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("ai_model_provider") +@Schema(description = "模型供应器表") +public class ModelProviderEntity { + + @TableId(type = IdType.ASSIGN_UUID) + @Schema(description = "主键") + private String id; + + @Schema(description = "模型类型(Memory/ASR/VAD/LLM/TTS)") + private String modelType; + + @Schema(description = "供应器类型,如 openai、") + private String providerCode; + + @Schema(description = "供应器名称") + private String name; + + @Schema(description = "供应器字段列表(JSON格式)") + @TableField(typeHandler = JacksonTypeHandler.class) + private String fields; + + @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; +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelConfigService.java b/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelConfigService.java new file mode 100644 index 00000000..1911be78 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelConfigService.java @@ -0,0 +1,22 @@ +package xiaozhi.modules.model.service; + +import xiaozhi.common.page.PageData; +import xiaozhi.modules.model.dto.ModelConfigBodyDTO; +import xiaozhi.modules.model.dto.ModelConfigDTO; + +import java.util.List; + +public interface ModelConfigService { + + List getModelCodeList(String modelType, String modelName); + + PageData getPageList(String modelType, String modelName, Integer page, Integer limit); + + ModelConfigDTO add(String modelType, String provideCode, ModelConfigBodyDTO modelConfigBodyDTO); + + ModelConfigDTO edit(String modelType, String provideCode, String id, ModelConfigBodyDTO modelConfigBodyDTO); + + void delete(String modelType, String provideCode, String id); + + List getVoiceList(String modelName, String voiceName); +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java b/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java new file mode 100644 index 00000000..d0d221cf --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/service/ModelProviderService.java @@ -0,0 +1,23 @@ +package xiaozhi.modules.model.service; + +import xiaozhi.modules.model.dto.ModelProviderDTO; +import xiaozhi.modules.model.entity.ModelProviderEntity; + +import java.util.List; + +public interface ModelProviderService { + +// List getModelNames(String modelType, String modelName); + + List getListByModelType(String modelType); + + ModelProviderDTO add(ModelProviderEntity modelProviderEntity); + + ModelProviderDTO edit(ModelProviderEntity modelProviderEntity); + + void delete(); + + List getList(String modelType, String provideCode); + + List getFieldList(String modelType, String provideCode); +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelConfigServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelConfigServiceImpl.java new file mode 100644 index 00000000..c7ab9e2e --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelConfigServiceImpl.java @@ -0,0 +1,124 @@ +package xiaozhi.modules.model.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import lombok.AllArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; +import xiaozhi.common.constant.Constant; +import xiaozhi.common.exception.RenException; +import xiaozhi.common.page.PageData; +import xiaozhi.common.service.impl.BaseServiceImpl; +import xiaozhi.common.utils.ConvertUtils; +import xiaozhi.modules.model.dao.ModelConfigDao; +import xiaozhi.modules.model.dto.ModelConfigBodyDTO; +import xiaozhi.modules.model.dto.ModelConfigDTO; +import xiaozhi.modules.model.dto.ModelProviderDTO; +import xiaozhi.modules.model.entity.ModelConfigEntity; +import xiaozhi.modules.model.service.ModelConfigService; +import xiaozhi.modules.model.service.ModelProviderService; +import xiaozhi.modules.timbre.service.TimbreService; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +@AllArgsConstructor +public class ModelConfigServiceImpl extends BaseServiceImpl implements ModelConfigService { + + private final ModelConfigDao modelConfigDao; + private final ModelProviderService modelProviderService; + private final TimbreService timbreService; + + private static final Logger logger = LoggerFactory.getLogger(ModelConfigServiceImpl.class); + + @Override + public List getModelCodeList(String modelType, String modelName) { + return modelConfigDao.getModelCodeList(modelType, modelName); + } + + @Override + public PageData getPageList(String modelType, String modelName, Integer page, Integer limit) { + Map params = new HashMap(); + params.put(Constant.PAGE, page); + params.put(Constant.LIMIT, limit); + IPage modelConfigEntityIPage = modelConfigDao.selectPage( + getPage(params, "sort", true), + new QueryWrapper() + .eq("model_type", modelType) + .like(StringUtils.isNotBlank(modelName), "model_name", modelName) + ); + return getPageData(modelConfigEntityIPage, ModelConfigDTO.class); + } + + @Override + public ModelConfigDTO add(String modelType, String provideCode, ModelConfigBodyDTO modelConfigBodyDTO) { + // 先验证有没有供应器 + if (StringUtils.isBlank(modelType) || StringUtils.isBlank(provideCode)) { + throw new RenException("modelType和provideCode不能为空"); + } + List providerList = modelProviderService.getList(modelType, provideCode); + if (CollectionUtil.isEmpty(providerList)) { + throw new RenException("供应器不存在"); + } + + // 再保存供应器提供的模型 + ModelConfigEntity modelConfigEntity = ConvertUtils.sourceToTarget(modelConfigBodyDTO, ModelConfigEntity.class); + modelConfigEntity.setModelType(modelType); + modelConfigDao.insert(modelConfigEntity); + return ConvertUtils.sourceToTarget(modelConfigEntity, ModelConfigDTO.class); + } + + @Override + public ModelConfigDTO edit(String modelType, String provideCode, String id, ModelConfigBodyDTO modelConfigBodyDTO) { + // 先验证有没有供应器 + if (StringUtils.isBlank(modelType) || StringUtils.isBlank(provideCode)) { + throw new RenException("modelType和provideCode不能为空"); + } + List providerList = modelProviderService.getList(modelType, provideCode); + if (CollectionUtil.isEmpty(providerList)) { + throw new RenException("供应器不存在"); + } + + // 再更新供应器提供的模型 + ModelConfigEntity modelConfigEntity = ConvertUtils.sourceToTarget(modelConfigBodyDTO, ModelConfigEntity.class); + modelConfigEntity.setId(Long.getLong(id)); + modelConfigEntity.setModelType(modelType); + modelConfigDao.updateById(modelConfigEntity); + return ConvertUtils.sourceToTarget(modelConfigEntity, ModelConfigDTO.class); + } + + @Override + public void delete(String modelType, String provideCode, String id) { + // 先验证有没有供应器 + if (StringUtils.isBlank(modelType) || StringUtils.isBlank(provideCode)) { + throw new RenException("modelType和provideCode不能为空"); + } + List providerList = modelProviderService.getList(modelType, provideCode); + if (CollectionUtil.isEmpty(providerList)) { + throw new RenException("供应器不存在"); + } + + modelConfigDao.deleteById(Long.getLong(id)); + } + + @Override + public List getVoiceList(String modelName, String voiceName) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("model_name", StringUtils.isBlank(modelName) ? "" : modelName); + queryWrapper.eq("model_type", "TTS"); + List modelConfigEntities = modelConfigDao.selectList(queryWrapper); + if (CollectionUtil.isEmpty(modelConfigEntities)) { + logger.warn("没有找到模型配置信息"); + return null; + } + ModelConfigEntity modelConfigEntity = modelConfigEntities.get(0); + Long id = modelConfigEntity.getId(); + + return timbreService.getVoiceNames(String.valueOf(id), voiceName); + } +} diff --git a/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java new file mode 100644 index 00000000..042749d9 --- /dev/null +++ b/main/manager-api/src/main/java/xiaozhi/modules/model/service/impl/ModelProviderServiceImpl.java @@ -0,0 +1,59 @@ +package xiaozhi.modules.model.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import lombok.AllArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import xiaozhi.common.service.impl.BaseServiceImpl; +import xiaozhi.common.utils.ConvertUtils; +import xiaozhi.modules.model.dao.ModelProviderDao; +import xiaozhi.modules.model.dto.ModelProviderDTO; +import xiaozhi.modules.model.entity.ModelProviderEntity; +import xiaozhi.modules.model.service.ModelProviderService; + +import java.util.List; + +@Service +@AllArgsConstructor +public class ModelProviderServiceImpl extends BaseServiceImpl implements ModelProviderService { + + private final ModelProviderDao modelProviderDao; + + @Override + public List getListByModelType(String modelType) { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("model_type", StringUtils.isBlank(modelType) ? "" : modelType); + List providerEntities = modelProviderDao.selectList(queryWrapper); + return ConvertUtils.sourceToTarget(providerEntities, ModelProviderDTO.class); + } + + @Override + public ModelProviderDTO add(ModelProviderEntity modelProviderEntity) { + return null; + } + + @Override + public ModelProviderDTO edit(ModelProviderEntity modelProviderEntity) { + return null; + } + + @Override + public void delete() { + + } + + @Override + public List getList(String modelType, String provideCode) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("model_type", StringUtils.isBlank(modelType) ? "" : modelType); + queryWrapper.eq("provide_code", StringUtils.isBlank(provideCode) ? "" : provideCode); + List providerEntities = modelProviderDao.selectList(queryWrapper); + return ConvertUtils.sourceToTarget(providerEntities, ModelProviderDTO.class); + } + + @Override + public List getFieldList(String modelType, String provideCode) { + return modelProviderDao.getFieldList(modelType, provideCode); + } +} 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 1520a850..55e3fa03 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 @@ -8,6 +8,8 @@ import org.apache.commons.lang3.StringUtils; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.web.filter.authc.AuthenticatingFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMethod; import xiaozhi.common.constant.Constant; import xiaozhi.common.exception.ErrorCode; @@ -24,12 +26,15 @@ import java.io.IOException; */ public class Oauth2Filter extends AuthenticatingFilter { + private static final Logger logger = LoggerFactory.getLogger(Oauth2Filter.class); + @Override protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) throws Exception { //获取请求token String token = getRequestToken((HttpServletRequest) request); if (StringUtils.isBlank(token)) { + logger.warn("createToken:token is empty"); return null; } @@ -49,7 +54,15 @@ public class Oauth2Filter extends AuthenticatingFilter { protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { //获取请求token,如果token不存在,直接返回401 String token = getRequestToken((HttpServletRequest) request); + + // TODO 调试接口,临时取消登录限制,需要 token 参数的除外 + if (true) { + return true; + } + if (StringUtils.isBlank(token)) { + logger.warn("onAccessDenied:token is empty"); + HttpServletResponse httpResponse = (HttpServletResponse) response; httpResponse.setContentType("application/json;charset=utf-8"); httpResponse.setHeader("Access-Control-Allow-Credentials", "true"); @@ -73,13 +86,14 @@ public class Oauth2Filter extends AuthenticatingFilter { httpResponse.setHeader("Access-Control-Allow-Origin", HttpContextUtils.getOrigin()); try { //处理登录失败的异常 + logger.error("onLoginFailure:登录失败!", e); Throwable throwable = e.getCause() == null ? e : e.getCause(); Result r = new Result().error(ErrorCode.UNAUTHORIZED, throwable.getMessage()); String json = JsonUtils.toJsonString(r); httpResponse.getWriter().print(json); } catch (IOException e1) { - + logger.error("onLoginFailure:登录失败! msg:{}", e1.getMessage(), e1); } return false; diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/CaptchaServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/CaptchaServiceImpl.java index fdc0d5b5..761ad139 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/CaptchaServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/CaptchaServiceImpl.java @@ -4,8 +4,11 @@ import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.wf.captcha.SpecCaptcha; import com.wf.captcha.base.Captcha; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import xiaozhi.common.redis.RedisKeys; import xiaozhi.common.redis.RedisUtils; +import xiaozhi.modules.security.oauth2.Oauth2Realm; import xiaozhi.modules.security.service.CaptchaService; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; @@ -29,6 +32,7 @@ public class CaptchaServiceImpl implements CaptchaService { * Local Cache 5分钟过期 */ Cache localCache = CacheBuilder.newBuilder().maximumSize(1000).expireAfterAccess(5, TimeUnit.MINUTES).build(); + private static final Logger logger = LoggerFactory.getLogger(Oauth2Realm.class); @Override public void create(HttpServletResponse response, String uuid) throws IOException { diff --git a/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/TimbreService.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/TimbreService.java index 9b6c73eb..044322e5 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/TimbreService.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/TimbreService.java @@ -7,6 +7,8 @@ import xiaozhi.modules.timbre.dto.TimbrePageDTO; import xiaozhi.modules.timbre.entity.TimbreEntity; import xiaozhi.modules.timbre.vo.TimbreDetailsVO; +import java.util.List; + /** * 音色的业务层的定义 @@ -46,4 +48,6 @@ public interface TimbreService extends BaseService { * @param ids 需要被删除的音色id列表 */ void delete(Long[] ids); + + List getVoiceNames(String ttsModelId, String voiceName); } \ No newline at end of file diff --git a/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/impl/TimbreServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/impl/TimbreServiceImpl.java index ce3c2b7b..fa2731bd 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/impl/TimbreServiceImpl.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/impl/TimbreServiceImpl.java @@ -1,7 +1,9 @@ package xiaozhi.modules.timbre.service.impl; +import cn.hutool.core.collection.CollectionUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -12,12 +14,13 @@ import xiaozhi.common.utils.ConvertUtils; import xiaozhi.modules.timbre.dao.TimbreDao; import xiaozhi.modules.timbre.dto.TimbreDataDTO; import xiaozhi.modules.timbre.dto.TimbrePageDTO; -import xiaozhi.modules.timbre.service.TimbreService; import xiaozhi.modules.timbre.entity.TimbreEntity; +import xiaozhi.modules.timbre.service.TimbreService; import xiaozhi.modules.timbre.vo.TimbreDetailsVO; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -25,9 +28,11 @@ import java.util.Map; * @author zjy * @since 2025-3-21 */ +@AllArgsConstructor @Service public class TimbreServiceImpl extends BaseServiceImpl implements TimbreService { + private final TimbreDao timbreDao; @Override public PageData page(TimbrePageDTO dto) { @@ -76,6 +81,21 @@ public class TimbreServiceImpl extends BaseServiceImpl baseDao.deleteBatchIds(Arrays.asList(ids)); } + @Override + public List getVoiceNames(String ttsModelId, String voiceName) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("ttsModelId", StringUtils.isBlank(ttsModelId) ? "" : ttsModelId); + if (StringUtils.isNotBlank(voiceName)) { + queryWrapper.like("name", voiceName); + } + List timbreEntities = timbreDao.selectList(queryWrapper); + if (CollectionUtil.isEmpty(timbreEntities)) { + return null; + } + + return timbreEntities.stream().map(TimbreEntity::getName).toList(); + } + /** * 处理是不是tts模型的id */ diff --git a/main/manager-api/src/main/resources/application.yml b/main/manager-api/src/main/resources/application.yml index 967f610e..03f6a044 100644 --- a/main/manager-api/src/main/resources/application.yml +++ b/main/manager-api/src/main/resources/application.yml @@ -29,7 +29,7 @@ spring: database: 0 host: 127.0.0.1 port: 6379 - password: # 密码(默认为空) + password: # 密码(默认为空) timeout: 6000ms # 连接超时时长(毫秒) lettuce: pool: @@ -39,7 +39,6 @@ spring: min-idle: 5 # 连接池中的最小空闲连接 main: allow-bean-definition-overriding: true - knife4j: enable: true basic: diff --git a/main/manager-api/src/main/resources/mapper/model/ModelConfigDao.xml b/main/manager-api/src/main/resources/mapper/model/ModelConfigDao.xml new file mode 100644 index 00000000..3f01ea5b --- /dev/null +++ b/main/manager-api/src/main/resources/mapper/model/ModelConfigDao.xml @@ -0,0 +1,10 @@ + + + + + + + \ No newline at end of file diff --git a/main/manager-api/src/main/resources/mapper/model/ModelProviderDao.xml b/main/manager-api/src/main/resources/mapper/model/ModelProviderDao.xml new file mode 100644 index 00000000..b17e24fc --- /dev/null +++ b/main/manager-api/src/main/resources/mapper/model/ModelProviderDao.xml @@ -0,0 +1,9 @@ + + + + + + + \ No newline at end of file diff --git a/main/manager-api/src/main/resources/mapper/sys/SysUserTokenDao.xml b/main/manager-api/src/main/resources/mapper/security/SysUserTokenDao.xml similarity index 100% rename from main/manager-api/src/main/resources/mapper/sys/SysUserTokenDao.xml rename to main/manager-api/src/main/resources/mapper/security/SysUserTokenDao.xml