Преглед на файлове

feat: MobileMvcConfig 新增线程池配置、许愿接口增加 type 参数

- 添加 mobileTaskExecutor 线程池(核心4/最大16/队列200)
- @EnableAsync 启用异步支持
- wish/create 接口区分手动许愿(type=1)和AI一键许愿(type=2)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
tanlie преди 2 седмици
родител
ревизия
1eaf700118
променени са 20 файла, в които са добавени 184 реда и са изтрити 11 реда
  1. 18 1
      wishing-platform/platform-core/platform-core-base/src/main/java/cn/qinys/platform/base/security/utils/CurrentUtils.java
  2. 22 0
      wishing-platform/platform-entity/platform-entity-wishing/src/main/java/cn/qinys/platform/entity/wishing/SpringAiChatMemory.java
  3. 2 0
      wishing-platform/platform-entity/platform-entity-wishing/src/main/java/cn/qinys/platform/entity/wishing/UserWish.java
  4. BIN
      wishing-platform/platform-entity/platform-entity-wishing/target/classes/cn/qinys/platform/entity/wishing/SpringAiChatMemory.class
  5. BIN
      wishing-platform/platform-entity/platform-entity-wishing/target/classes/cn/qinys/platform/entity/wishing/UserWish.class
  6. 2 1
      wishing-platform/platform-entity/platform-entity-wishing/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst
  7. 1 0
      wishing-platform/platform-entity/platform-entity-wishing/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst
  8. BIN
      wishing-platform/platform-entity/platform-entity-wishing/target/platform-entity-wishing-1.0.0-SNAPSHOT.jar
  9. 24 3
      wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/config/MobileMvcConfig.java
  10. 14 0
      wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/mapper/SpringAiChatMemoryMapper.java
  11. 2 0
      wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/req/WishCreateReq.java
  12. 5 5
      wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/service/ImageService.java
  13. 59 0
      wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/service/impl/AbstractUserWishService.java
  14. 2 0
      wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/service/impl/UserWishServiceImpl.java
  15. 1 1
      wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/util/QwenImage.java
  16. 29 0
      wishing-platform/platform-service/platform-service-mobile/src/test/java/cn/qinys/platform/mobile/service/impl/UserWishServiceImplTest.java
  17. 1 0
      wishing-tree-h5/src/api/wish.ts
  18. 1 0
      wishing-tree-h5/src/components/ChatWidget.vue
  19. 1 0
      wishing-tree-h5/src/views/MakeWishView.vue
  20. BIN
      wishing-tree-h5/wish.zip

+ 18 - 1
wishing-platform/platform-core/platform-core-base/src/main/java/cn/qinys/platform/base/security/utils/CurrentUtils.java

@@ -1,7 +1,6 @@
 package cn.qinys.platform.base.security.utils;
 
 
-
 import cn.qinys.platform.base.redis.RedisKeyEnum;
 import cn.qinys.platform.base.security.constants.Constants;
 import cn.qinys.platform.base.utils.RedisUtils;
