Browse Source

修复订阅消息问题

glx
glx 1 week ago
parent
commit
784b9b4a13
  1. 6
      src/main/java/com/youlai/boot/mini/controller/AiGenerationController.java
  2. 2
      src/main/java/com/youlai/boot/mini/controller/MiniUserController.java
  3. 2
      src/main/java/com/youlai/boot/mini/model/form/WxSubscribeAuthForm.java
  4. 2
      src/main/java/com/youlai/boot/mini/model/form/WxSubscribeSendForm.java
  5. 68
      src/main/java/com/youlai/boot/mini/service/impl/AiGenerationServiceImpl.java
  6. 1
      src/main/java/com/youlai/boot/mini/service/impl/MiniUserServiceImpl.java
  7. 15
      src/main/java/com/youlai/boot/mini/service/impl/WxSubscribeServiceImpl.java
  8. 3
      src/main/resources/application-dev.yml
  9. 1
      src/main/resources/mapper/mini/MiniUserSubscribeMapper.xml

6
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)

2
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<Void> updateCurrentUserInfo(@Valid MiniUserUpdateForm form) {
public Result<Void> updateCurrentUserInfo(@Valid @RequestBody MiniUserUpdateForm form) {
Long userId = SecurityUtils.getUserId();
miniUserService.updateCurrentUserInfo(userId, form);
return Result.success();

2
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;

2
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;

68
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<MiniAiGenerationTask> 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<MiniAiTaskMedia> 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<MiniAiTaskMedia> mediaList = aiTaskMediaMapper.selectList(mediaQueryWrapper);
@ -960,7 +944,7 @@ public class AiGenerationServiceImpl implements AiGenerationService {
));
// 5. 组装VO
return taskPage.convert(task -> {
IPage<AiGenerationTaskVO> 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);
}
}
}

1
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("头像上传失败");

15
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<Map<String, String>> dataList = new ArrayList<>();
// 2. 构建微信订阅消息参数(新版小程序订阅消息格式)
Map<String, Map<String, String>> dataMap = new HashMap<>();
for (Map.Entry<String, String> entry : form.getTemplateParams().entrySet()) {
Map<String, String> dataMap = new HashMap<>();
dataMap.put("name", entry.getKey());
dataMap.put("value", entry.getValue());
dataList.add(dataMap);
Map<String, String> valueMap = new HashMap<>();
valueMap.put("value", entry.getValue());
dataMap.put(entry.getKey(), valueMap);
}
Map<String, Object> 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));

3
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

1
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
</select>

Loading…
Cancel
Save