You've already forked FrameTour-BE
feat(notification): 添加微信订阅消息配置管理及幂等授权功能
- 新增微信订阅消息配置管理控制器,支持模板、场景、事件映射配置 - 实现用户通知授权服务的幂等控制,避免前端重试导致授权次数虚增 - 添加微信订阅消息发送日志记录,用于幂等与排障 - 新增视频生成完成时的订阅消息触发功能 - 实现场景模板查询接口,返回用户授权余额信息 - 添加模板V2相关数据表映射器和实体类 - 集成微信订阅消息触发服务到任务完成流程中
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
package com.ycwl.basic.repository;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.ycwl.basic.mapper.WechatSubscribeEventTemplateMapper;
|
||||
import com.ycwl.basic.mapper.WechatSubscribeSceneTemplateMapper;
|
||||
import com.ycwl.basic.mapper.WechatSubscribeTemplateConfigMapper;
|
||||
import com.ycwl.basic.model.pc.notify.entity.WechatSubscribeEventTemplateEntity;
|
||||
import com.ycwl.basic.model.pc.notify.entity.WechatSubscribeSceneTemplateEntity;
|
||||
import com.ycwl.basic.model.pc.notify.entity.WechatSubscribeTemplateConfigEntity;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 微信订阅消息配置仓库(scenic 覆盖:scenic_id=具体值 > scenic_id=0)
|
||||
*
|
||||
* @Author: System
|
||||
* @Date: 2025/12/31
|
||||
*/
|
||||
@Component
|
||||
public class WechatSubscribeNotifyConfigRepository {
|
||||
|
||||
private static final long DEFAULT_SCENIC_ID = 0L;
|
||||
|
||||
private final WechatSubscribeTemplateConfigMapper templateConfigMapper;
|
||||
private final WechatSubscribeSceneTemplateMapper sceneTemplateMapper;
|
||||
private final WechatSubscribeEventTemplateMapper eventTemplateMapper;
|
||||
|
||||
public WechatSubscribeNotifyConfigRepository(WechatSubscribeTemplateConfigMapper templateConfigMapper,
|
||||
WechatSubscribeSceneTemplateMapper sceneTemplateMapper,
|
||||
WechatSubscribeEventTemplateMapper eventTemplateMapper) {
|
||||
this.templateConfigMapper = templateConfigMapper;
|
||||
this.sceneTemplateMapper = sceneTemplateMapper;
|
||||
this.eventTemplateMapper = eventTemplateMapper;
|
||||
}
|
||||
|
||||
public List<WechatSubscribeSceneTemplateEntity> listEffectiveSceneTemplateMappings(Long scenicId, String sceneKey) {
|
||||
Objects.requireNonNull(scenicId, "scenicId is null");
|
||||
if (StringUtils.isBlank(sceneKey)) {
|
||||
throw new IllegalArgumentException("sceneKey is blank");
|
||||
}
|
||||
|
||||
List<Long> scenicIds = List.of(DEFAULT_SCENIC_ID, scenicId);
|
||||
QueryWrapper<WechatSubscribeSceneTemplateEntity> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("scene_key", sceneKey)
|
||||
.in("scenic_id", scenicIds);
|
||||
List<WechatSubscribeSceneTemplateEntity> rows = sceneTemplateMapper.selectList(wrapper);
|
||||
return pickEffectiveByTemplateKey(rows, scenicId).values().stream()
|
||||
.filter(this::isEnabled)
|
||||
.sorted((a, b) -> {
|
||||
int cmp = Integer.compare(safeInt(a.getSortOrder()), safeInt(b.getSortOrder()));
|
||||
if (cmp != 0) {
|
||||
return cmp;
|
||||
}
|
||||
return Objects.toString(a.getTemplateKey(), "").compareTo(Objects.toString(b.getTemplateKey(), ""));
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public List<WechatSubscribeEventTemplateEntity> listEffectiveEventTemplateMappings(Long scenicId, String eventKey) {
|
||||
Objects.requireNonNull(scenicId, "scenicId is null");
|
||||
if (StringUtils.isBlank(eventKey)) {
|
||||
throw new IllegalArgumentException("eventKey is blank");
|
||||
}
|
||||
|
||||
List<Long> scenicIds = List.of(DEFAULT_SCENIC_ID, scenicId);
|
||||
QueryWrapper<WechatSubscribeEventTemplateEntity> wrapper = new QueryWrapper<>();
|
||||
wrapper.eq("event_key", eventKey)
|
||||
.in("scenic_id", scenicIds);
|
||||
List<WechatSubscribeEventTemplateEntity> rows = eventTemplateMapper.selectList(wrapper);
|
||||
return pickEffectiveByTemplateKey(rows, scenicId).values().stream()
|
||||
.filter(this::isEnabled)
|
||||
.sorted((a, b) -> {
|
||||
int cmp = Integer.compare(safeInt(a.getSortOrder()), safeInt(b.getSortOrder()));
|
||||
if (cmp != 0) {
|
||||
return cmp;
|
||||
}
|
||||
return Objects.toString(a.getTemplateKey(), "").compareTo(Objects.toString(b.getTemplateKey(), ""));
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public Map<String, WechatSubscribeTemplateConfigEntity> getEffectiveTemplateConfigs(Long scenicId,
|
||||
Collection<String> templateKeys) {
|
||||
Objects.requireNonNull(scenicId, "scenicId is null");
|
||||
if (CollectionUtils.isEmpty(templateKeys)) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
List<Long> scenicIds = List.of(DEFAULT_SCENIC_ID, scenicId);
|
||||
QueryWrapper<WechatSubscribeTemplateConfigEntity> wrapper = new QueryWrapper<>();
|
||||
wrapper.in("template_key", templateKeys)
|
||||
.in("scenic_id", scenicIds);
|
||||
List<WechatSubscribeTemplateConfigEntity> rows = templateConfigMapper.selectList(wrapper);
|
||||
Map<String, WechatSubscribeTemplateConfigEntity> effective = new HashMap<>();
|
||||
for (WechatSubscribeTemplateConfigEntity row : rows) {
|
||||
if (row == null || row.getTemplateKey() == null) {
|
||||
continue;
|
||||
}
|
||||
WechatSubscribeTemplateConfigEntity existing = effective.get(row.getTemplateKey());
|
||||
if (existing == null) {
|
||||
effective.put(row.getTemplateKey(), row);
|
||||
continue;
|
||||
}
|
||||
if (Objects.equals(row.getScenicId(), scenicId)) {
|
||||
effective.put(row.getTemplateKey(), row);
|
||||
}
|
||||
}
|
||||
return effective;
|
||||
}
|
||||
|
||||
private boolean isEnabled(WechatSubscribeSceneTemplateEntity entity) {
|
||||
return entity != null && Objects.equals(entity.getEnabled(), 1);
|
||||
}
|
||||
|
||||
private boolean isEnabled(WechatSubscribeEventTemplateEntity entity) {
|
||||
return entity != null && Objects.equals(entity.getEnabled(), 1);
|
||||
}
|
||||
|
||||
private static int safeInt(Integer value) {
|
||||
return value != null ? value : 0;
|
||||
}
|
||||
|
||||
private static <T> Map<String, T> pickEffectiveByTemplateKey(List<T> rows, Long scenicId) {
|
||||
Map<String, T> effective = new HashMap<>();
|
||||
if (rows == null || rows.isEmpty()) {
|
||||
return effective;
|
||||
}
|
||||
for (T row : rows) {
|
||||
String templateKey = getTemplateKey(row);
|
||||
if (templateKey == null) {
|
||||
continue;
|
||||
}
|
||||
T existing = effective.get(templateKey);
|
||||
if (existing == null) {
|
||||
effective.put(templateKey, row);
|
||||
continue;
|
||||
}
|
||||
Long rowScenicId = getScenicId(row);
|
||||
if (Objects.equals(rowScenicId, scenicId)) {
|
||||
effective.put(templateKey, row);
|
||||
}
|
||||
}
|
||||
return effective;
|
||||
}
|
||||
|
||||
private static String getTemplateKey(Object row) {
|
||||
if (row instanceof WechatSubscribeSceneTemplateEntity entity) {
|
||||
return entity.getTemplateKey();
|
||||
}
|
||||
if (row instanceof WechatSubscribeEventTemplateEntity entity) {
|
||||
return entity.getTemplateKey();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Long getScenicId(Object row) {
|
||||
if (row instanceof WechatSubscribeSceneTemplateEntity entity) {
|
||||
return entity.getScenicId();
|
||||
}
|
||||
if (row instanceof WechatSubscribeEventTemplateEntity entity) {
|
||||
return entity.getScenicId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user