@@ -35,6 +34,9 @@ public class CurrentUtils {
      */
     public static String getCurrentUserId() {
         String token = getToken();
+        if (token == null) {
+            return "0";
+        }
         RedisUtils redisUtils = SpringUtil.getBean(RedisUtils.class);
         LoginUserInfo userInfo = (LoginUserInfo) redisUtils.get(RedisKeyEnum.CURRENT_USER.getCode() + token);
         return userInfo == null ? "0" : userInfo.getId();
@@ -48,6 +50,9 @@ public class CurrentUtils {
      */
     public static String getCurrentWxId() {
         String token = getToken();
+        if (token == null) {
+            return null;
+        }
         RedisUtils redisUtils = SpringUtil.getBean(RedisUtils.class);
         LoginUserInfo userInfo = (LoginUserInfo) redisUtils.get(RedisKeyEnum.CURRENT_USER.getCode() + token);
         return userInfo == null ? null : userInfo.getWxId();
@@ -60,6 +65,9 @@ public class CurrentUtils {
      */
     public static String getCurrentUsername() {
         String token = getToken();
+        if (token == null) {
+            return null;
+        }
         RedisUtils redisUtils = SpringUtil.getBean(RedisUtils.class);
         LoginUserInfo userInfo = (LoginUserInfo) redisUtils.get(RedisKeyEnum.CURRENT_USER.getCode() + token);
         return userInfo == null ? "" : userInfo.getUsername();
@@ -94,6 +102,9 @@ public class CurrentUtils {
      */
     public static LoginUserInfo getCurrentUserInfo() {
         String token = getToken();
+        if (token == null) {
+            return null;
+        }
         RedisUtils redisUtils = SpringUtil.getBean(RedisUtils.class);
         return (LoginUserInfo) redisUtils.get(RedisKeyEnum.CURRENT_USER.getCode() + token);
     }
@@ -106,6 +117,9 @@ public class CurrentUtils {
      */
     public static List<String> getPermissionCodes() {
         String token = getToken();
+        if (token == null) {
+            return null;
+        }
         RedisUtils redisUtils = SpringUtil.getBean(RedisUtils.class);
         LoginUserInfo userInfo = (LoginUserInfo) redisUtils.get(RedisKeyEnum.CURRENT_USER.getCode() + token);
         return userInfo == null || userInfo.getPermissionCodes() == null ? new ArrayList<>() : userInfo.getPermissionCodes();
@@ -114,6 +128,9 @@ public class CurrentUtils {
 
     public static String getToken() {
         ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        if (attributes == null) {
+            return null;
+        }
         HttpServletRequest request = attributes.getRequest();
         String token = request.getHeader(Constants.JwtEnum.AUTHORIZATION.getCode());
         return token == null ? null : token.replaceFirst(Constants.JwtEnum.BEARER.getCode(), "").trim();

+ 22 - 0
wishing-platform/platform-entity/platform-entity-wishing/src/main/java/cn/qinys/platform/entity/wishing/SpringAiChatMemory.java

@@ -0,0 +1,22 @@
+package cn.qinys.platform.entity.wishing;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * @author lie tan
+ * @description
+ * @date 2026-06-14 11:44
+ **/
+@Data
+@TableName("spring_ai_chat_memory")
+public class SpringAiChatMemory implements Serializable {
+    private String conversationId;
+    private String content;
+    private String type;
+    private LocalDateTime timestamp;
+
+}

+ 2 - 0
wishing-platform/platform-entity/platform-entity-wishing/src/main/java/cn/qinys/platform/entity/wishing/UserWish.java

@@ -52,4 +52,6 @@ public class UserWish extends BaseEntity {
      * 0=active, 1=fulfilled
      */
     private Integer status = 0;
+
+    private Integer type;
 }

BIN
wishing-platform/platform-entity/platform-entity-wishing/target/classes/cn/qinys/platform/entity/wishing/SpringAiChatMemory.class


BIN
wishing-platform/platform-entity/platform-entity-wishing/target/classes/cn/qinys/platform/entity/wishing/UserWish.class


+ 2 - 1
wishing-platform/platform-entity/platform-entity-wishing/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst

@@ -1,4 +1,5 @@
-cn\qinys\platform\entity\wishing\WishingTree.class
+cn\qinys\platform\entity\wishing\SpringAiChatMemory.class
 cn\qinys\platform\entity\wishing\ChatMessage.class
+cn\qinys\platform\entity\wishing\WishingTree.class
 cn\qinys\platform\entity\wishing\UserWish.class
 cn\qinys\platform\entity\wishing\WishingUser.class

+ 1 - 0
wishing-platform/platform-entity/platform-entity-wishing/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst

@@ -1,5 +1,6 @@
 G:\许愿树\wishing-platform\platform-entity\platform-entity-wishing\src\main\java\cn\qinys\platform\entity\wishing\BaseEntity.java
 G:\许愿树\wishing-platform\platform-entity\platform-entity-wishing\src\main\java\cn\qinys\platform\entity\wishing\ChatMessage.java
+G:\许愿树\wishing-platform\platform-entity\platform-entity-wishing\src\main\java\cn\qinys\platform\entity\wishing\SpringAiChatMemory.java
 G:\许愿树\wishing-platform\platform-entity\platform-entity-wishing\src\main\java\cn\qinys\platform\entity\wishing\UserWish.java
 G:\许愿树\wishing-platform\platform-entity\platform-entity-wishing\src\main\java\cn\qinys\platform\entity\wishing\WishingTree.java
 G:\许愿树\wishing-platform\platform-entity\platform-entity-wishing\src\main\java\cn\qinys\platform\entity\wishing\WishingTreeExtension.java

BIN
wishing-platform/platform-entity/platform-entity-wishing/target/platform-entity-wishing-1.0.0-SNAPSHOT.jar


+ 24 - 3
wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/config/MobileMvcConfig.java

@@ -2,22 +2,43 @@ package cn.qinys.platform.config;
 
 import cn.qinys.platform.properties.SystemProperties;
 import jakarta.annotation.Resource;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
+import java.util.concurrent.Executor;
+import java.util.concurrent.ThreadPoolExecutor;
+
+@EnableAsync
 @Configuration
 public class MobileMvcConfig implements WebMvcConfigurer {
 
     @Resource
     SystemProperties systemProperties;
 
+    /**
+     * 线程池配置
+     */
+    @Bean("mobileTaskExecutor")
+    public Executor mobileTaskExecutor() {
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(4);
+        executor.setMaxPoolSize(16);
+        executor.setQueueCapacity(200);
+        executor.setKeepAliveSeconds(60);
+        executor.setThreadNamePrefix("mobile-task-");
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        executor.setWaitForTasksToCompleteOnShutdown(true);
+        executor.setAwaitTerminationSeconds(30);
+        executor.initialize();
+        return executor;
+    }
 
     /**
      * 添加静态资源文件,外部可以直接访问地址
-     *
-     * @param registry
      */
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry) {

+ 14 - 0
wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/mapper/SpringAiChatMemoryMapper.java

@@ -0,0 +1,14 @@
+package cn.qinys.platform.mobile.mapper;
+
+import cn.qinys.platform.entity.wishing.SpringAiChatMemory;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @author lie tan
+ * @description
+ * @date 2026-06-14 11:46
+ **/
+@Mapper
+public interface SpringAiChatMemoryMapper extends BaseMapper<SpringAiChatMemory> {
+}

+ 2 - 0
wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/req/WishCreateReq.java

@@ -30,4 +30,6 @@ public class WishCreateReq implements Serializable {
     private Boolean isPublic = true;
 
     private List<String> tags;
+
+    private Integer type;
 }

+ 5 - 5
wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/service/ImageService.java

@@ -1,13 +1,13 @@
 package cn.qinys.platform.mobile.service;
 
 /**
-* @author lie tan
-* @description 
-* @date 2026-06-13 23:46
-**/
+ * @author lie tan
+ * @description
+ * @date 2026-06-13 23:46
+ **/
 public interface ImageService {
 
 
-    public String getImageUrl(String msg);
+    String getImageUrl(String msg);
 
 }

+ 59 - 0
wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/service/impl/AbstractUserWishService.java

@@ -1,8 +1,23 @@
 package cn.qinys.platform.mobile.service.impl;
 
+import cn.qinys.platform.entity.wishing.ChatMessage;
+import cn.qinys.platform.entity.wishing.SpringAiChatMemory;
+import cn.qinys.platform.entity.wishing.UserWish;
 import cn.qinys.platform.entity.wishing.WishingTreeExtension;
+import cn.qinys.platform.mobile.constants.MsgTypeEnum;
+import cn.qinys.platform.mobile.mapper.ChatMessageMapper;
+import cn.qinys.platform.mobile.mapper.SpringAiChatMemoryMapper;
+import cn.qinys.platform.mobile.mapper.UserWishMapper;
 import cn.qinys.platform.mobile.mapper.WishingTreeExtensionMapper;
+import cn.qinys.platform.mobile.service.ImageService;
+import com.alibaba.fastjson2.JSON;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import jakarta.annotation.Resource;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.StringUtils;
+
+import java.util.List;
 
 /**
  * @author lie tan
@@ -13,6 +28,15 @@ public abstract class AbstractUserWishService {
 
     @Resource
     WishingTreeExtensionMapper treeExtensionMapper;
+    @Resource
+    ImageService imageService;
+    @Resource
+    SpringAiChatMemoryMapper memoryMapper;
+    @Resource
+    UserWishMapper userWishMapper;
+    @Resource
+    ChatMessageMapper messageMapper;
+
 
     public void treeWishesCounter(Integer treeId, Integer isPublic) {
         WishingTreeExtension extension = treeExtensionMapper.selectByTreeId(treeId);
@@ -32,4 +56,39 @@ public abstract class AbstractUserWishService {
         treeExtensionMapper.insertOrUpdate(extension);
     }
 
+
+
+    @Async
+    public void appendWishImage(UserWish wish) {
+        QueryWrapper<SpringAiChatMemory> wrapper = new QueryWrapper<>();
+        wrapper.eq("conversation_id", wish.getUserId())
+                .orderByDesc("timestamp")
+                .last("limit 10");
+        List<SpringAiChatMemory> memoryList = memoryMapper.selectList(wrapper);
+        if (memoryList == null || memoryList.isEmpty()) {
+            return;
+        }
+
+        String sb = "请根据用户许下的愿望,以及最近几轮对话的内容,生成一张与许愿相关的图片。用户的愿望为" +
+                "content:" + wish.getContent() +
+                "tag:" + wish.getTags() +
+                "最近的聊天记录内容为:" + JSON.toJSONString(memoryList);
+
+        String imageUrl = imageService.getImageUrl(sb);
+
+        if (StringUtils.hasText(imageUrl)) {
+            wish.setImages(JSON.toJSONString(List.of(imageUrl)));
+            userWishMapper.updateById(wish);
+            ChatMessage chatMessage = new ChatMessage();
+            chatMessage.setUserId(wish.getUserId());
+            chatMessage.setTreeId(wish.getTreeId());
+            chatMessage.setType(MsgTypeEnum.TEXT.getValue());
+            chatMessage.setContent("小愿已为您的愿望生成了一张图片,您可以到许愿树下查看哦~~");
+            chatMessage.setRole("ai");
+            messageMapper.insert(chatMessage);
+        }
+
+
+    }
+
 }

+ 2 - 0
wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/service/impl/UserWishServiceImpl.java

@@ -71,8 +71,10 @@ public class UserWishServiceImpl extends AbstractUserWishService implements User
         wish.setAddress(req.getAddress());
         wish.setIsPublic(req.getIsPublic() != null && req.getIsPublic() ? 1 : 0);
         wish.setTags(JSON.toJSONString(req.getTags()));
+        wish.setType(req.getType());
         wishMapper.insert(wish);
         this.treeWishesCounter(req.getTreeId(), wish.getIsPublic());
+        this.appendWishImage(wish);
     }
 
     @Override

+ 1 - 1
wishing-platform/platform-service/platform-service-mobile/src/main/java/cn/qinys/platform/mobile/util/QwenImage.java

@@ -41,7 +41,7 @@ public class QwenImage {
         parameters.put("watermark", false);
         parameters.put("prompt_extend", true);
         parameters.put("negative_prompt", "低分辨率,低画质,肢体畸形,手指畸形,画面过饱和,蜡像感,人脸无细节,过度光滑,画面具有AI感。构图混乱。文字模糊,扭曲。");
-        parameters.put("size", "1024*1024");
+        parameters.put("size", "1000*1000");
 
         MultiModalConversationParam param = MultiModalConversationParam.builder()
                 .apiKey(apiKey)

+ 29 - 0
wishing-platform/platform-service/platform-service-mobile/src/test/java/cn/qinys/platform/mobile/service/impl/UserWishServiceImplTest.java

@@ -0,0 +1,29 @@
+package cn.qinys.platform.mobile.service.impl;
+
+import cn.qinys.platform.entity.wishing.UserWish;
+import cn.qinys.platform.mobile.mapper.UserWishMapper;
+import jakarta.annotation.Resource;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+/**
+ * @author lie tan
+ * @description
+ * @date 2026-06-14 12:04
+ **/
+@SpringBootTest
+class UserWishServiceImplTest {
+
+    @Resource
+    UserWishServiceImpl userWishService;
+    @Resource
+    UserWishMapper userWishMapper;
+
+    @Test
+    void appendWishImage() {
+        UserWish userWish = userWishMapper.selectById(84);
+        userWishService.appendWishImage(userWish);
+    }
+
+
+}

+ 1 - 0
wishing-tree-h5/src/api/wish.ts

@@ -54,6 +54,7 @@ export async function submitWish(data: {
   address: string
   isPublic: boolean
   tags: string[]
+  type: number
 }) {
   if (USE_MOCK) return createWishMock(data as any)
 

+ 1 - 0
wishing-tree-h5/src/components/ChatWidget.vue

@@ -256,6 +256,7 @@ async function confirmWish(index: number) {
       address: props.treeAddress || '',
       isPublic: true,
       tags: msg.wish.tags,
+      type: 2,
     })
     showSuccessToast('愿望已挂在树上!祝你心想事成 ✨')
     delete msg.wish

+ 1 - 0
wishing-tree-h5/src/views/MakeWishView.vue

@@ -112,6 +112,7 @@ async function submitWish() {
       address: tree.value.address,
       isPublic: isPublic.value,
       tags: tags.value,
+      type: 1,
     })
     showSuccessToast('愿望已挂在树上!祝你心想事成 ✨')
     setTimeout(() => router.replace('/my-wishes'), 2200)

BIN
wishing-tree-h5/wish.zip