refactor(notifications): 重构通知系统使用统一的微信订阅通知触发服务

- 移除 UserNotificationAuthController 中的 getScenicTemplatesWithAuth 方法
- 从 ScenicRepository 中删除微信模板ID相关方法和配置
- 重命名 WechatSubscribeNotifyTriggerService 为 notifyTriggerService
- 更新 TaskTaskServiceImpl 中的视频生成通知逻辑
- 重构 DownloadNotificationTasker 中的通知发送方式
- 统一使用 WechatSubscribeNotifyTriggerRequest 和 WechatSubscribeNotifyTriggerResult
- 移除 ZT 消息服务相关代码
- 简化变量传递和通知模板逻辑
This commit is contained in:
2026-01-06 15:35:09 +08:00
parent 95e86fb996
commit 123a081eab
4 changed files with 61 additions and 405 deletions

View File

@@ -92,100 +92,4 @@ public class UserNotificationAuthController {
return ApiResponse.fail("记录授权失败: " + e.getMessage()); return ApiResponse.fail("记录授权失败: " + e.getMessage());
} }
} }
/**
* 获取景区通知模板ID及用户授权余额
* 复制AppWxNotifyController中的逻辑,并额外返回用户对应的授权余额
*/
@GetMapping("/{scenicId}/templates")
public ApiResponse<ScenicTemplateAuthResp> getScenicTemplatesWithAuth(@PathVariable("scenicId") Long scenicId) {
log.debug("获取景区通知模板ID及用户授权余额: scenicId={}", scenicId);
try {
// 获取当前用户ID
Long memberId = JwtTokenUtil.getWorker().getUserId();
// 获取景区的所有模板ID(复制自AppWxNotifyController的逻辑)
List<String> templateIds = new ArrayList<>() {{
String videoGeneratedTemplateId = scenicRepository.getVideoGeneratedTemplateId(scenicId);
if (StringUtils.isNotBlank(videoGeneratedTemplateId)) {
add(videoGeneratedTemplateId);
}
String videoDownloadTemplateId = scenicRepository.getVideoDownloadTemplateId(scenicId);
if (StringUtils.isNotBlank(videoDownloadTemplateId)) {
add(videoDownloadTemplateId);
}
String videoPreExpireTemplateId = scenicRepository.getVideoPreExpireTemplateId(scenicId);
if (StringUtils.isNotBlank(videoPreExpireTemplateId)) {
add(videoPreExpireTemplateId);
}
}};
// 构建响应对象
ScenicTemplateAuthResp resp = new ScenicTemplateAuthResp();
resp.setScenicId(scenicId);
// 查询每个模板的授权余额信息
List<ScenicTemplateAuthResp.TemplateAuthInfo> templateAuthInfos = new ArrayList<>();
for (String templateId : templateIds) {
ScenicTemplateAuthResp.TemplateAuthInfo templateAuthInfo =
new ScenicTemplateAuthResp.TemplateAuthInfo();
templateAuthInfo.setTemplateId(templateId);
if (templateId.equals(scenicRepository.getVideoGeneratedTemplateId(scenicId))) {
templateAuthInfo.setTitle("视频生成通知");
templateAuthInfo.setDescription("当视频生成完成时,我们将提醒您");
} else if (templateId.equals(scenicRepository.getVideoDownloadTemplateId(scenicId))) {
templateAuthInfo.setTitle("视频下载通知");
templateAuthInfo.setDescription("当您的视频未购买时,我们将提醒您");
} else if (templateId.equals(scenicRepository.getVideoPreExpireTemplateId(scenicId))) {
templateAuthInfo.setTitle("视频即将过期通知");
templateAuthInfo.setDescription("当您的视频即将过期时,我们将提醒您及时下载");
} else {
templateAuthInfo.setTitle("未知模板类型");
templateAuthInfo.setDescription("未知的模板类型");
}
// 获取授权详情
try {
com.ycwl.basic.model.pc.notify.entity.UserNotificationAuthorizationEntity authEntity =
userNotificationAuthorizationService.checkAuthorization(memberId, templateId, scenicId);
if (authEntity != null) {
templateAuthInfo.setAuthorizationCount(authEntity.getAuthorizationCount());
templateAuthInfo.setConsumedCount(authEntity.getConsumedCount());
templateAuthInfo.setRemainingCount(authEntity.getRemainingCount());
templateAuthInfo.setHasAuthorization(authEntity.getRemainingCount() != null && authEntity.getRemainingCount() > 0);
} else {
// 没有授权记录
templateAuthInfo.setAuthorizationCount(0);
templateAuthInfo.setConsumedCount(0);
templateAuthInfo.setRemainingCount(0);
templateAuthInfo.setHasAuthorization(false);
}
} catch (Exception e) {
log.warn("获取模板授权信息失败: templateId={}, scenicId={}, memberId={}, error={}",
templateId, scenicId, memberId, e.getMessage());
// 获取失败时设置为无授权
templateAuthInfo.setAuthorizationCount(0);
templateAuthInfo.setConsumedCount(0);
templateAuthInfo.setRemainingCount(0);
templateAuthInfo.setHasAuthorization(false);
}
templateAuthInfos.add(templateAuthInfo);
}
resp.setTemplates(templateAuthInfos);
log.debug("成功获取景区通知模板ID及用户授权余额: scenicId={}, templateCount={}, memberId={}",
scenicId, templateIds.size(), memberId);
return ApiResponse.success(resp);
} catch (Exception e) {
log.error("获取景区通知模板ID及用户授权余额失败: scenicId={}", scenicId, e);
return ApiResponse.fail("获取授权信息失败: " + e.getMessage());
}
}
} }

