diff --git a/pom.xml b/pom.xml
index f98f389..f671c24 100644
--- a/pom.xml
+++ b/pom.xml
@@ -145,6 +145,12 @@
1.39.0
+
+
+ org.redisson
+ redisson-spring-boot-starter
+ 3.27.0
+
org.springframework.boot
diff --git a/src/main/java/cn/yinlihupo/common/util/RedisService.java b/src/main/java/cn/yinlihupo/common/util/RedisService.java
new file mode 100644
index 0000000..94f4f52
--- /dev/null
+++ b/src/main/java/cn/yinlihupo/common/util/RedisService.java
@@ -0,0 +1,243 @@
+package cn.yinlihupo.common.util;
+
+import org.redisson.api.RMap;
+import org.redisson.api.RSet;
+import org.redisson.api.RedissonClient;
+import org.springframework.stereotype.Service;
+
+import java.time.Duration;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Redis 服务类
+ * 提供常用的 Redis 操作封装
+ */
+@Service
+public class RedisService {
+
+ private final RedissonClient redissonClient;
+
+ public RedisService(RedissonClient redissonClient) {
+ this.redissonClient = redissonClient;
+ }
+
+ /**
+ * 存储对象到 Redis(带过期时间)
+ *
+ * @param key 键
+ * @param value 值
+ * @param duration 过期时间
+ */
+ public void set(String key, T value, Duration duration) {
+ redissonClient.getBucket(key).set(value, duration.toMillis(), TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * 存储对象到 Redis(永不过期)
+ *
+ * @param key 键
+ * @param value 值
+ */
+ public void set(String key, T value) {
+ redissonClient.getBucket(key).set(value);
+ }
+
+ /**
+ * 获取对象
+ *
+ * @param key 键
+ * @return 值,不存在返回 null
+ */
+ @SuppressWarnings("unchecked")
+ public T get(String key) {
+ return (T) redissonClient.getBucket(key).get();
+ }
+
+ /**
+ * 删除键
+ *
+ * @param key 键
+ * @return 是否删除成功
+ */
+ public boolean delete(String key) {
+ return redissonClient.getBucket(key).delete();
+ }
+
+ /**
+ * 检查键是否存在
+ *
+ * @param key 键
+ * @return 是否存在
+ */
+ public boolean exists(String key) {
+ return redissonClient.getBucket(key).isExists();
+ }
+
+ /**
+ * 设置过期时间
+ *
+ * @param key 键
+ * @param duration 过期时间
+ * @return 是否设置成功
+ */
+ public boolean expire(String key, Duration duration) {
+ return redissonClient.getBucket(key).expire(duration.toMillis(), TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * 获取匹配模式的所有键
+ *
+ * @param pattern 匹配模式
+ * @return 键集合
+ */
+ public Set keys(String pattern) {
+ Iterable keys = redissonClient.getKeys().getKeysByPattern(pattern);
+ Set result = new HashSet<>();
+ keys.forEach(result::add);
+ return result;
+ }
+
+ /**
+ * 批量删除匹配模式的键
+ *
+ * @param pattern 匹配模式
+ * @return 删除的数量
+ */
+ public long deleteByPattern(String pattern) {
+ return redissonClient.getKeys().deleteByPattern(pattern);
+ }
+
+ /**
+ * 存储到 Hash
+ *
+ * @param key 键
+ * @param field 字段
+ * @param value 值
+ * @param duration 过期时间(可选,传 null 表示不设置过期)
+ */
+ public void hSet(String key, String field, T value, Duration duration) {
+ RMap map = redissonClient.getMap(key);
+ map.put(field, value);
+ if (duration != null) {
+ map.expire(duration.toMillis(), TimeUnit.MILLISECONDS);
+ }
+ }
+
+ /**
+ * 从 Hash 获取值
+ *
+ * @param key 键
+ * @param field 字段
+ * @return 值
+ */
+ @SuppressWarnings("unchecked")
+ public T hGet(String key, String field) {
+ RMap map = redissonClient.getMap(key);
+ return (T) map.get(field);
+ }
+
+ /**
+ * 从 Hash 删除字段
+ *
+ * @param key 键
+ * @param field 字段
+ * @return 删除的数量
+ */
+ public long hDel(String key, String field) {
+ RMap map = redissonClient.getMap(key);
+ return map.remove(field) != null ? 1 : 0;
+ }
+
+ /**
+ * 获取 Hash 所有字段和值
+ *
+ * @param key 键
+ * @return 字段值映射
+ */
+ public Map hGetAll(String key) {
+ RMap map = redissonClient.getMap(key);
+ return new HashMap<>(map.readAllMap());
+ }
+
+ /**
+ * 获取 Hash 所有值
+ *
+ * @param key 键
+ * @return 值集合
+ */
+ public Collection hGetAllValues(String key) {
+ RMap map = redissonClient.getMap(key);
+ return map.values();
+ }
+
+ /**
+ * 检查 Hash 字段是否存在
+ *
+ * @param key 键
+ * @param field 字段
+ * @return 是否存在
+ */
+ public boolean hExists(String key, String field) {
+ RMap map = redissonClient.getMap(key);
+ return map.containsKey(field);
+ }
+
+ /**
+ * 获取 Hash 大小
+ *
+ * @param key 键
+ * @return 大小
+ */
+ public int hSize(String key) {
+ RMap map = redissonClient.getMap(key);
+ return map.size();
+ }
+
+ /**
+ * 添加到 Set
+ *
+ * @param key 键
+ * @param value 值
+ * @return 是否添加成功
+ */
+ public boolean sAdd(String key, String value) {
+ RSet set = redissonClient.getSet(key);
+ return set.add(value);
+ }
+
+ /**
+ * 从 Set 移除
+ *
+ * @param key 键
+ * @param value 值
+ * @return 是否移除成功
+ */
+ public boolean sRem(String key, String value) {
+ RSet set = redissonClient.getSet(key);
+ return set.remove(value);
+ }
+
+ /**
+ * 获取 Set 所有成员
+ *
+ * @param key 键
+ * @return 成员集合
+ */
+ public Set sMembers(String key) {
+ RSet set = redissonClient.getSet(key);
+ return new HashSet<>(set.readAll());
+ }
+
+ /**
+ * 检查 Set 是否包含成员
+ *
+ * @param key 键
+ * @param value 值
+ * @return 是否包含
+ */
+ public boolean sIsMember(String key, String value) {
+ RSet set = redissonClient.getSet(key);
+ return set.contains(value);
+ }
+}
diff --git a/src/main/java/cn/yinlihupo/controller/project/ProjectInitSseController.java b/src/main/java/cn/yinlihupo/controller/project/ProjectInitSseController.java
index b1f7939..584cca6 100644
--- a/src/main/java/cn/yinlihupo/controller/project/ProjectInitSseController.java
+++ b/src/main/java/cn/yinlihupo/controller/project/ProjectInitSseController.java
@@ -5,16 +5,16 @@ import cn.yinlihupo.common.enums.AsyncTaskStatus;
import cn.yinlihupo.common.sse.SseChannelManager;
import cn.yinlihupo.common.sse.SseMessage;
import cn.yinlihupo.common.util.ResultUtils;
+import cn.yinlihupo.common.util.SecurityUtils;
+import cn.yinlihupo.domain.vo.ProjectInitTaskVO;
import cn.yinlihupo.service.project.ProjectInitAsyncService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -37,7 +37,7 @@ public class ProjectInitSseController {
/**
* 通过 SSE 提交项目初始化任务
- * 使用通用 SSE 通道,通过 userId 推送进度
+ * SSE 推送已在 Service 层自动处理
*
* @param userId 用户ID
* @param file 项目资料文件
@@ -58,18 +58,10 @@ public class ProjectInitSseController {
}
try {
- // 提交异步任务,带进度回调
- String taskId = projectInitAsyncService.submitPreviewTask(file, taskVO -> {
- // 构建消息并推送
- SseMessage message = SseMessage.of(MESSAGE_TYPE, "progress", userId, taskVO);
- sseChannelManager.send(userId, message);
-
- // 任务完成或失败,推送完成事件
- if (isTaskFinished(taskVO.getStatus())) {
- SseMessage completeMessage = SseMessage.of(MESSAGE_TYPE, "complete", userId, taskVO);
- sseChannelManager.send(userId, completeMessage);
- }
- });
+ Long userIdLong = Long.valueOf(userId);
+
+ // 提交异步任务(SSE 推送由 Service 层自动处理)
+ String taskId = projectInitAsyncService.submitPreviewTask(file, userIdLong);
// 推送任务提交成功事件
Map submittedData = new HashMap<>();
@@ -99,20 +91,74 @@ public class ProjectInitSseController {
}
}
+ /**
+ * 查询我的任务列表
+ * 根据当前登录用户的token查询其所有任务
+ *
+ * @return 任务列表
+ */
+ @GetMapping("/my-tasks")
+ public BaseResponse> getMyTasks() {
+ Long userId = SecurityUtils.getCurrentUserId();
+ if (userId == null) {
+ return ResultUtils.error("用户未登录");
+ }
+
+ List tasks = projectInitAsyncService.getTasksByUserId(userId);
+ return ResultUtils.success(tasks);
+ }
+
+ /**
+ * 查询我的任务统计信息
+ *
+ * @return 统计信息
+ */
+ @GetMapping("/my-tasks/stats")
+ public BaseResponse