diff --git a/src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java b/src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java index abdf9cc..8fa65b1 100644 --- a/src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java +++ b/src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java @@ -22,6 +22,9 @@ import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.youlai.boot.mini.model.query.AiTaskMediaQuery; +import com.youlai.boot.mini.model.vo.AiGenerationTaskVO; import java.util.List; import com.youlai.boot.mini.model.vo.UserUploadMediaVO; @@ -134,4 +137,13 @@ public class AiGenerationController { return Result.success(success); } + @Operation(summary = "查询我的AI生成任务历史") + @GetMapping("/my/history") + @Log(module = LogModuleEnum.AI_TASK_MEDIA, value = ActionTypeEnum.LIST) + public Result> getMyAiGenerateHistory(@Valid AiTaskMediaQuery query) { + Long userId = SecurityUtils.getUserId(); + IPage result = aiGenerationService.getMyAiGenerateHistory(query, userId); + return Result.success(result); + } + } diff --git a/src/main/java/com/youlai/boot/mini/model/query/AiTaskMediaQuery.java b/src/main/java/com/youlai/boot/mini/model/query/AiTaskMediaQuery.java new file mode 100644 index 0000000..171b7aa --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/query/AiTaskMediaQuery.java @@ -0,0 +1,21 @@ +package com.youlai.boot.mini.model.query; + +import com.youlai.boot.common.base.BaseQuery; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +/** + * 用户AI生成任务历史查询参数 + */ +@Getter +@Setter +@Schema(description = "用户AI生成任务历史查询参数") +public class AiTaskMediaQuery extends BaseQuery { + + @Schema(description = "任务状态:0=生成中 1=成功 2=失败 3=超时 4=已取消,不传查全部") + private Integer status; + + @Schema(description = "生成类型:img_single(单图), img_grid_4(四宫格), video(视频),不传查全部") + private String type; +} diff --git a/src/main/java/com/youlai/boot/mini/model/vo/AiGenerationTaskVO.java b/src/main/java/com/youlai/boot/mini/model/vo/AiGenerationTaskVO.java new file mode 100644 index 0000000..1f7a502 --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/vo/AiGenerationTaskVO.java @@ -0,0 +1,39 @@ +package com.youlai.boot.mini.model.vo; + +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import java.util.Date; +import java.util.List; + +/** + * AI生成任务列表VO + */ +@Getter +@Setter +@Schema(description = "AI生成任务列表VO") +public class AiGenerationTaskVO { + +// @Hidden +// @Schema(description = "任务ID",hidden = true) +// private Long id; + + @Schema(description = "任务唯一标识") + private String uuid; + + @Schema(description = "生成类型:img_single(单图), img_grid_4(四宫格), video(视频)") + private String type; + + @Schema(description = "任务状态:0=生成中 1=成功 2=失败 3=超时 4=已取消") + private Integer status; + + @Schema(description = "消耗积分") + private Integer pointsConsumed; + + @Schema(description = "创建时间") + private Date createTime; + + @Schema(description = "生成内容列表") + private List generateContent; +} diff --git a/src/main/java/com/youlai/boot/mini/model/vo/MiniAiTaskMediaVO.java b/src/main/java/com/youlai/boot/mini/model/vo/MiniAiTaskMediaVO.java new file mode 100644 index 0000000..1ff32ff --- /dev/null +++ b/src/main/java/com/youlai/boot/mini/model/vo/MiniAiTaskMediaVO.java @@ -0,0 +1,39 @@ +package com.youlai.boot.mini.model.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import java.util.Date; + +/** + * AI生成媒体内容VO + */ +@Getter +@Setter +@Schema(description = "AI生成媒体内容VO") +public class MiniAiTaskMediaVO { + + @Schema(description = "唯一标识") + private String uuid; + + @Schema(description = "媒体类型,image-图片,video-视频") + private String mediaType; + + @Schema(description = "资源URL") + private String sourceUrl; + + @Schema(description = "缩略图URL(视频需要)") + private String thumbnailUrl; + + @Schema(description = "宽度(像素)") + private Integer width; + + @Schema(description = "高度(像素)") + private Integer height; + + @Schema(description = "时长(秒,视频用)") + private Integer duration; + + @Schema(description = "创建时间") + private Date createTime; +} diff --git a/src/main/java/com/youlai/boot/mini/service/AiGenerationService.java b/src/main/java/com/youlai/boot/mini/service/AiGenerationService.java index 9634936..f2f971e 100644 --- a/src/main/java/com/youlai/boot/mini/service/AiGenerationService.java +++ b/src/main/java/com/youlai/boot/mini/service/AiGenerationService.java @@ -8,6 +8,9 @@ import com.youlai.boot.mini.model.form.AiVideoGenerateForm; import com.youlai.boot.mini.model.entity.MiniAiGenerationTask; import com.youlai.boot.mini.model.form.AiFourPanelCallbackForm; import com.youlai.boot.mini.model.vo.AiVideoCallbackVO; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.youlai.boot.mini.model.query.AiTaskMediaQuery; +import com.youlai.boot.mini.model.vo.AiGenerationTaskVO; import com.youlai.boot.mini.model.vo.UserUploadMediaVO; import org.springframework.web.multipart.MultipartFile; @@ -35,4 +38,6 @@ public interface AiGenerationService { boolean deleteUploadMedia(Long userId, String uuid); + IPage getMyAiGenerateHistory(AiTaskMediaQuery query, Long userId); + } diff --git a/src/main/java/com/youlai/boot/mini/service/impl/AiGenerationServiceImpl.java b/src/main/java/com/youlai/boot/mini/service/impl/AiGenerationServiceImpl.java index 9678429..cc7fae9 100644 --- a/src/main/java/com/youlai/boot/mini/service/impl/AiGenerationServiceImpl.java +++ b/src/main/java/com/youlai/boot/mini/service/impl/AiGenerationServiceImpl.java @@ -10,6 +10,8 @@ import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.youlai.boot.common.exception.BusinessException; import com.youlai.boot.common.exception.MsgException; import com.youlai.boot.common.util.FileUtils; @@ -23,7 +25,10 @@ import com.youlai.boot.mini.mapper.MiniAiTaskMediaMapper; import com.youlai.boot.mini.model.entity.MiniAiGenerationTask; import com.youlai.boot.mini.model.entity.MiniAiTaskMedia; import com.youlai.boot.mini.model.form.*; +import com.youlai.boot.mini.model.query.AiTaskMediaQuery; +import com.youlai.boot.mini.model.vo.AiGenerationTaskVO; import com.youlai.boot.mini.model.vo.AiVideoCallbackVO; +import com.youlai.boot.mini.model.vo.MiniAiTaskMediaVO; import com.youlai.boot.mini.model.vo.UserUploadMediaVO; import com.youlai.boot.mini.service.AiGenerationService; import com.youlai.boot.mini.service.MiniPointRecordService; @@ -43,6 +48,8 @@ import java.io.InputStream; import java.net.URL; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Map; import java.util.*; import java.util.stream.Collectors; import java.util.concurrent.CompletableFuture; @@ -896,4 +903,74 @@ public class AiGenerationServiceImpl implements AiGenerationService { return aiTaskMediaMapper.updateById(media) > 0; } + + @Override + public IPage getMyAiGenerateHistory(AiTaskMediaQuery query, Long userId) { + // 1. 分页查询当前用户的生成任务 + LambdaQueryWrapper taskQueryWrapper = new LambdaQueryWrapper<>(); + taskQueryWrapper.eq(MiniAiGenerationTask::getMiniUserId, userId); + // 任务状态筛选 + if (query.getStatus() != null) { + taskQueryWrapper.eq(MiniAiGenerationTask::getStatus, query.getStatus()); + } + // 生成类型筛选 + if (query.getType() != null) { + taskQueryWrapper.eq(MiniAiGenerationTask::getType, query.getType()); + } + taskQueryWrapper.orderByDesc(MiniAiGenerationTask::getCreateTime); + IPage taskPage = aiGenerationTaskMapper.selectPage(new Page<>(query.getPageNum(), query.getPageSize()), taskQueryWrapper); + + if (taskPage.getRecords().isEmpty()) { + return taskPage.convert(task -> new AiGenerationTaskVO()); + } + + // 2. 提取所有任务ID + List taskIds = taskPage.getRecords().stream() + .map(MiniAiGenerationTask::getId) + .collect(Collectors.toList()); + + // 3. 批量查询这些任务对应的AI生成媒体内容 + LambdaQueryWrapper mediaQueryWrapper = new LambdaQueryWrapper<>(); + mediaQueryWrapper.in(MiniAiTaskMedia::getTaskId, taskIds); + mediaQueryWrapper.eq(MiniAiTaskMedia::getFileSource, "ai_generate"); + mediaQueryWrapper.eq(MiniAiTaskMedia::getDeleted, false); + + List mediaList = aiTaskMediaMapper.selectList(mediaQueryWrapper); + + // 4. 先按任务ID分组媒体内容,再批量转换为VO + Map> rawMediaGroupMap = mediaList.stream() + .collect(Collectors.groupingBy(MiniAiTaskMedia::getTaskId)); + + // 转换为VO分组 + Map> mediaGroupMap = rawMediaGroupMap.entrySet().stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + entry -> entry.getValue().stream().map(media -> { + MiniAiTaskMediaVO mediaVO = new MiniAiTaskMediaVO(); + mediaVO.setUuid(media.getUuid()); + mediaVO.setMediaType(media.getMediaType()); + mediaVO.setSourceUrl(media.getSourceUrl()); + mediaVO.setThumbnailUrl(media.getThumbnailUrl()); + mediaVO.setWidth(media.getWidth()); + mediaVO.setHeight(media.getHeight()); + mediaVO.setDuration(media.getDuration()); + mediaVO.setCreateTime(media.getCreateTime()); + return mediaVO; + }).collect(Collectors.toList()) + )); + + // 5. 组装VO + return taskPage.convert(task -> { + AiGenerationTaskVO vo = new AiGenerationTaskVO(); +// vo.setId(task.getId()); + vo.setUuid(task.getUuid()); + vo.setType(task.getType()); + vo.setStatus(task.getStatus()); + vo.setPointsConsumed(task.getPointsConsumed()); + vo.setCreateTime(task.getCreateTime()); + vo.setGenerateContent(mediaGroupMap.getOrDefault(task.getId(), Collections.emptyList())); + return vo; + }); + } + }