From 3d6f82701e655f6e13247056ad20862a9adec02a Mon Sep 17 00:00:00 2001 From: Kurisu Date: Wed, 22 Mar 2023 17:55:03 +0800 Subject: [PATCH] feature(*): 公共池线索开始逻辑 --- doc/v2.0/update.sql | 33 +++++++++++++++++---------------- fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/pub/PubCluePool.java | 4 ++++ fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/AbstractFollowStrategy.java | 13 ------------- fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/FollowStrategy.java | 16 ++++++++++++++++ fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/PubFollowStrategy.java | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/pub/PubFollowBizService.java | 12 ++++++++++++ 6 files changed, 226 insertions(+), 37 deletions(-) diff --git a/doc/v2.0/update.sql b/doc/v2.0/update.sql index 0eacb16..4363705 100644 --- a/doc/v2.0/update.sql +++ b/doc/v2.0/update.sql @@ -64,7 +64,6 @@ CREATE TABLE IF NOT EXISTS fw_valhalla.pub_stand_staff_info shop_id bigint not null comment '门店id', shop_name varchar(255) null comment '门店名称', group_id bigint not null comment '集团id', - defeat_reason int(3) null comment '关单原因 1:主动放弃 2:进另一门店 3:角色变动战败 4:到期战败', create_time datetime not null, update_time datetime null, constraint pub_stand_staff_info_staff_id_group_id_uindex @@ -116,22 +115,24 @@ create unique index public_pool_frame_no_group_id_uindex create table if not exists fw_valhalla.pub_clue_pool ( - id bigint auto_increment + id bigint auto_increment primary key, - vin varchar(128) not null comment '车架号', - start_time date not null comment '开始时间', - deadline date not null comment '转换截止时间', - close_time datetime null comment '关闭时间', - begun tinyint(1) null comment '是否已经开始', - state int(3) not null comment '状态: 1、转换中 2、已转换 3、转换失败', - source_type int(5) null comment '来源类型 1:公共池 2:公共池活动', - adviser_id bigint not null comment '顾问id', - adviser_name varchar(32) null comment '顾问名称', - shop_id bigint not null comment '门店id', - shop_name varchar(128) null comment '门店名称', - group_id bigint not null comment '集团id', - create_time datetime null, - update_time datetime null, + vin varchar(128) not null comment '车架号', + start_time date not null comment '开始时间', + deadline date not null comment '转换截止时间', + close_time datetime null comment '关闭时间', + begun tinyint(1) null comment '是否已经开始', + state int(3) not null comment '状态: 1、转换中 2、已转换 3、转换失败', + source_type int(5) null comment '来源类型 1:公共池 2:公共池活动', + next_time date null comment '下次跟进时间', + adviser_id bigint not null comment '顾问id', + adviser_name varchar(32) null comment '顾问名称', + shop_id bigint not null comment '门店id', + shop_name varchar(128) null comment '门店名称', + group_id bigint not null comment '集团id', + defeat_reason int(3) null comment '关单原因 1:主动放弃 2:进另一门店 3:角色变动战败 4:到期战败', + create_time datetime null, + update_time datetime null, constraint pub_clue_pool_customer_id_adviser_id_uindex unique (vin, adviser_id) ) diff --git a/fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/pub/PubCluePool.java b/fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/pub/PubCluePool.java index 5c9c7fa..e443c09 100644 --- a/fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/pub/PubCluePool.java +++ b/fw-valhalla-domain/src/main/java/cn/fw/valhalla/domain/db/pub/PubCluePool.java @@ -49,6 +49,10 @@ public class PubCluePool extends BaseAuditableTimeEntity { */ private Boolean begun; /** + * 下次跟进时间 + */ + private LocalDate nextTime; + /** * 顾问id */ private Long adviserId; diff --git a/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/AbstractFollowStrategy.java b/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/AbstractFollowStrategy.java index 4ab3bb9..85be2ff 100644 --- a/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/AbstractFollowStrategy.java +++ b/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/AbstractFollowStrategy.java @@ -841,19 +841,6 @@ public abstract class AbstractFollowStrategy implements FollowStrategy { return dynamicMap; } - protected LocalDateTime calTime(LocalDateTime baseTime, SettingUnitEnum unit, long value) { - switch (unit) { - case HOUR: - return baseTime.plusHours(value); - case MONTH: - return baseTime.plusMonths(value); - case MINUTE: - return baseTime.plusMinutes(value); - default: - return baseTime.plusDays(value); - } - } - protected void createSecondaryTask(FollowClue clue, Long userId) { ClueTask redistributionTask = new ClueTask(); redistributionTask.setClueId(clue.getId()); diff --git a/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/FollowStrategy.java b/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/FollowStrategy.java index 8f37bfd..a199f42 100644 --- a/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/FollowStrategy.java +++ b/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/FollowStrategy.java @@ -4,10 +4,12 @@ import cn.fw.valhalla.domain.db.OriginalData; import cn.fw.valhalla.domain.db.follow.ClueTask; import cn.fw.valhalla.domain.db.follow.FollowClue; import cn.fw.valhalla.domain.enums.FollowTypeEnum; +import cn.fw.valhalla.domain.enums.SettingUnitEnum; import cn.fw.valhalla.domain.vo.setting.SettingVO; import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; /** @@ -108,4 +110,18 @@ public interface FollowStrategy { */ @Transactional(rollbackFor = Exception.class) void syncEndTask(ClueTask task); + + + default LocalDateTime calTime(LocalDateTime baseTime, SettingUnitEnum unit, long value) { + switch (unit) { + case HOUR: + return baseTime.plusHours(value); + case MONTH: + return baseTime.plusMonths(value); + case MINUTE: + return baseTime.plusMinutes(value); + default: + return baseTime.plusDays(value); + } + } } diff --git a/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/PubFollowStrategy.java b/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/PubFollowStrategy.java index 6c4c801..6ca23d5 100644 --- a/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/PubFollowStrategy.java +++ b/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/follow/strategy/impl/PubFollowStrategy.java @@ -1,23 +1,37 @@ package cn.fw.valhalla.service.bus.follow.strategy.impl; +import cn.fw.shirasawa.sdk.enums.BusinessTypeEnum; +import cn.fw.shirasawa.sdk.enums.DataTypeEnum; +import cn.fw.valhalla.common.utils.DateUtil; import cn.fw.valhalla.domain.db.OriginalData; import cn.fw.valhalla.domain.db.follow.ClueTask; import cn.fw.valhalla.domain.db.follow.FollowClue; import cn.fw.valhalla.domain.db.pub.PubCluePool; -import cn.fw.valhalla.domain.enums.FollowTypeEnum; -import cn.fw.valhalla.domain.enums.PublicClueStateEnum; -import cn.fw.valhalla.domain.enums.TaskDefeatTypeEnum; -import cn.fw.valhalla.domain.enums.TaskStateEnum; -import cn.fw.valhalla.service.bus.follow.strategy.AbstractFollowStrategy; +import cn.fw.valhalla.domain.dto.CustomerDetailDto; +import cn.fw.valhalla.domain.enums.*; +import cn.fw.valhalla.domain.vo.setting.SettingVO; +import cn.fw.valhalla.rpc.oop.OopService; +import cn.fw.valhalla.rpc.oop.dto.ShopDTO; +import cn.fw.valhalla.rpc.shirasawa.ShirasawaRpcService; +import cn.fw.valhalla.rpc.shirasawa.dto.ClueStopDTO; +import cn.fw.valhalla.rpc.shirasawa.dto.FollowInitDTO; +import cn.fw.valhalla.service.bus.cust.CustomerBizService; +import cn.fw.valhalla.service.bus.follow.strategy.FollowStrategy; +import cn.fw.valhalla.service.bus.setting.SettingBizService; +import cn.fw.valhalla.service.data.ClueTaskService; import cn.fw.valhalla.service.data.PubCluePoolService; +import cn.fw.valhalla.service.data.StammkundePoolService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.*; import static cn.fw.common.businessvalidator.Validator.BV; +import static cn.fw.valhalla.service.bus.setting.strategy.SettingStrategy.COMMON_BRAND_ID; /** * 公共池线索跟进 @@ -30,12 +44,30 @@ import static cn.fw.common.businessvalidator.Validator.BV; */ @Slf4j @Component -public class PubFollowStrategy extends AbstractFollowStrategy { +public class PubFollowStrategy implements FollowStrategy { private final PubCluePoolService pubCluePoolService; + private final ClueTaskService clueTaskService; + private final CustomerBizService customerBizService; + private final ShirasawaRpcService shirasawaRpcService; + private final OopService oopService; + private final SettingBizService settingBizService; + private final StammkundePoolService stammkundePoolService; @Autowired - public PubFollowStrategy(final PubCluePoolService pubCluePoolService) { + public PubFollowStrategy(final PubCluePoolService pubCluePoolService, + final ClueTaskService clueTaskService, + final CustomerBizService customerBizService, + final ShirasawaRpcService shirasawaRpcService, + final OopService oopService, + final SettingBizService settingBizService, + final StammkundePoolService stammkundePoolService) { this.pubCluePoolService = pubCluePoolService; + this.clueTaskService = clueTaskService; + this.customerBizService = customerBizService; + this.shirasawaRpcService = shirasawaRpcService; + this.oopService = oopService; + this.settingBizService = settingBizService; + this.stammkundePoolService = stammkundePoolService; } @Override @@ -54,9 +86,44 @@ public class PubFollowStrategy extends AbstractFollowStrategy { return false; } + /** + * 公共池线索跟进此方法无效 + * + * @param followClue + * @return + */ @Override public void startClue(final FollowClue followClue) { + } + @Override + public void settingChanged(List setting, Long groupId) { + // 更改设置不影响公共池线索跟进 + } + + @Override + public void forceStopClue(final FollowClue clue) { + + } + + + public void startClue(final PubCluePool pubClue) { + ClueTask clueTask = new ClueTask(); + clueTask.setClueId(pubClue.getId()); + clueTask.setType(getFollowType()); + clueTask.setBeginTime(pubClue.getStartTime().atStartOfDay()); + clueTask.setRedistribution(Boolean.FALSE); + clueTask.setDeadline(pubClue.getDeadline().atStartOfDay()); + clueTask.setState(TaskStateEnum.ONGOING); + clueTask.setGroupId(pubClue.getGroupId()); + clueTask.setFollowShop(pubClue.getShopId()); + clueTask.setFollowUser(pubClue.getAdviserId()); + clueTask.setFollowUserName(pubClue.getAdviserName()); + clueTaskService.save(clueTask); + + final FollowInitDTO followInitDTO = creteFollowInitDTO(pubClue, clueTask); + pubClue.setNextTime(clueTask.getDeadline().plusDays(1L).toLocalDate()); + shirasawaRpcService.createFollowData(followInitDTO); } @Override @@ -75,6 +142,26 @@ public class PubFollowStrategy extends AbstractFollowStrategy { } @Override + public void forceStopTask(final ClueTask task) { + + } + + @Override + public void onFollowComplete(final ClueTask task, final Long preRecordId, final LocalDate originTime, final boolean overdue) { + + } + + @Override + public void createNextFollowTodo(final FollowClue clue) { + + } + + @Override + public void syncEndTask(final ClueTask task) { + + } + + @Override @Transactional(rollbackFor = Exception.class) public void closeTask(final ClueTask task) { final Long clueId = task.getClueId(); @@ -93,7 +180,89 @@ public class PubFollowStrategy extends AbstractFollowStrategy { pubCluePool.setState(PublicClueStateEnum.DEFEAT); pubCluePool.setDefeatReason(task.getReason()); pubCluePoolService.updateById(pubCluePool); - redisTemplate.opsForSet().add(generateStopKey(), String.valueOf(clueId)); customerBizService.pubTaskEndAbandon(pubCluePool); } + + private boolean rpcStopTask(ClueTask clueTask) { + ClueStopDTO clueStopDTO = new ClueStopDTO(); + clueStopDTO.setType(DataTypeEnum.ofValue(clueTask.getType().getValue())); + clueStopDTO.setBusinessType(BusinessTypeEnum.AS); + if (TaskStateEnum.DEFEAT.equals(clueTask.getState())) { + clueStopDTO.setTermination(Boolean.TRUE); + } + clueStopDTO.setDetailId(String.valueOf(clueTask.getId())); + clueStopDTO.setShopId(clueTask.getFinishShop()); + ShopDTO shop = oopService.shop(clueTask.getFinishShop()); + if (Objects.nonNull(shop)) { + clueStopDTO.setShopName(shop.getShortName()); + } + clueStopDTO.setCompleteTime(DateUtil.localDateTime2Date(clueTask.getCloseTime())); + clueStopDTO.setGroupId(clueTask.getGroupId()); + clueStopDTO.setUserId(clueTask.getFollowUser()); + clueStopDTO.setUserName(clueTask.getFollowUserName()); + return shirasawaRpcService.stopTask(clueStopDTO); + } + + private FollowInitDTO creteFollowInitDTO(PubCluePool pubClue, ClueTask clueTask) { + CustomerDetailDto customerDetailDto = customerBizService.queryByFrameNo(pubClue.getVin(), pubClue.getGroupId()); + BV.notNull(customerDetailDto, () -> "档案信息有误"); + + final FollowInitDTO followInitDTO = FollowInitDTO.builder() + .businessType(BusinessTypeEnum.AS) + .type(DataTypeEnum.ofValue(getFollowType().getValue())) + .customerId(customerDetailDto.getId()) + .customerName(customerDetailDto.getName()) + .memberId(customerDetailDto.getMemberId()) + .plateNo(customerDetailDto.getPlateNo()) + .frameNo(pubClue.getVin()) + .contacts(customerDetailDto.getMobile()) + .detailId(String.valueOf(clueTask.getId())) + .generateTime(DateUtil.localDateTime2Date(clueTask.getBeginTime())) + .deadline(DateUtil.localDateTime2Date(clueTask.getDeadline())) + .groupId(clueTask.getGroupId()) + .shopId(clueTask.getFollowShop()) + .userId(clueTask.getFollowUser()) + .userName(clueTask.getFollowUserName()) + .bizId(pubClue.getVin()) + .secondary(Boolean.FALSE) + .build(); + followInitDTO.setShopName(pubClue.getShopName()); + // 除事故车以外,其他待办跟进时长统一配置 + Optional setting = settingBizService.querySettingByType(FollowTypeEnum.OT, SettingTypeEnum.EFFECTIVE_TIME, clueTask.getGroupId(), COMMON_BRAND_ID); + setting.ifPresent(r -> { + LocalDateTime dateTime = calTime(clueTask.getBeginTime(), Objects.requireNonNull(SettingUnitEnum.ofValue(r.getUnit())), r.getDetailValue()); + followInitDTO.setFirstRecordDeadline(DateUtil.localDateTime2Date(dateTime.minusSeconds(1L))); + }); + Map noteMap = createNoteMap(pubClue, customerDetailDto); + followInitDTO.setNoteMap(noteMap); + return followInitDTO; + } + + + private Map createNoteMap(PubCluePool pubClue, CustomerDetailDto detailDto) { + Map dynamicMap = new HashMap<>(); + if (Objects.nonNull(pubClue)) { + int count = Optional.ofNullable(detailDto.getArrivalCount()).orElse(0); + Date buyDate = detailDto.getBuyDate(); + Date expires = detailDto.getInsuranceExpires(); + + String name = detailDto.getName(); + String vin = pubClue.getVin(); + String arrivalCount = String.valueOf(count); + String defeatCount = "0"; + String vehicleAge = String.valueOf(Math.abs(DateUtil.sub(buyDate, new Date(), "y"))); + String _buyDate = DateUtil.getStringDateShort(buyDate); + String insuranceExpires = DateUtil.getStringDateShort(expires); + + dynamicMap.put("name", name); + dynamicMap.put("vin", vin); + dynamicMap.put("arrivalCount", arrivalCount); + dynamicMap.put("defeatCount", defeatCount); + dynamicMap.put("vehicleAge", vehicleAge + "年"); + dynamicMap.put("buyDate", _buyDate); + dynamicMap.put("insuranceExpires", insuranceExpires); + } + return dynamicMap; + } + } diff --git a/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/pub/PubFollowBizService.java b/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/pub/PubFollowBizService.java index d8ea1c1..e8f1d8f 100644 --- a/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/pub/PubFollowBizService.java +++ b/fw-valhalla-service/src/main/java/cn/fw/valhalla/service/bus/pub/PubFollowBizService.java @@ -104,6 +104,17 @@ public class PubFollowBizService { } /** + * 开始线索 + * @param pool + */ + @Transactional(rollbackFor = Exception.class) + public void startClue(PubCluePool pool) { + pubFollowStrategy.startClue(pool); + pool.setBegun(Boolean.TRUE); + pubCluePoolService.updateById(pool); + } + + /** * 角色变动结束线索 * * @param id @@ -126,6 +137,7 @@ public class PubFollowBizService { * * @param pool */ + @Transactional(rollbackFor = Exception.class) public void endClue(PubCluePool pool) { ClueTask task = clueTaskService.getOne(Wrappers.lambdaQuery() .eq(ClueTask::getClueId, pool.getId()) -- libgit2 0.22.2