View File

@@ -1,7 +1,5 @@
package com.ycwl.basic.repository; package com.ycwl.basic.repository;
import com.ycwl.basic.facebody.enums.FaceBodyAdapterType;
import com.ycwl.basic.integration.common.util.ConfigValueUtil;
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO; import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
import com.ycwl.basic.integration.common.response.PageResponse; import com.ycwl.basic.integration.common.response.PageResponse;
import com.ycwl.basic.integration.scenic.service.ScenicIntegrationService; import com.ycwl.basic.integration.scenic.service.ScenicIntegrationService;
@@ -14,8 +12,6 @@ import com.ycwl.basic.model.pc.mp.MpNotifyConfigEntity;
import com.ycwl.basic.model.pc.mp.ScenicMpNotifyVO; import com.ycwl.basic.model.pc.mp.ScenicMpNotifyVO;
import com.ycwl.basic.model.pc.scenic.entity.ScenicEntity; import com.ycwl.basic.model.pc.scenic.entity.ScenicEntity;
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery; import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
import com.ycwl.basic.pay.enums.PayAdapterType;
import com.ycwl.basic.storage.enums.StorageType;
import com.ycwl.basic.utils.JacksonUtil; import com.ycwl.basic.utils.JacksonUtil;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager; import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -41,8 +37,6 @@ public class ScenicRepository {
public static final String SCENIC_MP_CACHE_KEY = "scenic:%s:mp"; public static final String SCENIC_MP_CACHE_KEY = "scenic:%s:mp";
public static final String SCENIC_MP_NOTIFY_CACHE_KEY = "scenic:%s:mpNotify"; public static final String SCENIC_MP_NOTIFY_CACHE_KEY = "scenic:%s:mpNotify";
@Autowired
private MpNotifyConfigMapper mpNotifyConfigMapper;
public ScenicV2DTO getScenicBasic(Long id) { public ScenicV2DTO getScenicBasic(Long id) {
ScenicV2DTO scenicDTO = scenicIntegrationService.getScenic(id); ScenicV2DTO scenicDTO = scenicIntegrationService.getScenic(id);
@@ -70,61 +64,6 @@ public class ScenicRepository {
return mpConfigEntity; return mpConfigEntity;
} }
public ScenicMpNotifyVO getScenicMpNotifyConfig(Long scenicId) {
if (redisTemplate.hasKey(String.format(SCENIC_MP_NOTIFY_CACHE_KEY, scenicId))) {
return JacksonUtil.parseObject(redisTemplate.opsForValue().get(String.format(SCENIC_MP_NOTIFY_CACHE_KEY, scenicId)), ScenicMpNotifyVO.class);
}
MpConfigEntity mpConfig = getScenicMpConfig(scenicId);
if (mpConfig == null) {
return null;
}
ScenicMpNotifyVO mpNotifyConfig = new ScenicMpNotifyVO();
mpNotifyConfig.setAppId(mpConfig.getAppId());
mpNotifyConfig.setAppSecret(mpConfig.getAppSecret());
mpNotifyConfig.setMpId(mpConfig.getId());
mpNotifyConfig.setAppState(mpConfig.getState());
List<MpNotifyConfigEntity> mpNotifyConfigList = mpNotifyConfigMapper.listByMpId(mpConfig.getId());
mpNotifyConfigList.forEach(item -> {
switch (item.getType()) {
case 0:
mpNotifyConfig.setVideoGeneratedTemplateId(item.getTemplateId());
break;
case 1:
mpNotifyConfig.setVideoDownloadTemplateId(item.getTemplateId());
break;
case 2:
mpNotifyConfig.setVideoPreExpireTemplateId(item.getTemplateId());
break;
}
});
redisTemplate.opsForValue().set(String.format(SCENIC_MP_NOTIFY_CACHE_KEY, scenicId), JacksonUtil.toJSONString(mpNotifyConfig));
return mpNotifyConfig;
}
public String getVideoGeneratedTemplateId(Long scenicId) {
ScenicMpNotifyVO scenicMpNotifyConfig = getScenicMpNotifyConfig(scenicId);
if (scenicMpNotifyConfig != null) {
return scenicMpNotifyConfig.getVideoGeneratedTemplateId();
}
return null;
}
public String getVideoDownloadTemplateId(Long scenicId) {
ScenicMpNotifyVO scenicMpNotifyConfig = getScenicMpNotifyConfig(scenicId);
if (scenicMpNotifyConfig != null) {
return scenicMpNotifyConfig.getVideoDownloadTemplateId();
}
return null;
}
public String getVideoPreExpireTemplateId(Long scenicId) {
ScenicMpNotifyVO scenicMpNotifyConfig = getScenicMpNotifyConfig(scenicId);
if (scenicMpNotifyConfig != null) {
return scenicMpNotifyConfig.getVideoPreExpireTemplateId();
}
return null;
}
public List<ScenicV2DTO> list(ScenicReqQuery scenicReqQuery) { public List<ScenicV2DTO> list(ScenicReqQuery scenicReqQuery) {
try { try {
// 将 ScenicReqQuery 参数转换为 zt-scenic 服务需要的参数 // 将 ScenicReqQuery 参数转换为 zt-scenic 服务需要的参数

View File

@@ -8,7 +8,6 @@ import com.ycwl.basic.enums.TemplateRenderStatus;
import com.ycwl.basic.integration.common.manager.DeviceConfigManager; import com.ycwl.basic.integration.common.manager.DeviceConfigManager;
import com.ycwl.basic.integration.common.manager.RenderWorkerConfigManager; import com.ycwl.basic.integration.common.manager.RenderWorkerConfigManager;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager; import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import com.ycwl.basic.integration.message.dto.ZtMessage;
import com.ycwl.basic.integration.message.service.ZtMessageProducerService; import com.ycwl.basic.integration.message.service.ZtMessageProducerService;
import com.ycwl.basic.repository.MemberRelationRepository; import com.ycwl.basic.repository.MemberRelationRepository;
import com.ycwl.basic.repository.SourceRepository; import com.ycwl.basic.repository.SourceRepository;
@@ -16,10 +15,7 @@ import com.ycwl.basic.utils.JacksonUtil;
import com.ycwl.basic.biz.OrderBiz; import com.ycwl.basic.biz.OrderBiz;
import com.ycwl.basic.biz.TemplateBiz; import com.ycwl.basic.biz.TemplateBiz;
import com.ycwl.basic.constant.StorageConstant; import com.ycwl.basic.constant.StorageConstant;
import com.ycwl.basic.mapper.FaceMapper;
import com.ycwl.basic.mapper.FaceSampleMapper;
import com.ycwl.basic.mapper.MemberMapper; import com.ycwl.basic.mapper.MemberMapper;
import com.ycwl.basic.mapper.SourceMapper;
import com.ycwl.basic.mapper.TaskMapper; import com.ycwl.basic.mapper.TaskMapper;
import com.ycwl.basic.mapper.VideoMapper; import com.ycwl.basic.mapper.VideoMapper;
import com.ycwl.basic.model.mobile.order.IsBuyRespVO; import com.ycwl.basic.model.mobile.order.IsBuyRespVO;
@@ -28,7 +24,6 @@ import com.ycwl.basic.model.pc.faceSample.entity.FaceSampleEntity;
import com.ycwl.basic.model.pc.member.resp.MemberRespVO; import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
import com.ycwl.basic.model.pc.mp.MpConfigEntity; import com.ycwl.basic.model.pc.mp.MpConfigEntity;
import com.ycwl.basic.model.pc.renderWorker.entity.RenderWorkerEntity; import com.ycwl.basic.model.pc.renderWorker.entity.RenderWorkerEntity;
import com.ycwl.basic.model.pc.scenic.entity.ScenicConfigEntity;
import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO; import com.ycwl.basic.integration.scenic.dto.scenic.ScenicV2DTO;
import com.ycwl.basic.model.pc.source.entity.SourceEntity; import com.ycwl.basic.model.pc.source.entity.SourceEntity;
import com.ycwl.basic.model.pc.task.entity.TaskEntity; import com.ycwl.basic.model.pc.task.entity.TaskEntity;
@@ -124,7 +119,7 @@ public class TaskTaskServiceImpl implements TaskService {
@Autowired @Autowired
private NotificationAuthUtils notificationAuthUtils; private NotificationAuthUtils notificationAuthUtils;
@Autowired @Autowired
private WechatSubscribeNotifyTriggerService wechatSubscribeNotifyTriggerService; private WechatSubscribeNotifyTriggerService notifyTriggerService;
@Autowired @Autowired
private FaceStatusManager faceStatusManager; private FaceStatusManager faceStatusManager;
@@ -636,93 +631,26 @@ public class TaskTaskServiceImpl implements TaskService {
return; return;
} }
String openId = member.getOpenId(); String openId = member.getOpenId();
ScenicV2DTO scenic = scenicRepository.getScenicBasic(item.getScenicId());
MpConfigEntity scenicMp = scenicRepository.getScenicMpConfig(member.getScenicId()); MpConfigEntity scenicMp = scenicRepository.getScenicMpConfig(member.getScenicId());
if (StringUtils.isNotBlank(openId) && scenicMp != null) { if (StringUtils.isNotBlank(openId) && scenicMp != null) {
// 发送模板消息
Map<String, Object> variables = new HashMap<>(); Map<String, Object> variables = new HashMap<>();
variables.put("taskId", taskId); variables.put("taskId", taskId);
variables.put("scenicId", scenic.getId());
variables.put("scenicName", scenic.getName());
variables.put("faceId", item.getFaceId()); variables.put("faceId", item.getFaceId());
variables.put("videoId", item.getVideoId()); variables.put("videoId", item.getVideoId());
variables.put("nowTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm")); variables.put("videoCreateTime", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm"));
try {
ScenicV2DTO scenicBasic = scenicRepository.getScenicBasic(item.getScenicId());
if (scenicBasic != null && StringUtils.isNotBlank(scenicBasic.getName())) {
variables.put("scenicName", scenicBasic.getName());
}
} catch (Exception e) {
log.debug("获取景区名称失败: scenicId={}, error={}", item.getScenicId(), e.getMessage());
}
WechatSubscribeNotifyTriggerResult triggerResult = wechatSubscribeNotifyTriggerService.trigger( WechatSubscribeNotifyTriggerRequest request = WechatSubscribeNotifyTriggerRequest.builder()
"VIDEO_GENERATED", .scenicId(item.getScenicId())
WechatSubscribeNotifyTriggerRequest.builder() .memberId(item.getMemberId())
.scenicId(item.getScenicId()) .openId(member.getOpenId())
.memberId(memberId) .bizId(String.valueOf(item.getId()))
.openId(openId) .variables(variables)
.bizId(String.valueOf(taskId)) .build();
.variables(variables) WechatSubscribeNotifyTriggerResult triggerResult = notifyTriggerService.trigger("VIDEO_GENERATED", request);
.build()
);
if (triggerResult.isConfigFound()) {
log.info("memberId:{} VIDEO_GENERATED订阅消息触发完成 sentCount={}, skippedCount={}",
memberId, triggerResult.getSentCount(), triggerResult.getSkippedCount());
return;
}
String templateId = scenicRepository.getVideoGeneratedTemplateId(item.getScenicId());
if (StringUtils.isBlank(templateId)) {
log.warn("未配置视频生成通知模板");
return;
}
// 检查并消费通知授权
if (!notificationAuthUtils.checkAndConsumeAuthorization(memberId, templateId, item.getScenicId())) {
log.debug("用户[memberId={}]对模板[templateId={}]授权不足,跳过视频生成通知", memberId, templateId);
return;
}
ScenicV2DTO scenic = scenicRepository.getScenicBasic(item.getScenicId());
ScenicConfigManager configManager = scenicRepository.getScenicConfigManager(item.getScenicId());
String configTitle = configManager.getString("first_notification_title");
String configContent = configManager.getString("first_notification_content");
if (StringUtils.isBlank(configTitle) || StringUtils.isBlank(configContent)) {
log.info("景区[{}]未配置第一次通知内容,跳过发送通知", scenic.getName());
return;
}
String title = configTitle.replace("【景区】", scenic.getName());
String page;
if (configManager.getBoolean("grouping_enable", false)) {
page = "pages/travelVideoCenter/index?type=1&scenicId=" + item.getScenicId() + "&faceId=" + item.getFaceId();
} else {
page = "pages/videoSynthesis/index?type=1&scenicId=" + item.getScenicId() + "&faceId=" + item.getFaceId();
}
/**
* 视频名称 {{thing1.DATA}}
* 生成时间 {{time4.DATA}}
* 备注 {{thing3.DATA}}
*/
Map<String, Object> dataParam = new HashMap<>();
dataParam.put("thing1", title);
dataParam.put("time4", DateUtil.format(new Date(), "yyyy-MM-dd HH:mm"));
dataParam.put("thing3", configContent);
// 构建extra,只包含data和page
Map<String, Object> extra = new HashMap<>();
extra.put("data", dataParam);
extra.put("page", page);
// 使用ZT消息服务发送通知(第一次通知)
ZtMessage msg = new ZtMessage();
msg.setChannelId(templateId);
msg.setTitle(title);
msg.setContent("" + item.getFaceId() + "/" + item.getVideoId() + ""+configContent);
msg.setTarget(openId);
msg.setExtra(extra);
msg.setSendReason("视频生成通知");
msg.setSendBiz("视频生成");
ztMessageProducerService.send(msg);
log.info("memberId:{} 视频生成通知发送成功", memberId);
} }
} }

View File

@@ -12,11 +12,14 @@ import com.ycwl.basic.model.pc.coupon.resp.CouponRespVO;
import com.ycwl.basic.model.pc.member.resp.MemberRespVO; import com.ycwl.basic.model.pc.member.resp.MemberRespVO;
import com.ycwl.basic.model.pc.mp.MpConfigEntity; import com.ycwl.basic.model.pc.mp.MpConfigEntity;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager; import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import com.ycwl.basic.model.pc.notify.req.WechatSubscribeNotifyTriggerRequest;
import com.ycwl.basic.model.pc.notify.resp.WechatSubscribeNotifyTriggerResult;
import com.ycwl.basic.model.pc.scenic.entity.ScenicEntity; import com.ycwl.basic.model.pc.scenic.entity.ScenicEntity;
import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery; import com.ycwl.basic.model.pc.scenic.req.ScenicReqQuery;
import com.ycwl.basic.repository.ScenicRepository; import com.ycwl.basic.repository.ScenicRepository;
import com.ycwl.basic.repository.TemplateRepository; import com.ycwl.basic.repository.TemplateRepository;
import com.ycwl.basic.integration.common.manager.ScenicConfigManager; import com.ycwl.basic.integration.common.manager.ScenicConfigManager;
import com.ycwl.basic.service.notify.WechatSubscribeNotifyTriggerService;
import com.ycwl.basic.utils.NotificationAuthUtils; import com.ycwl.basic.utils.NotificationAuthUtils;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@@ -48,7 +51,7 @@ public class DownloadNotificationTasker {
@Autowired @Autowired
private MemberMapper memberMapper; private MemberMapper memberMapper;
@Autowired @Autowired
private CouponMapper couponMapper; private WechatSubscribeNotifyTriggerService notifyTriggerService;
@Autowired @Autowired
private ZtMessageProducerService ztMessageProducerService; private ZtMessageProducerService ztMessageProducerService;
@Autowired @Autowired
@@ -61,70 +64,31 @@ public class DownloadNotificationTasker {
Set<Long> sentMemberIds = ConcurrentHashMap.newKeySet(); Set<Long> sentMemberIds = ConcurrentHashMap.newKeySet();
videoMapper.listRelationByCreateTime(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000), new Date()) videoMapper.listRelationByCreateTime(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000), new Date())
.forEach(item -> { .forEach(item -> {
if (item.getIsBuy() == 1) {
return;
}
// 检查该用户是否已经发送过通知,避免重复发送 // 检查该用户是否已经发送过通知,避免重复发送
if (sentMemberIds.contains(item.getMemberId())) { if (sentMemberIds.contains(item.getMemberId())) {
log.debug("用户[memberId={}]已发送过下载通知,跳过", item.getMemberId()); log.debug("用户[memberId={}]已发送过下载通知,跳过", item.getMemberId());
return; return;
} }
sentMemberIds.add(item.getMemberId()); sentMemberIds.add(item.getMemberId());
if (item.getIsBuy() == 1) {
return;
}
MemberRespVO member = memberMapper.getById(item.getMemberId()); MemberRespVO member = memberMapper.getById(item.getMemberId());
// 发送模板消息 // 发送模板消息
String templateId = scenicRepository.getVideoDownloadTemplateId(item.getScenicId()); HashMap<String, Object> variables = new HashMap<>();
if (StringUtils.isBlank(templateId)) {
log.info("模板消息为空");
return;
}
// 检查并消费通知授权
if (!notificationAuthUtils.checkAndConsumeAuthorization(item.getMemberId(), templateId, item.getScenicId())) {
log.debug("用户[memberId={}]对模板[templateId={}]授权不足,跳过下载通知", item.getMemberId(), templateId);
return;
}
ScenicV2DTO scenic = scenicRepository.getScenicBasic(item.getScenicId()); ScenicV2DTO scenic = scenicRepository.getScenicBasic(item.getScenicId());
ScenicConfigManager configManager = scenicRepository.getScenicConfigManager(item.getScenicId()); variables.put("scenicName", scenic.getName());
String configTitle = configManager.getString("second_notification_title"); variables.put("scenicId", scenic.getId());
String configContent = configManager.getString("second_notification_content"); variables.put("faceId", item.getFaceId());
WechatSubscribeNotifyTriggerRequest request = WechatSubscribeNotifyTriggerRequest.builder()
if (StringUtils.isBlank(configTitle) || StringUtils.isBlank(configContent)) { .scenicId(item.getScenicId())
log.info("景区[{}]未配置第二次通知内容,跳过发送通知", scenic.getName()); .memberId(item.getMemberId())
return; .openId(member.getOpenId())
} .bizId(String.valueOf(item.getId()))
.variables(variables)
String title = configTitle.replace("【景区】", scenic.getName()); .build();
String page; WechatSubscribeNotifyTriggerResult result = notifyTriggerService.trigger("NOT_BUY_NOTIFY", request);
if (configManager.getBoolean("grouping_enable", false)) {
page = "pages/travelVideoCenter/index?type=2&scenicId=" + item.getScenicId() + "&faceId=" + item.getFaceId();
} else {
page = "pages/videoSynthesis/index?type=2&scenicId=" + item.getScenicId() + "&faceId=" + item.getFaceId();
}
/**
* 景区 {{thing1.DATA}}
* 备注 {{thing3.DATA}}
*/
Map<String, Object> dataParam = new HashMap<>();
dataParam.put("thing1", title);
dataParam.put("thing3", configContent);
// 构建extra,只包含data和page
Map<String, Object> extra = new HashMap<>();
extra.put("data", dataParam);
extra.put("page", page);
// 使用ZT消息服务发送通知(第二次通知)
ZtMessage msg = new ZtMessage();
msg.setChannelId(templateId);
msg.setTitle(title);
msg.setContent("" + item.getFaceId() + ""+configContent);
msg.setTarget(member.getOpenId());
msg.setExtra(extra);
msg.setSendReason("第二次通知");
msg.setSendBiz("定时通知");
ztMessageProducerService.send(msg);
}); });
} }
@@ -151,62 +115,22 @@ public class DownloadNotificationTasker {
if (videoStoreDay == null) { if (videoStoreDay == null) {
videoStoreDay = 3; videoStoreDay = 3;
} }
// 发送模板消息
String templateId = scenicRepository.getVideoPreExpireTemplateId(item.getScenicId());
if (StringUtils.isBlank(templateId)) {
log.info("模板消息为空");
return;
}
// 检查并消费通知授权
if (!notificationAuthUtils.checkAndConsumeAuthorization(item.getMemberId(), templateId, item.getScenicId())) {
log.debug("用户[memberId={}]对模板[templateId={}]授权不足,跳过过期提醒通知", item.getMemberId(), templateId);
return;
}
ScenicV2DTO scenic = scenicRepository.getScenicBasic(item.getScenicId());
ScenicConfigManager configManager = scenicRepository.getScenicConfigManager(item.getScenicId());
String configTitle = configManager.getString("third_notification_title");
String configContent = configManager.getString("third_notification_content");
if (StringUtils.isBlank(configTitle) || StringUtils.isBlank(configContent)) {
log.info("景区[{}]未配置第三次通知内容,跳过发送通知", scenic.getName());
return;
}
String title = configTitle.replace("【景区】", scenic.getName());
String page;
if (configManager.getBoolean("grouping_enable", false)) {
page = "pages/travelVideoCenter/index?type=3&scenicId=" + item.getScenicId() + "&faceId=" + item.getFaceId();
} else {
page = "pages/videoSynthesis/index?type=3&scenicId=" + item.getScenicId() + "&faceId=" + item.getFaceId();
}
/**
* 影像名称 {{thing1.DATA}}
* 过期时间 {{time2.DATA}}
* 备注 {{thing3.DATA}}
*/
Date expireDate = new Date(item.getCreateTime().getTime() + videoStoreDay * 24 * 60 * 60 * 1000); Date expireDate = new Date(item.getCreateTime().getTime() + videoStoreDay * 24 * 60 * 60 * 1000);
Map<String, Object> dataParam = new HashMap<>(); // 发送模板消息
dataParam.put("thing1", title); HashMap<String, Object> variables = new HashMap<>();
dataParam.put("time2", DateUtil.format(expireDate, "yyyy-MM-dd HH:mm")); ScenicV2DTO scenic = scenicRepository.getScenicBasic(item.getScenicId());
dataParam.put("thing3", configContent); variables.put("scenicName", scenic.getName());
variables.put("scenicId", scenic.getId());
// 构建extra,只包含data和page variables.put("faceId", item.getFaceId());
Map<String, Object> extra = new HashMap<>(); variables.put("expireDate", expireDate);
extra.put("data", dataParam); WechatSubscribeNotifyTriggerRequest request = WechatSubscribeNotifyTriggerRequest.builder()
extra.put("page", page); .scenicId(item.getScenicId())
.memberId(item.getMemberId())
// 使用ZT消息服务发送通知(第三次通知 - 过期提醒) .openId(member.getOpenId())
ZtMessage msg = new ZtMessage(); .bizId(String.valueOf(item.getId()))
msg.setChannelId(templateId); .variables(variables)
msg.setTitle(title); .build();
msg.setContent("" + item.getFaceId() + ""+configContent); WechatSubscribeNotifyTriggerResult result = notifyTriggerService.trigger("EXPIRE_NOTIFY", request);
msg.setTarget(member.getOpenId());
msg.setExtra(extra);
msg.setSendReason("第三次通知");
msg.setSendBiz("定时通知");
ztMessageProducerService.send(msg);
}); });
} }
@@ -254,57 +178,18 @@ public class DownloadNotificationTasker {
MemberRespVO member = memberMapper.getById(item.getMemberId()); MemberRespVO member = memberMapper.getById(item.getMemberId());
// 发送模板消息 // 发送模板消息
String templateId = scenicRepository.getVideoDownloadTemplateId(item.getScenicId()); HashMap<String, Object> variables = new HashMap<>();
if (StringUtils.isBlank(templateId)) { variables.put("scenicName", scenic.getName());
log.info("模板消息为空"); variables.put("scenicId", scenic.getId());
return; variables.put("faceId", item.getFaceId());
} WechatSubscribeNotifyTriggerRequest request = WechatSubscribeNotifyTriggerRequest.builder()
.scenicId(item.getScenicId())
// 检查并消费通知授权 .memberId(item.getMemberId())
if (!notificationAuthUtils.checkAndConsumeAuthorization(item.getMemberId(), templateId, item.getScenicId())) { .openId(member.getOpenId())
log.debug("用户[memberId={}]对模板[templateId={}]授权不足,跳过额外下载通知", item.getMemberId(), templateId); .bizId(String.valueOf(item.getId()))
return; .variables(variables)
} .build();
WechatSubscribeNotifyTriggerResult result = notifyTriggerService.trigger("TIME_TRIGGER_NOTIFY", request);
ScenicConfigManager configManager = scenicRepository.getScenicConfigManager(scenicId);
String configTitle = configManager.getString("second_notification_title");
String configContent = configManager.getString("second_notification_content");
if (StringUtils.isBlank(configTitle) || StringUtils.isBlank(configContent)) {
log.info("景区[{}]未配置第一次通知内容,跳过发送通知", scenic.getName());
return;
}
String title = configTitle.replace("【景区】", scenic.getName());
String page;
if (configManager.getBoolean("grouping_enable", false)) {
page = "pages/travelVideoCenter/index?type=2&scenicId=" + item.getScenicId() + "&faceId=" + item.getFaceId();
} else {
page = "pages/videoSynthesis/index?type=2&scenicId=" + item.getScenicId() + "&faceId=" + item.getFaceId();
}
/**
* 景区 {{thing1.DATA}}
* 备注 {{thing3.DATA}}
*/
Map<String, Object> dataParam = new HashMap<>();
dataParam.put("thing1", title);
dataParam.put("thing3", configContent);
// 构建extra,只包含data和page
Map<String, Object> extra = new HashMap<>();
extra.put("data", dataParam);
extra.put("page", page);
// 使用ZT消息服务发送通知(额外下载通知)
ZtMessage msg = new ZtMessage();
msg.setChannelId(templateId);
msg.setTitle(title);
msg.setContent("" + item.getFaceId() + ""+configContent);
msg.setTarget(member.getOpenId());
msg.setExtra(extra);
msg.setSendReason("景区额外配置:" + scenicConfig.getString("extra_notification_time"));
msg.setSendBiz("定时通知");
ztMessageProducerService.send(msg);
}); });
}); });
} }