REQ-3754: 批量查询epic

This commit is contained in:
yanglin 2025-02-28 14:20:12 +08:00
parent 80d1606fa4
commit 7bb8ee037b
13 changed files with 167 additions and 166 deletions

View File

@ -1,5 +1,21 @@
package cn.axzo.msg.center.event.outer;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import cn.axzo.framework.rocketmq.Event;
import cn.axzo.framework.rocketmq.EventConsumer;
import cn.axzo.framework.rocketmq.EventHandler;
@ -19,21 +35,7 @@ import cn.axzo.msg.center.nimpush.device.PushDevice;
import cn.axzo.msg.center.nimpush.device.PushDeviceService;
import cn.axzo.msg.center.push.PushData;
import cn.axzo.msg.center.service.enums.TerminalTypeEnum;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
@Slf4j
@Component
@ -127,9 +129,8 @@ public class PushYouMengMessageHandler implements EventHandler, InitializingBean
log.info("push-handler, 模板code:{},appType不合法, event: {}", card.getTemplateCode(), event);
return;
}
PushDevice device = pushDeviceService
.createDeviceSnapshots()
.getDevice(Long.parseLong(newMessageHistory.getReceivePersonId()));
long personId = Long.parseLong(newMessageHistory.getReceivePersonId());
PushDevice device = pushDeviceService.getDevice(personId);
if(!device.shouldPush(appType, PushChannel.YOU_MENG)) {
log.info("push-handler, 模板code:{}, 友盟push不适用, event: {}", card.getTemplateCode(), event);
return;

View File

@ -1,5 +1,18 @@
package cn.axzo.msg.center.message.service.card;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.im.center.api.feign.MessageApi;
import cn.axzo.im.center.api.vo.req.SendTemplateMessageParam;
@ -42,18 +55,6 @@ import cn.axzo.msg.center.utils.BatchController;
import cn.axzo.msg.center.utils.RecordCursor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.support.TransactionTemplate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
/**
* @author yanglin
@ -106,7 +107,7 @@ public class CardManager {
cardDao.saveBatch(sendModel.getCards());
sendLogger.reloadAndLogCards("send:enqueue");
});
PushDeviceSnapshots deviceSnapshots = pushDeviceService.createDeviceSnapshots();
PushDeviceSnapshots deviceSnapshots = pushDeviceService.createDeviceSnapshots(sendModel.receiverPersonIds());
BatchController groupExecutor = new BatchController("sendCard", request, executor);
for (CardGroup group : sendModel.getCardGroups()) {
groupExecutor.submit(() -> {

View File

@ -1,5 +1,14 @@
package cn.axzo.msg.center.message.service.card.domain;
import static java.util.stream.Collectors.toSet;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import cn.axzo.msg.center.domain.entity.Card;
import cn.axzo.msg.center.message.domain.vo.GeneralMessagePushVO;
import cn.axzo.msg.center.message.service.card.CardRequestContext;
@ -11,12 +20,6 @@ import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
/**
* @author yanglin
*/
@ -35,6 +38,10 @@ public class CardSendModel {
cards.add(card);
}
public Set<Long> receiverPersonIds() {
return cards.stream().map(Card::getReceiverPersonId).collect(toSet());
}
public Collection<CardGroup> getCardGroups() {
HashMap<CardGroupKey, CardGroup> groups = new HashMap<>();
for (Card card : cards) {

View File

@ -1,5 +1,18 @@
package cn.axzo.msg.center.message.service.impl.v3;
import static cn.axzo.msg.center.common.utils.PlaceholderResolver.getDefaultResolver;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import cn.axzo.msg.center.domain.entity.MessageTemplateButtonV3;
import cn.axzo.msg.center.domain.entity.MessageTemplateGroupV3;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
@ -20,19 +33,8 @@ import cn.axzo.msg.center.service.pending.response.v3.model.ParsedModelV3;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedTemplateV3;
import cn.axzo.msg.center.service.pending.response.v3.model.PhoneInfo;
import cn.axzo.trade.datasecurity.core.util.DataSecurityHelper;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import static cn.axzo.msg.center.common.utils.PlaceholderResolver.getDefaultResolver;
/**
* @author yanglin
@ -154,7 +156,8 @@ public class ModelV3Parser {
}
});
// 提前排序避免并发问题
parsedModel.sortButtons();
return parsedModel;
}

View File

@ -1,13 +1,18 @@
package cn.axzo.msg.center.message.service.todo.manage.event;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import com.alibaba.fastjson.JSON;
import lombok.Getter;
import org.springframework.context.ApplicationEvent;
import static java.util.stream.Collectors.toSet;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import org.springframework.context.ApplicationEvent;
import com.alibaba.fastjson.JSON;
import cn.axzo.msg.center.domain.entity.Todo;
import cn.axzo.msg.center.message.domain.dto.TemplateModelV3;
import lombok.Getter;
/**
* @author yanglin
@ -23,6 +28,10 @@ public class NewTodoEvent extends ApplicationEvent {
this.todos = todos;
}
public Set<Long> executorPersonIds() {
return todos.stream().map(Todo::getExecutorPersonId).collect(toSet());
}
@Override
public String toString() {
HashMap<String, Object> fields = new HashMap<>();

View File

@ -1,5 +1,19 @@
package cn.axzo.msg.center.message.service.todo.manage.event;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import cn.axzo.msg.center.dal.TodoBusinessDao;
import cn.axzo.msg.center.dal.TodoBusinesses;
import cn.axzo.msg.center.domain.entity.MessageEntity;
@ -23,20 +37,8 @@ import cn.axzo.msg.center.service.domain.CardUrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfigWalker;
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author yanglin
@ -64,7 +66,7 @@ class TodoPushSender implements ApplicationListener<NewTodoEvent> {
if (!pushData.determinePushable(log, event.getTemplateModel().getTemplateCode()))
return;
List<PushTerminalEnum> pushTerminals = template.determinePushTerminals();
PushDeviceSnapshots deviceSnapshots = pushDeviceService.createDeviceSnapshots();
PushDeviceSnapshots deviceSnapshots = pushDeviceService.createDeviceSnapshots(event.executorPersonIds());
ArrayList<YoumengPush> pushes = new ArrayList<>();
for (Todo todo : event.getTodos()) {
PushDevice pushDevice = deviceSnapshots.getDevice(todo.getExecutorPersonId());

View File

@ -72,7 +72,7 @@ public class TodoPushSenderNim implements ApplicationListener<NewTodoEvent> {
if (pushData != null && !pushData.determinePushable(log, parsedModelV3.getTemplateCode())) {
return;
}
PushDeviceSnapshots deviceSnapshots = pushDeviceService.createDeviceSnapshots();
PushDeviceSnapshots deviceSnapshots = pushDeviceService.createDeviceSnapshots(event.executorPersonIds());
for (Todo todo : event.getTodos()) {
executor.submit(() -> {
for (AppTypeEnum appType : appTypes) {

View File

@ -1,5 +1,7 @@
package cn.axzo.msg.center.nimpush.device;
import java.util.List;
import cn.axzo.epic.client.vo.response.ApkDeviceMaxCodeResp;
import cn.axzo.im.center.common.enums.AppTypeEnum;
import cn.axzo.msg.center.nimpush.PushChannel;
@ -7,8 +9,6 @@ import cn.axzo.msg.center.service.enums.PushTerminalEnum;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import java.util.List;
/**
* @author yanglin
*/
@ -16,9 +16,7 @@ import java.util.List;
public class PushDevice {
private final PushDeviceService pushDeviceService;
private final Long personId;
private volatile List<ApkDeviceMaxCodeResp> cache;
private final List<ApkDeviceMaxCodeResp> devices;
public boolean shouldPush(AppTypeEnum appType,
PushChannel pushChannel) {
@ -30,20 +28,7 @@ public class PushDevice {
public boolean shouldPush(PushTerminalEnum pushTerminal,
PushChannel pushChannel) {
List<ApkDeviceMaxCodeResp> devices = getDevices();
return pushDeviceService.shouldPush(pushTerminal, pushChannel, devices);
}
private List<ApkDeviceMaxCodeResp> getDevices() {
List<ApkDeviceMaxCodeResp> cache = this.cache;
if (cache != null)
return cache;
synchronized (this) {
cache = this.cache;
if (cache == null)
cache = this.cache = pushDeviceService.getPersonDevices(personId);
}
return cache;
}
}

View File

@ -1,8 +1,22 @@
package cn.axzo.msg.center.nimpush.device;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSON;
import cn.axzo.epic.client.common.enums.AppTerminalTypeEnum;
import cn.axzo.epic.client.feign.AppDeviceApi;
import cn.axzo.epic.client.vo.request.FetchDeviceByPersonIdAndTerminalReq;
import cn.axzo.epic.client.vo.request.BatchFetchDeviceByPersonIdAndTerminalReq;
import cn.axzo.epic.client.vo.response.ApkDeviceMaxCodeResp;
import cn.axzo.msg.center.common.enums.SystemTypeEnum;
import cn.axzo.msg.center.common.utils.BizAssertions;
@ -10,16 +24,8 @@ import cn.axzo.msg.center.inside.notices.config.PendingMessageBizConfig;
import cn.axzo.msg.center.inside.notices.config.push.PushDeviceVersion;
import cn.axzo.msg.center.nimpush.PushChannel;
import cn.axzo.msg.center.service.enums.PushTerminalEnum;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.function.Supplier;
/**
* @author yanglin
@ -32,18 +38,19 @@ public class PushDeviceService {
private final AppDeviceApi appDeviceApi;
private final PendingMessageBizConfig cfg;
public PushDeviceSnapshots createDeviceSnapshots() {
return new PushDeviceSnapshots(this);
public PushDevice getDevice(long personId) {
return createDeviceSnapshots(Collections.singletonList(personId)).getDevice(personId);
}
List<ApkDeviceMaxCodeResp> getPersonDevices(Long personId) {
FetchDeviceByPersonIdAndTerminalReq request =
new FetchDeviceByPersonIdAndTerminalReq();
request.setPersonId(personId);
public PushDeviceSnapshots createDeviceSnapshots(Collection<Long> personIds) {
ArrayList<Long> uniquePersonIds = new ArrayList<>(new HashSet<>(personIds));
BatchFetchDeviceByPersonIdAndTerminalReq request = new BatchFetchDeviceByPersonIdAndTerminalReq();
request.setPersonIds(uniquePersonIds);
request.setTerminals(Arrays.asList(
AppTerminalTypeEnum.CMP, AppTerminalTypeEnum.CM));
return BizAssertions.assertResponse(
appDeviceApi.fetchCodeByPersonIdAndTerminal(request));
List<ApkDeviceMaxCodeResp> devices = BizAssertions.assertResponse(
appDeviceApi.batchfetchCodeByPersonIdAndTerminal(request));
return new PushDeviceSnapshots(this, devices);
}
boolean shouldPush(PushTerminalEnum pushTerminal,
@ -104,5 +111,4 @@ public class PushDeviceService {
return SystemTypeEnum.IOS;
return null;
}
}

View File

@ -1,11 +1,18 @@
package cn.axzo.msg.center.nimpush.device;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.groupingBy;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import cn.axzo.epic.client.vo.response.ApkDeviceMaxCodeResp;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
/**
* @author yanglin
*/
@ -14,13 +21,19 @@ public class PushDeviceSnapshots {
private final Map<Long, PushDevice> cache = new ConcurrentHashMap<>();
private final PushDeviceService pushDeviceService;
private final List<ApkDeviceMaxCodeResp> devices;
private Map<Long, List<ApkDeviceMaxCodeResp>> personId2Devices;
public PushDevice getDevice(Long personId) {
return cache.computeIfAbsent(personId, this::createDevice);
}
private PushDevice createDevice(Long personId) {
return new PushDevice(pushDeviceService, personId);
if (personId2Devices == null)
personId2Devices = devices.stream().collect(groupingBy(ApkDeviceMaxCodeResp::getPersonId));
List<ApkDeviceMaxCodeResp> personDevices = personId2Devices.getOrDefault(personId, emptyList());
return new PushDevice(pushDeviceService, personDevices);
}
}

View File

@ -1,5 +1,9 @@
package cn.axzo.msg.center.service.pending.response.v3;
import java.util.ArrayList;
import org.apache.commons.collections4.CollectionUtils;
import cn.axzo.msg.center.service.domain.CardUrlConfig;
import cn.axzo.msg.center.service.domain.card.AppVersionConfig;
import cn.axzo.msg.center.service.domain.card.StateImageConfig;
@ -12,10 +16,6 @@ import cn.axzo.msg.center.service.pending.response.v3.model.ParsedGroupV3;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedKV;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedModelV3;
import cn.axzo.msg.center.service.pending.response.v3.model.ParsedTemplateV3;
import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.Comparator;
/**
* @author yanglin
@ -41,9 +41,7 @@ public class ParsedModelV3Walker {
}
for (ParsedGroupV3 group : new ArrayList<>(model.determineGroups()))
visitGroup(visitor, group);
ArrayList<ParsedButtonV3> buttons = new ArrayList<>(model.determineButtons());
buttons.sort(Comparator.comparingInt(ParsedButtonV3::determinePriority));
for (ParsedButtonV3 button : buttons)
for (ParsedButtonV3 button : new ArrayList<>(model.determineButtons()))
visitButton(visitor, button);
if (template != null)
visitor.exitTemplate(template);

View File

@ -1,19 +1,7 @@
package cn.axzo.msg.center.service.pending.response.v3.model;
import cn.axzo.msg.center.push.PushData;
import cn.axzo.msg.center.push.PushMessage;
import cn.axzo.msg.center.service.domain.CardUrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.enums.GroupType;
import cn.axzo.msg.center.service.pending.response.MessageButtonProvider;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Getter;
import lombok.Setter;
import static java.util.stream.Collectors.toList;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -21,7 +9,21 @@ import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import static java.util.stream.Collectors.toList;
import javax.annotation.Nullable;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import cn.axzo.msg.center.push.PushData;
import cn.axzo.msg.center.push.PushMessage;
import cn.axzo.msg.center.service.domain.CardUrlConfig;
import cn.axzo.msg.center.service.domain.UrlConfig;
import cn.axzo.msg.center.service.enums.GroupType;
import cn.axzo.msg.center.service.pending.response.MessageButtonProvider;
import lombok.Getter;
import lombok.Setter;
/**
* @author yanglin
@ -94,10 +96,13 @@ public class ParsedModelV3 implements MessageButtonProvider<ParsedButtonV3>, Pus
return groups == null ? Collections.emptyList() : groups;
}
public List<ParsedButtonV3> determineButtons() {
List<ParsedButtonV3> buttons = this.buttons == null ? Collections.emptyList() : this.buttons;
public void sortButtons() {
if (buttons == null) return;
buttons.sort(Comparator.comparingInt(ParsedButtonV3::determinePriority));
return buttons;
}
public List<ParsedButtonV3> determineButtons() {
return this.buttons == null ? Collections.emptyList() : this.buttons;
}
public void removeEmptyKVGroups() {

View File

@ -1,29 +0,0 @@
package cn.axzo.msg.center.nimpush.device;
import cn.axzo.epic.client.vo.response.ApkDeviceMaxCodeResp;
import cn.axzo.msg.center.MsgCenterApplication;
import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
/**
* @author yanglin
*/
@SpringBootTest(classes = MsgCenterApplication.class)
@RequiredArgsConstructor(onConstructor_ = @Autowired)
class PushDeviceServiceTest {
private final PushDeviceService pushDeviceService;
@Test
void exec() {
List<ApkDeviceMaxCodeResp> devices = pushDeviceService.getPersonDevices(80792L);
System.out.println();
}
}