Commit dfdbcd39 by 徐高华

member好友关联时间

parent b391d149
package com.gic.haoban.manage.service.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.dto.SubscribeMessageDTO;
import com.gic.clerk.api.dto.ClerkDTO;
import com.gic.clerk.api.service.ClerkService;
import com.gic.commons.util.GICMQClientUtil;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.dubbo.entity.ProviderLocalTag;
import com.gic.enterprise.api.dto.StoreDTO;
import com.gic.enterprise.api.service.StoreService;
import com.gic.haoban.common.utils.DingUtils;
import com.gic.haoban.common.utils.EntityUtil;
import com.gic.haoban.common.utils.StringUtil;
import com.gic.haoban.manage.api.dto.ExternalClerkRelatedDTO;
import com.gic.haoban.manage.api.dto.MemberUnionidRelatedDTO;
import com.gic.haoban.manage.api.dto.SecretSettingDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.dto.qdto.hm.WxUserAddLogQDTO;
import com.gic.haoban.manage.api.enums.SecretTypeEnum;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.dao.mapper.*;
import com.gic.haoban.manage.service.entity.*;
import com.gic.haoban.manage.service.service.ExternalClerkRelatedService;
import com.gic.haoban.manage.service.service.SecretSettingService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.service.hm.WxUserAddLogService;
import com.gic.member.api.dto.MemberDTO;
import com.gic.member.api.dto.MemberSourceDetailDTO;
import com.gic.member.api.dto.MemberSourceShowDTO;
import com.gic.member.api.service.MemberApiService;
import com.gic.member.api.service.MemberEntranceApiService;
import com.gic.member.api.service.MemberService;
import com.gic.mq.sdk.GicMQClient;
import com.gic.redis.data.util.RedisUtil;
import com.gic.search.engine.api.dto.ESResponseQuerySingle;
import com.gic.search.engine.api.dto.dynamic.DynamicSearchDTO;
import com.gic.search.engine.api.service.dynamic.ESDataDynamicOperationApiService;
import com.gic.wechat.api.dto.qywx.QywxNewExternalUseridDTO;
import com.gic.wechat.api.service.qywx.QywxUserApiService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
import static org.slf4j.LoggerFactory.getLogger;
@Service
public class ExternalClerkRelatedServiceImpl implements ExternalClerkRelatedService {
private static final Logger logger = getLogger(ExternalClerkRelatedServiceImpl.class);
@Autowired
private TabHaobanExternalClerkRelatedMapper mapper;
@Autowired
private ESDataDynamicOperationApiService esDataDynamicOperationApiService;
@Autowired
private MemberService memberService;
@Autowired
private MemberApiService memberApiService;
@Autowired
private WxUserAddLogService wxUserAddLogService;
@Autowired
private StoreService storeService;
@Autowired
private ClerkService clerkService;
@Autowired
private MemberEntranceApiService memberEntranceApiService;
@Autowired
private Config config;
@Autowired
private WxEnterpriseService wxEnterpriseService;
@Autowired
private MemberUnionidRelatedMapper memberUnionidRelatedMapper;
@Autowired
private QywxUserApiService qywxUserApiService;
@Autowired
private TabHaobanRepairExternalUserMapper tabHaobanRepairExternalUserMapper;
@Autowired
private SecretSettingService secretSettingService;
@Override
public void insert(TabHaobanExternalClerkRelated related) {
String clerkId = related.getClerkId();
String externalUserId = related.getExternalUserId();
TabHaobanExternalClerkRelated tab = mapper.selectByClerkIdAndExternalUserId(clerkId, externalUserId);
if (tab == null) {
String uuId = StringUtil.randomUUID();
related.setStatusFlag(related.getStatusFlag() != null ? related.getStatusFlag() : 1);
related.setExternalClerkRelatedId(uuId);
related.setCreateTime(new Date());
related.setUpdateTime(new Date());
mapper.insertSelective(related);
}
}
@Override
public void delByUserIdAndExternalUserId(MemberUnionidRelatedDTO dto) {
String staffId = dto.getStaffId();
String externalUserid = dto.getExternalUserid();
int count = mapper.delByUserIdAndExternalUserId(externalUserid,staffId);
if (count <= 0) {
logger.error("无需删除的好友数据:{}", JSON.toJSONString(dto));
return;
}
String wxEnterpriseId = dto.getWxEnterpriseId() ;
List<TabHaobanExternalClerkRelated> deleteRelatedList = mapper.listByExTernalUseridAndWxUserId(externalUserid, staffId, 2);
if (CollectionUtils.isEmpty(deleteRelatedList)) {
logger.info("无解除的好友关系:externalUserid:{},staffId:{}", externalUserid,staffId);
return;
}
TabHaobanExternalClerkRelated related = deleteRelatedList.get(0);
String enterpriseId = related.getEnterpriseId() ;
//该企微该会员所有关联关系解除后通知会员
List<TabHaobanExternalClerkRelated> list = mapper.listByExternalUseridAndWxEnterpriseId(dto.getExternalUserid(), wxEnterpriseId, Arrays.asList("1", "3", "4"));
if (CollectionUtils.isEmpty(list)) {
//删除的好友关系
List<TabHaobanExternalClerkRelated> haobanExternalClerkRelatedList = mapper.listByExternalUseridAndWxEnterpriseId(dto.getExternalUserid(), wxEnterpriseId, Collections.singletonList("2"));
for (TabHaobanExternalClerkRelated externalClerkRelated : haobanExternalClerkRelatedList) {
String memberId = externalClerkRelated.getMemberId();
logger.info("通知会员 删除会员后更新为非企微好友 memberId:{}", memberId);
memberApiService.updateMemberQywxFlag(enterpriseId, memberId, 0);
memberApiService.updateMemberQywxEveryOccasion(enterpriseId, memberId, 0, new Date());
}
} else {
//删除后 每次回调会员
for (TabHaobanExternalClerkRelated externalClerkRelated : deleteRelatedList) {
String memberId = externalClerkRelated.getMemberId();
logger.info("通知会员 删除会员后更新为非企微好友时间 memberId:{}", memberId);
memberApiService.updateMemberQywxEveryOccasion(enterpriseId, memberId, 1, new Date());
}
}
//添加日志
WxUserAddLogQDTO wxUserAddLogQDTO = new WxUserAddLogQDTO();
wxUserAddLogQDTO.setWxEnterpriseId(wxEnterpriseId);
wxUserAddLogQDTO.setEnterpriseId(enterpriseId);
wxUserAddLogQDTO.setMemberId(related.getMemberId());
wxUserAddLogQDTO.setUnionid(related.getUnionid());
wxUserAddLogQDTO.setDelFlag(true);
wxUserAddLogQDTO.setExternalUserid(related.getExternalUserId());
wxUserAddLogQDTO.setStaffId(related.getStaffId());
wxUserAddLogQDTO.setClerkId(related.getClerkId());
wxUserAddLogService.save(wxUserAddLogQDTO);
//定制
addDelFriendEvent(related.getUnionid(), related.getClerkId(), wxEnterpriseId, enterpriseId, related.getMemberId(), related.getStoreId(), 0);
}
/**
* 欧泊莱定制需求
*
* @param unionId
* @param clerkId
* @param enterpriseId
* @param memberId
* @param storeId
*/
private void addDelFriendEvent(String unionId, String clerkId, String wxEnterpriseId, String enterpriseId, String memberId, String storeId, Integer changeType) {
String addDelFriendEvent = config.getAddDelFriendEvent();
if (!addDelFriendEvent.contains(wxEnterpriseId)) {
logger.info("非定制,无需广播通知");
return;
}
if (StringUtils.isBlank(memberId)) {
logger.info("会员不存在:{}", memberId);
return;
}
logger.info("欧泊莱定制:推送会员,memberId:{},changeType:{}", memberId, changeType);
//欧泊莱定制需求
ClerkDTO clerkDTO = clerkService.getClerkByClerkId(clerkId);
StoreDTO storeDTO = storeService.getStore(storeId);
MemberDTO member = memberService.getMember(memberId);
if (member == null) {
logger.info("会员不存在:{}", memberId);
return;
}
GicMQClient clientInstance = GICMQClientUtil.getClientInstance();
try {
JSONObject msgBody = new JSONObject();
msgBody.put("cardNo", member.getCardNum());
msgBody.put("enterpriseId", enterpriseId);
msgBody.put("unionid", unionId);
if (storeDTO != null) {
msgBody.put("storeName", storeDTO.getStoreName());
msgBody.put("storeCode", storeDTO.getStoreCode());
}
if (clerkDTO != null) {
msgBody.put("clerkName", clerkDTO.getClerkName());
msgBody.put("clerkCode", clerkDTO.getClerkCode());
}
msgBody.put("changeType", changeType);
if (changeType == 0) {
msgBody.put("delUserContact", 0);
msgBody.put("delCreateTime", new Date());
} else {
msgBody.put("addCreateTime", "");
}
//获取渠道
List<String> list = new ArrayList<>();
MemberSourceShowDTO memberSourceShowDTO = memberEntranceApiService.getMemberSourceByMemberId(enterpriseId, memberId);
if (memberSourceShowDTO != null && CollectionUtils.isNotEmpty(memberSourceShowDTO.getMemberSourceList())) {
for (MemberSourceDetailDTO memberSourceDetailDTO : memberSourceShowDTO.getMemberSourceList()) {
if (null != memberSourceDetailDTO.getHighlight() && memberSourceDetailDTO.getHighlight() == 1) {
list.add(memberSourceDetailDTO.getParentSourceCode());
}
}
}
SubscribeMessageDTO subscribeMessageDTO = new SubscribeMessageDTO();
subscribeMessageDTO.setEvent("addDelFriendEvent");
subscribeMessageDTO.setTopic("member");
subscribeMessageDTO.setEnterpriseId(enterpriseId);
subscribeMessageDTO.setMemberId(memberId);
subscribeMessageDTO.setMemberChannels(list);
subscribeMessageDTO.setMsgBody(msgBody.toJSONString());
clientInstance.sendMessage("dealQywxExternalUserEvent", JSONObject.toJSONString(subscribeMessageDTO));
} catch (Exception e) {
logger.info("加好友事件订阅通知:{}", e.getMessage(), e);
}
}
@Override
public void delByUserIdAndExternalUserIdBatch(String wxEnterpriseId, String staffId, List<String> externalUserids) {
mapper.delByUserIdAndExternalUserIdBatch(staffId, wxEnterpriseId, externalUserids);
}
@Override
public void delByStoreIdAndStaffId(String storeId, String staffId) {
mapper.delByStoreIdAndStaffId(storeId, staffId);
}
@Override
public void delByStoreIds(Collection<String> storeIds) {
mapper.delByStoreIds(storeIds);
}
@Override
public void cleanStaffRelated(String wxEnterpriseId, List<String> staffIds) {
if (staffIds != null && !staffIds.isEmpty()) {
mapper.cleanStaffRelated(wxEnterpriseId, staffIds);
}
}
@Override
public void update(TabHaobanExternalClerkRelated exsitDTO) {
exsitDTO.setUpdateTime(new Date());
mapper.updateByPrimaryKeySelective(exsitDTO);
}
@Override
public List<TabHaobanExternalClerkRelated> listByExternalUseridAndWxUserId(String externalUserid, String staffId) {
return mapper.listByExTernalUseridAndWxUserId(externalUserid, staffId, 1);
}
@Override
public List<TabHaobanExternalClerkRelated> listByExTernalUseridAndWxUserIdAllStatus(String wxEnterpriseId, String externalUserid, String staffId) {
return mapper.listByExTernalUseridAndWxUserIdAllStatus(wxEnterpriseId, externalUserid, staffId);
}
@Override
public ExternalClerkRelatedDTO getByMemberId(String staffId, String memberId) {
return EntityUtil.changeEntityByJSON(ExternalClerkRelatedDTO.class, mapper.getByMemberId(staffId, memberId));
}
@Override
public List<TabHaobanExternalClerkRelated> listExternalByUnionId(String enterpriseId, String unionId) {
return mapper.listExternalByUnionId(enterpriseId, unionId);
}
@Override
public List<TabHaobanExternalClerkRelated> listExternalByExternalUserid(String wxEnterpriseId, String externalUserid) {
return mapper.listByExternalUserId(wxEnterpriseId, externalUserid);
}
@Override
public String checkAndUpdateMemberByUnonId(String enterpriseId, String memberId, String unionId) {
String returnFields = "id";
try {
JSONObject searchJson = new JSONObject();
searchJson.put("id", memberId);
DynamicSearchDTO search = new DynamicSearchDTO();
search.setSearchJson(searchJson);
search.setEnterpriseId(enterpriseId);
search.setColumnCategoryCode("member");
if (StringUtils.isNotBlank(returnFields)) {
search.setReturnFileds(returnFields);
}
ESResponseQuerySingle single = esDataDynamicOperationApiService.queryDataSingle(search);
JSONObject res = single.getRes();
logger.info("返回数据:{}", JSONObject.toJSONString(res));
if (res != null && res.size() > 0) {
return memberId;
}
MemberDTO memberDTO = memberService.getMemberByUnionid(unionId, enterpriseId);
if (null == memberDTO || memberDTO.getMemberId() == null) {
logger.info("会员不存在:{}", unionId);
return null;
}
//更新会员id
mapper.updateMemberIdByMemberId(memberDTO.getMemberId(), memberId, enterpriseId);
return memberDTO.getMemberId();
} catch (Exception e) {
logger.info("从搜索引擎中搜索会员数据异常, memberId : {}", memberId);
}
return null;
}
@Override
public void repairExternalUserId(String wxEnterpriseIds) {
logger.info("外部联系人检查,wxEnterpriseIds={}", wxEnterpriseIds);
DingUtils.send("外部联系人修复消息,企业=" + wxEnterpriseIds + ",tranceid=" + ProviderLocalTag.tag.get().traceId, false);
if (StringUtils.isEmpty(wxEnterpriseIds)) {
return;
}
Object cache = RedisUtil.getCache("repairExternalUserId");
String[] arr = wxEnterpriseIds.split(",");
for (int i = 0; i < arr.length; i++) {
String wxEnterpriseId = arr[i];
if (StringUtils.isEmpty(wxEnterpriseId)) {
continue;
}
int type = 0 ;
if(wxEnterpriseId.endsWith("_")) {
wxEnterpriseId = wxEnterpriseId.substring(0,wxEnterpriseId.length()-1) ;
type = 1 ;
}
WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
if (null == qwDTO) {
logger.info("外部联系人检查,企业不存在,wxEnterpriseId={}", wxEnterpriseId);
continue;
}
SecretSettingDTO secret = this.secretSettingService.getSecretSetting(wxEnterpriseId, SecretTypeEnum.CUSTOMIZED_APP.getVal());
int pageSize = 800;
int pageNum = 0;
while (true) {
List<TabHaobanExternalClerkRelated> list = this.mapper.listPageByWxenterpriseId(wxEnterpriseId, pageNum * pageSize, pageSize,type);
if (CollectionUtils.isEmpty(list)) {
logger.info("{}完成",wxEnterpriseId);
break;
}
pageNum++;
Set<String> externalUserIdSet = list.stream().map(dto -> dto.getExternalUserId()).collect(Collectors.toSet());
Map<String,Date> dateMap = list.stream().collect(Collectors.toMap(TabHaobanExternalClerkRelated::getExternalUserId, TabHaobanExternalClerkRelated::getCreateTime,(k1,k2)->k1)) ;
List<String> externalUserIdList = new ArrayList<>();
externalUserIdList.addAll(externalUserIdSet);
List<MemberUnionidRelated> unionidlist = this.memberUnionidRelatedMapper.listByWxEnterpriseIdAndExternalUserId(wxEnterpriseId, externalUserIdList);
Map<String, String> map = unionidlist.stream().filter(dto -> StringUtils.isNotBlank(dto.getExternalUserid()) && StringUtils.isNotBlank(dto.getSelfExternalUserid()))
.collect(Collectors.toMap(MemberUnionidRelated::getExternalUserid, MemberUnionidRelated::getSelfExternalUserid, (k1, k2) -> k1));
logger.info("外部联系人检查,第{}次,好友数={},unionid表数={},{}", pageNum, externalUserIdList.size(), unionidlist.size(),wxEnterpriseId);
List<String> delList = new ArrayList<>();
Set<String> checkSet = unionidlist.stream().map(dto -> dto.getExternalUserid()).collect(Collectors.toSet());
List<String> checkList = new ArrayList<>();
checkList.addAll(checkSet);
for (String item : externalUserIdList) {
if (!checkList.contains(item)) {
delList.add(item);
}
}
logger.info("外部联系人检查,unionid表不存在记录的数量={},待检查数={}", delList.size(), checkList.size());
List<String> notExistQwList = new ArrayList<>();
List<TabHaobanRepairExternalUser> errorList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(checkList)) {
List<String> qwList = new ArrayList<>();
List<QywxNewExternalUseridDTO> newExternalUseridList = null;
if (null != cache) {
newExternalUseridList = this.qywxUserApiService.getNewExternalUseridByList(qwDTO.getThirdCorpid(), config.getWxSuiteid(), checkList);
} else {
newExternalUseridList = this.qywxUserApiService.getSelfNewExternalUseridByList(qwDTO.getDkCorpid(), secret.getSecretVal(), checkList);
}
if (null != newExternalUseridList) {
logger.info("外部联系人检查,查询企微数={},返回数={}", checkList.size(), newExternalUseridList.size());
for (QywxNewExternalUseridDTO qywxNewExternalUseridDTO : newExternalUseridList) {
String new_external_userid = qywxNewExternalUseridDTO.getNew_external_userid();
String external_userid = qywxNewExternalUseridDTO.getExternal_userid();
qwList.add(external_userid);
if (new_external_userid.equals(external_userid)) {
continue;
} else {
logger.info("外部联系人检查,数据异常={}", new_external_userid, external_userid);
TabHaobanRepairExternalUser user = new TabHaobanRepairExternalUser();
user.setId(UniqueIdUtils.uniqueLong());
user.setUserId(external_userid);
user.setWxEnterpriseId(wxEnterpriseId);
user.setStatusFlag(111);
user.setRemark(new_external_userid);
if(null != dateMap.get(external_userid)) {
user.setUpdateTime(dateMap.get(external_userid));
}
errorList.add(user);
}
}
if (checkList.size() != newExternalUseridList.size()) {
for (String item : checkList) {
if (!qwList.contains(item)) {
notExistQwList.add(item);
}
}
}
} else {
logger.info("外部联系人检查,调用企业异常");
}
// 通过外部联系人查询不到
if (CollectionUtils.isNotEmpty(notExistQwList)) {
// 需要用自建的查询的
List<String> selfList = new ArrayList<>();
List<TabHaobanRepairExternalUser> addList = new ArrayList<>();
for (String item : notExistQwList) {
TabHaobanRepairExternalUser user = new TabHaobanRepairExternalUser();
user.setId(UniqueIdUtils.uniqueLong());
user.setUserId(item);
if (StringUtils.isNotBlank(map.get(item)) && !map.get(item).equals(item)) {
selfList.add(map.get(item));
}
user.setSelfUserId(map.get(item));
user.setWxEnterpriseId(wxEnterpriseId);
user.setStatusFlag(11);
user.setRemark("外部联系人ID错误");
if(StringUtils.isBlank(user.getSelfUserId())) {
user.setStatusFlag(12);
user.setRemark("unionid表记录存在,但代开联系人id NULL");
}
if(null != dateMap.get(item)) {
user.setUpdateTime(dateMap.get(item));
}
addList.add(user);
}
if (CollectionUtils.isNotEmpty(selfList)) {
newExternalUseridList = null;
if (null != cache) {
newExternalUseridList = this.qywxUserApiService.getNewExternalUseridByList(qwDTO.getThirdCorpid(), config.getWxSuiteid(), selfList);
} else {
newExternalUseridList = this.qywxUserApiService.getSelfNewExternalUseridByList(qwDTO.getDkCorpid(), secret.getSecretVal(), selfList);
}
Map<String, String> selfMap = new HashMap<>();
if (null != newExternalUseridList) {
selfMap = newExternalUseridList.stream().collect(Collectors.toMap(QywxNewExternalUseridDTO::getExternal_userid, QywxNewExternalUseridDTO::getNew_external_userid, (k1, k2) -> k1));
}
for (TabHaobanRepairExternalUser item : addList) {
item.setNewUserId(selfMap.get(item.getSelfUserId()));
}
}
this.tabHaobanRepairExternalUserMapper.batchInsert(addList);
}
// unionid表不存在的记录
if (CollectionUtils.isNotEmpty(delList)) {
List<TabHaobanRepairExternalUser> addList = new ArrayList<>();
for (String item : delList) {
TabHaobanRepairExternalUser user = new TabHaobanRepairExternalUser();
user.setId(UniqueIdUtils.uniqueLong());
user.setUserId(item);
user.setWxEnterpriseId(wxEnterpriseId);
user.setStatusFlag(1);
user.setRemark("无unionid表记录");
if(null != dateMap.get(item)) {
user.setUpdateTime(dateMap.get(item));
}
addList.add(user);
}
this.tabHaobanRepairExternalUserMapper.batchInsert(addList);
}
// 错误的ID
if (CollectionUtils.isNotEmpty(errorList)) {
this.tabHaobanRepairExternalUserMapper.batchInsert(errorList);
}
}
}
}
}
@Override
public List<String> getByStoreIdAndStaffId(String storeId, String staffId) {
return mapper.getByStoreIdAndStaffId(storeId, staffId);
}
@Override
public int getCountByMemberId(String memberId) {
return mapper.getCountByMemberId(memberId);
}
@Override
public void updateClerkInfo(String staffId, String oldClerkId, String newClerkId) {
ClerkDTO clerk = this.clerkService.getclerkById(newClerkId);
this.mapper.updateClerkInfo(staffId,oldClerkId , newClerkId , clerk.getStoreId());
}
/**
* 外部联系人
*
* @param staffId
* @return
*/
@Override
public List<String> queryExternalRelatedWithStaffId(String staffId) {
return this.mapper.queryExternalUserIdWithStaffId(staffId);
}
/***
* 查询会员与导购的关系
* @param staffId
* @param memberIds
* @return
*/
@Override
public List<TabHaobanExternalClerkRelated> queryClerkMemberRelations(String staffId, List<String> memberIds) {
if (StringUtils.isBlank(staffId)) {
logger.info("查询导购与会员的关系,staffId不存在 {}", staffId);
return Collections.emptyList();
}
if (CollectionUtils.isEmpty(memberIds)) {
logger.info("查询导购与会员的关系,会员id数组为空 {}", staffId);
return Collections.emptyList();
}
return this.mapper.queryClerkMemberRelations(staffId, memberIds);
}
}
package com.gic.haoban.manage.service.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.dto.SubscribeMessageDTO;
import com.gic.clerk.api.dto.ClerkDTO;
import com.gic.clerk.api.service.ClerkService;
import com.gic.commons.util.GICMQClientUtil;
import com.gic.commons.util.UniqueIdUtils;
import com.gic.dubbo.entity.ProviderLocalTag;
import com.gic.enterprise.api.dto.StoreDTO;
import com.gic.enterprise.api.service.StoreService;
import com.gic.haoban.common.utils.DingUtils;
import com.gic.haoban.common.utils.EntityUtil;
import com.gic.haoban.common.utils.StringUtil;
import com.gic.haoban.manage.api.dto.ExternalClerkRelatedDTO;
import com.gic.haoban.manage.api.dto.MemberUnionidRelatedDTO;
import com.gic.haoban.manage.api.dto.SecretSettingDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.dto.qdto.hm.WxUserAddLogQDTO;
import com.gic.haoban.manage.api.enums.SecretTypeEnum;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.dao.mapper.*;
import com.gic.haoban.manage.service.entity.*;
import com.gic.haoban.manage.service.service.ExternalClerkRelatedService;
import com.gic.haoban.manage.service.service.SecretSettingService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.haoban.manage.service.service.hm.WxUserAddLogService;
import com.gic.member.api.dto.MemberDTO;
import com.gic.member.api.dto.MemberSourceDetailDTO;
import com.gic.member.api.dto.MemberSourceShowDTO;
import com.gic.member.api.service.MemberApiService;
import com.gic.member.api.service.MemberEntranceApiService;
import com.gic.member.api.service.MemberService;
import com.gic.mq.sdk.GicMQClient;
import com.gic.redis.data.util.RedisUtil;
import com.gic.search.engine.api.dto.ESResponseQuerySingle;
import com.gic.search.engine.api.dto.dynamic.DynamicSearchDTO;
import com.gic.search.engine.api.service.dynamic.ESDataDynamicOperationApiService;
import com.gic.wechat.api.dto.qywx.QywxNewExternalUseridDTO;
import com.gic.wechat.api.service.qywx.QywxUserApiService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
import static org.slf4j.LoggerFactory.getLogger;
@Service
public class ExternalClerkRelatedServiceImpl implements ExternalClerkRelatedService {
private static final Logger logger = getLogger(ExternalClerkRelatedServiceImpl.class);
@Autowired
private TabHaobanExternalClerkRelatedMapper mapper;
@Autowired
private ESDataDynamicOperationApiService esDataDynamicOperationApiService;
@Autowired
private MemberService memberService;
@Autowired
private MemberApiService memberApiService;
@Autowired
private WxUserAddLogService wxUserAddLogService;
@Autowired
private StoreService storeService;
@Autowired
private ClerkService clerkService;
@Autowired
private MemberEntranceApiService memberEntranceApiService;
@Autowired
private Config config;
@Autowired
private WxEnterpriseService wxEnterpriseService;
@Autowired
private MemberUnionidRelatedMapper memberUnionidRelatedMapper;
@Autowired
private QywxUserApiService qywxUserApiService;
@Autowired
private TabHaobanRepairExternalUserMapper tabHaobanRepairExternalUserMapper;
@Autowired
private SecretSettingService secretSettingService;
@Override
public void insert(TabHaobanExternalClerkRelated related) {
String clerkId = related.getClerkId();
String externalUserId = related.getExternalUserId();
TabHaobanExternalClerkRelated tab = mapper.selectByClerkIdAndExternalUserId(clerkId, externalUserId);
if (tab == null) {
String uuId = StringUtil.randomUUID();
related.setStatusFlag(related.getStatusFlag() != null ? related.getStatusFlag() : 1);
related.setExternalClerkRelatedId(uuId);
related.setCreateTime(new Date());
related.setUpdateTime(new Date());
mapper.insertSelective(related);
}
}
@Override
public void delByUserIdAndExternalUserId(MemberUnionidRelatedDTO dto) {
String staffId = dto.getStaffId();
String externalUserid = dto.getExternalUserid();
int count = mapper.delByUserIdAndExternalUserId(externalUserid,staffId);
if (count <= 0) {
logger.error("无需删除的好友数据:{}", JSON.toJSONString(dto));
return;
}
String wxEnterpriseId = dto.getWxEnterpriseId() ;
List<TabHaobanExternalClerkRelated> deleteRelatedList = mapper.listByExTernalUseridAndWxUserId(externalUserid, staffId, 2);
if (CollectionUtils.isEmpty(deleteRelatedList)) {
logger.info("无解除的好友关系:externalUserid:{},staffId:{}", externalUserid,staffId);
return;
}
TabHaobanExternalClerkRelated related = deleteRelatedList.get(0);
String enterpriseId = related.getEnterpriseId() ;
//该企微该会员所有关联关系解除后通知会员
List<TabHaobanExternalClerkRelated> list = mapper.listByExternalUseridAndWxEnterpriseId(dto.getExternalUserid(), wxEnterpriseId, Arrays.asList("1", "3", "4"));
if (CollectionUtils.isEmpty(list)) {
//删除的好友关系
List<TabHaobanExternalClerkRelated> haobanExternalClerkRelatedList = mapper.listByExternalUseridAndWxEnterpriseId(dto.getExternalUserid(), wxEnterpriseId, Collections.singletonList("2"));
for (TabHaobanExternalClerkRelated externalClerkRelated : haobanExternalClerkRelatedList) {
String memberId = externalClerkRelated.getMemberId();
logger.info("通知会员 删除会员后更新为非企微好友 memberId:{}", memberId);
memberApiService.updateMemberQywxFlag(enterpriseId, memberId, 0);
memberApiService.updateMemberQywxEveryOccasion(enterpriseId, memberId, 0, new Date());
}
} else {
//删除后 每次回调会员
/*for (TabHaobanExternalClerkRelated externalClerkRelated : deleteRelatedList) {
String memberId = externalClerkRelated.getMemberId();
logger.info("通知会员 删除会员后更新为非企微好友时间 memberId:{}", memberId);
memberApiService.updateMemberQywxEveryOccasion(enterpriseId, memberId, 1, new Date());
}*/
}
//添加日志
WxUserAddLogQDTO wxUserAddLogQDTO = new WxUserAddLogQDTO();
wxUserAddLogQDTO.setWxEnterpriseId(wxEnterpriseId);
wxUserAddLogQDTO.setEnterpriseId(enterpriseId);
wxUserAddLogQDTO.setMemberId(related.getMemberId());
wxUserAddLogQDTO.setUnionid(related.getUnionid());
wxUserAddLogQDTO.setDelFlag(true);
wxUserAddLogQDTO.setExternalUserid(related.getExternalUserId());
wxUserAddLogQDTO.setStaffId(related.getStaffId());
wxUserAddLogQDTO.setClerkId(related.getClerkId());
wxUserAddLogService.save(wxUserAddLogQDTO);
//定制
addDelFriendEvent(related.getUnionid(), related.getClerkId(), wxEnterpriseId, enterpriseId, related.getMemberId(), related.getStoreId(), 0);
}
/**
* 欧泊莱定制需求
*
* @param unionId
* @param clerkId
* @param enterpriseId
* @param memberId
* @param storeId
*/
private void addDelFriendEvent(String unionId, String clerkId, String wxEnterpriseId, String enterpriseId, String memberId, String storeId, Integer changeType) {
String addDelFriendEvent = config.getAddDelFriendEvent();
if (!addDelFriendEvent.contains(wxEnterpriseId)) {
logger.info("非定制,无需广播通知");
return;
}
if (StringUtils.isBlank(memberId)) {
logger.info("会员不存在:{}", memberId);
return;
}
logger.info("欧泊莱定制:推送会员,memberId:{},changeType:{}", memberId, changeType);
//欧泊莱定制需求
ClerkDTO clerkDTO = clerkService.getClerkByClerkId(clerkId);
StoreDTO storeDTO = storeService.getStore(storeId);
MemberDTO member = memberService.getMember(memberId);
if (member == null) {
logger.info("会员不存在:{}", memberId);
return;
}
GicMQClient clientInstance = GICMQClientUtil.getClientInstance();
try {
JSONObject msgBody = new JSONObject();
msgBody.put("cardNo", member.getCardNum());
msgBody.put("enterpriseId", enterpriseId);
msgBody.put("unionid", unionId);
if (storeDTO != null) {
msgBody.put("storeName", storeDTO.getStoreName());
msgBody.put("storeCode", storeDTO.getStoreCode());
}
if (clerkDTO != null) {
msgBody.put("clerkName", clerkDTO.getClerkName());
msgBody.put("clerkCode", clerkDTO.getClerkCode());
}
msgBody.put("changeType", changeType);
if (changeType == 0) {
msgBody.put("delUserContact", 0);
msgBody.put("delCreateTime", new Date());
} else {
msgBody.put("addCreateTime", "");
}
//获取渠道
List<String> list = new ArrayList<>();
MemberSourceShowDTO memberSourceShowDTO = memberEntranceApiService.getMemberSourceByMemberId(enterpriseId, memberId);
if (memberSourceShowDTO != null && CollectionUtils.isNotEmpty(memberSourceShowDTO.getMemberSourceList())) {
for (MemberSourceDetailDTO memberSourceDetailDTO : memberSourceShowDTO.getMemberSourceList()) {
if (null != memberSourceDetailDTO.getHighlight() && memberSourceDetailDTO.getHighlight() == 1) {
list.add(memberSourceDetailDTO.getParentSourceCode());
}
}
}
SubscribeMessageDTO subscribeMessageDTO = new SubscribeMessageDTO();
subscribeMessageDTO.setEvent("addDelFriendEvent");
subscribeMessageDTO.setTopic("member");
subscribeMessageDTO.setEnterpriseId(enterpriseId);
subscribeMessageDTO.setMemberId(memberId);
subscribeMessageDTO.setMemberChannels(list);
subscribeMessageDTO.setMsgBody(msgBody.toJSONString());
clientInstance.sendMessage("dealQywxExternalUserEvent", JSONObject.toJSONString(subscribeMessageDTO));
} catch (Exception e) {
logger.info("加好友事件订阅通知:{}", e.getMessage(), e);
}
}
@Override
public void delByUserIdAndExternalUserIdBatch(String wxEnterpriseId, String staffId, List<String> externalUserids) {
mapper.delByUserIdAndExternalUserIdBatch(staffId, wxEnterpriseId, externalUserids);
}
@Override
public void delByStoreIdAndStaffId(String storeId, String staffId) {
mapper.delByStoreIdAndStaffId(storeId, staffId);
}
@Override
public void delByStoreIds(Collection<String> storeIds) {
mapper.delByStoreIds(storeIds);
}
@Override
public void cleanStaffRelated(String wxEnterpriseId, List<String> staffIds) {
if (staffIds != null && !staffIds.isEmpty()) {
mapper.cleanStaffRelated(wxEnterpriseId, staffIds);
}
}
@Override
public void update(TabHaobanExternalClerkRelated exsitDTO) {
exsitDTO.setUpdateTime(new Date());
mapper.updateByPrimaryKeySelective(exsitDTO);
}
@Override
public List<TabHaobanExternalClerkRelated> listByExternalUseridAndWxUserId(String externalUserid, String staffId) {
return mapper.listByExTernalUseridAndWxUserId(externalUserid, staffId, 1);
}
@Override
public List<TabHaobanExternalClerkRelated> listByExTernalUseridAndWxUserIdAllStatus(String wxEnterpriseId, String externalUserid, String staffId) {
return mapper.listByExTernalUseridAndWxUserIdAllStatus(wxEnterpriseId, externalUserid, staffId);
}
@Override
public ExternalClerkRelatedDTO getByMemberId(String staffId, String memberId) {
return EntityUtil.changeEntityByJSON(ExternalClerkRelatedDTO.class, mapper.getByMemberId(staffId, memberId));
}
@Override
public List<TabHaobanExternalClerkRelated> listExternalByUnionId(String enterpriseId, String unionId) {
return mapper.listExternalByUnionId(enterpriseId, unionId);
}
@Override
public List<TabHaobanExternalClerkRelated> listExternalByExternalUserid(String wxEnterpriseId, String externalUserid) {
return mapper.listByExternalUserId(wxEnterpriseId, externalUserid);
}
@Override
public String checkAndUpdateMemberByUnonId(String enterpriseId, String memberId, String unionId) {
String returnFields = "id";
try {
JSONObject searchJson = new JSONObject();
searchJson.put("id", memberId);
DynamicSearchDTO search = new DynamicSearchDTO();
search.setSearchJson(searchJson);
search.setEnterpriseId(enterpriseId);
search.setColumnCategoryCode("member");
if (StringUtils.isNotBlank(returnFields)) {
search.setReturnFileds(returnFields);
}
ESResponseQuerySingle single = esDataDynamicOperationApiService.queryDataSingle(search);
JSONObject res = single.getRes();
logger.info("返回数据:{}", JSONObject.toJSONString(res));
if (res != null && res.size() > 0) {
return memberId;
}
MemberDTO memberDTO = memberService.getMemberByUnionid(unionId, enterpriseId);
if (null == memberDTO || memberDTO.getMemberId() == null) {
logger.info("会员不存在:{}", unionId);
return null;
}
//更新会员id
mapper.updateMemberIdByMemberId(memberDTO.getMemberId(), memberId, enterpriseId);
return memberDTO.getMemberId();
} catch (Exception e) {
logger.info("从搜索引擎中搜索会员数据异常, memberId : {}", memberId);
}
return null;
}
@Override
public void repairExternalUserId(String wxEnterpriseIds) {
logger.info("外部联系人检查,wxEnterpriseIds={}", wxEnterpriseIds);
DingUtils.send("外部联系人修复消息,企业=" + wxEnterpriseIds + ",tranceid=" + ProviderLocalTag.tag.get().traceId, false);
if (StringUtils.isEmpty(wxEnterpriseIds)) {
return;
}
Object cache = RedisUtil.getCache("repairExternalUserId");
String[] arr = wxEnterpriseIds.split(",");
for (int i = 0; i < arr.length; i++) {
String wxEnterpriseId = arr[i];
if (StringUtils.isEmpty(wxEnterpriseId)) {
continue;
}
int type = 0 ;
if(wxEnterpriseId.endsWith("_")) {
wxEnterpriseId = wxEnterpriseId.substring(0,wxEnterpriseId.length()-1) ;
type = 1 ;
}
WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
if (null == qwDTO) {
logger.info("外部联系人检查,企业不存在,wxEnterpriseId={}", wxEnterpriseId);
continue;
}
SecretSettingDTO secret = this.secretSettingService.getSecretSetting(wxEnterpriseId, SecretTypeEnum.CUSTOMIZED_APP.getVal());
int pageSize = 800;
int pageNum = 0;
while (true) {
List<TabHaobanExternalClerkRelated> list = this.mapper.listPageByWxenterpriseId(wxEnterpriseId, pageNum * pageSize, pageSize,type);
if (CollectionUtils.isEmpty(list)) {
logger.info("{}完成",wxEnterpriseId);
break;
}
pageNum++;
Set<String> externalUserIdSet = list.stream().map(dto -> dto.getExternalUserId()).collect(Collectors.toSet());
Map<String,Date> dateMap = list.stream().collect(Collectors.toMap(TabHaobanExternalClerkRelated::getExternalUserId, TabHaobanExternalClerkRelated::getCreateTime,(k1,k2)->k1)) ;
List<String> externalUserIdList = new ArrayList<>();
externalUserIdList.addAll(externalUserIdSet);
List<MemberUnionidRelated> unionidlist = this.memberUnionidRelatedMapper.listByWxEnterpriseIdAndExternalUserId(wxEnterpriseId, externalUserIdList);
Map<String, String> map = unionidlist.stream().filter(dto -> StringUtils.isNotBlank(dto.getExternalUserid()) && StringUtils.isNotBlank(dto.getSelfExternalUserid()))
.collect(Collectors.toMap(MemberUnionidRelated::getExternalUserid, MemberUnionidRelated::getSelfExternalUserid, (k1, k2) -> k1));
logger.info("外部联系人检查,第{}次,好友数={},unionid表数={},{}", pageNum, externalUserIdList.size(), unionidlist.size(),wxEnterpriseId);
List<String> delList = new ArrayList<>();
Set<String> checkSet = unionidlist.stream().map(dto -> dto.getExternalUserid()).collect(Collectors.toSet());
List<String> checkList = new ArrayList<>();
checkList.addAll(checkSet);
for (String item : externalUserIdList) {
if (!checkList.contains(item)) {
delList.add(item);
}
}
logger.info("外部联系人检查,unionid表不存在记录的数量={},待检查数={}", delList.size(), checkList.size());
List<String> notExistQwList = new ArrayList<>();
List<TabHaobanRepairExternalUser> errorList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(checkList)) {
List<String> qwList = new ArrayList<>();
List<QywxNewExternalUseridDTO> newExternalUseridList = null;
if (null != cache) {
newExternalUseridList = this.qywxUserApiService.getNewExternalUseridByList(qwDTO.getThirdCorpid(), config.getWxSuiteid(), checkList);
} else {
newExternalUseridList = this.qywxUserApiService.getSelfNewExternalUseridByList(qwDTO.getDkCorpid(), secret.getSecretVal(), checkList);
}
if (null != newExternalUseridList) {
logger.info("外部联系人检查,查询企微数={},返回数={}", checkList.size(), newExternalUseridList.size());
for (QywxNewExternalUseridDTO qywxNewExternalUseridDTO : newExternalUseridList) {
String new_external_userid = qywxNewExternalUseridDTO.getNew_external_userid();
String external_userid = qywxNewExternalUseridDTO.getExternal_userid();
qwList.add(external_userid);
if (new_external_userid.equals(external_userid)) {
continue;
} else {
logger.info("外部联系人检查,数据异常={}", new_external_userid, external_userid);
TabHaobanRepairExternalUser user = new TabHaobanRepairExternalUser();
user.setId(UniqueIdUtils.uniqueLong());
user.setUserId(external_userid);
user.setWxEnterpriseId(wxEnterpriseId);
user.setStatusFlag(111);
user.setRemark(new_external_userid);
if(null != dateMap.get(external_userid)) {
user.setUpdateTime(dateMap.get(external_userid));
}
errorList.add(user);
}
}
if (checkList.size() != newExternalUseridList.size()) {
for (String item : checkList) {
if (!qwList.contains(item)) {
notExistQwList.add(item);
}
}
}
} else {
logger.info("外部联系人检查,调用企业异常");
}
// 通过外部联系人查询不到
if (CollectionUtils.isNotEmpty(notExistQwList)) {
// 需要用自建的查询的
List<String> selfList = new ArrayList<>();
List<TabHaobanRepairExternalUser> addList = new ArrayList<>();
for (String item : notExistQwList) {
TabHaobanRepairExternalUser user = new TabHaobanRepairExternalUser();
user.setId(UniqueIdUtils.uniqueLong());
user.setUserId(item);
if (StringUtils.isNotBlank(map.get(item)) && !map.get(item).equals(item)) {
selfList.add(map.get(item));
}
user.setSelfUserId(map.get(item));
user.setWxEnterpriseId(wxEnterpriseId);
user.setStatusFlag(11);
user.setRemark("外部联系人ID错误");
if(StringUtils.isBlank(user.getSelfUserId())) {
user.setStatusFlag(12);
user.setRemark("unionid表记录存在,但代开联系人id NULL");
}
if(null != dateMap.get(item)) {
user.setUpdateTime(dateMap.get(item));
}
addList.add(user);
}
if (CollectionUtils.isNotEmpty(selfList)) {
newExternalUseridList = null;
if (null != cache) {
newExternalUseridList = this.qywxUserApiService.getNewExternalUseridByList(qwDTO.getThirdCorpid(), config.getWxSuiteid(), selfList);
} else {
newExternalUseridList = this.qywxUserApiService.getSelfNewExternalUseridByList(qwDTO.getDkCorpid(), secret.getSecretVal(), selfList);
}
Map<String, String> selfMap = new HashMap<>();
if (null != newExternalUseridList) {
selfMap = newExternalUseridList.stream().collect(Collectors.toMap(QywxNewExternalUseridDTO::getExternal_userid, QywxNewExternalUseridDTO::getNew_external_userid, (k1, k2) -> k1));
}
for (TabHaobanRepairExternalUser item : addList) {
item.setNewUserId(selfMap.get(item.getSelfUserId()));
}
}
this.tabHaobanRepairExternalUserMapper.batchInsert(addList);
}
// unionid表不存在的记录
if (CollectionUtils.isNotEmpty(delList)) {
List<TabHaobanRepairExternalUser> addList = new ArrayList<>();
for (String item : delList) {
TabHaobanRepairExternalUser user = new TabHaobanRepairExternalUser();
user.setId(UniqueIdUtils.uniqueLong());
user.setUserId(item);
user.setWxEnterpriseId(wxEnterpriseId);
user.setStatusFlag(1);
user.setRemark("无unionid表记录");
if(null != dateMap.get(item)) {
user.setUpdateTime(dateMap.get(item));
}
addList.add(user);
}
this.tabHaobanRepairExternalUserMapper.batchInsert(addList);
}
// 错误的ID
if (CollectionUtils.isNotEmpty(errorList)) {
this.tabHaobanRepairExternalUserMapper.batchInsert(errorList);
}
}
}
}
}
@Override
public List<String> getByStoreIdAndStaffId(String storeId, String staffId) {
return mapper.getByStoreIdAndStaffId(storeId, staffId);
}
@Override
public int getCountByMemberId(String memberId) {
return mapper.getCountByMemberId(memberId);
}
@Override
public void updateClerkInfo(String staffId, String oldClerkId, String newClerkId) {
ClerkDTO clerk = this.clerkService.getclerkById(newClerkId);
this.mapper.updateClerkInfo(staffId,oldClerkId , newClerkId , clerk.getStoreId());
}
/**
* 外部联系人
*
* @param staffId
* @return
*/
@Override
public List<String> queryExternalRelatedWithStaffId(String staffId) {
return this.mapper.queryExternalUserIdWithStaffId(staffId);
}
/***
* 查询会员与导购的关系
* @param staffId
* @param memberIds
* @return
*/
@Override
public List<TabHaobanExternalClerkRelated> queryClerkMemberRelations(String staffId, List<String> memberIds) {
if (StringUtils.isBlank(staffId)) {
logger.info("查询导购与会员的关系,staffId不存在 {}", staffId);
return Collections.emptyList();
}
if (CollectionUtils.isEmpty(memberIds)) {
logger.info("查询导购与会员的关系,会员id数组为空 {}", staffId);
return Collections.emptyList();
}
return this.mapper.queryClerkMemberRelations(staffId, memberIds);
}
}
package com.gic.haoban.manage.service.service.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.gic.api.base.commons.Page;
import com.gic.clerk.api.dto.ClerkDTO;
import com.gic.clerk.api.service.ClerkService;
import com.gic.clerk.api.service.RightService;
import com.gic.commons.util.EntityUtil;
import com.gic.enterprise.api.dto.StoreDTO;
import com.gic.enterprise.api.service.StoreService;
import com.gic.haoban.base.api.common.BasePageInfo;
import com.gic.haoban.common.utils.PageUtil;
import com.gic.haoban.common.utils.StringUtil;
import com.gic.haoban.manage.api.dto.CommonMQDTO;
import com.gic.haoban.manage.api.dto.StaffClerkRelationDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.dto.qdto.hm.HmQrcodeQDTO;
import com.gic.haoban.manage.api.enums.BindTypeEnum;
import com.gic.haoban.manage.api.enums.ChannelCodeEnum;
import com.gic.haoban.manage.api.service.HaobanCommonMQApiService;
import com.gic.haoban.manage.api.service.hm.HmClerkRelationApiService;
import com.gic.haoban.manage.api.service.hm.HmQrcodeApiService;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanExternalClerkRelatedMapper;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanMemberClerkChatConfigMapper;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanStaffClerkRelationMapper;
import com.gic.haoban.manage.service.entity.MemberClerkChatConfig;
import com.gic.haoban.manage.service.entity.TabHaobanClerkMainStoreRelated;
import com.gic.haoban.manage.service.entity.TabHaobanStaff;
import com.gic.haoban.manage.service.entity.TabHaobanStaffClerkRelation;
import com.gic.haoban.manage.service.service.ClerkMainStoreRelatedService;
import com.gic.haoban.manage.service.service.ExternalClerkRelatedService;
import com.gic.haoban.manage.service.service.StaffClerkBindLogService;
import com.gic.haoban.manage.service.service.StaffClerkRelationService;
import com.gic.haoban.manage.service.service.StaffService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.member.api.service.MemberApiService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@Service
public class StaffClerkRelationServiceImpl implements StaffClerkRelationService {
private static final Logger logger = LoggerFactory.getLogger(StaffClerkRelationService.class);
@Autowired
private TabHaobanStaffClerkRelationMapper mapper;
@Autowired
private StaffClerkBindLogService staffClerkBindLogService;
@Autowired
private ExternalClerkRelatedService externalClerkRelatedService;
@Autowired
private HaobanCommonMQApiService haobanCommonMQApiService ;
@Autowired
private ClerkMainStoreRelatedService clerkMainStoreRelatedService;
@Autowired
private TabHaobanExternalClerkRelatedMapper externalClerkRelatedMapper;
@Autowired
private TabHaobanMemberClerkChatConfigMapper memberClerkChatConfigMapper;
@Autowired
private StoreService storeService ;
@Autowired
private HmQrcodeApiService hmQrcodeApiService;
@Autowired
private StaffService staffService;
@Autowired
private HmClerkRelationApiService hmClerkRelationApiService;
@Autowired
private WxEnterpriseService wxEnterpriseService;
@Autowired
private MemberApiService memberApiService;
@Autowired
private ClerkService clerkService;
@Autowired
private RightService rightService;
@Override
public List<StaffClerkRelationDTO> listBindCode(String wxEnterpriseId, String enterpriseId, Set<String> clerkCodeList) {
return this.filterDelClerkList(mapper.listBindCode(wxEnterpriseId, enterpriseId, clerkCodeList));
}
@Override
public List<StaffClerkRelationDTO> listBindCodeByStaffId(List<String> enterpriseIdList, String staffId) {
return this.filterDelClerkList(mapper.listBindCodeByStaffId(enterpriseIdList, staffId));
}
/*
* 导购进行解绑/换导购,更新好友和导购关联关系
*/
@Override
public boolean delBind(String oldClerkId, String optStaffId, int channelCode, String newClerkId, String wxEnterpriseId) {
boolean changeClerkFlag = StringUtils.isNotEmpty(newClerkId) ;
logger.info("导购解绑/换导购={},oldClerkId={},optStaffId={}",changeClerkFlag,oldClerkId,optStaffId);
if(StringUtils.isNotEmpty(optStaffId) && "-1".equals(optStaffId)) {
TabHaobanStaff staff = this.staffService.selectById(optStaffId) ;
if(null != staff) {
wxEnterpriseId = staff.getWxEnterpriseId() ;
}
}
// wxEnterpriseId非必传
StaffClerkRelationDTO clerkRelation = mapper.getOneByClerkId(oldClerkId, wxEnterpriseId);
if (null == clerkRelation) {
logger.info("老的绑定关联不存在,oldClerkId={}", oldClerkId);
return true;
}
// 如果是区经
if(clerkRelation.getManageFlag()==1) {
this.mapper.changeStatusByClerkId(oldClerkId, 0);
return true ;
}
wxEnterpriseId = clerkRelation.getWxEnterpriseId() ;
String enterpriseId = clerkRelation.getEnterpriseId();
logger.info("当前删除换绑的商户={},{}",enterpriseId,wxEnterpriseId);
String staffId = clerkRelation.getStaffId() ;
String storeId = clerkRelation.getStoreId() ;
boolean needFlush = false ;
boolean delFlag = true ;
if(StringUtils.isEmpty(newClerkId)) {
// 成员关联的门店
List<StaffClerkRelationDTO> relationList = this.listByStaffId(wxEnterpriseId, staffId) ;
Set<String> set = relationList.stream().map(o->o.getEnterpriseId()).collect(Collectors.toSet()) ;
// 否关联的多个商户
boolean multipleFlag = set.size() > 1 ;
List<String> storeIdList = relationList.stream().filter(o->!storeId.equals(o.getStoreId()) && o.getEnterpriseId().equals(enterpriseId)).map(o->o.getStoreId()).collect(Collectors.toList()) ;
logger.info("成员{},关联门店数={},同商户下的门店={}",staffId,relationList.size(),JSON.toJSON(storeIdList));
if(CollectionUtils.isNotEmpty(storeIdList)) {
if(multipleFlag) {
needFlush = true ;
TabHaobanClerkMainStoreRelated currentMainStore = this.clerkMainStoreRelatedService.selectStaffMainStore(staffId, wxEnterpriseId);
String mainStoreEnterpriseId = null ;
if(null == currentMainStore) {
mainStoreEnterpriseId = enterpriseId ;
}else {
String mainStoreId = currentMainStore.getStoreId() ;
StoreDTO store = this.storeService.getStore(mainStoreId) ;
mainStoreEnterpriseId = store.getEnterpriseId() ;
}
logger.info("当前主门店商户和处理商户是否一致{},{}",mainStoreEnterpriseId,enterpriseId);
if(mainStoreEnterpriseId.equals(enterpriseId)) {
// 删除关联关系
this.mapper.changeStatusByClerkId(oldClerkId, 0);
delFlag = false ;
TabHaobanClerkMainStoreRelated mainStoreRelation = this.clerkMainStoreRelatedService.getMainStoreByStaffId(staffId, wxEnterpriseId, storeIdList) ;
String newStoreId = mainStoreRelation.getStoreId() ;
StaffClerkRelationDTO mainClerk = this.getOneBindByStoreId(staffId, newStoreId) ;
newClerkId = mainClerk.getClerkId() ;
logger.info("查询到成员的主门店导购={},{}",staffId,newClerkId);
needFlush = false ;
}
}else {
// 删除关联关系
this.mapper.changeStatusByClerkId(oldClerkId, 0);
delFlag = false ;
TabHaobanClerkMainStoreRelated mainStore = this.clerkMainStoreRelatedService.getMainStoreByStaffId(staffId, wxEnterpriseId, storeIdList) ;
String newStoreId = mainStore.getStoreId() ;
StaffClerkRelationDTO mainClerk = this.getOneBindByStoreId(staffId, newStoreId) ;
newClerkId = mainClerk.getClerkId() ;
logger.info("查询到成员的主门店导购={},{}",staffId,newClerkId);
}
}
}
// 删除关联关系
if(delFlag) {
this.mapper.changeStatusByClerkId(oldClerkId, 0);
}
if(StringUtils.isNotBlank(newClerkId)) {
List<String> memberIdList = this.externalClerkRelatedMapper.listByClerkId(staffId, oldClerkId) ;
this.externalClerkRelatedService.updateClerkInfo(staffId , oldClerkId , newClerkId) ;
if(CollectionUtils.isNotEmpty(memberIdList)) {
for(String memberId : memberIdList) {
logger.info("会员={}",memberId);
CommonMQDTO dto = new CommonMQDTO();
dto.setType(3);
Map<String,String> map = new HashMap<>() ;
map.put("enterpriseId", enterpriseId) ;
map.put("memberId", memberId) ;
map.put("clerkId", newClerkId) ;
dto.setParams(map);
this.haobanCommonMQApiService.putCommonMessage(dto);
}
}
}else {
logger.info("成员删除所有关联导购={}",staffId);
List<String> memberIds = externalClerkRelatedService.getByStoreIdAndStaffId(storeId, staffId);
//删除 并设置主门店
clerkMainStoreRelatedService.delMainStore(staffId, storeId, wxEnterpriseId);
//推入日志
delMemberQywxFlag(enterpriseId, memberIds);
}
if(needFlush) {
logger.info("解绑自动刷新好友,staffId={}",staffId);
this.clerkMainStoreRelatedService.reflushExternal(wxEnterpriseId, staffId);
}
this.staffClerkBindLogService.pushToMq(staffId, optStaffId, BindTypeEnum.UNBIND.getVal(), channelCode, clerkRelation.getStaffClerkRelationId());
//废弃活码
this.hmClerkRelationApiService.delByClerkId(oldClerkId, enterpriseId, wxEnterpriseId, channelCode, null);
return true;
}
private void delMemberQywxFlag(String enterpriseId, List<String> memberIds) {
for (String memberId : memberIds) {
//解绑通知会员
int count = externalClerkRelatedService.getCountByMemberId(memberId);
if (count == 0) {
logger.info("通知会员 删除企微好友,该会员无任何好友关系,memberId:{}", memberId);
memberApiService.updateMemberQywxFlag(enterpriseId, memberId, 0);
memberApiService.updateMemberQywxEveryOccasion(enterpriseId, memberId, 0, new Date());
continue;
}
logger.info("通知会员 删除企微好友 每次调用更新为非企微好友时间 memberId:{}", memberId);
memberApiService.updateMemberQywxEveryOccasion(enterpriseId, memberId, 1, new Date());
}
}
@Override
public boolean delBindByStoreIds(String wxEnterpriseId, Set<String> storeIds, String optStaffId, int channelCode) {
if (CollectionUtils.isEmpty(storeIds)) {
logger.info("没有传门店列表:{}", wxEnterpriseId);
return true;
}
List<String> storeIdList = new ArrayList<>();
storeIdList.addAll(storeIds) ;
List<StaffClerkRelationDTO> needUnbind = mapper.listByStoreIds(wxEnterpriseId, storeIdList);
if (CollectionUtils.isEmpty(needUnbind)) {
logger.info("没有门店绑定了需要解绑的:{}", wxEnterpriseId);
return true;
}
for (StaffClerkRelationDTO staffClerkRelation : needUnbind) {
String enterpriseId = staffClerkRelation.getEnterpriseId();
//删除好友通知会员
List<String> memberIds = externalClerkRelatedService.getByStoreIdAndStaffId(staffClerkRelation.getStoreId(), staffClerkRelation.getStaffId());
delMemberQywxFlag(enterpriseId, memberIds);
}
List<String> need = needUnbind.stream().map(tab -> tab.getStaffClerkRelationId()).collect(Collectors.toList());
//清除绑定
mapper.delByStoreIds(storeIds);
//删除主门店
clerkMainStoreRelatedService.delMainStoreByStoreIds(storeIds);
//放入队列
staffClerkBindLogService.pushToMqBatch(optStaffId, BindTypeEnum.UNBIND.getVal(), channelCode, need);
for (StaffClerkRelationDTO clerkRelation : needUnbind) {
//废弃活码
String enterpriseId = clerkRelation.getEnterpriseId();
hmClerkRelationApiService.delByClerkId(clerkRelation.getClerkId(), enterpriseId, wxEnterpriseId, channelCode);
}
return true;
}
@Override
public String bind(StaffClerkRelationDTO dto, String optStaffId, int channelCode) {
String staffId = dto.getStaffId();
TabHaobanStaff tabHaobanStaff = staffService.selectById(staffId);
if (tabHaobanStaff == null) {
logger.error("员工不存在:{}", staffId);
return "";
}
ClerkDTO clerkDTO = clerkService.getClerkByClerkId(dto.getClerkId());
if (clerkDTO != null) {
dto.setClerkType(clerkDTO.getClerkType());
}
String staffClerkRelationId = insert(dto);
if (StringUtils.isNotBlank(staffClerkRelationId)) {
String wxEnterpriseId = dto.getWxEnterpriseId();
Integer manageFlag = dto.getManageFlag();
String enterpriseId = dto.getEnterpriseId();
//导购和店长需要设置主门店
if (manageFlag != null && manageFlag == 1) {
//do nothing
} else {
logger.info("设置主门店并创建活码:manageFlag:{},staffId:{}", manageFlag, staffId);
TabHaobanClerkMainStoreRelated mainStore = clerkMainStoreRelatedService.getMainStoreByStaffId(staffId, wxEnterpriseId);
// 判断是主门店
if(null != mainStore && mainStore.getStoreId().equals(dto.getStoreId())) {
this.clerkMainStoreRelatedService.reflushExternal(wxEnterpriseId, staffId);
}
//有活码权限的企业
boolean flag = rightService.hasRightForAdmin(enterpriseId, "hb_m0206");
if (flag) {
// 绑定自动创建活码
HmQrcodeQDTO hmQrcodeQDTO = new HmQrcodeQDTO();
hmQrcodeQDTO.setHmType(1);
hmQrcodeQDTO.setWxEnterpriseId(wxEnterpriseId);
hmQrcodeQDTO.setEnterpriseId(enterpriseId);
hmQrcodeQDTO.setName(tabHaobanStaff.getStaffName());
hmQrcodeQDTO.setPassFlag(1);
hmQrcodeQDTO.setStoreId(dto.getStoreId());
hmQrcodeQDTO.setClerkIdList(Collections.singletonList(dto.getClerkId()));
hmQrcodeQDTO.setInvokingType(channelCode);
hmQrcodeApiService.add(hmQrcodeQDTO);
}
}
//推入日志
staffClerkBindLogService.pushToMq(staffId, optStaffId, BindTypeEnum.BIND.getVal(), channelCode, staffClerkRelationId);
}
return staffClerkRelationId;
}
@Override
public StaffClerkRelationDTO getBindByClerkId(String clerkId, String wxEnterpriseId) {
return this.filterDelClerk(mapper.getOneByClerkId(clerkId, wxEnterpriseId));
}
@Override
public StaffClerkRelationDTO getByCodeAndEnterpriseId(String clerkCode, String enterpriseId) {
return mapper.getByCodeAndEnterpriseId(clerkCode, enterpriseId);
}
@Override
public StaffClerkRelationDTO getStaffClerkRelationDTO(String clerkCode, String enterpriseId) {
return mapper.getStaffClerkRelationDTO(clerkCode, enterpriseId);
}
@Override
public String insert(StaffClerkRelationDTO staffClerkRelation) {
Integer manageFlag = staffClerkRelation.getManageFlag();
String uuid = StringUtil.randomUUID();
staffClerkRelation.setStaffClerkRelationId(uuid);
staffClerkRelation.setCreateTime(new Date());
staffClerkRelation.setUpdateTime(new Date());
staffClerkRelation.setStatusFlag(1);
staffClerkRelation.setOpenConcatFlag(1);
staffClerkRelation.setManageFlag(manageFlag == null ? 0 : manageFlag);
TabHaobanStaffClerkRelation relation = EntityUtil.changeEntityByJSON(TabHaobanStaffClerkRelation.class, staffClerkRelation);
mapper.insert(relation);
return uuid;
}
@Override
public int cleanStaffClerk(String wxEnterpriseId, List<String> delStaffIds) {
delStaffIds.forEach(staffId -> {
List<StaffClerkRelationDTO> relationDTOS = listBindCodeByStaffId(null, staffId);
if (CollectionUtils.isNotEmpty(relationDTOS)) {
relationDTOS.forEach(mid -> {
staffClerkBindLogService.pushToMq(mid.getStaffId(), "-1", BindTypeEnum.UNBIND.getVal(), ChannelCodeEnum.WEIXIN_DEL.getCode(), mid.getStaffClerkRelationId());
});
}
});
int ret = mapper.cleanStaffDepart(wxEnterpriseId, delStaffIds);
externalClerkRelatedService.cleanStaffRelated(wxEnterpriseId, delStaffIds);
return ret;
}
@Override
public StaffClerkRelationDTO getOneBindByStoreId(String staffId, String storeId) {
StaffClerkRelationDTO dto = this.filterDelClerk(mapper.getOneByStoreIdAndStaffId(storeId,staffId));
return dto ;
}
@Override
public StaffClerkRelationDTO getByClerkId(String clerkId) {
return this.filterDelClerk(mapper.getOneByClerkId(clerkId, null));
}
@Override
public StaffClerkRelationDTO getByClerkId(String clerkId, String wxEnterpriseId) {
StaffClerkRelationDTO staffClerkRelation = mapper.getOneByClerkId(clerkId, wxEnterpriseId);
return EntityUtil.changeEntityNew(StaffClerkRelationDTO.class, staffClerkRelation);
}
@Override
public List<StaffClerkRelationDTO> listByClerkIds(List<String> clerkList) {
if (CollectionUtils.isEmpty(clerkList)) {
return Collections.EMPTY_LIST;
}
return mapper.listByClerkIds(clerkList, null);
}
@Override
public List<StaffClerkRelationDTO> listByStaffId(String wxEnterpriseId, String staffId) {
return EntityUtil.changeEntityListByJSON(StaffClerkRelationDTO.class, mapper.lisByStaffId(wxEnterpriseId, staffId, null));
}
@Override
public List<StaffClerkRelationDTO> listByStaffId(String wxEnterpriseId, String staffId, List<String> storeIdList) {
return EntityUtil.changeEntityListByJSON(StaffClerkRelationDTO.class, mapper.lisByStaffId(wxEnterpriseId, staffId, storeIdList));
}
@Override
public void saveChatConfig(MemberClerkChatConfig memberClerkChatConfig) {
memberClerkChatConfig.setStatus(1);
memberClerkChatConfig.setCreateTime(new Date());
memberClerkChatConfig.setUpdateTime(new Date());
memberClerkChatConfigMapper.insert(memberClerkChatConfig);
}
@Override
public MemberClerkChatConfig getChatConfig(String staffId, String memberId) {
MemberClerkChatConfig chatConfig = memberClerkChatConfigMapper.getChatByMemberIdStaffId(memberId, staffId);
return chatConfig;
}
@Override
public List<String> listByWxEnterpriseId(String wxEnterpriseId) {
return mapper.listByWxEnterpriseId(wxEnterpriseId);
}
@Override
public Page<StaffClerkRelationDTO> pageByWxEnterpriseId(String wxEnterpriseId, BasePageInfo pageInfo) {
PageHelper.startPage(pageInfo);
List<StaffClerkRelationDTO> clerkBindList = mapper.pageByWxEnterpriseId(wxEnterpriseId);
Page<StaffClerkRelationDTO> retPage = PageUtil.changePageHelperToCurrentPage(new PageInfo<>(clerkBindList), StaffClerkRelationDTO.class);
return retPage;
}
@Override
public List<StaffClerkRelationDTO> listBindByStoreId(String wxEnterpriseId, String storeId) {
return mapper.listByStoreIds(wxEnterpriseId, Arrays.asList(storeId));
}
@Override
public List<StaffClerkRelationDTO> listBindStoreIdByEnterpriseId(String enterpriseId) {
List<StaffClerkRelationDTO> clerkRelations = mapper.listBindStoreIdByEnterpriseId(enterpriseId);
if (CollectionUtils.isEmpty(clerkRelations)) {
return new ArrayList<>();
}
return EntityUtil.changeEntityListNew(StaffClerkRelationDTO.class, clerkRelations);
}
@Override
public List<String> listRelationsStaffId(Set<String> staffIdList) {
return mapper.listRelationsStaffId(staffIdList);
}
@Override
public List<String> listWxUserIdByClerkIds(List<String> clerkList, String wxEnterpriseId) {
if (CollectionUtils.isEmpty(clerkList)) {
return null;
}
WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
if (qwDTO.needOpenUserId3th()) {
return mapper.listWxUserIdByClerkIds(clerkList, wxEnterpriseId,2);
}
return mapper.listWxUserIdByClerkIds(clerkList, wxEnterpriseId,1);
}
@Override
public List<StaffClerkRelationDTO> listIdsByWxUserIds(List<String> wxUserIds, String wxEnterpriseId, String enterpriseId) {
if (CollectionUtils.isEmpty(wxUserIds)) {
return null;
}
WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
if (qwDTO.needOpenUserId3th()) {
return mapper.listIdsByWxUserIds(wxUserIds, wxEnterpriseId, enterpriseId,2);
}
return mapper.listIdsByWxUserIds(wxUserIds, wxEnterpriseId, enterpriseId,1);
}
@Override
public List<StaffClerkRelationDTO> listIdsByNotInWxUserIds(List<String> wxUserIds, String wxEnterpriseId, String enterpriseId) {
if (CollectionUtils.isEmpty(wxUserIds)) {
return null;
}
WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
if (qwDTO.needOpenUserId3th()) {
return mapper.listIdsByNotInWxOpenUserIds(wxUserIds, wxEnterpriseId, enterpriseId);
}
return mapper.listIdsByNotInWxUserIds(wxUserIds, wxEnterpriseId, enterpriseId);
}
@Override
public int updateOpenConcatFlagById(Integer openConcatFlag, String staffClerkRelationId) {
return mapper.updateOpenConcatFlagById(openConcatFlag, staffClerkRelationId);
}
@Override
public boolean getBindByStaffIdAndEnterpriseId(String enterpriseId, String staffId) {
return mapper.getBindByStaffIdAndEnterpriseId(enterpriseId, staffId) > 0;
}
@Override
public List<StaffClerkRelationDTO> listManageBindByStaffId(String staffId) {
return this.filterDelClerkList(mapper.listManageBindByStaffId(staffId));
}
private List<StaffClerkRelationDTO> filterDelClerkList(List<StaffClerkRelationDTO> list) {
if(CollectionUtils.isEmpty(list)) {
return list ;
}
List<StaffClerkRelationDTO> retList = new ArrayList<>() ;
for(StaffClerkRelationDTO item : list) {
boolean delFlag = false ;
String clerkId = item.getClerkId() ;
ClerkDTO clerk = this.clerkService.getclerkById(clerkId) ;
if(null == clerk || clerk.getStatus() != 1) {
delFlag = true ;
}
if(!delFlag && null != clerk && clerk.getClerkType()<2 && StringUtils.isNotEmpty(clerk.getStoreId())) {
StoreDTO store = this.storeService.getStore(clerk.getStoreId()) ;
if(null == store || store.getStatus() == -3) {
delFlag = true ;
}
}
if(delFlag) {
this.mapper.delByClerkId(clerkId);
}else {
retList.add(item) ;
}
}
return retList ;
}
private StaffClerkRelationDTO filterDelClerk(StaffClerkRelationDTO dto) {
if(null == dto) {
return dto ;
}
String clerkId = dto.getClerkId() ;
ClerkDTO clerk = this.clerkService.getclerkById(clerkId) ;
boolean delFlag = false ;
if(null == clerk || clerk.getStatus() != 1) {
delFlag = true ;
}
if(!delFlag && null != clerk && clerk.getClerkType() <2 && StringUtils.isNotEmpty(clerk.getStoreId())) {
StoreDTO store = this.storeService.getStore(clerk.getStoreId()) ;
if(null == store || store.getStatus() == -3) {
delFlag = true ;
}
}
if(delFlag) {
this.mapper.delByClerkId(clerkId);
dto = null ;
}
return dto ;
}
/**
* 获取企业下所有关联关系
*
* @param enterpriseId
* @return
*/
@Override
public List<String> listAllClerkIdsByEnterpriseId(String enterpriseId) {
return this.mapper.listAllClerkIdsByEnterpriseId(enterpriseId);
}
@Override
public List<StaffClerkRelationDTO>listByWxEnterpriseIdAndStaffId(String wxEnterpriseId, Set<String> staffIdList) {
return this.mapper.listByWxEnterpriseIdAndStaffId(wxEnterpriseId,staffIdList);
}
@Override
public List<String> listAllStaffIdByEnterpriseId(String enterpriseId, String wxEnterpriseId) {
return this.mapper.listAllStaffIdByEnterpriseId(enterpriseId,wxEnterpriseId);
}
}
package com.gic.haoban.manage.service.service.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.gic.api.base.commons.Page;
import com.gic.clerk.api.dto.ClerkDTO;
import com.gic.clerk.api.service.ClerkService;
import com.gic.clerk.api.service.RightService;
import com.gic.commons.util.EntityUtil;
import com.gic.enterprise.api.dto.StoreDTO;
import com.gic.enterprise.api.service.StoreService;
import com.gic.haoban.base.api.common.BasePageInfo;
import com.gic.haoban.common.utils.PageUtil;
import com.gic.haoban.common.utils.StringUtil;
import com.gic.haoban.manage.api.dto.CommonMQDTO;
import com.gic.haoban.manage.api.dto.StaffClerkRelationDTO;
import com.gic.haoban.manage.api.dto.WxEnterpriseQwDTO;
import com.gic.haoban.manage.api.dto.qdto.hm.HmQrcodeQDTO;
import com.gic.haoban.manage.api.enums.BindTypeEnum;
import com.gic.haoban.manage.api.enums.ChannelCodeEnum;
import com.gic.haoban.manage.api.service.HaobanCommonMQApiService;
import com.gic.haoban.manage.api.service.hm.HmClerkRelationApiService;
import com.gic.haoban.manage.api.service.hm.HmQrcodeApiService;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanExternalClerkRelatedMapper;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanMemberClerkChatConfigMapper;
import com.gic.haoban.manage.service.dao.mapper.TabHaobanStaffClerkRelationMapper;
import com.gic.haoban.manage.service.entity.MemberClerkChatConfig;
import com.gic.haoban.manage.service.entity.TabHaobanClerkMainStoreRelated;
import com.gic.haoban.manage.service.entity.TabHaobanStaff;
import com.gic.haoban.manage.service.entity.TabHaobanStaffClerkRelation;
import com.gic.haoban.manage.service.service.ClerkMainStoreRelatedService;
import com.gic.haoban.manage.service.service.ExternalClerkRelatedService;
import com.gic.haoban.manage.service.service.StaffClerkBindLogService;
import com.gic.haoban.manage.service.service.StaffClerkRelationService;
import com.gic.haoban.manage.service.service.StaffService;
import com.gic.haoban.manage.service.service.WxEnterpriseService;
import com.gic.member.api.service.MemberApiService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
@Service
public class StaffClerkRelationServiceImpl implements StaffClerkRelationService {
private static final Logger logger = LoggerFactory.getLogger(StaffClerkRelationService.class);
@Autowired
private TabHaobanStaffClerkRelationMapper mapper;
@Autowired
private StaffClerkBindLogService staffClerkBindLogService;
@Autowired
private ExternalClerkRelatedService externalClerkRelatedService;
@Autowired
private HaobanCommonMQApiService haobanCommonMQApiService ;
@Autowired
private ClerkMainStoreRelatedService clerkMainStoreRelatedService;
@Autowired
private TabHaobanExternalClerkRelatedMapper externalClerkRelatedMapper;
@Autowired
private TabHaobanMemberClerkChatConfigMapper memberClerkChatConfigMapper;
@Autowired
private StoreService storeService ;
@Autowired
private HmQrcodeApiService hmQrcodeApiService;
@Autowired
private StaffService staffService;
@Autowired
private HmClerkRelationApiService hmClerkRelationApiService;
@Autowired
private WxEnterpriseService wxEnterpriseService;
@Autowired
private MemberApiService memberApiService;
@Autowired
private ClerkService clerkService;
@Autowired
private RightService rightService;
@Override
public List<StaffClerkRelationDTO> listBindCode(String wxEnterpriseId, String enterpriseId, Set<String> clerkCodeList) {
return this.filterDelClerkList(mapper.listBindCode(wxEnterpriseId, enterpriseId, clerkCodeList));
}
@Override
public List<StaffClerkRelationDTO> listBindCodeByStaffId(List<String> enterpriseIdList, String staffId) {
return this.filterDelClerkList(mapper.listBindCodeByStaffId(enterpriseIdList, staffId));
}
/*
* 导购进行解绑/换导购,更新好友和导购关联关系
*/
@Override
public boolean delBind(String oldClerkId, String optStaffId, int channelCode, String newClerkId, String wxEnterpriseId) {
boolean changeClerkFlag = StringUtils.isNotEmpty(newClerkId) ;
logger.info("导购解绑/换导购={},oldClerkId={},optStaffId={}",changeClerkFlag,oldClerkId,optStaffId);
if(StringUtils.isNotEmpty(optStaffId) && "-1".equals(optStaffId)) {
TabHaobanStaff staff = this.staffService.selectById(optStaffId) ;
if(null != staff) {
wxEnterpriseId = staff.getWxEnterpriseId() ;
}
}
// wxEnterpriseId非必传
StaffClerkRelationDTO clerkRelation = mapper.getOneByClerkId(oldClerkId, wxEnterpriseId);
if (null == clerkRelation) {
logger.info("老的绑定关联不存在,oldClerkId={}", oldClerkId);
return true;
}
// 如果是区经
if(clerkRelation.getManageFlag()==1) {
this.mapper.changeStatusByClerkId(oldClerkId, 0);
return true ;
}
wxEnterpriseId = clerkRelation.getWxEnterpriseId() ;
String enterpriseId = clerkRelation.getEnterpriseId();
logger.info("当前删除换绑的商户={},{}",enterpriseId,wxEnterpriseId);
String staffId = clerkRelation.getStaffId() ;
String storeId = clerkRelation.getStoreId() ;
boolean needFlush = false ;
boolean delFlag = true ;
if(StringUtils.isEmpty(newClerkId)) {
// 成员关联的门店
List<StaffClerkRelationDTO> relationList = this.listByStaffId(wxEnterpriseId, staffId) ;
Set<String> set = relationList.stream().map(o->o.getEnterpriseId()).collect(Collectors.toSet()) ;
// 否关联的多个商户
boolean multipleFlag = set.size() > 1 ;
List<String> storeIdList = relationList.stream().filter(o->!storeId.equals(o.getStoreId()) && o.getEnterpriseId().equals(enterpriseId)).map(o->o.getStoreId()).collect(Collectors.toList()) ;
logger.info("成员{},关联门店数={},同商户下的门店={}",staffId,relationList.size(),JSON.toJSON(storeIdList));
if(CollectionUtils.isNotEmpty(storeIdList)) {
if(multipleFlag) {
needFlush = true ;
TabHaobanClerkMainStoreRelated currentMainStore = this.clerkMainStoreRelatedService.selectStaffMainStore(staffId, wxEnterpriseId);
String mainStoreEnterpriseId = null ;
if(null == currentMainStore) {
mainStoreEnterpriseId = enterpriseId ;
}else {
String mainStoreId = currentMainStore.getStoreId() ;
StoreDTO store = this.storeService.getStore(mainStoreId) ;
mainStoreEnterpriseId = store.getEnterpriseId() ;
}
logger.info("当前主门店商户和处理商户是否一致{},{}",mainStoreEnterpriseId,enterpriseId);
if(mainStoreEnterpriseId.equals(enterpriseId)) {
// 删除关联关系
this.mapper.changeStatusByClerkId(oldClerkId, 0);
delFlag = false ;
TabHaobanClerkMainStoreRelated mainStoreRelation = this.clerkMainStoreRelatedService.getMainStoreByStaffId(staffId, wxEnterpriseId, storeIdList) ;
String newStoreId = mainStoreRelation.getStoreId() ;
StaffClerkRelationDTO mainClerk = this.getOneBindByStoreId(staffId, newStoreId) ;
newClerkId = mainClerk.getClerkId() ;
logger.info("查询到成员的主门店导购={},{}",staffId,newClerkId);
needFlush = false ;
}
}else {
// 删除关联关系
this.mapper.changeStatusByClerkId(oldClerkId, 0);
delFlag = false ;
TabHaobanClerkMainStoreRelated mainStore = this.clerkMainStoreRelatedService.getMainStoreByStaffId(staffId, wxEnterpriseId, storeIdList) ;
String newStoreId = mainStore.getStoreId() ;
StaffClerkRelationDTO mainClerk = this.getOneBindByStoreId(staffId, newStoreId) ;
newClerkId = mainClerk.getClerkId() ;
logger.info("查询到成员的主门店导购={},{}",staffId,newClerkId);
}
}
}
// 删除关联关系
if(delFlag) {
this.mapper.changeStatusByClerkId(oldClerkId, 0);
}
if(StringUtils.isNotBlank(newClerkId)) {
List<String> memberIdList = this.externalClerkRelatedMapper.listByClerkId(staffId, oldClerkId) ;
this.externalClerkRelatedService.updateClerkInfo(staffId , oldClerkId , newClerkId) ;
if(CollectionUtils.isNotEmpty(memberIdList)) {
for(String memberId : memberIdList) {
logger.info("会员={}",memberId);
CommonMQDTO dto = new CommonMQDTO();
dto.setType(3);
Map<String,String> map = new HashMap<>() ;
map.put("enterpriseId", enterpriseId) ;
map.put("memberId", memberId) ;
map.put("clerkId", newClerkId) ;
dto.setParams(map);
this.haobanCommonMQApiService.putCommonMessage(dto);
}
}
}else {
logger.info("成员删除所有关联导购={}",staffId);
List<String> memberIds = externalClerkRelatedService.getByStoreIdAndStaffId(storeId, staffId);
//删除 并设置主门店
clerkMainStoreRelatedService.delMainStore(staffId, storeId, wxEnterpriseId);
//推入日志
delMemberQywxFlag(enterpriseId, memberIds);
}
if(needFlush) {
logger.info("解绑自动刷新好友,staffId={}",staffId);
this.clerkMainStoreRelatedService.reflushExternal(wxEnterpriseId, staffId);
}
this.staffClerkBindLogService.pushToMq(staffId, optStaffId, BindTypeEnum.UNBIND.getVal(), channelCode, clerkRelation.getStaffClerkRelationId());
//废弃活码
this.hmClerkRelationApiService.delByClerkId(oldClerkId, enterpriseId, wxEnterpriseId, channelCode, null);
return true;
}
private void delMemberQywxFlag(String enterpriseId, List<String> memberIds) {
for (String memberId : memberIds) {
//解绑通知会员
int count = externalClerkRelatedService.getCountByMemberId(memberId);
if (count == 0) {
logger.info("通知会员 删除企微好友,该会员无任何好友关系,memberId:{}", memberId);
memberApiService.updateMemberQywxFlag(enterpriseId, memberId, 0);
memberApiService.updateMemberQywxEveryOccasion(enterpriseId, memberId, 0, new Date());
continue;
}
//logger.info("通知会员 删除企微好友 每次调用更新为非企微好友时间 memberId:{}", memberId);
//memberApiService.updateMemberQywxEveryOccasion(enterpriseId, memberId, 1, new Date());
}
}
@Override
public boolean delBindByStoreIds(String wxEnterpriseId, Set<String> storeIds, String optStaffId, int channelCode) {
if (CollectionUtils.isEmpty(storeIds)) {
logger.info("没有传门店列表:{}", wxEnterpriseId);
return true;
}
List<String> storeIdList = new ArrayList<>();
storeIdList.addAll(storeIds) ;
List<StaffClerkRelationDTO> needUnbind = mapper.listByStoreIds(wxEnterpriseId, storeIdList);
if (CollectionUtils.isEmpty(needUnbind)) {
logger.info("没有门店绑定了需要解绑的:{}", wxEnterpriseId);
return true;
}
for (StaffClerkRelationDTO staffClerkRelation : needUnbind) {
String enterpriseId = staffClerkRelation.getEnterpriseId();
//删除好友通知会员
List<String> memberIds = externalClerkRelatedService.getByStoreIdAndStaffId(staffClerkRelation.getStoreId(), staffClerkRelation.getStaffId());
delMemberQywxFlag(enterpriseId, memberIds);
}
List<String> need = needUnbind.stream().map(tab -> tab.getStaffClerkRelationId()).collect(Collectors.toList());
//清除绑定
mapper.delByStoreIds(storeIds);
//删除主门店
clerkMainStoreRelatedService.delMainStoreByStoreIds(storeIds);
//放入队列
staffClerkBindLogService.pushToMqBatch(optStaffId, BindTypeEnum.UNBIND.getVal(), channelCode, need);
for (StaffClerkRelationDTO clerkRelation : needUnbind) {
//废弃活码
String enterpriseId = clerkRelation.getEnterpriseId();
hmClerkRelationApiService.delByClerkId(clerkRelation.getClerkId(), enterpriseId, wxEnterpriseId, channelCode);
}
return true;
}
@Override
public String bind(StaffClerkRelationDTO dto, String optStaffId, int channelCode) {
String staffId = dto.getStaffId();
TabHaobanStaff tabHaobanStaff = staffService.selectById(staffId);
if (tabHaobanStaff == null) {
logger.error("员工不存在:{}", staffId);
return "";
}
ClerkDTO clerkDTO = clerkService.getClerkByClerkId(dto.getClerkId());
if (clerkDTO != null) {
dto.setClerkType(clerkDTO.getClerkType());
}
String staffClerkRelationId = insert(dto);
if (StringUtils.isNotBlank(staffClerkRelationId)) {
String wxEnterpriseId = dto.getWxEnterpriseId();
Integer manageFlag = dto.getManageFlag();
String enterpriseId = dto.getEnterpriseId();
//导购和店长需要设置主门店
if (manageFlag != null && manageFlag == 1) {
//do nothing
} else {
logger.info("设置主门店并创建活码:manageFlag:{},staffId:{}", manageFlag, staffId);
TabHaobanClerkMainStoreRelated mainStore = clerkMainStoreRelatedService.getMainStoreByStaffId(staffId, wxEnterpriseId);
// 判断是主门店
if(null != mainStore && mainStore.getStoreId().equals(dto.getStoreId())) {
this.clerkMainStoreRelatedService.reflushExternal(wxEnterpriseId, staffId);
}
//有活码权限的企业
boolean flag = rightService.hasRightForAdmin(enterpriseId, "hb_m0206");
if (flag) {
// 绑定自动创建活码
HmQrcodeQDTO hmQrcodeQDTO = new HmQrcodeQDTO();
hmQrcodeQDTO.setHmType(1);
hmQrcodeQDTO.setWxEnterpriseId(wxEnterpriseId);
hmQrcodeQDTO.setEnterpriseId(enterpriseId);
hmQrcodeQDTO.setName(tabHaobanStaff.getStaffName());
hmQrcodeQDTO.setPassFlag(1);
hmQrcodeQDTO.setStoreId(dto.getStoreId());
hmQrcodeQDTO.setClerkIdList(Collections.singletonList(dto.getClerkId()));
hmQrcodeQDTO.setInvokingType(channelCode);
hmQrcodeApiService.add(hmQrcodeQDTO);
}
}
//推入日志
staffClerkBindLogService.pushToMq(staffId, optStaffId, BindTypeEnum.BIND.getVal(), channelCode, staffClerkRelationId);
}
return staffClerkRelationId;
}
@Override
public StaffClerkRelationDTO getBindByClerkId(String clerkId, String wxEnterpriseId) {
return this.filterDelClerk(mapper.getOneByClerkId(clerkId, wxEnterpriseId));
}
@Override
public StaffClerkRelationDTO getByCodeAndEnterpriseId(String clerkCode, String enterpriseId) {
return mapper.getByCodeAndEnterpriseId(clerkCode, enterpriseId);
}
@Override
public StaffClerkRelationDTO getStaffClerkRelationDTO(String clerkCode, String enterpriseId) {
return mapper.getStaffClerkRelationDTO(clerkCode, enterpriseId);
}
@Override
public String insert(StaffClerkRelationDTO staffClerkRelation) {
Integer manageFlag = staffClerkRelation.getManageFlag();
String uuid = StringUtil.randomUUID();
staffClerkRelation.setStaffClerkRelationId(uuid);
staffClerkRelation.setCreateTime(new Date());
staffClerkRelation.setUpdateTime(new Date());
staffClerkRelation.setStatusFlag(1);
staffClerkRelation.setOpenConcatFlag(1);
staffClerkRelation.setManageFlag(manageFlag == null ? 0 : manageFlag);
TabHaobanStaffClerkRelation relation = EntityUtil.changeEntityByJSON(TabHaobanStaffClerkRelation.class, staffClerkRelation);
mapper.insert(relation);
return uuid;
}
@Override
public int cleanStaffClerk(String wxEnterpriseId, List<String> delStaffIds) {
delStaffIds.forEach(staffId -> {
List<StaffClerkRelationDTO> relationDTOS = listBindCodeByStaffId(null, staffId);
if (CollectionUtils.isNotEmpty(relationDTOS)) {
relationDTOS.forEach(mid -> {
staffClerkBindLogService.pushToMq(mid.getStaffId(), "-1", BindTypeEnum.UNBIND.getVal(), ChannelCodeEnum.WEIXIN_DEL.getCode(), mid.getStaffClerkRelationId());
});
}
});
int ret = mapper.cleanStaffDepart(wxEnterpriseId, delStaffIds);
externalClerkRelatedService.cleanStaffRelated(wxEnterpriseId, delStaffIds);
return ret;
}
@Override
public StaffClerkRelationDTO getOneBindByStoreId(String staffId, String storeId) {
StaffClerkRelationDTO dto = this.filterDelClerk(mapper.getOneByStoreIdAndStaffId(storeId,staffId));
return dto ;
}
@Override
public StaffClerkRelationDTO getByClerkId(String clerkId) {
return this.filterDelClerk(mapper.getOneByClerkId(clerkId, null));
}
@Override
public StaffClerkRelationDTO getByClerkId(String clerkId, String wxEnterpriseId) {
StaffClerkRelationDTO staffClerkRelation = mapper.getOneByClerkId(clerkId, wxEnterpriseId);
return EntityUtil.changeEntityNew(StaffClerkRelationDTO.class, staffClerkRelation);
}
@Override
public List<StaffClerkRelationDTO> listByClerkIds(List<String> clerkList) {
if (CollectionUtils.isEmpty(clerkList)) {
return Collections.EMPTY_LIST;
}
return mapper.listByClerkIds(clerkList, null);
}
@Override
public List<StaffClerkRelationDTO> listByStaffId(String wxEnterpriseId, String staffId) {
return EntityUtil.changeEntityListByJSON(StaffClerkRelationDTO.class, mapper.lisByStaffId(wxEnterpriseId, staffId, null));
}
@Override
public List<StaffClerkRelationDTO> listByStaffId(String wxEnterpriseId, String staffId, List<String> storeIdList) {
return EntityUtil.changeEntityListByJSON(StaffClerkRelationDTO.class, mapper.lisByStaffId(wxEnterpriseId, staffId, storeIdList));
}
@Override
public void saveChatConfig(MemberClerkChatConfig memberClerkChatConfig) {
memberClerkChatConfig.setStatus(1);
memberClerkChatConfig.setCreateTime(new Date());
memberClerkChatConfig.setUpdateTime(new Date());
memberClerkChatConfigMapper.insert(memberClerkChatConfig);
}
@Override
public MemberClerkChatConfig getChatConfig(String staffId, String memberId) {
MemberClerkChatConfig chatConfig = memberClerkChatConfigMapper.getChatByMemberIdStaffId(memberId, staffId);
return chatConfig;
}
@Override
public List<String> listByWxEnterpriseId(String wxEnterpriseId) {
return mapper.listByWxEnterpriseId(wxEnterpriseId);
}
@Override
public Page<StaffClerkRelationDTO> pageByWxEnterpriseId(String wxEnterpriseId, BasePageInfo pageInfo) {
PageHelper.startPage(pageInfo);
List<StaffClerkRelationDTO> clerkBindList = mapper.pageByWxEnterpriseId(wxEnterpriseId);
Page<StaffClerkRelationDTO> retPage = PageUtil.changePageHelperToCurrentPage(new PageInfo<>(clerkBindList), StaffClerkRelationDTO.class);
return retPage;
}
@Override
public List<StaffClerkRelationDTO> listBindByStoreId(String wxEnterpriseId, String storeId) {
return mapper.listByStoreIds(wxEnterpriseId, Arrays.asList(storeId));
}
@Override
public List<StaffClerkRelationDTO> listBindStoreIdByEnterpriseId(String enterpriseId) {
List<StaffClerkRelationDTO> clerkRelations = mapper.listBindStoreIdByEnterpriseId(enterpriseId);
if (CollectionUtils.isEmpty(clerkRelations)) {
return new ArrayList<>();
}
return EntityUtil.changeEntityListNew(StaffClerkRelationDTO.class, clerkRelations);
}
@Override
public List<String> listRelationsStaffId(Set<String> staffIdList) {
return mapper.listRelationsStaffId(staffIdList);
}
@Override
public List<String> listWxUserIdByClerkIds(List<String> clerkList, String wxEnterpriseId) {
if (CollectionUtils.isEmpty(clerkList)) {
return null;
}
WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
if (qwDTO.needOpenUserId3th()) {
return mapper.listWxUserIdByClerkIds(clerkList, wxEnterpriseId,2);
}
return mapper.listWxUserIdByClerkIds(clerkList, wxEnterpriseId,1);
}
@Override
public List<StaffClerkRelationDTO> listIdsByWxUserIds(List<String> wxUserIds, String wxEnterpriseId, String enterpriseId) {
if (CollectionUtils.isEmpty(wxUserIds)) {
return null;
}
WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
if (qwDTO.needOpenUserId3th()) {
return mapper.listIdsByWxUserIds(wxUserIds, wxEnterpriseId, enterpriseId,2);
}
return mapper.listIdsByWxUserIds(wxUserIds, wxEnterpriseId, enterpriseId,1);
}
@Override
public List<StaffClerkRelationDTO> listIdsByNotInWxUserIds(List<String> wxUserIds, String wxEnterpriseId, String enterpriseId) {
if (CollectionUtils.isEmpty(wxUserIds)) {
return null;
}
WxEnterpriseQwDTO qwDTO = this.wxEnterpriseService.getQwInfo(wxEnterpriseId);
if (qwDTO.needOpenUserId3th()) {
return mapper.listIdsByNotInWxOpenUserIds(wxUserIds, wxEnterpriseId, enterpriseId);
}
return mapper.listIdsByNotInWxUserIds(wxUserIds, wxEnterpriseId, enterpriseId);
}
@Override
public int updateOpenConcatFlagById(Integer openConcatFlag, String staffClerkRelationId) {
return mapper.updateOpenConcatFlagById(openConcatFlag, staffClerkRelationId);
}
@Override
public boolean getBindByStaffIdAndEnterpriseId(String enterpriseId, String staffId) {
return mapper.getBindByStaffIdAndEnterpriseId(enterpriseId, staffId) > 0;
}
@Override
public List<StaffClerkRelationDTO> listManageBindByStaffId(String staffId) {
return this.filterDelClerkList(mapper.listManageBindByStaffId(staffId));
}
private List<StaffClerkRelationDTO> filterDelClerkList(List<StaffClerkRelationDTO> list) {
if(CollectionUtils.isEmpty(list)) {
return list ;
}
List<StaffClerkRelationDTO> retList = new ArrayList<>() ;
for(StaffClerkRelationDTO item : list) {
boolean delFlag = false ;
String clerkId = item.getClerkId() ;
ClerkDTO clerk = this.clerkService.getclerkById(clerkId) ;
if(null == clerk || clerk.getStatus() != 1) {
delFlag = true ;
}
if(!delFlag && null != clerk && clerk.getClerkType()<2 && StringUtils.isNotEmpty(clerk.getStoreId())) {
StoreDTO store = this.storeService.getStore(clerk.getStoreId()) ;
if(null == store || store.getStatus() == -3) {
delFlag = true ;
}
}
if(delFlag) {
this.mapper.delByClerkId(clerkId);
}else {
retList.add(item) ;
}
}
return retList ;
}
private StaffClerkRelationDTO filterDelClerk(StaffClerkRelationDTO dto) {
if(null == dto) {
return dto ;
}
String clerkId = dto.getClerkId() ;
ClerkDTO clerk = this.clerkService.getclerkById(clerkId) ;
boolean delFlag = false ;
if(null == clerk || clerk.getStatus() != 1) {
delFlag = true ;
}
if(!delFlag && null != clerk && clerk.getClerkType() <2 && StringUtils.isNotEmpty(clerk.getStoreId())) {
StoreDTO store = this.storeService.getStore(clerk.getStoreId()) ;
if(null == store || store.getStatus() == -3) {
delFlag = true ;
}
}
if(delFlag) {
this.mapper.delByClerkId(clerkId);
dto = null ;
}
return dto ;
}
/**
* 获取企业下所有关联关系
*
* @param enterpriseId
* @return
*/
@Override
public List<String> listAllClerkIdsByEnterpriseId(String enterpriseId) {
return this.mapper.listAllClerkIdsByEnterpriseId(enterpriseId);
}
@Override
public List<StaffClerkRelationDTO>listByWxEnterpriseIdAndStaffId(String wxEnterpriseId, Set<String> staffIdList) {
return this.mapper.listByWxEnterpriseIdAndStaffId(wxEnterpriseId,staffIdList);
}
@Override
public List<String> listAllStaffIdByEnterpriseId(String enterpriseId, String wxEnterpriseId) {
return this.mapper.listAllStaffIdByEnterpriseId(enterpriseId,wxEnterpriseId);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment