Commit eff15098 by 杨涛

直播课表基于微信群场景优化

parent 49bdfdbd
......@@ -10,7 +10,6 @@ import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
......@@ -32,7 +31,6 @@ import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan("com.pcloud")
@EnableEurekaClient
@EnableFeignClients("com.pcloud")
......@@ -221,4 +219,15 @@ public class BookApplication {
public Binding wxGroupUserBindBind(){
return RabbitMQFactory.bindingExchange(wxGroupUserBindQueue(), MQTopicProducer.WXGROUP_USER_BIND);
}
@Bean
public Queue wxLiveBroadcastReminderBindQueue(){
return RabbitMQFactory.queueBuilder(MQTopicConumer.WX_LIVE_BROADCAST_REMINDER);
}
@Bean
public Binding wxLiveBroadcastReminderBindBind(){
return RabbitMQFactory.bindingExchange(wxLiveBroadcastReminderBindQueue(), MQTopicProducer.WX_LIVE_BROADCAST_REMINDER);
}
}
package com.pcloud.book.consumer.live;
import com.google.common.collect.Lists;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.dto.ResponseDto;
import com.pcloud.common.permission.PermissionException;
import com.pcloud.common.utils.ResponseHandleUtil;
import com.pcloud.liveapp.live.dto.CourseListDto;
import com.pcloud.liveapp.live.service.LiveCourseService;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import java.util.List;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class LiveCons {
@Resource
private LiveCourseService liveCourseService;
@ParamLog("[获取直播课表]")
public List<CourseListDto> getList4BroadcastReminder(Long serverId, String serverType) {
try {
ResponseEntity<ResponseDto<List<CourseListDto>>> reminder = liveCourseService.getList4BroadcastReminder(serverId, serverType);
log.info("[获取直播课表] appId:{}, serverType:{}, reminder:{}", serverId, serverType, reminder);
List<CourseListDto> courseListDtos = ResponseHandleUtil.parseList(reminder, CourseListDto.class);
return courseListDtos;
} catch (PermissionException e) {
log.error("[获取直播课表] error appId:{}, serverType:{}, e:{}", serverId, serverType, e);
}
return Lists.newArrayList();
}
}
......@@ -3,6 +3,7 @@ package com.pcloud.book.group.biz;
import com.pcloud.book.group.dto.GroupAndUserNumberDTO;
import com.pcloud.book.group.dto.GroupQrcodeInfo4Advertising;
import com.pcloud.book.group.dto.GroupQrcodeInfoDTO;
import com.pcloud.book.group.dto.GroupQrcodeServerDTO;
import com.pcloud.book.group.entity.GroupQrcode;
import com.pcloud.book.group.vo.ClassifyQrcodeVO;
import com.pcloud.book.group.vo.GroupQrcodeBaseInfoVO;
......@@ -23,6 +24,12 @@ import java.util.Map;
public interface GroupQrcodeBiz {
/**
* 根据Server获取相关的群id
* @param serverId
* @return
*/
List<GroupQrcodeServerDTO> getWxGroupIdByServerId(List<Long> serverIds);
/**
* 更新群人数
*/
Integer updateGroupCount(String wxGroupId, Integer num);
......
package com.pcloud.book.group.biz.impl;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.pcloud.book.advertising.biz.AdvertisingSpaceBiz;
......@@ -23,6 +24,7 @@ import com.pcloud.book.group.dto.GroupNameAndMaxSeqDTO;
import com.pcloud.book.group.dto.GroupQrcodeDTO;
import com.pcloud.book.group.dto.GroupQrcodeInfo4Advertising;
import com.pcloud.book.group.dto.GroupQrcodeInfoDTO;
import com.pcloud.book.group.dto.GroupQrcodeServerDTO;
import com.pcloud.book.group.dto.PushAddUserMessageDTO;
import com.pcloud.book.group.dto.QrcodeNameAndProIdDTO;
import com.pcloud.book.group.dto.WeixinQrcodeDTO;
......@@ -117,6 +119,14 @@ public class GroupQrcodeBizImpl implements GroupQrcodeBiz {
// private static final AtomicBoolean IS_START = new AtomicBoolean(false);
@Override
public List<GroupQrcodeServerDTO> getWxGroupIdByServerId(List<Long> serverIds) {
if (CollectionUtils.isEmpty(serverIds)) {
return Lists.newArrayList();
}
return groupQrcodeDao.getWxGroupIdByServerId(serverIds);
}
/**
* 处理群人数线程池
*/
......
......@@ -2,7 +2,14 @@ package com.pcloud.book.group.dao;
import com.pcloud.book.advertising.dto.GroupTagDTO;
import com.pcloud.book.advertising.dto.WeixinClassifyInfoDTO;
import com.pcloud.book.group.dto.*;
import com.pcloud.book.group.dto.ChangeGroupNameDTO;
import com.pcloud.book.group.dto.GroupAndUserNumberDTO;
import com.pcloud.book.group.dto.GroupQrcodeDTO;
import com.pcloud.book.group.dto.GroupQrcodeFoAdDTO;
import com.pcloud.book.group.dto.GroupQrcodeInfo4Advertising;
import com.pcloud.book.group.dto.GroupQrcodeInfoDTO;
import com.pcloud.book.group.dto.GroupQrcodeServerDTO;
import com.pcloud.book.group.dto.UpdateQrDTO;
import com.pcloud.book.group.entity.GroupQrcode;
import com.pcloud.book.group.vo.ClassifyQrcodeVO;
import com.pcloud.book.group.vo.GroupQrcodeBaseInfoVO;
......@@ -18,6 +25,8 @@ import java.util.Map;
*/
public interface GroupQrcodeDao extends BaseDao<GroupQrcode> {
List<GroupQrcodeServerDTO> getWxGroupIdByServerId(List<Long> serverId);
Integer updateGroupCount(String wxGroupId, Integer num);
void updateGroupQrcode(Long groupQrcodeId, String qrcodeUrl, Long userId);
......
......@@ -5,7 +5,14 @@ import com.google.common.collect.Maps;
import com.pcloud.book.advertising.dto.GroupTagDTO;
import com.pcloud.book.advertising.dto.WeixinClassifyInfoDTO;
import com.pcloud.book.group.dao.GroupQrcodeDao;
import com.pcloud.book.group.dto.*;
import com.pcloud.book.group.dto.ChangeGroupNameDTO;
import com.pcloud.book.group.dto.GroupAndUserNumberDTO;
import com.pcloud.book.group.dto.GroupQrcodeDTO;
import com.pcloud.book.group.dto.GroupQrcodeFoAdDTO;
import com.pcloud.book.group.dto.GroupQrcodeInfo4Advertising;
import com.pcloud.book.group.dto.GroupQrcodeInfoDTO;
import com.pcloud.book.group.dto.GroupQrcodeServerDTO;
import com.pcloud.book.group.dto.UpdateQrDTO;
import com.pcloud.book.group.entity.GroupQrcode;
import com.pcloud.book.group.vo.ClassifyQrcodeVO;
import com.pcloud.book.group.vo.GroupQrcodeBaseInfoVO;
......@@ -26,6 +33,11 @@ import java.util.Map;
public class GroupQrcodeDaoImpl extends BaseDaoImpl<GroupQrcode> implements GroupQrcodeDao {
@Override
public List<GroupQrcodeServerDTO> getWxGroupIdByServerId(List<Long> list) {
return this.getSqlSession().selectList(this.getStatement("getWxGroupIdByServerId"), list);
}
@Override
public Integer updateGroupCount(String wxGroupId, Integer num) {
final Map<String, Object> map = Maps.newHashMap();
map.put("weixinGroupId", wxGroupId);
......
package com.pcloud.book.group.dto;
import java.io.Serializable;
import lombok.Data;
@Data
public class GroupQrcodeServerDTO implements Serializable {
/**
* 微信群id @chatroom
*/
private String wxGroupId;
/**
* 应用连接
*/
private String linkUrl;
/**
* 渠道id
*/
private Long channelId;
/**
* 社群书id
*/
private Long bookGroupId;
/**
* 所属分类id
*/
private Long classifyId;
/**
* 应用/作品ID
*/
private Long serveId;
/**
* APP or PRODUCT
*/
private String serveType;
/**
* book_group_qrcode表主键
*/
private Long groupQrcodeId;
}
......@@ -9,6 +9,7 @@ import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.book.biz.BookKeywordWarehouseBiz;
import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.live.LiveCons;
import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.consumer.wechatgroup.WechatGroupConsr;
import com.pcloud.book.group.biz.BookGroupBiz;
......@@ -64,6 +65,7 @@ import com.pcloud.common.utils.bean.ResponesUtils;
import com.pcloud.common.utils.cache.redis.JedisClusterUtils;
import com.pcloud.common.utils.httpclient.UrlUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.liveapp.live.dto.CourseListDto;
import com.pcloud.resourcecenter.product.dto.ProductDto;
import com.pcloud.resourcecenter.product.dto.ProductTypeDto;
import com.pcloud.wechatgroup.group.dto.RobotReplyDTO;
......@@ -134,6 +136,8 @@ public class BookKeywordBizImpl implements BookKeywordBiz {
private BookGroupBiz bookGroupBiz;
@Autowired
private GroupQrcodeBiz groupQrcodeBiz;
@Autowired
private LiveCons liveCons;
@Override
@ParamLog("新增关键词")
......@@ -521,9 +525,25 @@ public class BookKeywordBizImpl implements BookKeywordBiz {
if (isApp || isLink) {
AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(dto.getChannelId());
String linkUrl = SendWeixinRequestTools.splitUrlNew(accountSettingDto, replyKeywordDTO.getLinkUrl(), dto.getBookGroupId(), dto.getClassifyId(), qrcodeId);
String shortUrl4Own = UrlUtils.getShortUrl4Own(linkUrl);
replyKeywordDTO.setLinkUrl(linkUrl);
if (replyKeywordDTO.getLinkUrl().contains("/live/")) {
// 获取直播课信息
List<CourseListDto> list4BroadcastReminder = liveCons.getList4BroadcastReminder(replyKeywordDTO.getServeId(), replyKeywordDTO.getServeType());
replyKeywordDTO.setReplyType(ReplyTypeEnum.TEXT.value);
StringBuilder sb = new StringBuilder("【");
sb.append(CollectionUtils.isEmpty(list4BroadcastReminder) ? replyKeywordDTO.getDescription() : list4BroadcastReminder.get(0).getTableTitle())
.append("】近期将开播的课程\n");
if (!CollectionUtils.isEmpty(list4BroadcastReminder)) {
for (CourseListDto listDto : list4BroadcastReminder) {
sb.append("第").append(listDto.getSequenceNum()).append("课:").append(listDto.getTitle()).append("\n");
}
}
sb.append("查看更多课程表链接:").append(shortUrl4Own);
replyKeywordDTO.setContent(sb.toString());
}
if (!StringUtil.isEmpty(linkUrl)) {
replyKeywordDTO.setShortLinkUrl(UrlUtils.getShortUrl4Own(linkUrl));
replyKeywordDTO.setShortLinkUrl(shortUrl4Own);
}
}
String redisContent = JedisClusterUtils.getJson("BOOK:KEYWORD:" + userWxId + "-" + replyKeywordDTO.getKeywordId(), String.class);
......@@ -625,7 +645,24 @@ public class BookKeywordBizImpl implements BookKeywordBiz {
if (isApp || isLink) {
AccountSettingDto accountSettingDto = qrcodeSceneConsr.getWechatInfo(classifyQrcodeInfo.getChannelId());
String linkUrl = SendWeixinRequestTools.splitUrlNew(accountSettingDto, replyKeywordDTO.getLinkUrl(), classifyQrcodeInfo.getBookGroupId(), classifyQrcodeInfo.getClassifyId(), classifyQrcodeInfo.getGroupQrcodeId());
String shortUrl4Own = UrlUtils.getShortUrl4Own(linkUrl);
if (replyKeywordDTO.getLinkUrl().contains("live/C")) {
// 获取直播课信息
List<CourseListDto> list4BroadcastReminder = liveCons.getList4BroadcastReminder(replyKeywordDTO.getServeId(), replyKeywordDTO.getServeType());
replyKeywordDTO.setReplyType(ReplyTypeEnum.TEXT.value);
StringBuilder sb = new StringBuilder("【");
sb.append(CollectionUtils.isEmpty(list4BroadcastReminder) ? replyKeywordDTO.getDescription() : list4BroadcastReminder.get(0).getTableTitle())
.append("】近期将开播的课程\n");
if (!CollectionUtils.isEmpty(list4BroadcastReminder)) {
for (CourseListDto listDto : list4BroadcastReminder) {
sb.append("第").append(listDto.getSequenceNum()).append("课:").append(listDto.getTitle()).append("\n");
}
}
sb.append("查看更多课程表链接:").append(shortUrl4Own);
replyKeywordDTO.setContent(sb.toString());
}
replyKeywordDTO.setLinkUrl(linkUrl);
replyKeywordDTO.setShortLinkUrl(shortUrl4Own);
}
String redisContent = JedisClusterUtils.getJson("BOOK:KEYWORD:" + weixinGroupId + "-" + replyKeywordDTO.getKeywordId(), String.class);
// 同一群10秒内不回复同一关键词,60s不回复同一关键词 20190916降低消息量方案之一
......
......@@ -80,4 +80,9 @@ public class MQTopicConumer {
*/
public static final String CONSUMER_WXGROUP_USER_BIND = PREFIX + MQTopicProducer.WXGROUP_USER_BIND;
/**
* 直播开播提醒
*/
public static final String WX_LIVE_BROADCAST_REMINDER = PREFIX + MQTopicProducer.WX_LIVE_BROADCAST_REMINDER;
}
package com.pcloud.book.mq.topic;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.group.biz.GroupQrcodeBiz;
import com.pcloud.book.group.biz.WeixinQrcodeBiz;
import com.pcloud.book.group.dto.BookWxQrcodeDTO;
import com.pcloud.book.group.dto.GroupQrcodeServerDTO;
import com.pcloud.book.group.tools.SendWeixinRequestTools;
import com.pcloud.book.mq.config.MQTopicConumer;
import com.pcloud.channelcenter.wechat.dto.AccountSettingDto;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.utils.httpclient.UrlUtils;
import com.pcloud.liveapp.live.dto.LiveCourseDetailInfoDto;
import com.pcloud.liveapp.live.dto.TableDetailDto;
import com.sdk.wxgroup.SendTextMessageVO;
import com.sdk.wxgroup.WxGroupSDK;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeSet;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
@RabbitListener(queues = MQTopicConumer.WX_LIVE_BROADCAST_REMINDER)
public class WxLiveBroadcastReminderListener {
@Resource
private GroupQrcodeBiz groupQrcodeBiz;
@Resource
private QrcodeSceneConsr qrcodeSceneConsr;
@Autowired
private WeixinQrcodeBiz weixinQrcodeBiz;
/**
* 接收微信用户进群消息
*/
@ParamLog("直播开播提醒")
@RabbitHandler
public void onMessage(LiveCourseDetailInfoDto liveCourse) throws BizException {
if (Objects.isNull(liveCourse) || CollectionUtils.isEmpty(liveCourse.getTableDetailDtos())) {
return;
}
Map<Long, Long> collect = liveCourse.getTableDetailDtos().stream().collect(Collectors.toMap(TableDetailDto::getOriginId, TableDetailDto::getTableId));
final List<GroupQrcodeServerDTO> wxGroups = groupQrcodeBiz.getWxGroupIdByServerId(Lists.newArrayList(collect.keySet()));
log.info("[直播开播提醒] : liveCourse :{} wxGroups:{}", liveCourse, wxGroups);
if (CollectionUtils.isEmpty(wxGroups)) {
return;
}
final Map<Long, AccountSettingDto> accountMap = Maps.newHashMap();
List<String> wxGroupIds = wxGroups.stream().map(GroupQrcodeServerDTO::getWxGroupId).collect(Collectors.toList());
Map<String, BookWxQrcodeDTO> groupVersion = weixinQrcodeBiz.getGroupVersion(wxGroupIds);
final List<GroupQrcodeServerDTO> wxGroups2 = wxGroups.stream().collect(
Collectors. collectingAndThen(
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(GroupQrcodeServerDTO::getWxGroupId))), ArrayList::new)
);
for (GroupQrcodeServerDTO dto : wxGroups2) {
// 避免重复挂服务调用性能损耗
AccountSettingDto accountSettingDto = accountMap.get(dto.getChannelId());
if (Objects.isNull(accountSettingDto)) {
accountSettingDto = qrcodeSceneConsr.getWechatInfo(dto.getChannelId());
accountMap.put(dto.getChannelId(), accountSettingDto);
}
String linkUrl = SendWeixinRequestTools.splitUrlNew(accountSettingDto, dto.getLinkUrl(), dto.getBookGroupId(), dto.getClassifyId(), dto.getGroupQrcodeId());
// 定位到具体课程
String liveInfo = linkUrl.replace("liveinfo?", "lesson/" + liveCourse.getLessonId() + "?tableId=" + collect.get(dto.getServeId()) + "&");
String shortUrl4Own = UrlUtils.getShortUrl4Own(liveInfo);
SendTextMessageVO vo = new SendTextMessageVO();
vo.setContent("【" + liveCourse.getTitle() + "】即将开播啦,感兴趣的同学们可以开始进入啦。猛戳直播链接:" + shortUrl4Own);
vo.setWxGroupId(dto.getWxGroupId());
// 负载均衡会根据群获取该群活跃小号,所以传什么都不重要,写死为“我为你笑着”
vo.setAltId(Optional.ofNullable(groupVersion.get(dto.getWxGroupId())).orElse(new BookWxQrcodeDTO()).getRobotWxId());
vo.setIp(Optional.ofNullable(groupVersion.get(dto.getWxGroupId())).orElse(new BookWxQrcodeDTO()).getWechatGroupIp());
WxGroupSDK.sendTextMessage(vo);
}
}
}
......@@ -60,6 +60,31 @@
order by a.create_time desc
</select>
<select id="getWxGroupIdByServerId" parameterType="long" resultType="com.pcloud.book.group.dto.GroupQrcodeServerDTO">
SELECT
a.weixin_group_id AS wxGroupId,
a.id AS groupQrcodeId,
b.channel_id AS channelId,
b.book_group_id AS bookGroupId,
b.id AS classifyId,
d.link_url AS linkUrl,
d.serve_id AS serveId,
d.serve_type AS serveType
FROM
book_group_qrcode a
LEFT JOIN book_group_classify b ON a.classify_id = b.id
LEFT JOIN book_keyword c ON b.book_group_id = c.book_group_id
LEFT JOIN keyword d ON c.keyword_id = d.id
WHERE
d.serve_id in
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
AND a.is_delete = 0
AND b.is_delete = 0
AND c.is_delete = 0
AND d.is_delete = 0
</select>
<insert id="insert" parameterType="GroupQrcode" useGeneratedKeys="true"
keyProperty="id">
......
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