diff --git a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/music/AiMusicGenerateEnum.java b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/music/AiMusicGenerateEnum.java deleted file mode 100644 index d85d0aef1..000000000 --- a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/music/AiMusicGenerateEnum.java +++ /dev/null @@ -1,37 +0,0 @@ -package cn.iocoder.yudao.module.ai.enums.music; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -// TODO @xiaoxin:这个也叫 AiMusicGenerateModeEnum 吧。虽然长,但是和项目统一一点。 -/** - * AI 音乐状态的枚举 - * - * @author xiaoxin - */ -@AllArgsConstructor -@Getter -public enum AiMusicGenerateEnum { - - LYRIC("1", "歌词模式"), - DESCRIPTION("2", "描述模式"); - - /** - * 模式 - */ - private final String mode; - /** - * 模式名 - */ - private final String name; - - public static AiMusicGenerateEnum valueOfMode(String mode) { - for (AiMusicGenerateEnum modeEnum : AiMusicGenerateEnum.values()) { - if (modeEnum.getMode().equals(mode)) { - return modeEnum; - } - } - throw new IllegalArgumentException("未知模式: " + mode); - } - -} diff --git a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/music/AiMusicGenerateModeEnum.java b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/music/AiMusicGenerateModeEnum.java new file mode 100644 index 000000000..2bb6a120f --- /dev/null +++ b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/music/AiMusicGenerateModeEnum.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.ai.enums.music; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * AI 音乐状态的枚举 + * + * @author xiaoxin + */ +@AllArgsConstructor +@Getter +public enum AiMusicGenerateModeEnum { + + LYRIC(1, "歌词模式"), + DESCRIPTION(2, "描述模式"); + + /** + * 模式 + */ + private final Integer mode; + /** + * 模式名 + */ + private final String name; + +} diff --git a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/music/AiMusicStatusEnum.java b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/music/AiMusicStatusEnum.java index a5c5083c7..408dc93bc 100644 --- a/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/music/AiMusicStatusEnum.java +++ b/yudao-module-ai/yudao-module-ai-api/src/main/java/cn/iocoder/yudao/module/ai/enums/music/AiMusicStatusEnum.java @@ -12,14 +12,13 @@ import lombok.Getter; @Getter public enum AiMusicStatusEnum { - // @xin 文档中无失败这个返回值 TODO @xin:用 Integer 哈。另外个枚举类也是 - STREAMING("10", "进行中"), - COMPLETE("20", "完成"); + IN_PROGRESS(10, "进行中"), + SUCCESS(20, "已完成"); /** * 状态 */ - private final String status; + private final Integer status; /** * 状态名 diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/AiImageController.http b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/AiImageController.http new file mode 100644 index 000000000..b3d11ff30 --- /dev/null +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/AiImageController.http @@ -0,0 +1,13 @@ +### 生成音乐:Suno + +POST {{baseUrl}}/ai/music/generate +Content-Type: application/json +Authorization: {{token}} + +{ + "platform": "Suno", + "generateMode": 1, + "prompt": "来一首快乐的歌曲", + "modelVersion": "chirp-v3.5", + "tags": ["Happy"], + "title": "Happy Song" +} \ No newline at end of file diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/AiMusicController.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/AiMusicController.java index b9eeed2f2..92887f19a 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/AiMusicController.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/AiMusicController.java @@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; @Tag(name = "管理后台 - AI 音乐") @RestController @@ -27,7 +28,7 @@ public class AiMusicController { @PostMapping("/generate") @Operation(summary = "音乐生成") public CommonResult> generateMusic(@RequestBody @Valid AiSunoGenerateReqVO reqVO) { - return success(musicService.generateMusic(reqVO)); + return success(musicService.generateMusic(getLoginUserId(), reqVO)); } } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/vo/AiSunoGenerateReqVO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/vo/AiSunoGenerateReqVO.java index 3f8c51191..d1069e991 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/vo/AiSunoGenerateReqVO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/controller/admin/music/vo/AiSunoGenerateReqVO.java @@ -2,36 +2,37 @@ package cn.iocoder.yudao.module.ai.controller.admin.music.vo; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Data; import java.util.List; -@Schema(description = "管理后台 - 音乐生成 Request VO") +@Schema(description = "管理后台 - AI 音乐生成 Request VO") @Data public class AiSunoGenerateReqVO { - // TODO @xin:每个参数,必要的是否必填校验 - @Schema(description = "用于生成音乐音频的提示", example = "创作一首带有轻松吉他旋律的流行歌曲,[verse] 描述夏日海滩的宁静,[chorus] 节奏加快,表达对自由的向往。") - private String prompt; - - @Schema(description = "是否纯音乐", example = "true") - private Boolean makeInstrumental; - - @Schema(description = "模型版本, 默认 chirp-v3.5", example = "chirp-v3.5") - private String modelVersion; // 参见 AiModelEnum 枚举 - - @Schema(description = "音乐风格", example = "[\"pop\",\"jazz\",\"punk\"]") - private List tags; - - @Schema(description = "音乐/歌曲名称", example = "夜空中最亮的星") - private String title; - @Schema(description = "平台", requiredMode = Schema.RequiredMode.REQUIRED, example = "Suno") @NotBlank(message = "平台不能为空") private String platform; // 参见 AiPlatformEnum 枚举 @Schema(description = "生成模式", requiredMode = Schema.RequiredMode.REQUIRED, example = "2") - @NotBlank(message = "生成模式不能为空") - private String generateMode; // 参见 AiMusicGenerateEnum 枚举 + @NotNull(message = "生成模式不能为空") + private Integer generateMode; // 参见 AiMusicGenerateModeEnum 枚举 + + @Schema(description = "用于生成音乐音频的提示", requiredMode = Schema.RequiredMode.REQUIRED, + example = "创作一首带有轻松吉他旋律的流行歌曲,[verse] 描述夏日海滩的宁静,[chorus] 节奏加快,表达对自由的向往。") + private String prompt; + + @Schema(description = "是否纯音乐", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "true") + private Boolean makeInstrumental; + + @Schema(description = "模型版本", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "chirp-v3.5") + private String modelVersion; // 参见 AiModelEnum 枚举 + + @Schema(description = "音乐风格", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "[\"pop\",\"jazz\",\"punk\"]") + private List tags; + + @Schema(description = "音乐/歌曲名称", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "夜空中最亮的星") + private String title; } \ No newline at end of file diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/music/AiMusicDO.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/music/AiMusicDO.java index ea47666f7..5ec441418 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/music/AiMusicDO.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/dataobject/music/AiMusicDO.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.ai.dal.dataobject.music; +import cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.module.ai.enums.music.AiMusicGenerateModeEnum; import cn.iocoder.yudao.module.ai.enums.music.AiMusicStatusEnum; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; @@ -38,21 +40,19 @@ public class AiMusicDO extends BaseDO { */ private String title; - /** - * 图片地址 - */ - private String imageUrl; - /** * 歌词 */ private String lyric; + /** + * 图片地址 + */ + private String imageUrl; /** * 音频地址 */ private String audioUrl; - /** * 视频地址 */ @@ -63,7 +63,14 @@ public class AiMusicDO extends BaseDO { *

