Merge pull request #2860 from xinnan-tech/perf-manager-api-business

perf:优化字典接口、模型接口、音色资源部分业务逻辑
This commit is contained in:
milieyo
2026-01-20 09:17:24 +08:00
committed by GitHub
7 changed files with 68 additions and 45 deletions
@@ -56,7 +56,7 @@ public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, Mode
new QueryWrapper<ModelConfigEntity>() new QueryWrapper<ModelConfigEntity>()
.eq("model_type", modelType) .eq("model_type", modelType)
.eq("is_enabled", 1) .eq("is_enabled", 1)
.like(StringUtils.isNotBlank(modelName), "model_name", "%" + modelName + "%") .like(StringUtils.isNotBlank(modelName), "model_name", modelName)
.select("id", "model_name")); .select("id", "model_name"));
return ConvertUtils.sourceToTarget(entities, ModelBasicInfoDTO.class); return ConvertUtils.sourceToTarget(entities, ModelBasicInfoDTO.class);
} }
@@ -67,14 +67,14 @@ public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, Mode
new QueryWrapper<ModelConfigEntity>() new QueryWrapper<ModelConfigEntity>()
.eq("model_type", "llm") .eq("model_type", "llm")
.eq("is_enabled", 1) .eq("is_enabled", 1)
.like(StringUtils.isNotBlank(modelName), "model_name", "%" + modelName + "%") .like(StringUtils.isNotBlank(modelName), "model_name", modelName)
.select("id", "model_name", "config_json")); .select("id", "model_name", "config_json"));
return entities.stream().map(item -> { return entities.stream().map(item -> {
LlmModelBasicInfoDTO dto = new LlmModelBasicInfoDTO(); LlmModelBasicInfoDTO dto = new LlmModelBasicInfoDTO();
dto.setId(item.getId()); dto.setId(item.getId());
dto.setModelName(item.getModelName()); dto.setModelName(item.getModelName());
String type = item.getConfigJson().get("type").toString(); String type = item.getConfigJson().getOrDefault("type", "").toString();
dto.setType(type); dto.setType(type);
return dto; return dto;
}).toList(); }).toList();
@@ -91,14 +91,13 @@ public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, Mode
Page<ModelConfigEntity> pageInfo = new Page<>(curPage, pageSize); Page<ModelConfigEntity> pageInfo = new Page<>(curPage, pageSize);
// 添加排序规则:先按is_enabled降序,再按sort升序 // 添加排序规则:先按is_enabled降序,再按sort升序
pageInfo.addOrder(OrderItem.desc("is_enabled")); pageInfo.addOrder(OrderItem.desc("is_enabled"), OrderItem.asc("sort"));
pageInfo.addOrder(OrderItem.asc("sort"));
IPage<ModelConfigEntity> modelConfigEntityIPage = modelConfigDao.selectPage( IPage<ModelConfigEntity> modelConfigEntityIPage = modelConfigDao.selectPage(
pageInfo, pageInfo,
new QueryWrapper<ModelConfigEntity>() new QueryWrapper<ModelConfigEntity>()
.eq("model_type", modelType) .eq("model_type", modelType)
.like(StringUtils.isNotBlank(modelName), "model_name", "%" + modelName + "%")); .like(StringUtils.isNotBlank(modelName), "model_name", modelName));
return getPageData(modelConfigEntityIPage, ModelConfigDTO.class); return getPageData(modelConfigEntityIPage, ModelConfigDTO.class);
} }
@@ -489,7 +488,7 @@ public class ModelConfigServiceImpl extends BaseServiceImpl<ModelConfigDao, Mode
List<ModelConfigEntity> intentConfigs = modelConfigDao.selectList( List<ModelConfigEntity> intentConfigs = modelConfigDao.selectList(
new QueryWrapper<ModelConfigEntity>() new QueryWrapper<ModelConfigEntity>()
.eq("model_type", "Intent") .eq("model_type", "Intent")
.like("config_json", "%" + modelId + "%")); .like("config_json", modelId));
if (!intentConfigs.isEmpty()) { if (!intentConfigs.isEmpty()) {
throw new RenException(ErrorCode.LLM_REFERENCED_BY_INTENT); throw new RenException(ErrorCode.LLM_REFERENCED_BY_INTENT);
} }
@@ -124,12 +124,6 @@ public class ModelProviderServiceImpl extends BaseServiceImpl<ModelProviderDao,
return getPageData(modelProviderDao.selectPage(pageParam, wrapper), ModelProviderDTO.class); return getPageData(modelProviderDao.selectPage(pageParam, wrapper), ModelProviderDTO.class);
} }
public static void main(String[] args) {
String jsonString = "\"[]\"";
JSONArray jsonArray = new JSONArray(jsonString);
System.out.println("字符串转 JSONArray: " + jsonArray.toString());
}
@Override @Override
public ModelProviderDTO add(ModelProviderDTO modelProviderDTO) { public ModelProviderDTO add(ModelProviderDTO modelProviderDTO) {
UserDetail user = SecurityUser.getUser(); UserDetail user = SecurityUser.getUser();
@@ -153,8 +147,7 @@ public class ModelProviderServiceImpl extends BaseServiceImpl<ModelProviderDao,
UserDetail user = SecurityUser.getUser(); UserDetail user = SecurityUser.getUser();
modelProviderDTO.setUpdater(user.getId()); modelProviderDTO.setUpdater(user.getId());
modelProviderDTO.setUpdateDate(new Date()); modelProviderDTO.setUpdateDate(new Date());
if (modelProviderDao if (modelProviderDao.updateById(ConvertUtils.sourceToTarget(modelProviderDTO, ModelProviderEntity.class)) == 0) {
.updateById(ConvertUtils.sourceToTarget(modelProviderDTO, ModelProviderEntity.class)) == 0) {
throw new RenException(ErrorCode.UPDATE_DATA_FAILED); throw new RenException(ErrorCode.UPDATE_DATA_FAILED);
} }
return ConvertUtils.sourceToTarget(modelProviderDTO, ModelProviderDTO.class); return ConvertUtils.sourceToTarget(modelProviderDTO, ModelProviderDTO.class);
@@ -4,6 +4,7 @@ import java.util.List;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import xiaozhi.common.dao.BaseDao; import xiaozhi.common.dao.BaseDao;
import xiaozhi.modules.sys.entity.SysDictDataEntity; import xiaozhi.modules.sys.entity.SysDictDataEntity;
import xiaozhi.modules.sys.vo.SysDictDataItem; import xiaozhi.modules.sys.vo.SysDictDataItem;
@@ -23,4 +24,9 @@ public interface SysDictDataDao extends BaseDao<SysDictDataEntity> {
* @return 字典类型编码 * @return 字典类型编码
*/ */
String getTypeByTypeId(Long dictTypeId); String getTypeByTypeId(Long dictTypeId);
/**
* 根据字典数据ID集合获取字典类型编码集合
*/
List<String> getDictTypesByIdList(@Param("dictDataIdList") List<Long> dictDataIdList);
} }
@@ -1,9 +1,6 @@
package xiaozhi.modules.sys.service.impl; package xiaozhi.modules.sys.service.impl;
import java.util.List; import java.util.*;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@@ -23,6 +20,7 @@ import xiaozhi.common.redis.RedisKeys;
import xiaozhi.common.redis.RedisUtils; import xiaozhi.common.redis.RedisUtils;
import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.ConvertUtils;
import xiaozhi.common.utils.ToolUtil;
import xiaozhi.modules.sys.dao.SysDictDataDao; import xiaozhi.modules.sys.dao.SysDictDataDao;
import xiaozhi.modules.sys.dao.SysUserDao; import xiaozhi.modules.sys.dao.SysUserDao;
import xiaozhi.modules.sys.dto.SysDictDataDTO; import xiaozhi.modules.sys.dto.SysDictDataDTO;
@@ -104,13 +102,19 @@ public class SysDictDataServiceImpl extends BaseServiceImpl<SysDictDataDao, SysD
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void delete(Long[] ids) { public void delete(Long[] ids) {
for (Long id : ids) { List<Long> idList = Arrays.asList(ids);
SysDictDataEntity entity = baseDao.selectById(id); if (ToolUtil.isNotEmpty(idList)) {
// 删除Redis缓存 //批量删除redis字典
String dictType = baseDao.getTypeByTypeId(entity.getDictTypeId()); List<String> redisKeyList = new ArrayList<>();
redisUtils.delete(RedisKeys.getDictDataByTypeKey(dictType)); //批量获取字典类型
// 删除 List<String> dictTypeList = Optional.ofNullable(baseDao.getDictTypesByIdList(idList)).orElseGet(ArrayList::new);
deleteById(id); dictTypeList.forEach(dictType -> redisKeyList.add(RedisKeys.getDictDataByTypeKey(dictType)));
if (ToolUtil.isNotEmpty(redisKeyList)) {
//清除缓存
redisUtils.delete(redisKeyList);
}
//批量删除字典数据
deleteBatchIds(Arrays.asList(ids));
} }
} }
@@ -1,10 +1,6 @@
package xiaozhi.modules.timbre.service.impl; package xiaozhi.modules.timbre.service.impl;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -128,10 +124,7 @@ public class TimbreServiceImpl extends BaseServiceImpl<TimbreDao, TimbreEntity>
if (StringUtils.isNotBlank(voiceName)) { if (StringUtils.isNotBlank(voiceName)) {
queryWrapper.like("name", voiceName); queryWrapper.like("name", voiceName);
} }
List<TimbreEntity> timbreEntities = timbreDao.selectList(queryWrapper); List<TimbreEntity> timbreEntities = Optional.ofNullable(timbreDao.selectList(queryWrapper)).orElseGet(ArrayList::new);
if (timbreEntities == null) {
timbreEntities = new ArrayList<>();
}
List<VoiceDTO> voiceDTOs = timbreEntities.stream() List<VoiceDTO> voiceDTOs = timbreEntities.stream()
.map(entity -> { .map(entity -> {
VoiceDTO dto = new VoiceDTO(entity.getId(), entity.getName()); VoiceDTO dto = new VoiceDTO(entity.getId(), entity.getName());
@@ -4,12 +4,8 @@ import java.net.URI;
import java.net.http.HttpClient; import java.net.http.HttpClient;
import java.net.http.HttpRequest; import java.net.http.HttpRequest;
import java.net.http.HttpResponse; import java.net.http.HttpResponse;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays; import java.util.stream.Collectors;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -30,8 +26,11 @@ import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl; import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.common.utils.ConvertUtils; import xiaozhi.common.utils.ConvertUtils;
import xiaozhi.common.utils.DateUtils; import xiaozhi.common.utils.DateUtils;
import xiaozhi.common.utils.ToolUtil;
import xiaozhi.modules.model.entity.ModelConfigEntity; import xiaozhi.modules.model.entity.ModelConfigEntity;
import xiaozhi.modules.model.service.ModelConfigService; import xiaozhi.modules.model.service.ModelConfigService;
import xiaozhi.modules.sys.dao.SysUserDao;
import xiaozhi.modules.sys.entity.SysUserEntity;
import xiaozhi.modules.sys.service.SysUserService; import xiaozhi.modules.sys.service.SysUserService;
import xiaozhi.modules.voiceclone.dao.VoiceCloneDao; import xiaozhi.modules.voiceclone.dao.VoiceCloneDao;
import xiaozhi.modules.voiceclone.dto.VoiceCloneDTO; import xiaozhi.modules.voiceclone.dto.VoiceCloneDTO;
@@ -47,6 +46,7 @@ public class VoiceCloneServiceImpl extends BaseServiceImpl<VoiceCloneDao, VoiceC
private final ModelConfigService modelConfigService; private final ModelConfigService modelConfigService;
private final SysUserService sysUserService; private final SysUserService sysUserService;
private final SysUserDao sysUserDao;
private final ObjectMapper objectMapper; private final ObjectMapper objectMapper;
@Override @Override
@@ -104,9 +104,11 @@ public class VoiceCloneServiceImpl extends BaseServiceImpl<VoiceCloneDao, VoiceC
} }
} }
// 批量保存
List<VoiceCloneEntity> batchInsertList = new ArrayList<>();
// 遍历选择的音色ID,为每个音色ID创建一条记录 // 遍历选择的音色ID,为每个音色ID创建一条记录
int index = 0; int index = 0;
String namePrefix = DateUtils.format(new java.util.Date(), "MMddHHmm"); String namePrefix = DateUtils.format(new Date(), "MMddHHmm");
for (String voiceId : dto.getVoiceIds()) { for (String voiceId : dto.getVoiceIds()) {
index++; index++;
VoiceCloneEntity entity = new VoiceCloneEntity(); VoiceCloneEntity entity = new VoiceCloneEntity();
@@ -115,8 +117,10 @@ public class VoiceCloneServiceImpl extends BaseServiceImpl<VoiceCloneDao, VoiceC
entity.setName(namePrefix + "_" + index); entity.setName(namePrefix + "_" + index);
entity.setUserId(dto.getUserId()); entity.setUserId(dto.getUserId());
entity.setTrainStatus(0); // 默认训练中 entity.setTrainStatus(0); // 默认训练中
batchInsertList.add(entity);
baseDao.insert(entity); }
if (ToolUtil.isNotEmpty(batchInsertList)) {
insertBatch(batchInsertList);
} }
} }
@@ -187,6 +191,11 @@ public class VoiceCloneServiceImpl extends BaseServiceImpl<VoiceCloneDao, VoiceC
List<VoiceCloneResponseDTO> dtoList = new ArrayList<>(entityList.size()); List<VoiceCloneResponseDTO> dtoList = new ArrayList<>(entityList.size());
// 获取用户名称ID集合
Set<Long> userIdList = entityList.stream().map(VoiceCloneEntity::getUserId).collect(Collectors.toSet());
List<SysUserEntity> userList = sysUserDao.selectList(new QueryWrapper<SysUserEntity>().in("id", userIdList));
Map<Long, String> userMap = userList.stream().collect(Collectors.toMap(SysUserEntity::getId, SysUserEntity::getUsername));
// 转换每个实体为DTO // 转换每个实体为DTO
for (VoiceCloneEntity entity : entityList) { for (VoiceCloneEntity entity : entityList) {
VoiceCloneResponseDTO dto = ConvertUtils.sourceToTarget(entity, VoiceCloneResponseDTO.class); VoiceCloneResponseDTO dto = ConvertUtils.sourceToTarget(entity, VoiceCloneResponseDTO.class);
@@ -198,7 +207,7 @@ public class VoiceCloneServiceImpl extends BaseServiceImpl<VoiceCloneDao, VoiceC
// 设置用户名称 // 设置用户名称
if (entity.getUserId() != null) { if (entity.getUserId() != null) {
dto.setUserName(sysUserService.getByUserId(entity.getUserId()).getUsername()); dto.setUserName(userMap.get(entity.getUserId()));
} }
// 确保trainStatus字段被正确设置,前端需要这个字段来判断是否为克隆音频 // 确保trainStatus字段被正确设置,前端需要这个字段来判断是否为克隆音频
@@ -15,4 +15,23 @@
FROM sys_dict_type FROM sys_dict_type
WHERE id = #{dictTypeId} WHERE id = #{dictTypeId}
</select> </select>
<select id="getDictTypesByIdList" resultType="java.lang.String">
SELECT
dict_type
FROM
sys_dict_type
WHERE
id IN (
SELECT
dict_type_id
FROM
sys_dict_data
WHERE
id IN
<foreach collection="dictDataIdList" item="id" open="(" separator="," close=")">
#{id}
</foreach>
)
</select>
</mapper> </mapper>