|
|
@@ -0,0 +1,142 @@
|
|
|
+package com.tzld.longarticle.recommend.server.service.recommend;
|
|
|
+
|
|
|
+import com.tzld.longarticle.recommend.server.mapper.longArticle.LongArticleBaseMapper;
|
|
|
+import com.tzld.longarticle.recommend.server.model.dto.DemandSearchArticleRelationDTO;
|
|
|
+import com.tzld.longarticle.recommend.server.model.entity.aigc.PublishAccount;
|
|
|
+import com.tzld.longarticle.recommend.server.model.entity.longArticle.DemandPoolPromotionBind;
|
|
|
+import com.tzld.longarticle.recommend.server.repository.aigc.PublishAccountRepository;
|
|
|
+import com.tzld.longarticle.recommend.server.repository.longArticle.DemandPoolPromotionBindRepository;
|
|
|
+import com.google.common.collect.Lists;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 内容是否属于任一账号的过滤查询服务
|
|
|
+ *
|
|
|
+ * @author dyp
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+public class FilterContentByAccountService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private LongArticleBaseMapper longArticleBaseMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private DemandPoolPromotionBindRepository demandPoolPromotionBindRepository;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private PublishAccountRepository publishAccountRepository;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据 channelContentId 和账号ID查询内容是否属于任一账号。
|
|
|
+ * 判断标准:
|
|
|
+ * 1. 通过 channelContentId → experimentId → demand_search_queue.account → publish_account.id 判断所属账号
|
|
|
+ * 2. 通过 channelContentId 查询 demand_pool_promotion_bind,判断内容与所属账号
|
|
|
+ * 任一条件满足即视为通过。
|
|
|
+ *
|
|
|
+ * @param channelContentIds 内容渠道ID列表
|
|
|
+ * @param accountIds 账号ID列表
|
|
|
+ * @return 不在任一账号下的 channelContentId 列表(需要被过滤的内容)
|
|
|
+ */
|
|
|
+ public List<String> filterContentByAccount(List<String> channelContentIds, List<String> accountIds) {
|
|
|
+ if (CollectionUtils.isEmpty(channelContentIds) || CollectionUtils.isEmpty(accountIds)) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ Set<String> accountIdSet = new HashSet<>(accountIds);
|
|
|
+ Set<String> passedChannelContentIds = new HashSet<>();
|
|
|
+
|
|
|
+ // 检查1:channelContentId → experimentId → demand_search_queue.account → publish_account.id
|
|
|
+ List<DemandSearchArticleRelationDTO> demandRelations =
|
|
|
+ longArticleBaseMapper.getDemandExperimentIdByChannelContentIds(channelContentIds);
|
|
|
+
|
|
|
+ if (!CollectionUtils.isEmpty(demandRelations)) {
|
|
|
+ // 构建 channelContentId → experimentId 映射
|
|
|
+ Map<String, String> ccIdToExpId = demandRelations.stream()
|
|
|
+ .filter(d -> StringUtils.isNotBlank(d.getChannelContentId())
|
|
|
+ && StringUtils.isNotBlank(d.getExperimentId()))
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ DemandSearchArticleRelationDTO::getChannelContentId,
|
|
|
+ DemandSearchArticleRelationDTO::getExperimentId,
|
|
|
+ (v1, v2) -> v1));
|
|
|
+
|
|
|
+ if (!ccIdToExpId.isEmpty()) {
|
|
|
+ // experiment_id → account(账号名称),从 demand_search_queue 查询
|
|
|
+ List<String> experimentIds = new ArrayList<>(new HashSet<>(ccIdToExpId.values()));
|
|
|
+ Map<String, String> expIdToAccountName = new HashMap<>();
|
|
|
+ for (List<String> partition : Lists.partition(experimentIds, 500)) {
|
|
|
+ List<DemandSearchArticleRelationDTO> queueResults =
|
|
|
+ longArticleBaseMapper.getAccountByExperimentIds(partition);
|
|
|
+ if (!CollectionUtils.isEmpty(queueResults)) {
|
|
|
+ for (DemandSearchArticleRelationDTO r : queueResults) {
|
|
|
+ if (StringUtils.isNotBlank(r.getExperimentId()) && StringUtils.isNotBlank(r.getAccountId())) {
|
|
|
+ expIdToAccountName.put(r.getExperimentId(), r.getAccountId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!expIdToAccountName.isEmpty()) {
|
|
|
+ // account名称 → account_id,从 publish_account 查询
|
|
|
+ List<String> accountNames = new ArrayList<>(new HashSet<>(expIdToAccountName.values()));
|
|
|
+ Map<String, String> accountNameToId = new HashMap<>();
|
|
|
+ for (List<String> partition : Lists.partition(accountNames, 500)) {
|
|
|
+ List<PublishAccount> accounts = publishAccountRepository.findByNameIn(partition);
|
|
|
+ if (!CollectionUtils.isEmpty(accounts)) {
|
|
|
+ for (PublishAccount account : accounts) {
|
|
|
+ if (StringUtils.isNotBlank(account.getName()) && StringUtils.isNotBlank(account.getId())) {
|
|
|
+ accountNameToId.put(account.getName(), account.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 遍历 channelContentId → experimentId → accountName → accountId,判断是否属于目标账号
|
|
|
+ for (Map.Entry<String, String> entry : ccIdToExpId.entrySet()) {
|
|
|
+ String accountName = expIdToAccountName.get(entry.getValue());
|
|
|
+ if (StringUtils.isNotBlank(accountName)) {
|
|
|
+ String accountId = accountNameToId.get(accountName);
|
|
|
+ if (StringUtils.isNotBlank(accountId) && accountIdSet.contains(accountId)) {
|
|
|
+ passedChannelContentIds.add(entry.getKey());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查2:通过 channelContentId 查询 demand_pool_promotion_bind,判断内容与所属账号
|
|
|
+ List<String> remainingIds = channelContentIds.stream()
|
|
|
+ .filter(id -> !passedChannelContentIds.contains(id))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (!CollectionUtils.isEmpty(remainingIds)) {
|
|
|
+ List<DemandPoolPromotionBind> binds = demandPoolPromotionBindRepository
|
|
|
+ .findByPromotionChannelContentIdInAndAccountIdIn(remainingIds, accountIds);
|
|
|
+
|
|
|
+ if (!CollectionUtils.isEmpty(binds)) {
|
|
|
+ binds.stream()
|
|
|
+ .map(DemandPoolPromotionBind::getPromotionChannelContentId)
|
|
|
+ .filter(StringUtils::isNotBlank)
|
|
|
+ .forEach(passedChannelContentIds::add);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回未通过任一检查的 channelContentId(需要被过滤的内容)
|
|
|
+ List<String> filteredIds = channelContentIds.stream()
|
|
|
+ .filter(id -> !passedChannelContentIds.contains(id))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ log.info("filterContentByAccount, total:{}, passed:{}, filtered:{}",
|
|
|
+ channelContentIds.size(), passedChannelContentIds.size(), filteredIds.size());
|
|
|
+
|
|
|
+ return filteredIds;
|
|
|
+ }
|
|
|
+}
|