From 784b9b4a13c8dc6a4eea4ee839f8621f53c13c6f Mon Sep 17 00:00:00 2001 From: glx <783262171@qq.com> Date: Thu, 21 May 2026 10:17:45 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AE=A2=E9=98=85=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AiGenerationController.java | 6 +- .../mini/controller/MiniUserController.java | 2 +- .../mini/model/form/WxSubscribeAuthForm.java | 2 +- .../mini/model/form/WxSubscribeSendForm.java | 2 +- .../service/impl/AiGenerationServiceImpl.java | 68 +++++++++++-------- .../service/impl/MiniUserServiceImpl.java | 1 + .../service/impl/WxSubscribeServiceImpl.java | 15 ++-- src/main/resources/application-dev.yml | 3 +- .../mapper/mini/MiniUserSubscribeMapper.xml | 1 - 9 files changed, 56 insertions(+), 44 deletions(-) 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 8fa65b1..1b6277c 100644 --- a/src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java +++ b/src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java @@ -6,15 +6,12 @@ import com.youlai.boot.common.enums.ActionTypeEnum; import com.youlai.boot.common.enums.LogModuleEnum; import com.youlai.boot.common.result.Result; import com.youlai.boot.framework.security.util.SecurityUtils; -import com.youlai.boot.mini.model.entity.MiniAiTaskMedia; import com.youlai.boot.mini.model.form.*; import com.youlai.boot.mini.model.vo.AiVideoCallbackVO; import com.youlai.boot.mini.service.AiGenerationService; import com.youlai.boot.mini.service.WxSubscribeService; +import io.swagger.v3.oas.annotations.Hidden; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.enums.ParameterIn; -import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -111,6 +108,7 @@ public class AiGenerationController { return Result.success(); } + @Hidden @Operation(summary = "发送微信订阅消息") @PostMapping("/subscribe/send") @Log(module = LogModuleEnum.AI_GENERATION_TASK, value = ActionTypeEnum.INSERT) diff --git a/src/main/java/com/youlai/boot/mini/controller/MiniUserController.java b/src/main/java/com/youlai/boot/mini/controller/MiniUserController.java index 173645b..e62f335 100644 --- a/src/main/java/com/youlai/boot/mini/controller/MiniUserController.java +++ b/src/main/java/com/youlai/boot/mini/controller/MiniUserController.java @@ -46,7 +46,7 @@ public class MiniUserController { @Operation(summary = "修改当前登录用户基本信息") @PostMapping(value = "/updateInfo") @Log(module = LogModuleEnum.USER, value = ActionTypeEnum.UPDATE) - public Result updateCurrentUserInfo(@Valid MiniUserUpdateForm form) { + public Result updateCurrentUserInfo(@Valid @RequestBody MiniUserUpdateForm form) { Long userId = SecurityUtils.getUserId(); miniUserService.updateCurrentUserInfo(userId, form); return Result.success(); diff --git a/src/main/java/com/youlai/boot/mini/model/form/WxSubscribeAuthForm.java b/src/main/java/com/youlai/boot/mini/model/form/WxSubscribeAuthForm.java index e6c15d4..a7e90e3 100644 --- a/src/main/java/com/youlai/boot/mini/model/form/WxSubscribeAuthForm.java +++ b/src/main/java/com/youlai/boot/mini/model/form/WxSubscribeAuthForm.java @@ -12,7 +12,7 @@ import lombok.Data; @Schema(description = "上报用户订阅授权请求") public class WxSubscribeAuthForm { - @NotBlank(message = "用户ID不能为空") +// @NotBlank(message = "用户ID不能为空") @Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED) private Long userId; diff --git a/src/main/java/com/youlai/boot/mini/model/form/WxSubscribeSendForm.java b/src/main/java/com/youlai/boot/mini/model/form/WxSubscribeSendForm.java index c51ad18..04b11aa 100644 --- a/src/main/java/com/youlai/boot/mini/model/form/WxSubscribeSendForm.java +++ b/src/main/java/com/youlai/boot/mini/model/form/WxSubscribeSendForm.java @@ -13,7 +13,7 @@ import java.util.Map; @Schema(description = "发送订阅消息请求") public class WxSubscribeSendForm { - @NotBlank(message = "用户ID不能为空") +// @NotBlank(message = "用户ID不能为空") @Schema(description = "用户ID", requiredMode = Schema.RequiredMode.REQUIRED) private 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 cc7fae9..fa4e12f 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 @@ -554,11 +554,11 @@ public class AiGenerationServiceImpl implements AiGenerationService { WxSubscribeSendForm sendForm = new WxSubscribeSendForm(); sendForm.setUserId(task.getMiniUserId()); sendForm.setTemplateId(subscribeTemplate); - sendForm.setPage("pages/index/index"); + sendForm.setPage("pages/creation/list"); sendForm.setTemplateParams(Map.of( - "thing1", "您的AI视频作品已完成", - "time2", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")), - "phrase3", "点击查看状态" + "thing5", "您的AI视频作品已完成", + "time3", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm")), + "phrase4", "待查看" )); wxSubscribeService.sendMessage(sendForm); } catch (Exception e) { @@ -657,23 +657,7 @@ public class AiGenerationServiceImpl implements AiGenerationService { aiTaskMediaMapper.update(null, updateMediaWrapper); // 同步发送订阅消息通知 - if (StrUtil.isNotBlank(subscribeTemplate)) { - try { - WxSubscribeSendForm sendForm = new WxSubscribeSendForm(); - sendForm.setUserId(task.getMiniUserId()); - sendForm.setTemplateId(subscribeTemplate); - sendForm.setPage("pages/index/index"); - // 根据实际模板字段调整参数 - sendForm.setTemplateParams(Map.of( - "thing1", "您的AI绘画作品已完成", - "time2", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")), - "phrase3", "点击查看状态" - )); - wxSubscribeService.sendMessage(sendForm); - } catch (Exception e) { - log.error("单图任务{}发送订阅消息失败", task.getId(), e); - } - } + sendAiGenerateSuccessNotify(task.getMiniUserId(), subscribeTemplate, task.getId()); } log.info("四宫格任务{}回调处理完成,状态:{}", taskUuid, status); @@ -765,12 +749,12 @@ public class AiGenerationServiceImpl implements AiGenerationService { WxSubscribeSendForm sendForm = new WxSubscribeSendForm(); sendForm.setUserId(task.getMiniUserId()); sendForm.setTemplateId(subscribeTemplate); - sendForm.setPage("pages/index/index"); + sendForm.setPage("pages/creation/list"); // 根据实际模板字段调整参数 sendForm.setTemplateParams(Map.of( - "thing1", "您的AI绘画作品已完成", - "time2", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")), - "phrase3", "点击查看状态" + "thing5", "您的AI绘画作品已完成", + "time3", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm")), + "phrase4", "待查看" )); wxSubscribeService.sendMessage(sendForm); } catch (Exception e) { @@ -917,7 +901,7 @@ public class AiGenerationServiceImpl implements AiGenerationService { if (query.getType() != null) { taskQueryWrapper.eq(MiniAiGenerationTask::getType, query.getType()); } - taskQueryWrapper.orderByDesc(MiniAiGenerationTask::getCreateTime); + taskQueryWrapper.orderByDesc(MiniAiGenerationTask::getCreateTimestamp); IPage taskPage = aiGenerationTaskMapper.selectPage(new Page<>(query.getPageNum(), query.getPageSize()), taskQueryWrapper); if (taskPage.getRecords().isEmpty()) { @@ -932,7 +916,7 @@ public class AiGenerationServiceImpl implements AiGenerationService { // 3. 批量查询这些任务对应的AI生成媒体内容 LambdaQueryWrapper mediaQueryWrapper = new LambdaQueryWrapper<>(); mediaQueryWrapper.in(MiniAiTaskMedia::getTaskId, taskIds); - mediaQueryWrapper.eq(MiniAiTaskMedia::getFileSource, "ai_generate"); + mediaQueryWrapper.eq(MiniAiTaskMedia::getFileSource, "ai_generated"); mediaQueryWrapper.eq(MiniAiTaskMedia::getDeleted, false); List mediaList = aiTaskMediaMapper.selectList(mediaQueryWrapper); @@ -960,7 +944,7 @@ public class AiGenerationServiceImpl implements AiGenerationService { )); // 5. 组装VO - return taskPage.convert(task -> { + IPage convert = taskPage.convert(task -> { AiGenerationTaskVO vo = new AiGenerationTaskVO(); // vo.setId(task.getId()); vo.setUuid(task.getUuid()); @@ -971,6 +955,34 @@ public class AiGenerationServiceImpl implements AiGenerationService { vo.setGenerateContent(mediaGroupMap.getOrDefault(task.getId(), Collections.emptyList())); return vo; }); + log.info("用户{}查询AI生成任务历史成功,结果:{}", userId, convert.getRecords().toString()); + return convert; + } + + /** + * 发送AI绘画完成订阅消息通知 + * @param userId 接收用户ID + * @param templateId 订阅消息模板ID + * @param taskId 任务ID(仅用于日志) + */ + private void sendAiGenerateSuccessNotify(Long userId, String templateId, Long taskId) { + if (StrUtil.isBlank(templateId)) { + return; + } + try { + WxSubscribeSendForm sendForm = new WxSubscribeSendForm(); + sendForm.setUserId(userId); + sendForm.setTemplateId(templateId); + sendForm.setPage("pages/creation/list"); + sendForm.setTemplateParams(Map.of( + "thing5", "您的AI绘画作品已完成", + "time3", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm")), + "phrase4", "待查看" + )); + wxSubscribeService.sendMessage(sendForm); + } catch (Exception e) { + log.error("四宫格图片任务{}发送订阅消息失败", taskId, e); + } } } diff --git a/src/main/java/com/youlai/boot/mini/service/impl/MiniUserServiceImpl.java b/src/main/java/com/youlai/boot/mini/service/impl/MiniUserServiceImpl.java index 3a6daea..2aa35a1 100644 --- a/src/main/java/com/youlai/boot/mini/service/impl/MiniUserServiceImpl.java +++ b/src/main/java/com/youlai/boot/mini/service/impl/MiniUserServiceImpl.java @@ -132,6 +132,7 @@ public class MiniUserServiceImpl implements MiniUserService { log.warn("删除用户旧头像失败,userId={}, oldAvatar={}", userId, oldAvatar, e); } } + sysUserService.update(updateWrapper); } catch (Exception e) { log.error("user avatar upload failed", e); throw new MsgException("头像上传失败"); diff --git a/src/main/java/com/youlai/boot/mini/service/impl/WxSubscribeServiceImpl.java b/src/main/java/com/youlai/boot/mini/service/impl/WxSubscribeServiceImpl.java index 6d0f2a0..fc7c4d0 100644 --- a/src/main/java/com/youlai/boot/mini/service/impl/WxSubscribeServiceImpl.java +++ b/src/main/java/com/youlai/boot/mini/service/impl/WxSubscribeServiceImpl.java @@ -1,6 +1,7 @@ package com.youlai.boot.mini.service.impl; import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -58,6 +59,7 @@ public class WxSubscribeServiceImpl implements WxSubscribeService { userSubscribeMapper.updateById(exist); } else { MiniUserSubscribe subscribe = new MiniUserSubscribe(); + subscribe.setUuid(IdUtil.fastSimpleUUID()); subscribe.setUserId(form.getUserId()); subscribe.setTemplateId(form.getTemplateId()); subscribe.setStatus(form.getStatus()); @@ -87,13 +89,12 @@ public class WxSubscribeServiceImpl implements WxSubscribeService { return false; } - // 2. 构建微信订阅消息参数 - List> dataList = new ArrayList<>(); + // 2. 构建微信订阅消息参数(新版小程序订阅消息格式) + Map> dataMap = new HashMap<>(); for (Map.Entry entry : form.getTemplateParams().entrySet()) { - Map dataMap = new HashMap<>(); - dataMap.put("name", entry.getKey()); - dataMap.put("value", entry.getValue()); - dataList.add(dataMap); + Map valueMap = new HashMap<>(); + valueMap.put("value", entry.getValue()); + dataMap.put(entry.getKey(), valueMap); } Map messageMap = new HashMap<>(); @@ -102,7 +103,7 @@ public class WxSubscribeServiceImpl implements WxSubscribeService { messageMap.put("page", form.getPage()); messageMap.put("miniprogram_state", form.getMiniProgramState()); messageMap.put("lang", "zh_CN"); - messageMap.put("data", dataList); + messageMap.put("data", dataMap); // 3. 调用微信接口发送 String responseStr = wxMaService.post("https://api.weixin.qq.com/cgi-bin/message/subscribe/send", JSONUtil.toJsonStr(messageMap)); diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 35c102f..b20e303 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -94,6 +94,7 @@ security: - /api/v1/mini/ai/generation/single-image/task/callback # AIGeneration 单图任务回调 - /api/v1/mini/ai/generation/video/task/callback # AIGeneration 视频任务回调 - /api/v1/mini/ai/generation/four-panel/task/callback # AIGeneration 四宫格任务回调 + - /api/v1/mini/ai/generation/subscribe/send # AIGeneration 发送订阅消息 # 非安全端点路径,完全绕过 Spring Security 的过滤器 unsecured-urls: - ${springdoc.swagger-ui.path} @@ -239,7 +240,7 @@ ai: single-image-callback-url: http://192.168.31.197:30101/backend/api/v1/mini/ai/generation/single-image/task/callback four-panel-callback-url: http://192.168.31.197:30101/backend/api/v1/mini/ai/generation/four-panel/task/callback #需要内网穿透工具 由火山方舟 api 回调,ngrok http 30101 替换为内网穿透工具地址 - video-url: https://2dd0-153-34-180-144.ngrok-free.app/backend/api/v1/mini/ai/generation/video/task/callback + video-url: http://101.34.78.57:30101/backend/api/v1/mini/ai/generation/video/task/callback default: image-model: doubao-seedream-5-0-260128 video-model: doubao-seedance-2-0-260128 diff --git a/src/main/resources/mapper/mini/MiniUserSubscribeMapper.xml b/src/main/resources/mapper/mini/MiniUserSubscribeMapper.xml index c418984..3018fa3 100644 --- a/src/main/resources/mapper/mini/MiniUserSubscribeMapper.xml +++ b/src/main/resources/mapper/mini/MiniUserSubscribeMapper.xml @@ -9,7 +9,6 @@ SELECT openid FROM sys_user_social WHERE user_id = #{userId} - AND is_deleted = 0 LIMIT 1