* 枚举 {@link AiMusicStatusEnum} */ - private String status; + private Integer status; + + /** + * 生成模式 + * + * 枚举 {@link AiMusicGenerateModeEnum} + */ + private Integer generateMode; /** * 描述词 @@ -74,28 +81,17 @@ public class AiMusicDO extends BaseDO { */ private String prompt; - /** - * 生成模式 - */ - private String generateMode; - /** * 平台 *

- * 枚举 {@link cn.iocoder.yudao.framework.ai.core.enums.AiPlatformEnum} + * 枚举 {@link AiPlatformEnum} */ private String platform; - /** * 模型 */ private String model; - /** - * 错误信息 - */ - private String errorMessage; - /** * 音乐风格标签 */ @@ -107,4 +103,9 @@ public class AiMusicDO extends BaseDO { */ private String taskId; + /** + * 错误信息 + */ + private String errorMessage; + } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/music/AiMusicMapper.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/music/AiMusicMapper.java index 22b9cb5ae..973d1838d 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/music/AiMusicMapper.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/dal/mysql/music/AiMusicMapper.java @@ -4,10 +4,18 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.module.ai.dal.dataobject.music.AiMusicDO; import org.apache.ibatis.annotations.Mapper; +import java.util.List; + /** * AI 音乐 Mapper - * @author xiaoxin + * + * @author xiaoxin */ @Mapper public interface AiMusicMapper extends BaseMapperX { + + default List selectListByStatus(Integer status) { + return selectList(AiMusicDO::getStatus, status); + } + } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/job/sun/AiSunoSyncJob.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/job/music/AiSunoSyncJob.java similarity index 93% rename from yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/job/sun/AiSunoSyncJob.java rename to yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/job/music/AiSunoSyncJob.java index b634f3845..6d85ec27f 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/job/sun/AiSunoSyncJob.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/job/music/AiSunoSyncJob.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.module.ai.job.sun; +package cn.iocoder.yudao.module.ai.job.music; import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler; import cn.iocoder.yudao.module.ai.service.music.AiMusicService; diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/music/AiMusicService.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/music/AiMusicService.java index a634d2e4e..e32a5ac13 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/music/AiMusicService.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/music/AiMusicService.java @@ -1,7 +1,6 @@ package cn.iocoder.yudao.module.ai.service.music; import cn.iocoder.yudao.module.ai.controller.admin.music.vo.AiSunoGenerateReqVO; -import cn.iocoder.yudao.module.ai.dal.dataobject.music.AiMusicDO; import java.util.List; @@ -15,17 +14,11 @@ public interface AiMusicService { /** * 音乐生成 * + * @param userId 用户编号 * @param reqVO 请求参数 * @return 生成的音乐ID */ - List generateMusic(AiSunoGenerateReqVO reqVO); - - /** - * 获取未完成状态的任务 - * - * @return 未完成任务列表 - */ - List getUnCompletedTask(); + List generateMusic(Long userId, AiSunoGenerateReqVO reqVO); /** * 同步音乐任务 @@ -34,12 +27,4 @@ public interface AiMusicService { */ Integer syncMusic(); - /** - * 批量更新音乐信息 - * - * @param musicDOS 音乐信息 - * @return 是否成功 - */ - Boolean updateBatch(List musicDOS); - } diff --git a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/music/AiMusicServiceImpl.java b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/music/AiMusicServiceImpl.java index 361fcedfd..a9cee3a72 100644 --- a/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/music/AiMusicServiceImpl.java +++ b/yudao-module-ai/yudao-module-ai-biz/src/main/java/cn/iocoder/yudao/module/ai/service/music/AiMusicServiceImpl.java @@ -4,21 +4,19 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.text.StrPool; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi; -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.module.ai.controller.admin.music.vo.AiSunoGenerateReqVO; import cn.iocoder.yudao.module.ai.dal.dataobject.music.AiMusicDO; import cn.iocoder.yudao.module.ai.dal.mysql.music.AiMusicMapper; -import cn.iocoder.yudao.module.ai.enums.music.AiMusicGenerateEnum; +import cn.iocoder.yudao.module.ai.enums.music.AiMusicGenerateModeEnum; import cn.iocoder.yudao.module.ai.enums.music.AiMusicStatusEnum; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.*; -import java.util.stream.Collectors; -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; /** * AI 音乐 Service 实现类 @@ -36,112 +34,70 @@ public class AiMusicServiceImpl implements AiMusicService { private AiMusicMapper musicMapper; @Override - public List generateMusic(AiSunoGenerateReqVO reqVO) { + public List generateMusic(Long userId, AiSunoGenerateReqVO reqVO) { + // 1. 调用 Suno 生成音乐 List musicDataList; - if (Objects.equals(AiMusicGenerateEnum.LYRIC.getMode(), reqVO.getGenerateMode())) { + if (Objects.equals(AiMusicGenerateModeEnum.LYRIC.getMode(), reqVO.getGenerateMode())) { // 1.1 歌词模式 - SunoApi.MusicGenerateRequest sunoReq = new SunoApi.MusicGenerateRequest( + SunoApi.MusicGenerateRequest generateRequest = new SunoApi.MusicGenerateRequest( reqVO.getPrompt(), reqVO.getModelVersion(), CollUtil.join(reqVO.getTags(), StrPool.COMMA), reqVO.getTitle()); - musicDataList = sunoApi.customGenerate(sunoReq); - } else if (Objects.equals(AiMusicGenerateEnum.DESCRIPTION.getMode(), reqVO.getGenerateMode())) { + musicDataList = sunoApi.customGenerate(generateRequest); + } else if (Objects.equals(AiMusicGenerateModeEnum.DESCRIPTION.getMode(), reqVO.getGenerateMode())) { // 1.2 描述模式 - SunoApi.MusicGenerateRequest sunoReq = new SunoApi.MusicGenerateRequest( + SunoApi.MusicGenerateRequest generateRequest = new SunoApi.MusicGenerateRequest( reqVO.getPrompt(), reqVO.getModelVersion(), reqVO.getMakeInstrumental()); - musicDataList = sunoApi.generate(sunoReq); + musicDataList = sunoApi.generate(generateRequest); } else { - // TODO @xin:不用 log error,直接抛异常,吧 reqVO 呆进去,有全局处理的哈 - log.error("未知的生成模式:{}", reqVO.getGenerateMode()); - throw new IllegalArgumentException("未知的生成模式"); + throw new IllegalArgumentException(StrUtil.format("未知生成模式({})", reqVO)); } // 2. 插入数据库 - // TODO @xin:因为 insertMusicData 复用的比较少,所以不用愁单独的方法,直接写在这里就好啦 - return insertMusicData(musicDataList, reqVO.getGenerateMode(), reqVO.getPlatform()); - } - - // TODO @xin:1)service 里面,不要直接查询 db;2)不要用 ne,用 STREAMING 哈 - @Override - public List getUnCompletedTask() { - return musicMapper.selectList(new LambdaQueryWrapper().ne(AiMusicDO::getStatus, AiMusicStatusEnum.COMPLETE.getStatus())); + if (CollUtil.isEmpty(musicDataList)) { + return Collections.emptyList(); + } + List musicList = buildMusicDOList(musicDataList); + musicList.forEach(music -> music.setUserId(userId).setPlatform(music.getPlatform()).setGenerateMode(reqVO.getGenerateMode())); + musicMapper.insertBatch(musicList); + return convertList(musicList, AiMusicDO::getId); } @Override public Integer syncMusic() { - List unCompletedTask = this.getUnCompletedTask(); - if (CollUtil.isEmpty(unCompletedTask)) { - // TODO @xin:这里不用打,反正 Job 也打了 - log.info("Suno 无进行中任务需要更新!"); + List streamingTask = musicMapper.selectListByStatus(AiMusicStatusEnum.IN_PROGRESS.getStatus()); + if (CollUtil.isEmpty(streamingTask)) { return 0; } - log.info("[syncMusic][Suno 开始同步, 共 ({}) 个任务]", unCompletedTask.size()); + log.info("[syncMusic][Suno 开始同步, 共 ({}) 个任务]", streamingTask.size()); + // GET 请求,为避免参数过长,分批次处理 - // TODO @xin:建议批量更大一些。 - CollUtil.split(unCompletedTask, 4).forEach(chunk -> { - // TODO @xin:可以使用 CollectionUtils 里的 map 转换 - Map taskIdMap = CollUtil.toMap(chunk, new HashMap<>(), AiMusicDO::getTaskId, AiMusicDO::getId); + CollUtil.split(streamingTask, 36).forEach(chunkList -> { + Map taskIdMap = convertMap(chunkList, AiMusicDO::getTaskId, AiMusicDO::getId); List musicTaskList = sunoApi.getMusicList(new ArrayList<>(taskIdMap.keySet())); - // TODO @xin:查询不到,直接 return;这样真正逻辑的 85 - 87 就不用多一层括号 - if (CollUtil.isNotEmpty(musicTaskList)) { - List aiMusicDOS = buildMusicDOList(musicTaskList); - //回填id - aiMusicDOS.forEach(aiMusicDO -> aiMusicDO.setId(taskIdMap.get(aiMusicDO.getTaskId()))); - this.updateBatch(aiMusicDOS); - } else { + if (CollUtil.isEmpty(musicTaskList)) { log.warn("Suno 任务同步失败, 任务ID: [{}]", taskIdMap.keySet()); + return; } + // 更新进度 + List updateMusicList = buildMusicDOList(musicTaskList); + updateMusicList.forEach(music -> music.setId(taskIdMap.get(music.getTaskId()))); + musicMapper.updateBatch(updateMusicList); }); - return unCompletedTask.size(); - } - - // TODO @xin:这个方法,看着不用啦 - @Override - public Boolean updateBatch(List musicDOS) { - return musicMapper.updateBatch(musicDOS); - } - - /** - * 新增音乐数据并提交 suno任务 - * - * @param musicDataList 音乐数据列表 - * @return 音乐id集合 - */ - private List insertMusicData(List musicDataList, String generateMode, String platform) { - if (CollUtil.isEmpty(musicDataList)) { - return Collections.emptyList(); - } - List aiMusicDOList = buildMusicDOList(musicDataList).stream() - .map(musicDO -> musicDO.setUserId(getLoginUserId()) - .setGenerateMode(generateMode) - .setPlatform(platform)) - .toList(); - musicMapper.insertBatch(aiMusicDOList); - // TODO @xin:用 CollectionUtils 简化操作 - return aiMusicDOList.stream() - .map(AiMusicDO::getId) - .collect(Collectors.toList()); + return streamingTask.size(); } /** * 构建 AiMusicDO 集合 * - * @param musicTaskList suno 音乐任务列表 + * @param musicList suno 音乐任务列表 * @return AiMusicDO 集合 */ - private static List buildMusicDOList(List musicTaskList) { - // TODO @xin:想通的变量,放在同一行,避免过长。 - return CollectionUtils.convertList(musicTaskList, musicData -> new AiMusicDO() - .setTaskId(musicData.id()) - .setPrompt(musicData.prompt()) - .setGptDescriptionPrompt(musicData.gptDescriptionPrompt()) - .setAudioUrl(musicData.audioUrl()) - .setVideoUrl(musicData.videoUrl()) - .setImageUrl(musicData.imageUrl()) - .setLyric(musicData.lyric()) - .setTitle(musicData.title()) - .setStatus(Objects.equals("complete", musicData.status()) ? AiMusicStatusEnum.COMPLETE.getStatus() : AiMusicStatusEnum.STREAMING.getStatus()) - .setModel(musicData.modelName()) - // TODO @xin:可以用 hutool 的 StrUtil 的 split 之类的 - .setTags(StrUtil.isNotBlank(musicData.tags()) ? List.of(musicData.tags().split(StrPool.COMMA)) : null)); - } + private static List buildMusicDOList(List musicList) { + return convertList(musicList, musicData -> new AiMusicDO() + .setTaskId(musicData.id()).setModel(musicData.modelName()) + .setPrompt(musicData.prompt()).setGptDescriptionPrompt(musicData.gptDescriptionPrompt()) + .setAudioUrl(musicData.audioUrl()).setVideoUrl(musicData.videoUrl()).setImageUrl(musicData.imageUrl()) + .setTitle(musicData.title()).setLyric(musicData.lyric()).setTags(StrUtil.split(musicData.tags(), StrPool.COMMA)) + .setStatus(Objects.equals("complete", musicData.status()) ? AiMusicStatusEnum.SUCCESS.getStatus() : AiMusicStatusEnum.IN_PROGRESS.getStatus())); + } } diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java index 9b4100399..d62861571 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/config/YudaoAiAutoConfiguration.java @@ -63,7 +63,7 @@ public class YudaoAiAutoConfiguration { YudaoAiProperties.QianWenProperties qianWenProperties = yudaoAiProperties.getQianwen(); // 转换配置 QianWenOptions qianWenOptions = new QianWenOptions(); - qianWenOptions.setModel(qianWenProperties.getModel().getModel()); +// qianWenOptions.setModel(qianWenProperties.getModel().getModel()); TODO @fan:这里报错了 qianWenOptions.setTemperature(qianWenProperties.getTemperature()); // qianWenOptions.setTopK(qianWenProperties.getTopK()); TODO 芋艿:后续弄 qianWenOptions.setTopP(qianWenProperties.getTopP()); diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/suno/api/SunoApi.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/suno/api/SunoApi.java index a826a0ab1..d998fdbfa 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/suno/api/SunoApi.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/main/java/cn/iocoder/yudao/framework/ai/core/model/suno/api/SunoApi.java @@ -19,7 +19,7 @@ import java.util.function.Predicate; /** * Suno API - * + *

* 对接 Suno Proxy:suno-api * * @author xiaoxin diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java index a003d1bb7..42bb0a437 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/QianWenChatClientTests.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Scanner; import java.util.function.Consumer; +// TODO 芋艿:整理单测 /** * author: fansili * time: 2024/3/13 21:37 diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoChatClientMainTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoChatClientMainTests.java index 524bd3e0d..22bb31ae0 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoChatClientMainTests.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoChatClientMainTests.java @@ -18,6 +18,7 @@ import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.*; +// TODO 芋艿:整理单测 /** * author: fansili * time: 2024/3/13 20:47 diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoChatClientTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoChatClientTests.java index 8d9cb38e0..671af5e6d 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoChatClientTests.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoChatClientTests.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Scanner; import java.util.function.Consumer; +// TODO 芋艿:整理单测 /** * 讯飞星火 tests *

diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoOkHttpTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoOkHttpTests.java index 5a087412b..c0d4211e3 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoOkHttpTests.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/XingHuoOkHttpTests.java @@ -17,6 +17,7 @@ import java.security.NoSuchAlgorithmException; import java.text.SimpleDateFormat; import java.util.*; +// TODO 芋艿:整理单测 /** * 讯飞星火 tests *

diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/YiYanChatTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/YiYanChatTests.java index 55d16eab9..dc376c167 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/YiYanChatTests.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/chat/YiYanChatTests.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Scanner; +// TODO 芋艿:整理单测 /** * chat 文心一言 *

diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/openai/OpenAiImageClientTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/OpenAiImageClientTests.java similarity index 96% rename from yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/openai/OpenAiImageClientTests.java rename to yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/OpenAiImageClientTests.java index 53a4595f7..7d519c258 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/openai/OpenAiImageClientTests.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/image/OpenAiImageClientTests.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.framework.ai.openai; +package cn.iocoder.yudao.framework.ai.image; import org.springframework.ai.image.ImagePrompt; import org.springframework.ai.image.ImageResponse; @@ -15,6 +15,7 @@ import java.io.IOException; import java.util.Base64; import java.util.Scanner; +// TODO 芋艿:整理单测 /** * author: fansili * time: 2024/3/17 10:40 diff --git a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/suno/SunoTests.java b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/music/SunoTests.java similarity index 89% rename from yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/suno/SunoTests.java rename to yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/music/SunoTests.java index 5b4466805..ad43e373c 100644 --- a/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/suno/SunoTests.java +++ b/yudao-module-ai/yudao-spring-boot-starter-ai/src/test/java/cn/iocoder/yudao/framework/ai/music/SunoTests.java @@ -1,4 +1,4 @@ -package cn.iocoder.yudao.framework.ai.suno; +package cn.iocoder.yudao.framework.ai.music; import cn.iocoder.yudao.framework.ai.core.model.suno.api.SunoApi; import org.junit.Before; @@ -6,24 +6,24 @@ import org.junit.Test; import java.util.List; +// TODO 芋艿:整理单测 /** * @Author xiaoxin * @Date 2024/5/27 */ public class SunoTests { - SunoApi sunoApi; + private SunoApi sunoApi; @Before public void setup() { - String url = "https://suno-imrqwwui8-status2xxs-projects.vercel.app"; + String url = "https://suno-om0w1cy6e-status2xxs-projects.vercel.app"; this.sunoApi = new SunoApi(url); } @Test public void selectById() { System.out.println(sunoApi.getMusicList(List.of("d460ddda-7c87-4f34-b751-419b08a590ca,ff90ea66-49cd-4fd2-b44c-44267dfd5551"))); - } @Test diff --git a/yudao-server/src/main/resources/application.yaml b/yudao-server/src/main/resources/application.yaml index 45a043fba..5ffae8ae2 100644 --- a/yudao-server/src/main/resources/application.yaml +++ b/yudao-server/src/main/resources/application.yaml @@ -201,7 +201,7 @@ yudao.ai: notify-url: http://java.nat300.top/admin-api/ai/image/midjourney/notify suno: enable: true - base-url: https://suno-imrqwwui8-status2xxs-projects.vercel.app + base-url: https://suno-om0w1cy6e-status2xxs-projects.vercel.app --- #################### 芋道相关配置 ####################