Commit d87e8be5 by xugaojun

存量会员群发实现,dubbo配置,mq消息,群发逻辑,小程序构造实现

parent 685f54ca
package com.gic.haoban.manage.api.service.mq;
/**
* desc:微信会员消费服务
*
* @author: YongEn
* @date: 2022/2/16
**/
public interface MemberUnionRelateConsumer {
/**
* desc: 添加好友关系-存量会员新增
*
* @param messageParam 消息参数
* @author : YongEn
* @date : 2022/2/16
*/
void addMemberUnionRelate(String messageParam);
}
......@@ -9,6 +9,7 @@ import javax.servlet.http.HttpServletResponse;
import com.gic.haoban.app.customer.service.api.service.QywxTagSyncApiService;
import com.gic.haoban.manage.api.dto.WxEnterpriseDTO;
import com.gic.haoban.manage.api.service.ExternalClerkRelatedApiService;
import com.gic.haoban.task.manage.api.service.GroupSendOperateApiService;
import com.gic.wechat.api.service.qywx.QywxUserApiService;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
......@@ -65,6 +66,8 @@ public class EnterpriseController extends WebBaseController {
private ExternalClerkRelatedApiService externalClerkRelatedApiService;
@Autowired
private QywxUserApiService qywxUserApiService;
@Autowired
private GroupSendOperateApiService groupSendOperateApiService;
private static final String QYWX_TAG_OPRN_KEY = "qywx-tag-open";
private static final String QYWX_TAG_OPRN_KEY_LOCK = "qywx-tag-open-lock";
......@@ -392,4 +395,20 @@ public class EnterpriseController extends WebBaseController {
}
}
/**
* desc: 发送群发
*
* @param wxEnterpriseId 微信企业id
* @param content 文本内容
* @return : {@link HaobanResponse}
* @author : YongEn
* @date : 2022/2/17
*/
@RequestMapping("/send-mass")
public HaobanResponse sendMass(String wxEnterpriseId, String content) {
// 异步调用
groupSendOperateApiService.sendMbrFriendRelationMassBefore(wxEnterpriseId, content);
return resultResponse(HaoBanErrCode.ERR_1);
}
}
......@@ -66,5 +66,6 @@
<dubbo:reference interface="com.gic.haoban.manage.api.service.ExternalClerkRelatedApiService"
id="externalClerkRelatedApiService"/>
<dubbo:reference interface="com.gic.wechat.api.service.qywx.QywxUserApiService" id="qywxUserApiService"/>
<dubbo:reference interface="com.gic.haoban.task.manage.api.service.GroupSendOperateApiService" id="groupSendOperateApiService" async="true"/>
</beans>
package com.gic.haoban.manage.service.mq;
import com.gic.haoban.manage.api.service.mq.MemberUnionRelateConsumer;
import com.gic.haoban.manage.service.mq.processor.AddMemberUnionRelateConsumerProcessor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* desc:微信会员消费服务实现
*
* @author: YongEn
* @date: 2022/2/16
**/
@Service
public class MemberUnionRelateConsumerImpl implements MemberUnionRelateConsumer {
@Autowired
private AddMemberUnionRelateConsumerProcessor addMemberUnionRelateConsumerProcessor;
@Override
public void addMemberUnionRelate(String messageParam) {
addMemberUnionRelateConsumerProcessor.process(messageParam);
}
}
package com.gic.haoban.manage.service.mq.processor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* desc:处理器
*
* @author: YongEn
* @date: 2022/2/16
**/
public abstract class AbstractConsumerProcessor<S, R> {
private static final Logger logger = LoggerFactory.getLogger(AbstractConsumerProcessor.class);
public void process(S messageParam) {
logger.info("接收到消费处理, 参数{}", messageParam);
// 参数解析
R r = paramParse(messageParam);
// 执行处理
doProcess(r);
}
/**
* desc: 参数解析
*
* @param s 原数据
* @return : {@link R}
* @author : YongEn
* @date : 2022/2/16
*/
abstract R paramParse(S s);
/**
* desc: 执行处理
*
* @param r 解析参数
* @return :
* @author : YongEn
* @date : 2022/2/16
*/
abstract void doProcess(R r);
}
package com.gic.haoban.manage.service.mq.processor;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.gic.api.base.commons.JSONResponse;
import com.gic.commons.util.EntityUtil;
import com.gic.haoban.manage.api.dto.ExternalUserDTO;
import com.gic.haoban.manage.api.dto.MemberUnionidRelatedDTO;
import com.gic.haoban.manage.api.dto.StaffClerkRelationDTO;
import com.gic.haoban.manage.api.service.MemberUnionidRelatedApiService;
import com.gic.haoban.manage.service.config.Config;
import com.gic.haoban.manage.service.entity.*;
import com.gic.haoban.manage.service.exception.WxApiLimitException;
import com.gic.haoban.manage.service.pojo.ExternalUserPojo;
import com.gic.haoban.manage.service.pojo.bo.MemberUnionRelatedBO;
import com.gic.haoban.manage.service.service.*;
import com.gic.haoban.manage.service.util.EmojiFilterUtil;
import com.gic.wechat.api.dto.qywx.QywxExternalMessageDTO;
import com.gic.wechat.api.dto.qywx.QywxMessageMaterialDTO;
import com.gic.wechat.api.dto.qywx.QywxMiniprogramMaterialDTO;
import com.gic.wechat.api.enums.QywxMediaTypeEnum;
import com.gic.wechat.api.service.qywx.QywxSuiteApiService;
import com.gic.wechat.api.service.qywx.QywxUserApiService;
import com.google.common.collect.Lists;
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.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* desc:添加微信好友关系消息消费处理器
* 逻辑来源:
* @see MemberUnionidRelatedApiService#addMemberUnionidRelatedNew(com.gic.haoban.manage.api.dto.MemberUnionidRelatedDTO)
* @author: YongEn
* @date: 2022/2/16
**/
@Component
public class AddMemberUnionRelateConsumerProcessor extends AbstractConsumerProcessor<String, MemberUnionRelatedBO> {
private static final Logger logger = LoggerFactory.getLogger(AddMemberUnionRelateConsumerProcessor.class);
@Autowired
private QywxUserApiService qywxUserApiService;
@Autowired
private QywxSuiteApiService qywxSuiteApiService;
@Autowired
private Config config;
@Autowired
private MemberUnionRelatedService memberUnionRelatedService;
@Autowired
private StaffClerkRelationService staffClerkRelationService;
@Autowired
private ClerkMainStoreRelatedService clerkMainStoreRelatedService;
@Autowired
private WxEnterpriseRelatedService wxEnterpriseRelatedService;
@Autowired
private ExternalClerkRelatedService externalClerkRelatedService;
@Autowired
private StaffService staffService;
@Autowired
private MiniprogramSettingService miniprogramSettingService;
@Override
MemberUnionRelatedBO paramParse(String s) {
return JSON.parseObject(s, MemberUnionRelatedBO.class);
}
@Override
void doProcess(MemberUnionRelatedBO bo) {
String staffId = bo.getStaffId();
String wxEnterpriseId = bo.getWxEnterpriseId();
String externalUserid = bo.getExternalUserid();
String wxUserId = bo.getWxUserId();
MemberUnionidRelatedDTO dto = getAndMergeMemberUnion(bo);
if (Objects.isNull(dto)) {
logger.info("新增外部联系人, 自建与第三方均为空");
return;
}
MemberUnionidRelatedDTO exsitDTO = memberUnionRelatedService.getByParams(wxUserId, wxEnterpriseId, dto.getExternalName(), dto.getAddCreateTime());
String memberUnionidRelatedId;
if (Objects.isNull(exsitDTO)) {
// 创建memberUnion 临时表关联
memberUnionidRelatedId = memberUnionRelatedService.addMemberUnionidRelated(dto);
} else {
memberUnionidRelatedId = exsitDTO.getMemberUnionidRelatedId();
}
// 创建导购外部联系人导购
TabHaobanClerkMainStoreRelated mainStoreRelated = clerkMainStoreRelatedService.getMainStoreByStaffId(staffId, wxEnterpriseId);
if (mainStoreRelated == null) {
logger.info("【新增外部联系人】主门店为空:{}", staffId);
return;
}
StaffClerkRelationDTO staffClerkRelationDTO = staffClerkRelationService.getOneBindByStoreId(staffId, mainStoreRelated.getStoreId());
if (staffClerkRelationDTO == null) {
logger.info("【新增外部联系人】导购和clerk关联为空");
return;
}
String enterpriseId = staffClerkRelationDTO.getEnterpriseId();
TabHaobanWxEnterpriseRelated wxEnterpriseRelated = wxEnterpriseRelatedService.getByEnterpriseId(wxEnterpriseId, enterpriseId);
if (wxEnterpriseRelated == null) {
logger.info("没有存在企业关联:{},{}", staffClerkRelationDTO.getWxEnterpriseId(), enterpriseId);
return;
}
TabMiniprogramSetting miniprogramSetting = miniprogramSettingService.getMiniprogramSetting(wxEnterpriseId, enterpriseId);
if (null == miniprogramSetting) {
logger.info("需要配置小程序配置:wxEnterpriseId:{},enterpriseId:{}", wxEnterpriseId, enterpriseId);
return;
}
List<TabHaobanExternalClerkRelated> externalClerkRelateds = externalClerkRelatedService.listByExTernalUseridAndWxUserIdAllStatus(wxEnterpriseId, dto.getExternalUserid(), dto.getWxUserId());
if (CollectionUtils.isEmpty(externalClerkRelateds)){
logger.info("已经存在好友关系");
return;
}
String relationKey = SecureUtil.md5(staffId + externalUserid);
logger.info("新增TabHaobanExternalClerkRelated");
TabHaobanExternalClerkRelated related = new TabHaobanExternalClerkRelated();
related.setAddCreateTime(dto.getAddCreateTime());
related.setClerkId(null);
related.setEnterpriseId(null);
related.setExternalName(dto.getExternalName());
related.setExternalUserId(externalUserid);
related.setStaffId(staffId);
related.setHeadUrl(dto.getAvatar());
related.setMemberUnionidRelatedId(memberUnionidRelatedId);
related.setStoreId(staffClerkRelationDTO.getStoreId());
related.setRelationKey(relationKey);
related.setUnionid(null);
related.setWxEnterpriseId(wxEnterpriseId);
related.setWxUserId(wxUserId);
related.setMemberId(null);
externalClerkRelatedService.insert(related);
// 发送群发消息
JSONResponse jsonResponse = sendMessage(bo, relationKey, miniprogramSetting);
logger.info("存量会员群发执行结果:{}", JSON.toJSONString(jsonResponse));
}
private JSONResponse sendMessage(MemberUnionRelatedBO bo, String relationKey, TabMiniprogramSetting miniprogramSetting) {
String wxUserId = bo.getWxUserId();
QywxExternalMessageDTO dto = new QywxExternalMessageDTO();
// 文本内容
dto.setChatType("single");
dto.setContent(bo.getContent());
// sender
if (bo.getCorpid().length() > 20) {
TabHaobanStaff tabHaobanStaff = staffService.selectByUserIdAndEnterpriseId(wxUserId, bo.getWxEnterpriseId());
if (tabHaobanStaff == null) {
JSONResponse jp = new JSONResponse();
jp.setErrorCode(-1);
jp.setErrorMessage("员工未查询到,群发创建失败,userId:" + wxUserId);
return jp;
}
dto.setSenderUserId(tabHaobanStaff.getWxOpenUseId());
} else {
dto.setSenderUserId(wxUserId);
}
// 外部联系人id
dto.setExternalUserid(Lists.newArrayList(bo.getExternalUserid()));
List<QywxMessageMaterialDTO> messageMaterialList = new ArrayList<>(1);
QywxMiniprogramMaterialDTO miniprogramMaterialDTO = new QywxMiniprogramMaterialDTO();
miniprogramMaterialDTO.setTitle(miniprogramSetting.getTitle());
miniprogramMaterialDTO.setPicMediaId(miniprogramSetting.getMediaId());
miniprogramMaterialDTO.setAppid(miniprogramSetting.getAppId());
miniprogramMaterialDTO.setPage(config.getMemberOpenPage() + relationKey);
QywxMessageMaterialDTO materialDTO = new QywxMessageMaterialDTO();
materialDTO.setMsgType(QywxMediaTypeEnum.MINIPROGRAM.getName());
materialDTO.setMiniprogram(miniprogramMaterialDTO);
messageMaterialList.add(materialDTO);
dto.setAttachments(messageMaterialList);
// 创建企业群发
return qywxSuiteApiService.sendExternalMessage(bo.getCorpid(), config.getSuiteId(), dto);
}
private MemberUnionidRelatedDTO getAndMergeMemberUnion(MemberUnionRelatedBO bo) {
// 查询自建
ExternalUserDTO selfExternalUserDTO = getCorpSelfExternalUseridInfo(
bo.getWxEnterpriseId(),
bo.getWxUserId(),
bo.getExternalUserid(),
bo.getSecret(),
bo.getCorpid()
);
// 查询第三方
ExternalUserDTO thirdExternalUserDTO = getExternalUseridInfo(
bo.getWxEnterpriseId(),
bo.getWxUserId(),
bo.getExternalUserid(),
bo.getCorpid()
);
if (Objects.isNull(selfExternalUserDTO) && Objects.isNull(thirdExternalUserDTO)) {
logger.info("新增外部联系人, 自建与第三方均为空");
return null;
}
MemberUnionidRelatedDTO dto = EntityUtil.changeEntityNew(MemberUnionidRelatedDTO.class, bo);
// 合并数据
dto.setExternalName(EmojiFilterUtil.removeAllEmoji(
Objects.nonNull(selfExternalUserDTO) ? selfExternalUserDTO.getName() : thirdExternalUserDTO.getName()
));
dto.setAddCreateTime(
Objects.nonNull(selfExternalUserDTO) ? selfExternalUserDTO.getAddCreateTime() : thirdExternalUserDTO.getAddCreateTime()
);
dto.setAvatar(
Objects.nonNull(selfExternalUserDTO) ? selfExternalUserDTO.getAvatar() : thirdExternalUserDTO.getAvatar()
);
dto.setUnionid(
Objects.nonNull(selfExternalUserDTO) ? selfExternalUserDTO.getName() : null
);
dto.setSelfExternalUserid(
Objects.nonNull(selfExternalUserDTO) ? selfExternalUserDTO.getExternalUserId() : null
);
dto.setExternalUserid(
Objects.nonNull(thirdExternalUserDTO) ? thirdExternalUserDTO.getExternalUserId() : null
);
return dto;
}
public ExternalUserDTO getCorpSelfExternalUseridInfo(String wxEnterpriseId, String wxUserId, String externalUserId, String secret, String corpId) {
String unionIdJson = qywxUserApiService.getCorpSelfExternalUseridInfo(corpId, secret, externalUserId);
if (StringUtils.isBlank(unionIdJson)) {
logger.info("好友不存在");
return null;
} else if ("1".equals(unionIdJson)) {
logger.info("接口调用被限制");
throw new WxApiLimitException("getCorpSelfExternalUseridInfo接口调用被限制");
}
ExternalUserPojo pojo = getExternalUserPojo(unionIdJson, wxUserId, wxEnterpriseId);
return EntityUtil.changeEntityByJSON(ExternalUserDTO.class, pojo);
}
public ExternalUserDTO getExternalUseridInfo(String wxEnterpriseId, String wxUserId, String externalUserId, String corpId) {
String uJ = qywxUserApiService.getExternalUseridInfo(corpId, config.getWxSuiteid(), externalUserId);
if (StringUtils.isBlank(uJ)) {
logger.info("好友不存在");
return null;
} else if ("1".equals(uJ)) {
logger.info("限制次数");
throw new WxApiLimitException("getExternalUseridInfo接口次数限制");
}
String name = "";
String createTime = "";
String avatar = "";
Integer friendType = 1;
if (StringUtils.isNotBlank(uJ)) {
JSONObject jo = JSON.parseObject(uJ);
String external_contact = jo.getString("external_contact");
String uj_follow_user = jo.getString("follow_user");
JSONObject jt = null;
if (StringUtils.isNotBlank(external_contact)) {
jt = JSON.parseObject(external_contact);
name = EmojiFilterUtil.filterEmojiLast(jt.getString("name"), true);
if (StringUtils.isBlank(name)) {
name = "--";
}
friendType = jt.getInteger("type");
avatar = jt.getString("avatar");
}
if (StringUtils.isNotBlank(uj_follow_user)) {
JSONArray j = JSON.parseArray(uj_follow_user);
String uj_userId = "";
for (Object object : j) {
String followJson = JSON.toJSONString(object);
JSONObject follow = JSON.parseObject(followJson);
uj_userId = follow.getString("userid");
if (uj_userId.equals(wxUserId)) {
if (jt != null) {
externalUserId = jt.getString("external_userid");
createTime = follow.getString("createtime");
break;
}
}
}
}
}
ExternalUserPojo pojo = new ExternalUserPojo();
pojo.setExternalUserId(externalUserId);
pojo.setName(name);
pojo.setAddCreateTime(createTime);
pojo.setWxEnterpriseId(wxEnterpriseId);
pojo.setAvatar(avatar);
pojo.setFriendType(friendType);
return EntityUtil.changeEntityByJSON(ExternalUserDTO.class, pojo);
}
private ExternalUserPojo getExternalUserPojo(String unionIdJson, String userId1, String wxEnterpriseId) {
ExternalUserPojo pojo = new ExternalUserPojo();
String unionId = "";
String follow_user = "";
String createTime = "";
String userId = "";
String avatar = "";
String relaName = "";
String externalUserId = "";
if (StringUtils.isNotBlank(unionIdJson)) {
JSONObject jo = JSON.parseObject(unionIdJson);
String external_contact = jo.getString("external_contact");
if (StringUtils.isNotBlank(external_contact)) {
JSONObject jt = JSON.parseObject(external_contact);
unionId = jt.getString("unionid");
relaName = EmojiFilterUtil.filterEmojiLast(jt.getString("name"), true);
if (StringUtils.isBlank(relaName)) {
relaName = "--";
}
avatar = jt.getString("avatar");
externalUserId = jt.getString("external_userid");
}
follow_user = jo.getString("follow_user");
if (StringUtils.isNotBlank(follow_user)) {
JSONArray j = JSON.parseArray(follow_user);
for (Object object : j) {
String followJson = JSON.toJSONString(object);
JSONObject follow = JSON.parseObject(followJson);
userId = follow.getString("userid");
if (userId.equals(userId1)) {
createTime = follow.getString("createtime");
}
}
}
}
pojo.setAddCreateTime(createTime);
pojo.setAvatar(avatar);
pojo.setName(relaName);
pojo.setUnionId(unionId);
pojo.setExternalUserId(externalUserId);
pojo.setWxEnterpriseId(wxEnterpriseId);
return pojo;
}
}
package com.gic.haoban.manage.service.pojo.bo;
import java.io.Serializable;
/**
* desc:微信好友关联bo
*
* @author: YongEn
* @date: 2022/2/16
**/
public class MemberUnionRelatedBO implements Serializable {
private static final long serialVersionUID = 5596803679651418366L;
private String corpid;
private String wxEnterpriseId;
private String externalUserid;
private String wxUserId;
private String secret;
private String staffId;
private String content;
public String getCorpid() {
return corpid;
}
public void setCorpid(String corpid) {
this.corpid = corpid;
}
public String getWxEnterpriseId() {
return wxEnterpriseId;
}
public void setWxEnterpriseId(String wxEnterpriseId) {
this.wxEnterpriseId = wxEnterpriseId;
}
public String getExternalUserid() {
return externalUserid;
}
public void setExternalUserid(String externalUserid) {
this.externalUserid = externalUserid;
}
public String getWxUserId() {
return wxUserId;
}
public void setWxUserId(String wxUserId) {
this.wxUserId = wxUserId;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
public String getStaffId() {
return staffId;
}
public void setStaffId(String staffId) {
this.staffId = staffId;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
......@@ -99,6 +99,9 @@
<dubbo:service interface="com.gic.haoban.manage.api.service.out.WelcomeApiService"
ref="welcomeApiServiceImpl" timeout="10000"/>
<dubbo:service interface="com.gic.haoban.manage.api.service.mq.MemberUnionRelateConsumer"
ref="memberUnionRelateConsumerImpl" timeout="10000"/>
<dubbo:reference interface="com.gic.enterprise.api.service.DepartmentService" id="gicDepartmentService"/>
<dubbo:reference interface="com.gic.wechat.api.service.qywx.QywxDepartmentApiService"
id="qywxDepartmentApiService"/>
......
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