提交 25510db5 作者: 沈振路

根据人群包找用户

上级 0e7a7d0d
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages>
<language minSize="80" name="Java" />
</Languages>
</inspection_tool>
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="date" />
</inspection_tool>
<inspection_tool class="SerializableHasSerialVersionUIDField" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoreAnonymousInnerClasses" value="false" />
<option name="superClassString" value="java.awt.Component" />
</inspection_tool>
</profile>
</component>
\ No newline at end of file
package com.yaoyaozw.customer.components; package com.yaoyaozw.customer.components;
import cn.hutool.core.util.ObjectUtil;
import com.yaoyaozw.customer.vo.customer.CrowdPackageUserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List;
import java.util.stream.Collectors;
/** /**
* @author darker * @author darker
* @date 2022/9/28 15:16 * @date 2022/9/28 15:16
...@@ -10,9 +17,53 @@ import org.springframework.stereotype.Component; ...@@ -10,9 +17,53 @@ import org.springframework.stereotype.Component;
@Component @Component
public class CustomerServiceCommonAsyncComponent { public class CustomerServiceCommonAsyncComponent {
private final static Logger LOCAL_LOG = LoggerFactory.getLogger(CustomerServiceCommonAsyncComponent.class);
@Async("myExecutor")
public void addMatchUserIntoPackage(Long packageId, List<CrowdPackageUserVO> userList) {
long startTime = System.currentTimeMillis();
String packIdStr = packageId.toString();
// 筛选当前不在这个人群包的用户
List<CrowdPackageUserVO> userNotInPackageList = userList.stream()
// 保留现在不在该人群包的用户
.filter(item -> ObjectUtil.isNull(item.getInPackage()) || !item.getInPackage().contains(packIdStr))
.peek(item -> {
if (ObjectUtil.isNull(item.getInPackage())) {
item.setInPackage(packIdStr);
} else {
// 将当前人群包拼在后面
item.setInPackage(item.getInPackage() + "," + packIdStr);
}
}).collect(Collectors.toList());
LOCAL_LOG.info("人群包ID: {} 新增用户 {}个", packIdStr, userNotInPackageList.size());
long endTime = System.currentTimeMillis();
LOCAL_LOG.info("异步添加符合条件用户人群包完成, 耗时: {}ms", endTime - startTime);
}
@Async("myExecutor") @Async("myExecutor")
public void updateUserPackage() { public void removeUnMatchUserFromPackage(Long packageId, List<CrowdPackageUserVO> userList) {
long startTime = System.currentTimeMillis();
String packIdStr = packageId.toString();
// 筛选当前不在这个人群包的用户
List<CrowdPackageUserVO> userRemoveFromPackList = userList.stream()
// 移除现在在该人群包但不符合当前条件的用户
.filter(item -> ObjectUtil.isNotNull(item.getInPackage()) && item.getInPackage().contains(packIdStr))
.peek(item -> {
String removePackageStr = item.getInPackage().replace("," + packIdStr, "")
.replace(packIdStr + ",", "")
.replace(packIdStr, "");
item.setInPackage(removePackageStr);
}).collect(Collectors.toList());
LOCAL_LOG.info("人群包ID: {} 移除用户 {}个", packIdStr, userRemoveFromPackList.size());
long endTime = System.currentTimeMillis();
LOCAL_LOG.info("异步删除不符合条件用户所属人群包完成, 耗时: {}ms", endTime - startTime);
} }
......
...@@ -75,6 +75,12 @@ public class CrowdPackageController { ...@@ -75,6 +75,12 @@ public class CrowdPackageController {
return crowdPackageService.getOptions(conditionId); return crowdPackageService.getOptions(conditionId);
} }
@ApiOperation("更新用户列表所属的人群包")
@GetMapping("/updateUserPackageBatch")
public BaseResult updateUserPackageBatch(@RequestBody List<String> openIdList) {
return crowdPackageService.updateUserPackageBatch(openIdList);
}
} }
...@@ -15,8 +15,17 @@ public interface RegisterUserEntityMapper extends BaseMapper<RegisterUserEntity> ...@@ -15,8 +15,17 @@ public interface RegisterUserEntityMapper extends BaseMapper<RegisterUserEntity>
* 获取符合动态条件的用户 * 获取符合动态条件的用户
* *
* @param dynamicExpressList 动态表达列表 * @param dynamicExpressList 动态表达列表
* @param openId 指定openId
* @return {@link List}<{@link RegisterUserEntity}> * @return {@link List}<{@link RegisterUserEntity}>
*/ */
List<CrowdPackageUserVO> getUserMatchDynamicExpress(@Param("dynamicExpressList") List<String> dynamicExpressList); List<CrowdPackageUserVO> getUserMatchDynamicExpress(@Param("dynamicExpressList") List<String> dynamicExpressList, @Param("openId") String openId);
/**
* 更新用户所属人群包
*
* @param openId 用户 openId
* @param packageBelong 所属人群包
*/
void updateUserPackageBelong(@Param("openId") String openId, @Param("packageBelong") String packageBelong);
} }
\ No newline at end of file
...@@ -17,8 +17,17 @@ public interface CrowdPackageConditionMatchService extends IService<CrowdPackage ...@@ -17,8 +17,17 @@ public interface CrowdPackageConditionMatchService extends IService<CrowdPackage
* 从包中获取用户列表 * 从包中获取用户列表
* *
* @param packageId 包id * @param packageId 包id
* @param openId 用户openId
* @return {@link List}<{@link RegisterUserEntity}> * @return {@link List}<{@link RegisterUserEntity}>
*/ */
List<CrowdPackageUserVO> getUserListFromPackage(Long packageId); List<CrowdPackageUserVO> getUserListFromPackage(Long packageId, String openId);
/**
* 获取用户是否符合人群包条件
* @param packageId 人群包id
* @param openId 用户openId
* @return 结果
*/
Boolean getUserPackageBelong(Long packageId, String openId);
} }
...@@ -84,4 +84,20 @@ public interface CrowdPackageService extends IService<CrowdPackage> { ...@@ -84,4 +84,20 @@ public interface CrowdPackageService extends IService<CrowdPackage> {
* @return {@link GenericsResult}<{@link ConditionOptionResponseVO} * @return {@link GenericsResult}<{@link ConditionOptionResponseVO}
*/ */
GenericsResult<ConditionOptionResponseVO> getOptions(Long conditionId); GenericsResult<ConditionOptionResponseVO> getOptions(Long conditionId);
/**
* 更新用户所属人群包
* @param openId 用户标识
* @return 人群包id拼接
*/
BaseResult updateUserPackageBelong(String openId);
/**
* 批处理更新用户包
*
* @param openIdList 开放id列表
* @return {@link BaseResult}
*/
BaseResult updateUserPackageBatch(List<String> openIdList);
} }
...@@ -18,9 +18,10 @@ public interface RegisterUserEntityService extends IService<RegisterUserEntity>{ ...@@ -18,9 +18,10 @@ public interface RegisterUserEntityService extends IService<RegisterUserEntity>{
* 获取符合动态条件的用户 * 获取符合动态条件的用户
* *
* @param dynamicExpressList 动态表达列表 * @param dynamicExpressList 动态表达列表
* @param openId 指定用户openId
* @return {@link List}<{@link RegisterUserEntity}> * @return {@link List}<{@link RegisterUserEntity}>
*/ */
List<CrowdPackageUserVO> getUserMatchDynamicExpress(List<String> dynamicExpressList); List<CrowdPackageUserVO> getUserMatchDynamicExpress(List<String> dynamicExpressList, String openId);
} }
...@@ -38,7 +38,7 @@ public class CrowdPackageConditionMatchServiceImpl extends ServiceImpl<MaterialC ...@@ -38,7 +38,7 @@ public class CrowdPackageConditionMatchServiceImpl extends ServiceImpl<MaterialC
private RegisterUserEntityService userEntityService; private RegisterUserEntityService userEntityService;
@Override @Override
public List<CrowdPackageUserVO> getUserListFromPackage(Long packageId) { public List<CrowdPackageUserVO> getUserListFromPackage(Long packageId, String openId) {
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
// 获取人群包下的条件 // 获取人群包下的条件
...@@ -55,7 +55,7 @@ public class CrowdPackageConditionMatchServiceImpl extends ServiceImpl<MaterialC ...@@ -55,7 +55,7 @@ public class CrowdPackageConditionMatchServiceImpl extends ServiceImpl<MaterialC
LOCAL_LOG.info("获取SetupId列表耗时 {}ms, setupId列表长度: {}", getSetupIdTime - getConditionTime, setupIdList.size()); LOCAL_LOG.info("获取SetupId列表耗时 {}ms, setupId列表长度: {}", getSetupIdTime - getConditionTime, setupIdList.size());
// 根据动态条件获取用户列表 // 根据动态条件获取用户列表
List<CrowdPackageUserVO> userList = userEntityService.getUserMatchDynamicExpress(nonStaticConditionList); List<CrowdPackageUserVO> userList = userEntityService.getUserMatchDynamicExpress(nonStaticConditionList, openId);
long dynamicUserTime = System.currentTimeMillis(); long dynamicUserTime = System.currentTimeMillis();
LOCAL_LOG.info("获取SetupId列表符合动态条件的用户耗时 {}ms, 符合动态条件的用户: {}个", dynamicUserTime - getSetupIdTime, userList.size()); LOCAL_LOG.info("获取SetupId列表符合动态条件的用户耗时 {}ms, 符合动态条件的用户: {}个", dynamicUserTime - getSetupIdTime, userList.size());
...@@ -66,6 +66,16 @@ public class CrowdPackageConditionMatchServiceImpl extends ServiceImpl<MaterialC ...@@ -66,6 +66,16 @@ public class CrowdPackageConditionMatchServiceImpl extends ServiceImpl<MaterialC
long allUserTime = System.currentTimeMillis(); long allUserTime = System.currentTimeMillis();
LOCAL_LOG.info("获取符合全部条件的用户耗时: {}ms, 符合全部条件的用户: {}个", allUserTime - dynamicUserTime, userList.size()); LOCAL_LOG.info("获取符合全部条件的用户耗时: {}ms, 符合全部条件的用户: {}个", allUserTime - dynamicUserTime, userList.size());
if (CollectionUtil.isEmpty(userList)) {
LOCAL_LOG.info("人群包ID {}, 没有符合条件的用户", packageId);
}
return userList; return userList;
} }
@Override
public Boolean getUserPackageBelong(Long packageId, String openId) {
List<CrowdPackageUserVO> userList = this.getUserListFromPackage(packageId, openId);
return CollectionUtil.isNotEmpty(userList);
}
} }
...@@ -12,6 +12,7 @@ import com.yaoyaozw.customer.common.GenericsResult; ...@@ -12,6 +12,7 @@ import com.yaoyaozw.customer.common.GenericsResult;
import com.yaoyaozw.customer.components.SnowflakeComponent; import com.yaoyaozw.customer.components.SnowflakeComponent;
import com.yaoyaozw.customer.components.TokenManager; import com.yaoyaozw.customer.components.TokenManager;
import com.yaoyaozw.customer.constants.CrowdPackageCommonConstant; import com.yaoyaozw.customer.constants.CrowdPackageCommonConstant;
import com.yaoyaozw.customer.constants.CustomerCommonConstant;
import com.yaoyaozw.customer.dto.crowd.CrowdPackageQueryDTO; import com.yaoyaozw.customer.dto.crowd.CrowdPackageQueryDTO;
import com.yaoyaozw.customer.dto.crowd.CrowdPackageConditionDTO; import com.yaoyaozw.customer.dto.crowd.CrowdPackageConditionDTO;
import com.yaoyaozw.customer.entity.CrowdPackage; import com.yaoyaozw.customer.entity.CrowdPackage;
...@@ -20,19 +21,24 @@ import com.yaoyaozw.customer.entity.CrowdPackageConditionMatch; ...@@ -20,19 +21,24 @@ import com.yaoyaozw.customer.entity.CrowdPackageConditionMatch;
import com.yaoyaozw.customer.enums.CrowdPackageConditionEnum; import com.yaoyaozw.customer.enums.CrowdPackageConditionEnum;
import com.yaoyaozw.customer.mapper.KanbanCommonMapper; import com.yaoyaozw.customer.mapper.KanbanCommonMapper;
import com.yaoyaozw.customer.mapper.MaterialCrowdPackageMapper; import com.yaoyaozw.customer.mapper.MaterialCrowdPackageMapper;
import com.yaoyaozw.customer.mapper.RegisterUserEntityMapper;
import com.yaoyaozw.customer.service.CrowdPackageConditionMatchService; import com.yaoyaozw.customer.service.CrowdPackageConditionMatchService;
import com.yaoyaozw.customer.service.CrowdPackageConditionService; import com.yaoyaozw.customer.service.CrowdPackageConditionService;
import com.yaoyaozw.customer.service.CrowdPackageService; import com.yaoyaozw.customer.service.CrowdPackageService;
import com.yaoyaozw.customer.service.RegisterUserEntityService;
import com.yaoyaozw.customer.vo.CommonOptionResponseVO; import com.yaoyaozw.customer.vo.CommonOptionResponseVO;
import com.yaoyaozw.customer.vo.crowd.*; import com.yaoyaozw.customer.vo.crowd.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -53,6 +59,10 @@ public class CrowdPackageServiceImpl extends ServiceImpl<MaterialCrowdPackageMap ...@@ -53,6 +59,10 @@ public class CrowdPackageServiceImpl extends ServiceImpl<MaterialCrowdPackageMap
private TokenManager tokenManager; private TokenManager tokenManager;
@Autowired @Autowired
private CrowdPackageConditionMatchService matchService; private CrowdPackageConditionMatchService matchService;
@Autowired
private RegisterUserEntityMapper userEntityMapper;
@Autowired
private RedisTemplate redisTemplate;
@Override @Override
...@@ -131,6 +141,11 @@ public class CrowdPackageServiceImpl extends ServiceImpl<MaterialCrowdPackageMap ...@@ -131,6 +141,11 @@ public class CrowdPackageServiceImpl extends ServiceImpl<MaterialCrowdPackageMap
if (CollectionUtil.isEmpty(pageList)) { if (CollectionUtil.isEmpty(pageList)) {
return new GenericsResult<>(false, "暂无数据"); return new GenericsResult<>(false, "暂无数据");
} }
HashMap<String, Integer> entries = (HashMap<String, Integer>) redisTemplate.boundHashOps(CustomerCommonConstant.CROWD_HUMAN_NUN_REDIS_KEY).entries();
if (CollectionUtil.isNotEmpty(entries)) {
pageList.forEach(item -> item.setNumOfCrowdInPackage(entries.get(item.getId().toString())));
}
return new GenericsResult<>(pageList); return new GenericsResult<>(pageList);
} }
...@@ -186,6 +201,43 @@ public class CrowdPackageServiceImpl extends ServiceImpl<MaterialCrowdPackageMap ...@@ -186,6 +201,43 @@ public class CrowdPackageServiceImpl extends ServiceImpl<MaterialCrowdPackageMap
return new GenericsResult<>(new ConditionOptionResponseVO(conditionItem.getFrontType(), result)); return new GenericsResult<>(new ConditionOptionResponseVO(conditionItem.getFrontType(), result));
} }
@Override
public BaseResult updateUserPackageBelong(String openId) {
List<CrowdPackage> packageList = super.list();
StringBuilder packageConcatResult = new StringBuilder();
boolean isFirst = true;
for (CrowdPackage crowdPackage : packageList) {
Boolean matchPackage = matchService.getUserPackageBelong(crowdPackage.getId(), openId);
if (matchPackage) {
// 用户符合人群包条件
if (!isFirst) {
// 除了第一个,其他的要在数字前拼上逗号
packageConcatResult.append(",");
}
packageConcatResult.append(crowdPackage.getId());
isFirst = false;
}
}
String packageStr = packageConcatResult.toString();
userEntityMapper.updateUserPackageBelong(openId, StringUtils.isBlank(packageStr) ? null : packageStr);
LOCAL_LOG.info("用户openId: {} 人群包更新完成", openId);
return new BaseResult().success();
}
@Override
public BaseResult updateUserPackageBatch(List<String> openIdList) {
List<CrowdPackage> packageList = super.list();
return null;
}
/** /**
* 构造操作符 * 构造操作符
* *
......
...@@ -37,10 +37,11 @@ public class CustomerGraphicsServiceImpl extends ServiceImpl<CustomerGraphicsMap ...@@ -37,10 +37,11 @@ public class CustomerGraphicsServiceImpl extends ServiceImpl<CustomerGraphicsMap
@Override @Override
public BaseResult insertCustomerMessage(CustomerMessageSaveDTO saveDto) { public BaseResult insertCustomerMessage(CustomerMessageSaveDTO saveDto) {
Long packageId = saveDto.getPackageId();
LOCAL_LOG.info("根据人群包找到符合条件的用户数据"); LOCAL_LOG.info("根据人群包 {} 找符合条件的用户数据", packageId);
List<CrowdPackageUserVO> userList = matchService.getUserListFromPackage(saveDto.getPackageId()); List<CrowdPackageUserVO> userList = matchService.getUserListFromPackage(packageId, null);
redisTemplate.opsForHash().put(CustomerCommonConstant.CROWD_HUMAN_NUN_REDIS_KEY, saveDto.getPackageId().toString(), userList.size()); redisTemplate.opsForHash().put(CustomerCommonConstant.CROWD_HUMAN_NUN_REDIS_KEY, packageId.toString(), userList.size());
// TODO: 2022/9/28 根据人群包找到下面的人所在的公众号,进行链接获取 // TODO: 2022/9/28 根据人群包找到下面的人所在的公众号,进行链接获取
......
...@@ -52,9 +52,9 @@ public class RegisterUserEntityServiceImpl extends ServiceImpl<RegisterUserEntit ...@@ -52,9 +52,9 @@ public class RegisterUserEntityServiceImpl extends ServiceImpl<RegisterUserEntit
@Override @Override
public List<CrowdPackageUserVO> getUserMatchDynamicExpress(List<String> dynamicExpressList) { public List<CrowdPackageUserVO> getUserMatchDynamicExpress(List<String> dynamicExpressList, String openId) {
return baseMapper.getUserMatchDynamicExpress(dynamicExpressList); return baseMapper.getUserMatchDynamicExpress(dynamicExpressList, openId);
} }
} }
...@@ -21,4 +21,6 @@ public class CrowdPackageUserVO implements Serializable { ...@@ -21,4 +21,6 @@ public class CrowdPackageUserVO implements Serializable {
private Long setupId; private Long setupId;
private String inPackage;
} }
...@@ -26,21 +26,33 @@ ...@@ -26,21 +26,33 @@
rue.id, rue.id,
ai.account_id as accountId, ai.account_id as accountId,
rue.setup_id as setupId, rue.setup_id as setupId,
rue.open_id as openId rue.open_id as openId,
rue.in_package as inPackage
from register_user_entity rue from register_user_entity rue
left join authorizer_info ai left join authorizer_info ai
on rue.app_id = ai.appid on rue.app_id = ai.appid
where
<if test="openId != null and openId != ''">
rue.open_id = #{openId} and
</if>
timestampdiff(HOUR, rue.last_active, now()) &lt; 48
<if test="dynamicExpressList != null and dynamicExpressList.size() != 0"> <if test="dynamicExpressList != null and dynamicExpressList.size() != 0">
<where> <foreach collection="dynamicExpressList" open=" and " item="express" separator=" and ">
<foreach collection="dynamicExpressList" separator=" and " item="express">
${express} ${express}
</foreach> </foreach>
</where>
</if> </if>
</select> </select>
<update id="updateUserPackageBelong">
update register_user_entity
set in_package = #{packageBelong}
where open_id = #{openId}
</update>
</mapper> </mapper>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论