| @@ -9,11 +9,12 @@ import com.iformall.enums.*; | |||
| import com.iformall.service.invest.*; | |||
| import com.iformall.utils.DateUtils; | |||
| import lombok.extern.slf4j.Slf4j; | |||
| import org.apache.commons.collections.CollectionUtils; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.springframework.beans.factory.annotation.Autowired; | |||
| import org.springframework.core.env.Environment; | |||
| import org.springframework.scheduling.annotation.Scheduled; | |||
| import org.springframework.stereotype.Component; | |||
| import org.springframework.util.CollectionUtils; | |||
| import java.util.*; | |||
| @@ -22,6 +23,7 @@ import java.util.*; | |||
| @Component | |||
| public class InvestSchedule { | |||
| public static final String[] ENV_STR = {"dev", "test"}; | |||
| @Autowired | |||
| InvestBizService bizService; | |||
| @Autowired | |||
| @@ -35,52 +37,72 @@ public class InvestSchedule { | |||
| @Autowired | |||
| InvestFollowRecordService followRecordService; | |||
| @Autowired | |||
| Environment environment; | |||
| private static final String PREFIX = "招商定时任务"; | |||
| //@Scheduled(cron = "0 0 14 * * ?") // 每天下午两点执行定时任务 | |||
| @Scheduled(cron = "0 */5 * * * *?") // 测试,每5分钟执行 | |||
| @Scheduled(cron = "0 */30 * * * *?") // 测试,每5分钟执行 | |||
| public void messageSchedule() { | |||
| log.info("招商定时任务: 开始"); | |||
| log.info("{}: 开始", PREFIX); | |||
| //一个月内未完成提醒 | |||
| taskMonthMessage(); | |||
| //一周内未跟踪提醒 | |||
| demandWeekMessage(); | |||
| log.info("招商定时任务: 结束"); | |||
| log.info("{}: 结束", PREFIX); | |||
| } | |||
| private void taskMonthMessage() { | |||
| //已经存在的提醒 | |||
| List<InvestMessageEntity> taskMessages = messageService.listByTypeAndTag(EnumFollowType.TASK, EnumInvestMessageTag.TASK_CREATE); | |||
| List<InvestMessageEntity> taskMessages = messageService.listByTypeAndTag(EnumFollowType.TASK, EnumInvestMessageTag.TASK_MONTH); | |||
| ImmutableListMultimap<Long, InvestMessageEntity> taskMessageUserIdMap = Multimaps.index(taskMessages, InvestMessageEntity::getOwner); | |||
| //初始化时间条件 | |||
| Calendar start = Calendar.getInstance(); | |||
| Calendar end = Calendar.getInstance(); | |||
| //end.add(Calendar.MONTH, 1); | |||
| end.add(Calendar.DAY_OF_YEAR, 1); //测试 | |||
| if (environment.acceptsProfiles(ENV_STR)) { | |||
| end.add(Calendar.DAY_OF_YEAR, 1); //测试 | |||
| } else { | |||
| end.add(Calendar.MONTH, 1); | |||
| } | |||
| //查询满足条件 | |||
| List<InvestTaskEntity> tasks = taskService.listByStatusAndTime(Arrays.asList(EnumTaskStatus.INTENTION, EnumTaskStatus.NEGOTIATING), start.getTime(), end.getTime()); | |||
| log.info("{}:{} - {} 的任务数 :{}", PREFIX, start, end, tasks.size()); | |||
| if (tasks.isEmpty()) { | |||
| return; | |||
| } | |||
| for (InvestTaskEntity task : tasks) { | |||
| String owner = task.getOwner(); | |||
| if (StringUtils.isEmpty(owner)) { | |||
| log.warn("{}:taskID:{} owner不存在:{}, 跳过", PREFIX, task.getId(), task.getOwner()); | |||
| continue; | |||
| } | |||
| List<Long> ownerArray = JSONArray.parseArray(owner, Long.class); | |||
| for (Long ownerId : ownerArray) { | |||
| List<InvestMessageEntity> messageList = taskMessageUserIdMap.get(ownerId); | |||
| if (CollectionUtils.isEmpty(messageList)) { | |||
| continue; | |||
| } | |||
| for (InvestMessageEntity messageEntity : messageList) { | |||
| if (messageEntity.getTid().equals(task.getId())) { | |||
| continue; | |||
| if (CollectionUtils.isNotEmpty(messageList)) { | |||
| for (InvestMessageEntity messageEntity : messageList) { | |||
| if (messageEntity.getTid().equals(task.getId())) { | |||
| log.info("{}:taskID:{} 提醒已存在:{}, 跳过", PREFIX, task.getId(), messageEntity.getId()); | |||
| continue; | |||
| } | |||
| addTaskMessage(task, ownerArray); | |||
| } | |||
| String message = String.format(EnumInvestMessageType.TASK_REMIND.getInfo(), task.getId(), DateUtils.format(task.getLastTime())); | |||
| messageService.saveBatchMessage(ownerArray, message, EnumInvestMessageTag.TASK_MONTH, EnumFollowType.TASK, task.getId()); | |||
| } else { | |||
| addTaskMessage(task, ownerArray); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| private void addTaskMessage(InvestTaskEntity task, List<Long> ownerArray) { | |||
| String message = String.format(EnumInvestMessageType.TASK_REMIND.getInfo(), task.getId(), DateUtils.format(task.getLastTime())); | |||
| messageService.saveBatchMessage(ownerArray, message, EnumInvestMessageTag.TASK_MONTH, EnumFollowType.TASK, task.getId()); | |||
| log.info("{}:taskID:{} 为用户{}创建消息提醒", PREFIX, task.getId(), task.getOwner()); | |||
| } | |||
| private void demandWeekMessage() { | |||
| //已经存在的提醒 | |||
| List<InvestMessageEntity> demandMessages = messageService.listByTypeAndTag(EnumFollowType.DEMAND, EnumInvestMessageTag.CUSTOMER_WEEK); | |||
| @@ -88,8 +110,11 @@ public class InvestSchedule { | |||
| //初始化时间条件 | |||
| Calendar start = Calendar.getInstance(); | |||
| //start.add(Calendar.DAY_OF_YEAR, 7); | |||
| start.add(Calendar.DAY_OF_YEAR, 1); //测试 | |||
| if (environment.acceptsProfiles(ENV_STR)) { | |||
| start.add(Calendar.DAY_OF_YEAR, 1); //测试 | |||
| } else { | |||
| start.add(Calendar.DAY_OF_YEAR, 7); | |||
| } | |||
| //查询跟踪列表 | |||
| List<InvestFollowRecordEntity> follows = followRecordService.listByTime(EnumFollowType.DEMAND, start.getTime()); | |||
| @@ -101,29 +126,36 @@ public class InvestSchedule { | |||
| * 已经已经提醒过的用户 | |||
| */ | |||
| List<String> userDemandFlag = new ArrayList<>(); | |||
| for (InvestCustomerVo demand : demands) { | |||
| Long owner = demand.getDemandOwner(); | |||
| for (InvestCustomerVo customerVo : demands) { | |||
| Long owner = customerVo.getDemandOwner(); | |||
| if (Objects.isNull(owner)) { | |||
| log.warn("{}:customerID:{} owner不存在:{}, 跳过", PREFIX, customerVo.getId(), customerVo.getDemandOwner()); | |||
| continue; | |||
| } | |||
| List<InvestMessageEntity> messageList = demandMessageUserIdMap.get(owner); | |||
| if (CollectionUtils.isEmpty(messageList)) { | |||
| continue; | |||
| addCustomerMessage(customerVo, owner); | |||
| } | |||
| for (InvestMessageEntity messageEntity : messageList) { | |||
| if (messageEntity.getTid().equals(messageEntity.getId())) { | |||
| log.info("{}:taskID:{} 提醒已存在:{}, 跳过", PREFIX, customerVo.getId(), messageEntity.getId()); | |||
| continue; | |||
| } | |||
| String userDemandFlagItem = StringUtils.join(messageEntity.getOwner(), messageEntity.getId()); | |||
| //已经提醒过的用户不在提醒 | |||
| if (userDemandFlag.contains(userDemandFlagItem)) { | |||
| log.info("{}:taskID:{} 提醒已存在:{}, 跳过", PREFIX, customerVo.getId(), userDemandFlagItem); | |||
| continue; | |||
| } | |||
| String message = String.format(EnumInvestMessageType.COSTOMER_REMIND.getInfo(), demand.getId()); | |||
| messageService.saveBatchMessage(Arrays.asList(owner), message, EnumInvestMessageTag.CUSTOMER_WEEK, EnumFollowType.DEMAND, demand.getId()); | |||
| addCustomerMessage(customerVo, owner); | |||
| userDemandFlag.add(userDemandFlagItem); | |||
| } | |||
| } | |||
| } | |||
| private void addCustomerMessage(InvestCustomerVo customerVo, Long owner) { | |||
| String message = String.format(EnumInvestMessageType.COSTOMER_REMIND.getInfo(), customerVo.getId()); | |||
| messageService.saveBatchMessage(Arrays.asList(owner), message, EnumInvestMessageTag.CUSTOMER_WEEK, EnumFollowType.DEMAND, customerVo.getId()); | |||
| log.info("{}:customerID:{} 为用户{}创建消息提醒", PREFIX, customerVo.getId(), customerVo.getDemandOwner()); | |||
| } | |||
| } | |||
| @@ -78,9 +78,9 @@ public class InvestCustomerEntity extends InvestBaseEntity { | |||
| /** | |||
| * 招商渠道:0-无;1-电视;2-广播;3-报纸;4-刊物;5-物联网;6-招商活动;7-中介机构;8-自定义渠道 | |||
| */ | |||
| @io.swagger.annotations.ApiModelProperty(value = "招商渠道:0-无;1-电视;2-广播;3-报纸;4-刊物;5-物联网;6-招商活动;7-中介机构;8-自定义渠道", name = "investChannel") | |||
| @io.swagger.annotations.ApiModelProperty(value = "招商渠道:0-无;1-电视;2-广播;3-报纸;4-刊物;5-物联网;6-招商活动;7-中介机构;8-自定义渠道", name = "investChannel" ,reference = "EnumInvestChannel") | |||
| @LogColumn | |||
| private EnumInvestChannel investChannel ; | |||
| private String investChannel ; | |||
| /** | |||
| * 更新时间 | |||
| @@ -22,15 +22,15 @@ public class InvestCustomerVo extends InvestCustomerEntity { | |||
| @Excel(name = "品牌*", width = 30, orderNum = "1") | |||
| private String brandName; | |||
| @Excel(name = "经营业态*", width = 20, orderNum = "3") | |||
| @Excel(name = "经营业态*", width = 20, orderNum = "4") | |||
| private String business; | |||
| @Excel(name = "意向租赁面积", width = 20, orderNum = "5") | |||
| @Excel(name = "意向铺位*", width = 20, orderNum = "5") | |||
| private String shopNumber; | |||
| @Excel(name = "意向租凭面积", width = 20, orderNum = "6") | |||
| private Integer rentArea; | |||
| @Excel(name = "预计开业时间", width = 20, orderNum = "6") | |||
| @Excel(name = "预计开业时间", width = 20, orderNum = "7") | |||
| private String openingTime; | |||
| @Excel(name = "意向铺位*", width = 20, orderNum = "4") | |||
| private String shopNumber; | |||
| } | |||
| @@ -1,40 +0,0 @@ | |||
| package com.iformall.domain.vo.invest; | |||
| import cn.afterturn.easypoi.excel.annotation.Excel; | |||
| import lombok.Data; | |||
| import javax.validation.constraints.NotNull; | |||
| import javax.validation.constraints.Pattern; | |||
| import java.io.Serializable; | |||
| @Data | |||
| public class InvestCustomerVoT implements Serializable { | |||
| @Excel(name="品牌*",width = 20,orderNum = "1") | |||
| @io.swagger.annotations.ApiModelProperty(value="品牌",name="brandName") | |||
| @NotNull | |||
| private String brandName; | |||
| @Excel(name="品牌负责人*",width = 20,orderNum = "2") | |||
| @io.swagger.annotations.ApiModelProperty(value="品牌负责人",name="name") | |||
| @NotNull | |||
| private String name; | |||
| @Excel(name = "负责人电话*", width = 20, orderNum = "3") | |||
| @io.swagger.annotations.ApiModelProperty(value="负责人电话",name="phone") | |||
| @NotNull | |||
| @Pattern(regexp = "1[0123456789]\\d{9}", message = "手机号不正确") | |||
| private String phone; | |||
| @Excel(name="经营业态*",width = 20,orderNum = "4") | |||
| @io.swagger.annotations.ApiModelProperty(value="用户昵称",name="business") | |||
| @NotNull | |||
| private String business; | |||
| @Excel(name="意向铺位*",width = 20,orderNum = "5") | |||
| @io.swagger.annotations.ApiModelProperty(value="学历",name="shopNumber") | |||
| @NotNull | |||
| private String shopNumber; | |||
| @Excel(name="意向租凭面积",width = 20,orderNum = "2") | |||
| @io.swagger.annotations.ApiModelProperty(value="意向租凭面积",name="rentArea") | |||
| private Integer rentArea; | |||
| @Excel(name="预计开业时间",width = 20,orderNum = "6") | |||
| @io.swagger.annotations.ApiModelProperty(value="预计开业时间",name="openingTime") | |||
| private String openingTime; | |||
| } | |||
| @@ -105,8 +105,7 @@ public class InvestHelper { | |||
| } | |||
| /** | |||
| * | |||
| * @param value the object to check | |||
| * @param value the object to check | |||
| * @param message the exception message to use if the assertion fails | |||
| */ | |||
| public static void checkResult(Object value, String message) { | |||
| @@ -154,7 +153,7 @@ public class InvestHelper { | |||
| return (T) T.valueOf(enumType, name); | |||
| } | |||
| public <T, R> ImmutableListMultimap<R, T> getMultiMap(Collection<T> dataList) { | |||
| public <T, R> ImmutableListMultimap<R, T> getMultiMap(Collection<T> dataList) { | |||
| return Multimaps.index(dataList, new com.google.common.base.Function<T, R>() { | |||
| @Nullable | |||
| @Override | |||
| @@ -167,24 +166,24 @@ public class InvestHelper { | |||
| }); | |||
| } | |||
| public static <T, R> Map<R, T> getMap(Collection<T> dataList, Function<T, R> keyMapper) { | |||
| return dataList.parallelStream().collect(Collectors.toMap(keyMapper, entity -> entity)); | |||
| public static <T, R> Map<R, T> getMap(Collection<T> dataList, Function<T, R> keyMapper) { | |||
| return dataList.parallelStream().collect(Collectors.toMap(keyMapper, entity -> entity, (k1, k2) -> k1)); | |||
| } | |||
| public static <T, R> Collection<R> getIds(Collection<T> dataList, Function<? super T, R> mapper) { | |||
| return dataList.parallelStream().map(mapper).collect(Collectors.toList()); | |||
| } | |||
| public static <T, R> Collection<R> getIds(Collection<T> dataList, Predicate<T> predicate,Function<? super T, R> mapper) { | |||
| public static <T, R> Collection<R> getIds(Collection<T> dataList, Predicate<T> predicate, Function<? super T, R> mapper) { | |||
| return dataList.parallelStream().filter(predicate).map(mapper).collect(Collectors.toList()); | |||
| } | |||
| public static String addContractId(String content,Long rentId,Integer ContractType) { | |||
| public static String addContractId(String content, Long rentId, Integer ContractType) { | |||
| Map contentMap = JSON.parseObject(content, Map.class); | |||
| if(Objects.nonNull(rentId)) { | |||
| if (Objects.nonNull(rentId)) { | |||
| contentMap.put(InvestTaskEntity.KEY_CONTRACT_ID, String.valueOf(rentId)); | |||
| } | |||
| if(Objects.nonNull(ContractType)) { | |||
| if (Objects.nonNull(ContractType)) { | |||
| contentMap.put(InvestTaskEntity.KEY_CONTRACT_TYPE, ContractType); | |||
| } | |||
| return JsonUtil.obj2Json(contentMap); | |||
| @@ -233,9 +233,9 @@ public class InvestBizServiceImpl implements InvestBizService { | |||
| ImportParams params = new ImportParams(); | |||
| // 需要验证 | |||
| params.setImportFields(new String[]{"品牌*", "品牌负责人*", "负责人电话*", "经营业态*", "意向铺位*", "意向租凭面积", "预计开业时间"}); | |||
| IExcelDataHandler<InvestCustomerVoT> handler = new ExcelDataHandlerDefaultImpl<InvestCustomerVoT>() { | |||
| IExcelDataHandler<InvestCustomerVo> handler = new ExcelDataHandlerDefaultImpl<InvestCustomerVo>() { | |||
| @Override | |||
| public Object importHandler(InvestCustomerVoT obj, String name, Object value) { | |||
| public Object importHandler(InvestCustomerVo obj, String name, Object value) { | |||
| if (value == null) { | |||
| value = ""; | |||
| } | |||
| @@ -246,10 +246,10 @@ public class InvestBizServiceImpl implements InvestBizService { | |||
| handler.setNeedHandlerFields(new String[]{"品牌*", "品牌负责人*", "负责人电话*", "经营业态*", "意向铺位*"}); | |||
| params.setNeedVerify(true); | |||
| ExcelImportResult<InvestCustomerVoT> datalist = null; | |||
| ExcelImportResult<InvestCustomerVo> datalist = null; | |||
| try { | |||
| datalist = ExcelImportUtil.importExcelMore(file, InvestCustomerVoT.class, params); | |||
| datalist = ExcelImportUtil.importExcelMore(file, InvestCustomerVo.class, params); | |||
| } catch (Exception e) { | |||
| setRedisValue(importKey, "1", "0", "0", "1", true); | |||
| log.error(e.getMessage()); | |||
| @@ -266,8 +266,8 @@ public class InvestBizServiceImpl implements InvestBizService { | |||
| return; | |||
| } | |||
| List<InvestCustomerVoT> successList = datalist.getList(); | |||
| List<InvestCustomerVoT> failList = datalist.getFailList(); | |||
| List<InvestCustomerVo> successList = datalist.getList(); | |||
| List<InvestCustomerVo> failList = datalist.getFailList(); | |||
| log.info("验证通过的数量: " + successList.size()); | |||
| log.info("验证未通过的数量: " + failList.size()); | |||
| @@ -288,12 +288,14 @@ public class InvestBizServiceImpl implements InvestBizService { | |||
| Map<String, WxBusiness> businesseMap = getBusinessMap(); | |||
| //商铺信息 | |||
| WxShop shopQuery = new WxShop(); | |||
| shopQuery.setTenantId(InvestUserContext.getUser().getTenantId()); | |||
| List<WxShop> shops = shopService.listAsPage(null, 1, Integer.MAX_VALUE).getList(); | |||
| Map<String, WxShop> shopMap = getMap(shops, WxShop::getShopNumber); | |||
| //商铺信息 | |||
| LambdaQueryWrapper<InvestCustomerEntity> customerQuery = new LambdaQueryWrapper<>(); | |||
| customerQuery.in(InvestCustomerEntity::getPhone, getIds(successList, InvestCustomerVoT::getPhone)); | |||
| customerQuery.in(InvestCustomerEntity::getPhone, getIds(successList, InvestCustomerVo::getPhone)); | |||
| List<InvestCustomerEntity> customers = customerService.list(customerQuery); | |||
| Map<String, InvestCustomerEntity> customerMap = getMap(customers, InvestCustomerEntity::getPhone); | |||
| @@ -348,7 +350,7 @@ public class InvestBizServiceImpl implements InvestBizService { | |||
| return getMap(brands, WxBrand::getName); | |||
| } | |||
| private InvestDemandDto convetCustomer(InvestCustomerVoT customerVoT, Map<String, WxBrand> brandMap, Map<String, WxBusiness> businesseMap, Map<String, WxShop> shopMap, Map<String, InvestCustomerEntity> customerMap) { | |||
| private InvestDemandDto convetCustomer(InvestCustomerVo customerVoT, Map<String, WxBrand> brandMap, Map<String, WxBusiness> businesseMap, Map<String, WxShop> shopMap, Map<String, InvestCustomerEntity> customerMap) { | |||
| InvestCustomerEntity customerEntity = new InvestCustomerEntity(); | |||
| if (Objects.isNull(brandMap.get(customerVoT.getBrandName()))) { | |||
| return null; | |||
| @@ -1063,13 +1065,10 @@ public class InvestBizServiceImpl implements InvestBizService { | |||
| Map<Integer, WxBusiness> bussinessMap = getMap(businessService.getByIds(getIds(customers, InvestCustomerEntity::getBusinessId)), WxBusiness::getId); | |||
| List<InvestCustomerVo> resultList = new ArrayList<>(); | |||
| for (InvestCustomerEntity costomerItem : customers) { | |||
| InvestDemandEntity demandItem = demindsMap.get(costomerItem.getId()); | |||
| WxShop shop = null; | |||
| if (Objects.nonNull(demandItem)) { | |||
| shop = shopsMap.get(demandItem.getTargetId()); | |||
| } | |||
| Optional<InvestDemandEntity> demandItem = Optional.ofNullable(demindsMap.get(costomerItem.getId())); | |||
| WxShop shop = shopsMap.get(demandItem.orElse(null)); | |||
| WxBrand brand = brandMap.get(costomerItem.getBrandId()); | |||
| resultList.add(buildCustomerItem(demandItem, costomerItem, brand, shop, bussinessMap.get(costomerItem.getBusinessId()))); | |||
| resultList.add(buildCustomerItem(demandItem.orElse(null), costomerItem, brand, shop, bussinessMap.get(costomerItem.getBusinessId()))); | |||
| } | |||
| return resultList; | |||
| } | |||
| @@ -1088,13 +1087,10 @@ public class InvestBizServiceImpl implements InvestBizService { | |||
| List<InvestDemandVo> resultList = new ArrayList<>(); | |||
| for (InvestCustomerEntity costomerItem : customers) { | |||
| InvestDemandEntity demandItem = demindsMap.get(costomerItem.getId()); | |||
| WxShop shop = null; | |||
| if (Objects.nonNull(demandItem)) { | |||
| shop = shopsMap.get(demandItem.getTargetId()); | |||
| } | |||
| Optional<InvestDemandEntity> demandItem = Optional.ofNullable(demindsMap.get(costomerItem.getId())); | |||
| WxShop shop = shopsMap.get(demandItem.orElse(null)); | |||
| WxBrand brand = brandMap.get(costomerItem.getBrandId()); | |||
| resultList.add(buildDemindItem(demandItem, costomerItem, brand, shop, usersMap)); | |||
| resultList.add(buildDemindItem(demandItem.orElse(null), costomerItem, brand, shop, usersMap)); | |||
| } | |||
| return resultList; | |||
| } | |||