Commit c9324899 by 田超

Merge branch 'feature/1004072' into 'master'

feat: [1004072] 小睿资源广场

See merge request rays/pcloud-book!1139
parents dbf9ab07 46ce5d37
...@@ -99,4 +99,24 @@ public interface AppletService { ...@@ -99,4 +99,24 @@ public interface AppletService {
ResponseEntity<ResponseDto<Map<Long, AppletAppOrProductDTO>>> getAppOrProductBrowseCount(@RequestParam("recordType") Integer recordType, ResponseEntity<ResponseDto<Map<Long, AppletAppOrProductDTO>>> getAppOrProductBrowseCount(@RequestParam("recordType") Integer recordType,
@RequestBody List<Long> serveIds); @RequestBody List<Long> serveIds);
@ApiOperation("mySql 足迹数据同步到 clickHouse")
@GetMapping("fixAppletRecordDataSync4CH")
void fixAppletRecordDataSync4CH(@RequestParam(value = "createDate", required = false) String createDate);
@ApiOperation("并更新缓存")
@GetMapping("updateAggrStatisCache")
void updateAggrStatisCache();
@ApiOperation("mySql 足迹数据同步到 clickHouse,并更新缓存")
@GetMapping("syncDataAndUpdateCache")
void syncDataAndUpdateCache(@RequestParam(value = "createDate", required = false) String createDate);
@ApiOperation("更新 applet_record.type_code 旧数据")
@GetMapping("handleAppletRecordTypeCode")
ResponseEntity<ResponseDto<Object>> handleAppletRecordTypeCode(@RequestParam(value = "lastAppletRecordId", required = false) Long lastAppletRecordId);
@ApiOperation("停止更新 applet_record.type_code 旧数据")
@GetMapping("stopHandleAppletRecordTypeCode")
void stopHandleAppletRecordTypeCode();
} }
...@@ -230,6 +230,13 @@ ...@@ -230,6 +230,13 @@
<version>${wxgroup-sdk.version}</version> <version>${wxgroup-sdk.version}</version>
</dependency> </dependency>
<!-- clickHouse数据库 -->
<dependency>
<groupId>ru.yandex.clickhouse</groupId>
<artifactId>clickhouse-jdbc</artifactId>
<version>0.2.1</version>
</dependency>
<!--ES相关--> <!--ES相关-->
<dependency> <dependency>
<groupId>org.springframework.data</groupId> <groupId>org.springframework.data</groupId>
......
...@@ -41,7 +41,7 @@ import java.util.Map; ...@@ -41,7 +41,7 @@ import java.util.Map;
@PropertySource({"classpath:properties/book.properties", "classpath:public_system.properties"}) @PropertySource({"classpath:properties/book.properties", "classpath:public_system.properties"})
@Configuration @Configuration
@EnableSwagger2 @EnableSwagger2
@MapperScan(basePackages = {"com.pcloud.book.*.mapper"}) @MapperScan(basePackages = {"com.pcloud.book.*.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory")
public class BookApplication { public class BookApplication {
public static void main(String[] args) { public static void main(String[] args) {
......
package com.pcloud.book.applet.biz;
import com.pcloud.common.page.PageBeanNew;
public interface AppletRecordAggrStatisBiz {
PageBeanNew getAggrStatis(Long wechatUserId,String keyword, Integer sourceType, Integer rankType, Integer currentPage, Integer numPerPage);
/**
* mySql 数据同步到 clickHouse
*/
void fixAppletRecordDataSync4CH(String createDate);
/**
* 更新缓存
*/
void updateAggrStatisCache();
/**
* 同步数据并更新缓存
*/
void syncDataAndUpdateCache(String date);
}
...@@ -74,4 +74,10 @@ public interface AppletRecordBiz { ...@@ -74,4 +74,10 @@ public interface AppletRecordBiz {
* @return * @return
*/ */
Map<Long, AppletAppOrProductDTO> getAppOrProductBrowseCount(Integer recordType, List<Long> serveIds); Map<Long, AppletAppOrProductDTO> getAppOrProductBrowseCount(Integer recordType, List<Long> serveIds);
}
\ No newline at end of file void fillAppletRecord(List<AppletRecordDTO> recordList, Integer bookType);
Object handleAppletRecordTypeCode(Long lastAppletRecordId);
void stopHandleAppletRecordTypeCode();
}
package com.pcloud.book.applet.biz.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import com.pcloud.book.applet.biz.AppletRecordAggrStatisBiz;
import com.pcloud.book.applet.biz.AppletRecordBiz;
import com.pcloud.book.applet.biz.ServeCollectBiz;
import com.pcloud.book.applet.contants.AppletConstants;
import com.pcloud.book.applet.dao.AppletRecordDao;
import com.pcloud.book.applet.dto.AppletRecordDTO;
import com.pcloud.book.applet.entity.AppletRecord;
import com.pcloud.book.applet.entity.ServeCollect;
import com.pcloud.book.applet.enums.AppletRankTypeEnum;
import com.pcloud.book.applet.enums.AppletRecordTypeEnum;
import com.pcloud.book.applet.enums.AppletSourceTypeEnum;
import com.pcloud.book.group.dao.WeworkTeacherFriendRecordDao;
import com.pcloud.book.mapper.clickhouse.AppletRecordCHMapper;
import com.pcloud.book.util.common.YesOrNoEnums;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.utils.DateUtils;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.cache.redis.JedisClusterUtils;
import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.readercenter.common.enums.YesOrNoNumEnum;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@Service("appletRecordAggrStatisBiz")
public class AppletRecordAggrStatisBizImpl implements AppletRecordAggrStatisBiz {
private static final Logger LOGGER = LoggerFactory.getLogger(AppletRecordAggrStatisBizImpl.class);
@Autowired
private AppletRecordCHMapper appletRecordCHMapper;
@Autowired
private AppletRecordBiz appletRecordBiz;
@Autowired
private AppletRecordDao appletRecordDao;
@Autowired
private WeworkTeacherFriendRecordDao weworkTeacherFriendRecordDao;
@Autowired
private ServeCollectBiz serveCollectBiz;
@Override
public PageBeanNew getAggrStatis(Long wechatUserId, String keyword, Integer sourceType, Integer rankType, Integer currentPage, Integer numPerPage) {
String cacheKey = MessageFormat.format("{0}_{1}_{2}", AppletConstants.APPLET_RESOURCE_AGGR_STATIS, sourceType, rankType);
List<AppletRecordDTO> aggrStatis = JedisClusterUtils.getJsonList(cacheKey, AppletRecordDTO.class);
if(ListUtils.isEmpty(aggrStatis)){
return new PageBeanNew(currentPage, numPerPage, 0, Lists.newArrayList());
}
if(StringUtils.isNotEmpty(keyword)){
List<AppletRecordDTO> collect = aggrStatis.stream().filter(x -> x.getFromName().contains(keyword)).collect(Collectors.toList());
if(CollectionUtil.isEmpty(collect)){
return new PageBeanNew(currentPage, numPerPage, 0, Lists.newArrayList());
}
List<AppletRecordDTO> list = aggrStatis.stream().filter(x -> x.getFromName().contains(keyword)).skip(currentPage * numPerPage).limit(numPerPage).collect(Collectors.toList());
fillCollect(wechatUserId, list);
return new PageBeanNew(currentPage, numPerPage, collect.size(), list);
} else {
List<AppletRecordDTO> list = aggrStatis.stream().skip(currentPage * numPerPage).limit(numPerPage).collect(Collectors.toList());
fillCollect(wechatUserId, list);
return new PageBeanNew(currentPage, numPerPage, aggrStatis.size(), list);
}
}
@Override
public void syncDataAndUpdateCache(String date){
fixAppletRecordDataSync4CH(date);
updateAggrStatisCache();
}
/**
* 将 clickHouse 的资源排行信息加入到 redis 缓存
*/
@Override
public void updateAggrStatisCache() {
for (AppletSourceTypeEnum sourceType : AppletSourceTypeEnum.values()) {
for (AppletRankTypeEnum rankType : AppletRankTypeEnum.values()) {
String cacheKey = MessageFormat.format("{0}_{1}_{2}", AppletConstants.APPLET_RESOURCE_AGGR_STATIS, sourceType.value, rankType.value);
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("offset", 0);
paramMap.put("limit", 100);
addDateCondition(rankType.value, paramMap);
addTypeCodeCondition(sourceType.value, paramMap);
List<AppletRecordDTO> aggrStatis = null;
// 导师需要在另外表里查询
if(sourceType.value == AppletSourceTypeEnum.ANSWER_1V1.value){
paramMap.put("recordType", AppletRecordTypeEnum.WX_WORK_TEACHER.value);
aggrStatis = weworkTeacherFriendRecordDao.getAggrStatis(paramMap);
} else {
aggrStatis = appletRecordCHMapper.getAggrStatis(paramMap);
}
// 加载其它数据
appletRecordBiz.fillAppletRecord(aggrStatis, YesOrNoNumEnum.NO.getValue());
// 删除部分不存在的数据
aggrStatis = aggrStatis.stream().filter(x->x.getSourceDelete() == 0).collect(Collectors.toList());
// 设置缓存
JedisClusterUtils.setJsonList(cacheKey, aggrStatis, 3600 * 24);
}
}
}
@Override
public void fixAppletRecordDataSync4CH(String createDate) {
if(StringUtil.isEmpty(createDate)){
createDate = DateUtils.getShortDateStr(DateUtils.getDate(-1));
}
// 分批插入的大小
Integer finalBatchSize = 1000;
final List<AppletRecord> result = new LinkedList<>();
appletRecordDao.fixAppletRecordDataSync4CH(createDate, new ResultHandler<AppletRecord>(){
@Override
public void handleResult(ResultContext<? extends AppletRecord> resultContext) {
result.add(resultContext.getResultObject());
if(result.size() == finalBatchSize){
appletRecordCHMapper.batchInsert(result);
LOGGER.info("[AppletRecordAggrStatisBizImpl.fixDataSync4CH] CH数据同步,NUM:{},数据满1000条,插入一次", resultContext.getResultCount());
result.clear();
}
}
});
if(CollUtil.isNotEmpty(result)){
appletRecordCHMapper.batchInsert(result);
}
appletRecordCHMapper.optimize();
LOGGER.info("[AppletRecordAggrStatisBizImpl.fixDataSync4CH] CH数据同步结束");
}
private void addDateCondition(Integer rankType, HashMap<String, Object> paramMap) {
if(rankType == 2){
// 月榜
paramMap.put("beginDate", DateUtils.formatDate(DateUtils.addDay(DateUtils.getDayBegin(), -30)));
paramMap.put("endDate", DateUtils.formatDate(DateUtils.addDay(DateUtils.getDayEnd(), -1)));
}
if(rankType == 3){
// 周榜
paramMap.put("beginDate", DateUtils.getShortDateStr(DateUtils.addDay(DateUtils.getDayBegin(), -7)));
paramMap.put("endDate", DateUtils.getShortDateStr(DateUtils.addDay(DateUtils.getDayEnd(), -1)));
}
}
private void addTypeCodeCondition(Integer sourceType, HashMap<String, Object> paramMap) {
List<Map> recordTypes = Lists.newArrayList();
HashMap<String, Object> recordTypeMap;
switch (sourceType){
case 1:
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.PRODUCT.value);
recordTypeMap.put("typeCodes", Lists.newArrayList("VIDEO_SCHEDULE", "AUDIO", "AUDIO_SCHEDULE", "VIDEO", "SCHEDULE", "TUTORIAL"));
recordTypes.add(recordTypeMap);
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.APP.value);
recordTypeMap.put("typeCodes", Lists.newArrayList("MATCH_LISTEN", "AUDIO", "LISTEN", "VIDEO", "LIVE_TIMETABLE"));
recordTypes.add(recordTypeMap);
paramMap.put("recordTypes", recordTypes);
break;
case 2:
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.NEWS.value);
recordTypes.add(recordTypeMap);
paramMap.put("recordTypes", recordTypes);
break;
case 3:
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.PRODUCT.value);
recordTypeMap.put("typeCodes", Lists.newArrayList("PRETEST", "FORMAT", "LINK", "ARTICLE", "PDF"));
recordTypes.add(recordTypeMap);
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.APP.value);
recordTypeMap.put("typeCodes", Lists.newArrayList("GROUP", "ZSCORE", "BOOKCARD", "ITEM_BANK", "SPECIAL", "RECITE_WORD", "BOOK", "WORD_DICTATION", "ORAL_EVALUATION", "BOOK_CLICK", "STROKE_ORDER"));
recordTypes.add(recordTypeMap);
paramMap.put("recordTypes", recordTypes);
break;
case 4:
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.BOOK_RECOMMEND.value);
recordTypes.add(recordTypeMap);
paramMap.put("recordTypes", recordTypes);
break;
case 5:
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.PRODUCT.value);
recordTypeMap.put("typeCodes", Lists.newArrayList("VIDEO_SCHEDULE", "AUDIO_SCHEDULE", "PDF"));
recordTypes.add(recordTypeMap);
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.APP.value);
recordTypeMap.put("typeCodes", Lists.newArrayList("ANSWER", "TEST_PAPER", "TEACH_RESOURCE", "COURSE_WARE", "PDF"));
recordTypes.add(recordTypeMap);
paramMap.put("recordTypes", recordTypes);
break;
case 6:
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.ADVISER_GROUP.value);
recordTypes.add(recordTypeMap);
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.MODEL_GROUP.value);
recordTypes.add(recordTypeMap);
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.THIRD_GROUP.value);
recordTypes.add(recordTypeMap);
paramMap.put("recordTypes", recordTypes);
break;
case 7:
/* recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.WX_WORK_TEACHER.value);
recordTypes.add(recordTypeMap);
paramMap.put("recordTypes", recordTypes); */
break;
case 8:
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.PRODUCT.value);
recordTypeMap.put("typeCodes", Lists.newArrayList("ATTENDANCE_TASK"));
recordTypes.add(recordTypeMap);
recordTypeMap = new HashMap<>();
recordTypeMap.put("recordType", AppletRecordTypeEnum.APP.value);
recordTypeMap.put("typeCodes", Lists.newArrayList("CLOCK", "WISH", "FLAG", "TEST"));
recordTypes.add(recordTypeMap);
paramMap.put("recordTypes", recordTypes);
break;
}
}
private void fillCollect(Long wechatUserId, List<AppletRecordDTO> list) {
List<ServeCollect> serveCollectList = serveCollectBiz.getList4RightsSettingByWechatUserId(wechatUserId);
if (ListUtils.isEmpty(serveCollectList)) {
return;
}
List<ServeCollect> collect4Product = serveCollectList.stream().filter(e -> Objects.equals(e.getServeType(), AppletRecordTypeEnum.PRODUCT.value)).collect(Collectors.toList());
List<ServeCollect> collect4App = serveCollectList.stream().filter(e -> Objects.equals(e.getServeType(), AppletRecordTypeEnum.APP.value)).collect(Collectors.toList());
Map<Long, ServeCollect> serveCollectMap4Product = new HashMap<>();
Map<Long, ServeCollect> serveCollectMap4App = new HashMap<>();
if (!ListUtils.isEmpty(collect4Product)) {
serveCollectMap4Product = collect4Product.stream().collect(Collectors.toMap(e -> e.getServeId(), a -> a, (k1, k2) -> k1));
}
if (!ListUtils.isEmpty(collect4App)) {
serveCollectMap4App = collect4App.stream().collect(Collectors.toMap(e -> e.getServeId(), a -> a, (k1, k2) -> k1));
}
List<AppletRecordDTO> productOrApps = list.stream().filter(e -> Objects.equals(e.getRecordType(), AppletRecordTypeEnum.PRODUCT.value) ||
Objects.equals(e.getRecordType(), AppletRecordTypeEnum.APP.value)).collect(Collectors.toList());
if (!ListUtils.isEmpty(productOrApps)) {
for (AppletRecordDTO item : productOrApps) {
if (Objects.equals(item.getRecordType(), AppletRecordTypeEnum.PRODUCT.value) && MapUtils.isNotEmpty(serveCollectMap4Product) &&
null != serveCollectMap4Product.get(item.getFromId())) {
item.setIsCollect(YesOrNoEnums.YES.getValue());
} else if (Objects.equals(item.getRecordType(), AppletRecordTypeEnum.APP.value) && MapUtils.isNotEmpty(serveCollectMap4App) &&
null != serveCollectMap4App.get(item.getFromId())) {
item.setIsCollect(YesOrNoEnums.YES.getValue());
}
}
}
}
}
package com.pcloud.book.applet.biz.impl; package com.pcloud.book.applet.biz.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil; import cn.hutool.core.map.MapUtil;
import com.google.common.collect.Lists;
import com.pcloud.appcenter.app.dto.AppDto; import com.pcloud.appcenter.app.dto.AppDto;
import com.pcloud.book.applet.biz.AppletBooklistBiz; import com.pcloud.book.applet.biz.AppletBooklistBiz;
import com.pcloud.book.applet.biz.AppletNewsBiz; import com.pcloud.book.applet.biz.AppletNewsBiz;
...@@ -28,6 +30,8 @@ import com.pcloud.book.base.exception.BookBizException; ...@@ -28,6 +30,8 @@ import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.book.consumer.app.AppConsr; import com.pcloud.book.consumer.app.AppConsr;
import com.pcloud.book.consumer.channel.QrcodeSceneConsr; import com.pcloud.book.consumer.channel.QrcodeSceneConsr;
import com.pcloud.book.consumer.resource.ProductConsr; import com.pcloud.book.consumer.resource.ProductConsr;
import com.pcloud.book.group.biz.WeworkTeacherBiz;
import com.pcloud.book.group.dto.WxWorkTeacherDTO;
import com.pcloud.book.group.enums.AppAndProductTypeEnum; import com.pcloud.book.group.enums.AppAndProductTypeEnum;
import com.pcloud.book.group.tools.SendWeixinRequestTools; import com.pcloud.book.group.tools.SendWeixinRequestTools;
import com.pcloud.book.rightsSetting.biz.RightsSettingBiz; import com.pcloud.book.rightsSetting.biz.RightsSettingBiz;
...@@ -42,6 +46,7 @@ import com.pcloud.common.page.PageParam; ...@@ -42,6 +46,7 @@ import com.pcloud.common.page.PageParam;
import com.pcloud.common.utils.BeanUtils; import com.pcloud.common.utils.BeanUtils;
import com.pcloud.common.utils.ListUtils; import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.NumberUtil; import com.pcloud.common.utils.NumberUtil;
import com.pcloud.common.utils.cache.redis.JedisClusterUtils;
import com.pcloud.common.utils.string.StringUtil; import com.pcloud.common.utils.string.StringUtil;
import com.pcloud.readercenter.common.enums.YesOrNoNumEnum; import com.pcloud.readercenter.common.enums.YesOrNoNumEnum;
import com.pcloud.resourcecenter.product.dto.ProductDto; import com.pcloud.resourcecenter.product.dto.ProductDto;
...@@ -74,6 +79,9 @@ public class AppletRecordBizImpl implements AppletRecordBiz { ...@@ -74,6 +79,9 @@ public class AppletRecordBizImpl implements AppletRecordBiz {
private static final Logger LOGGER = LoggerFactory.getLogger(AppletRecordBizImpl.class); private static final Logger LOGGER = LoggerFactory.getLogger(AppletRecordBizImpl.class);
private static final String HANDLE_APPLET_RECORD_TYPE_CODE_KEY = "BOOK:AppletRecordBizImpl:handleAppletRecordTypeCode";
private static final String HANDLE_APPLET_RECORD_TYPE_CODE_STATUS_KEY = "BOOK:AppletRecordBizImpl:handleAppletRecordTypeCode:runStatus";
@Autowired @Autowired
private AppletRecordDao appletRecordDao; private AppletRecordDao appletRecordDao;
@Autowired @Autowired
...@@ -96,6 +104,8 @@ public class AppletRecordBizImpl implements AppletRecordBiz { ...@@ -96,6 +104,8 @@ public class AppletRecordBizImpl implements AppletRecordBiz {
private AppletRecordDayServeDao appletRecordDayServeDao; private AppletRecordDayServeDao appletRecordDayServeDao;
@Autowired @Autowired
private AppletRecordServeDao appletRecordServeDao; private AppletRecordServeDao appletRecordServeDao;
@Autowired
private WeworkTeacherBiz weworkTeacherBiz;
@Override @Override
@ParamLog("通过ID查询单条数据") @ParamLog("通过ID查询单条数据")
...@@ -231,7 +241,8 @@ public class AppletRecordBizImpl implements AppletRecordBiz { ...@@ -231,7 +241,8 @@ public class AppletRecordBizImpl implements AppletRecordBiz {
return MapUtils.isEmpty(appletAppOrProductDTOMap) ? new HashMap<>() : appletAppOrProductDTOMap; return MapUtils.isEmpty(appletAppOrProductDTOMap) ? new HashMap<>() : appletAppOrProductDTOMap;
} }
private void fillAppletRecord(List<AppletRecordDTO> recordList, Integer bookType) { @Override
public void fillAppletRecord(List<AppletRecordDTO> recordList, Integer bookType) {
if (ListUtils.isEmpty(recordList)) { if (ListUtils.isEmpty(recordList)) {
return; return;
} }
...@@ -254,6 +265,8 @@ public class AppletRecordBizImpl implements AppletRecordBiz { ...@@ -254,6 +265,8 @@ public class AppletRecordBizImpl implements AppletRecordBiz {
map(appletRecordDTO -> appletRecordDTO.getFromId()).distinct().collect(Collectors.toList()); map(appletRecordDTO -> appletRecordDTO.getFromId()).distinct().collect(Collectors.toList());
List<Long> bookListIds = recordList.stream().filter(appletRecordDTO -> AppletRecordTypeEnum.BOOK_LIST.value.equals(appletRecordDTO.getRecordType())). List<Long> bookListIds = recordList.stream().filter(appletRecordDTO -> AppletRecordTypeEnum.BOOK_LIST.value.equals(appletRecordDTO.getRecordType())).
map(appletRecordDTO -> appletRecordDTO.getFromId()).distinct().collect(Collectors.toList()); map(appletRecordDTO -> appletRecordDTO.getFromId()).distinct().collect(Collectors.toList());
List<Long> wxWorkTeacherIds = recordList.stream().filter(appletRecordDTO -> AppletRecordTypeEnum.WX_WORK_TEACHER.value.equals(appletRecordDTO.getRecordType())).
map(appletRecordDTO -> appletRecordDTO.getFromId()).distinct().collect(Collectors.toList());
//资源map //资源map
Map<Long, AppletNewsDTO> newsDtoMap = new HashMap<>(); Map<Long, AppletNewsDTO> newsDtoMap = new HashMap<>();
Future<Map<Long, AppletNewsDTO>> newsDtoMapFuture = null; Future<Map<Long, AppletNewsDTO>> newsDtoMapFuture = null;
...@@ -273,6 +286,7 @@ public class AppletRecordBizImpl implements AppletRecordBiz { ...@@ -273,6 +286,7 @@ public class AppletRecordBizImpl implements AppletRecordBiz {
Future<Map<Long, AppletOuterBooklistDTO>> appletOuterBooklistDTOMapFuture = null; Future<Map<Long, AppletOuterBooklistDTO>> appletOuterBooklistDTOMapFuture = null;
Map<Long, AppletBooklistDTO> appletBooklistDTOMap = new HashMap<>(); Map<Long, AppletBooklistDTO> appletBooklistDTOMap = new HashMap<>();
Future<Map<Long, AppletBooklistDTO>> appletBooklistDTOMapFuture = null; Future<Map<Long, AppletBooklistDTO>> appletBooklistDTOMapFuture = null;
Future<Map<Long, WxWorkTeacherDTO>> wxWorkTeacherDTOHashMapFuture = null;
if (!ListUtils.isEmpty(newsIds)) { if (!ListUtils.isEmpty(newsIds)) {
newsDtoMapFuture = ThreadPoolUtils.FILL_APPLET_RECORD.submit(() -> appletNewsBiz.getByIds4Record(newsIds)); newsDtoMapFuture = ThreadPoolUtils.FILL_APPLET_RECORD.submit(() -> appletNewsBiz.getByIds4Record(newsIds));
...@@ -303,6 +317,9 @@ public class AppletRecordBizImpl implements AppletRecordBiz { ...@@ -303,6 +317,9 @@ public class AppletRecordBizImpl implements AppletRecordBiz {
if (!ListUtils.isEmpty(bookListIds)) { if (!ListUtils.isEmpty(bookListIds)) {
appletBooklistDTOMapFuture = ThreadPoolUtils.FILL_APPLET_RECORD.submit(() -> appletBooklistBiz.getBookListMap(bookListIds)); appletBooklistDTOMapFuture = ThreadPoolUtils.FILL_APPLET_RECORD.submit(() -> appletBooklistBiz.getBookListMap(bookListIds));
} }
if (!ListUtils.isEmpty(wxWorkTeacherIds)) {
wxWorkTeacherDTOHashMapFuture = ThreadPoolUtils.FILL_APPLET_RECORD.submit(() -> weworkTeacherBiz.getWxWorkTeacherByIds(wxWorkTeacherIds));
}
//存储已经删除群的群分类; 精选文章类型并且跳转链接包含qrcode.5rs.me //存储已经删除群的群分类; 精选文章类型并且跳转链接包含qrcode.5rs.me
Iterator<AppletRecordDTO> iterator = recordList.iterator(); Iterator<AppletRecordDTO> iterator = recordList.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
...@@ -335,10 +352,33 @@ public class AppletRecordBizImpl implements AppletRecordBiz { ...@@ -335,10 +352,33 @@ public class AppletRecordBizImpl implements AppletRecordBiz {
} else if (Objects.equals(AppletRecordTypeEnum.BOOK_LIST.value, appletRecordDTO.getRecordType())) { } else if (Objects.equals(AppletRecordTypeEnum.BOOK_LIST.value, appletRecordDTO.getRecordType())) {
//填充精选书单信息 //填充精选书单信息
fillAppletBooklist4Record(appletBooklistDTOMap, appletBooklistDTOMapFuture, appletRecordDTO); fillAppletBooklist4Record(appletBooklistDTOMap, appletBooklistDTOMapFuture, appletRecordDTO);
} else if (Objects.equals(AppletRecordTypeEnum.WX_WORK_TEACHER.value, appletRecordDTO.getRecordType())) {
// 填充企业微信客服
fillWxWorkTeacher4Record(wxWorkTeacherDTOHashMapFuture, appletRecordDTO);
} }
} }
} }
private void fillWxWorkTeacher4Record(Future<Map<Long, WxWorkTeacherDTO>> wxWorkTeacherDTOHashMapFuture, AppletRecordDTO appletRecordDTO) {
Map<Long, WxWorkTeacherDTO> wxWorkTeacherDTOHashMap = null;
try {
wxWorkTeacherDTOHashMap = wxWorkTeacherDTOHashMapFuture.get();
} catch (InterruptedException | ExecutionException e) {
LOGGER.error("获取企业微信客服错误: {}==", e);
}
if (MapUtil.isEmpty(wxWorkTeacherDTOHashMap)) {
appletRecordDTO.setSourceDelete(YesOrNoNumEnum.YES.getValue());
return;
}
WxWorkTeacherDTO wxWorkTeacherDTO = wxWorkTeacherDTOHashMap.get(appletRecordDTO.getFromId());
if (null == wxWorkTeacherDTO) {
appletRecordDTO.setSourceDelete(YesOrNoNumEnum.YES.getValue());
return;
}
appletRecordDTO.setFromName(wxWorkTeacherDTO.getNickname());
appletRecordDTO.setWxWorkTeacherDTO(wxWorkTeacherDTO);
}
private void fillAppletBooklist4Record(Map<Long, AppletBooklistDTO> appletBooklistDTOMap, Future<Map<Long, AppletBooklistDTO>> appletBooklistDTOMapFuture, AppletRecordDTO appletRecordDTO) { private void fillAppletBooklist4Record(Map<Long, AppletBooklistDTO> appletBooklistDTOMap, Future<Map<Long, AppletBooklistDTO>> appletBooklistDTOMapFuture, AppletRecordDTO appletRecordDTO) {
try { try {
appletBooklistDTOMap = appletBooklistDTOMapFuture.get(); appletBooklistDTOMap = appletBooklistDTOMapFuture.get();
...@@ -531,5 +571,76 @@ public class AppletRecordBizImpl implements AppletRecordBiz { ...@@ -531,5 +571,76 @@ public class AppletRecordBizImpl implements AppletRecordBiz {
appletRecordDTO.setAppletAppOrProductDTO(appletAppOrProductDTO); appletRecordDTO.setAppletAppOrProductDTO(appletAppOrProductDTO);
} }
@Override
public Object handleAppletRecordTypeCode(Long lastAppletRecordId){
LOGGER.info("手动处理应用作品和资讯的typeCode");
if(lastAppletRecordId == null){
lastAppletRecordId = 0L;
}
String runStatus = "running";
String lock = JedisClusterUtils.get(HANDLE_APPLET_RECORD_TYPE_CODE_KEY);
if(!StringUtil.isEmpty(lock)){
throw new BizException(BizException.DB_DML_FAIL.getCode(), "请不要重复执行");
}
JedisClusterUtils.set(HANDLE_APPLET_RECORD_TYPE_CODE_KEY, "lock", 3600);
// 解除停止状态
JedisClusterUtils.set(HANDLE_APPLET_RECORD_TYPE_CODE_STATUS_KEY, "running", 3600);
Map<String, Object> paramMap;
try {
while ("running".equalsIgnoreCase(runStatus)) {
paramMap = MapUtil.<String, Object>builder()
.put("recordTypes", Lists.newArrayList(5, 6))
.put("offset", 0)
.put("limit", 100)
.put("lastAppletRecordId", lastAppletRecordId)
.build();
// 每次处理100条数据
List<AppletRecordDTO> recordList = appletRecordDao.getHandleAppletRecordTypeCode(paramMap);
if (CollectionUtil.isNotEmpty(recordList)) {
fillTypeCode4List(recordList);
appletRecordDao.batchUpdateTypeCode(recordList);
lastAppletRecordId = recordList.get(recordList.size()-1).getId();
} else {
runStatus = "complete";
break;
}
Thread.sleep(1);
runStatus = JedisClusterUtils.get(HANDLE_APPLET_RECORD_TYPE_CODE_STATUS_KEY);
}
return MapUtil.<String, Object>builder()
.put("runStatus", runStatus)
.put("lastAppletRecordId", lastAppletRecordId)
.put("msg", "stop".equalsIgnoreCase(runStatus) ? "执行被终止" : "执行完成")
.build();
} catch (Exception e){
LOGGER.info("handleAppletRecordTypeCode 执行出现异常,lastAppletRecordId:" + lastAppletRecordId.toString(), e);
return MapUtil.<String, Object>builder()
.put("runStatus", runStatus)
.put("lastAppletRecordId", lastAppletRecordId)
.put("msg", "执行出现异常")
.build();
} finally {
// 移除执行锁
JedisClusterUtils.del(HANDLE_APPLET_RECORD_TYPE_CODE_KEY);
}
}
private void fillTypeCode4List(List<AppletRecordDTO> recordList) {
fillAppletRecord(recordList, YesOrNoNumEnum.YES.getValue());
recordList.stream().forEach(appletRecordDTO -> {
if (Objects.equals(AppletRecordTypeEnum.PRODUCT.value, appletRecordDTO.getRecordType()) && null != appletRecordDTO.getAppletAppOrProductDTO()) {
// 填充作品信息
appletRecordDTO.setTypeCode(appletRecordDTO.getAppletAppOrProductDTO().getServeTypeCode());
} else if (Objects.equals(AppletRecordTypeEnum.APP.value, appletRecordDTO.getRecordType()) && null != appletRecordDTO.getAppletAppOrProductDTO()) {
// 填充应用信息
appletRecordDTO.setTypeCode(appletRecordDTO.getAppletAppOrProductDTO().getServeTypeCode());
}
});
}
@Override
public void stopHandleAppletRecordTypeCode() {
JedisClusterUtils.set(HANDLE_APPLET_RECORD_TYPE_CODE_STATUS_KEY, "stop", 3600);
}
} }
\ No newline at end of file
...@@ -75,6 +75,11 @@ public class AppletConstants { ...@@ -75,6 +75,11 @@ public class AppletConstants {
public static final String APPLET_RECORD_HISTORY_STATIS_REPORT_LAST_DATE = CacheConstant.BOOK + "APPLET:HISTORY_REPORT_LAST_DATE_"; public static final String APPLET_RECORD_HISTORY_STATIS_REPORT_LAST_DATE = CacheConstant.BOOK + "APPLET:HISTORY_REPORT_LAST_DATE_";
/** /**
* 小睿资源广场统计
*/
public static final String APPLET_RESOURCE_AGGR_STATIS = CacheConstant.BOOK +"APPLET:getAggrStatis";
/**
* 未配置答案的书刊 * 未配置答案的书刊
*/ */
public static final List<Long> NO_ANSWER_BOOK = Arrays.asList( public static final List<Long> NO_ANSWER_BOOK = Arrays.asList(
......
...@@ -7,6 +7,7 @@ import com.pcloud.book.applet.dto.AppletUserBookcaseDTO; ...@@ -7,6 +7,7 @@ import com.pcloud.book.applet.dto.AppletUserBookcaseDTO;
import com.pcloud.book.applet.dto.ReadBookDayStatisDTO; import com.pcloud.book.applet.dto.ReadBookDayStatisDTO;
import com.pcloud.book.applet.entity.AppletRecord; import com.pcloud.book.applet.entity.AppletRecord;
import com.pcloud.common.core.dao.BaseDao; import com.pcloud.common.core.dao.BaseDao;
import org.apache.ibatis.session.ResultHandler;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
...@@ -33,4 +34,10 @@ public interface AppletRecordDao extends BaseDao<AppletRecord> { ...@@ -33,4 +34,10 @@ public interface AppletRecordDao extends BaseDao<AppletRecord> {
Long getStatisUserCount(Date prevMonday, Date prevSunday); Long getStatisUserCount(Date prevMonday, Date prevSunday);
Map<Long, AppletAppOrProductDTO> getAppOrProductBrowseCount(Integer recordType, List<Long> serveIds); Map<Long, AppletAppOrProductDTO> getAppOrProductBrowseCount(Integer recordType, List<Long> serveIds);
void fixAppletRecordDataSync4CH(String createDate, ResultHandler<AppletRecord> appletRecordResultHandler);
List<AppletRecordDTO> getHandleAppletRecordTypeCode(Map<String, Object> paramMap);
void batchUpdateTypeCode(List<AppletRecordDTO> recordList);
} }
...@@ -9,6 +9,7 @@ import com.pcloud.book.applet.dto.AppletUserBookcaseDTO; ...@@ -9,6 +9,7 @@ import com.pcloud.book.applet.dto.AppletUserBookcaseDTO;
import com.pcloud.book.applet.dto.ReadBookDayStatisDTO; import com.pcloud.book.applet.dto.ReadBookDayStatisDTO;
import com.pcloud.book.applet.entity.AppletRecord; import com.pcloud.book.applet.entity.AppletRecord;
import com.pcloud.common.core.dao.BaseDaoImpl; import com.pcloud.common.core.dao.BaseDaoImpl;
import org.apache.ibatis.session.ResultHandler;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.Date; import java.util.Date;
...@@ -74,4 +75,20 @@ public class AppletRecordDaoImpl extends BaseDaoImpl<AppletRecord> implements Ap ...@@ -74,4 +75,20 @@ public class AppletRecordDaoImpl extends BaseDaoImpl<AppletRecord> implements Ap
paramMap.put("serveIds", serveIds); paramMap.put("serveIds", serveIds);
return this.sqlSessionTemplate.selectMap(getStatement("getAppOrProductBrowseCount"), paramMap, "serveId"); return this.sqlSessionTemplate.selectMap(getStatement("getAppOrProductBrowseCount"), paramMap, "serveId");
} }
@Override
public void fixAppletRecordDataSync4CH(String createDate, ResultHandler<AppletRecord> handler) {
Map<String, Object> params = MapUtil.<String, Object>builder().put("createDate", createDate).build();
getSqlSession().select(getStatement("fixAppletRecordDataSync4CH"), params, handler);
}
@Override
public List<AppletRecordDTO> getHandleAppletRecordTypeCode(Map<String, Object> paramMap) {
return getSqlSession().selectList(getStatement("getHandleAppletRecordTypeCode"), paramMap);
}
@Override
public void batchUpdateTypeCode(List<AppletRecordDTO> recordList) {
getSqlSession().update(getStatement("batchUpdateTypeCode"), recordList);
}
} }
package com.pcloud.book.applet.dto; package com.pcloud.book.applet.dto;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.pcloud.book.group.dto.WxWorkTeacherDTO;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
...@@ -52,6 +53,9 @@ public class AppletRecordDTO { ...@@ -52,6 +53,9 @@ public class AppletRecordDTO {
@ApiModelProperty("书单推荐") @ApiModelProperty("书单推荐")
private AppletOuterBooklistDTO appletOuterBooklistDTO; private AppletOuterBooklistDTO appletOuterBooklistDTO;
@ApiModelProperty("企业微信客服")
private WxWorkTeacherDTO wxWorkTeacherDTO;
@ApiModelProperty("资源是否已经被删除 0 未删除,1 已删除") @ApiModelProperty("资源是否已经被删除 0 未删除,1 已删除")
private Integer sourceDelete; private Integer sourceDelete;
...@@ -73,4 +77,15 @@ public class AppletRecordDTO { ...@@ -73,4 +77,15 @@ public class AppletRecordDTO {
@ApiModelProperty("上下架状态") @ApiModelProperty("上下架状态")
private Integer showState; private Integer showState;
@ApiModelProperty("应用、作品类型")
private String typeCode;
@ApiModelProperty("用户量")
private Integer userCount;
@ApiModelProperty("点击量")
private Integer clickCount;
@ApiModelProperty("是否收藏")
private Integer isCollect;
} }
package com.pcloud.book.applet.enums;
public enum AppletRankTypeEnum {
ALL(1), // 总榜
MONTH(2), // 月榜
WEEK(3); // 周榜
public Integer value;
AppletRankTypeEnum(Integer value) {
this.value = value;
}
}
package com.pcloud.book.applet.enums;
public enum AppletSourceTypeEnum {
ONLINE_LESSON(1), // 线上课程
HOT_NEWS(2), // 热点资讯
LEARN_TOOL(3), // 学习工具
RECOMMEND_BOOK(4), // 推荐书单
RESOURCE_TOPIC(5), // 资源专题
LEARN_GROUP(6), // 学习交流群
ANSWER_1V1(7), // 1v1辅导答疑
LEARN_CLOCK(8); // 学习打卡
public Integer value;
AppletSourceTypeEnum(Integer value) {
this.value = value;
}
}
package com.pcloud.book.applet.facade;
import com.pcloud.book.applet.biz.AppletRecordAggrStatisBiz;
import com.pcloud.common.dto.ResponseDto;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.permission.PermissionException;
import com.pcloud.common.utils.cookie.Cookie;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* (AppletRecordAggrWeekStatis)表控制层
*
* @author makejava
* @since 2020-12-21 10:35:33
*/
@RestController("appletRecordAggrStatisFacade")
@RequestMapping("appletRecordAggrStatis")
public class AppletRecordAggrStatisFacade {
@Autowired
private AppletRecordAggrStatisBiz appletRecordAggrStatisBiz;
@ApiOperation("分页查询")
@GetMapping("getList")
public ResponseDto<?> getAggrStatis(@CookieValue("userInfo") String userInfo,
@RequestParam(value = "keyword", required = false) String keyword,
@RequestParam(value = "sourceType", defaultValue = "1") Integer sourceType,
@RequestParam(value = "rankType", required = false, defaultValue = "1") Integer rankType,
@RequestParam(value = "currentPage", defaultValue = "0") Integer currentPage,
@RequestParam(value = "numPerPage", defaultValue = "10") Integer numPerPage)
throws BizException, PermissionException {
Long wechatUserId = Cookie.getId(userInfo, Cookie._WECHAT_USER_ID);
return new ResponseDto<>(appletRecordAggrStatisBiz.getAggrStatis(wechatUserId, keyword, sourceType, rankType, currentPage, numPerPage));
}
}
...@@ -7,6 +7,7 @@ import com.pcloud.book.applet.biz.AppletBookClassifyBiz; ...@@ -7,6 +7,7 @@ import com.pcloud.book.applet.biz.AppletBookClassifyBiz;
import com.pcloud.book.applet.biz.AppletNewsBiz; import com.pcloud.book.applet.biz.AppletNewsBiz;
import com.pcloud.book.applet.biz.AppletRecordBiz; import com.pcloud.book.applet.biz.AppletRecordBiz;
import com.pcloud.book.applet.biz.AppletRecordStatisBiz; import com.pcloud.book.applet.biz.AppletRecordStatisBiz;
import com.pcloud.book.applet.biz.AppletRecordAggrStatisBiz;
import com.pcloud.book.applet.biz.AppletThirdResourcesStaticBiz; import com.pcloud.book.applet.biz.AppletThirdResourcesStaticBiz;
import com.pcloud.book.applet.biz.ServeCollectBiz; import com.pcloud.book.applet.biz.ServeCollectBiz;
import com.pcloud.book.applet.dto.AppletAppOrProductDTO; import com.pcloud.book.applet.dto.AppletAppOrProductDTO;
...@@ -75,6 +76,8 @@ public class AppletServiceImpl implements AppletService { ...@@ -75,6 +76,8 @@ public class AppletServiceImpl implements AppletService {
private AppletRecordStatisBiz appletRecordStatisBiz; private AppletRecordStatisBiz appletRecordStatisBiz;
@Autowired @Autowired
private AppletRecordBiz appletRecordBiz; private AppletRecordBiz appletRecordBiz;
@Autowired
private AppletRecordAggrStatisBiz appletRecordAggrStatisBiz;
@Override @Override
...@@ -180,4 +183,34 @@ public class AppletServiceImpl implements AppletService { ...@@ -180,4 +183,34 @@ public class AppletServiceImpl implements AppletService {
Map<Long, AppletAppOrProductDTO> appletAppOrProductDTOMap = appletRecordBiz.getAppOrProductBrowseCount(recordType, serveIds); Map<Long, AppletAppOrProductDTO> appletAppOrProductDTOMap = appletRecordBiz.getAppOrProductBrowseCount(recordType, serveIds);
return ResponseHandleUtil.toResponse(appletAppOrProductDTOMap); return ResponseHandleUtil.toResponse(appletAppOrProductDTOMap);
} }
@Override
@GetMapping("fixAppletRecordDataSync4CH")
public void fixAppletRecordDataSync4CH(@RequestParam(value = "createDate", required = false) String createDate){
appletRecordAggrStatisBiz.fixAppletRecordDataSync4CH(createDate);
}
@Override
@GetMapping("updateAggrStatisCache")
public void updateAggrStatisCache(){
appletRecordAggrStatisBiz.updateAggrStatisCache();
}
@Override
@GetMapping("syncDataAndUpdateCache")
public void syncDataAndUpdateCache(@RequestParam(value = "createDate", required = false) String createDate){
appletRecordAggrStatisBiz.syncDataAndUpdateCache(createDate);
}
@Override
@GetMapping("handleAppletRecordTypeCode")
public ResponseEntity<ResponseDto<Object>> handleAppletRecordTypeCode(@RequestParam(value = "lastAppletRecordId", required = false) Long lastAppletRecordId){
return ResponseHandleUtil.toResponse(appletRecordBiz.handleAppletRecordTypeCode(lastAppletRecordId));
}
@Override
@GetMapping("stopHandleAppletRecordTypeCode")
public void stopHandleAppletRecordTypeCode(){
appletRecordBiz.stopHandleAppletRecordTypeCode();
}
} }
package com.pcloud.book.config.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
/**
* clickhouse 数据源配置
*/
@Slf4j
@Configuration
@MapperScan(basePackages = "com.pcloud.book.mapper.clickhouse", sqlSessionFactoryRef = "clickHouseSqlSessionFactory")
public class CHDataSource {
@Bean(name = "clickHouseDataSource")
@ConfigurationProperties(prefix = "spring.datasourceCh")
public DataSource druidDataSource() {
log.info("[初始化clickhouse数据源 - druidDataSource]");
return new DruidDataSource();
}
@Bean("clickHouseSqlSessionFactory")
public SqlSessionFactory clickHouseSqlSessionFactory(@Qualifier("clickHouseDataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath:/clickhouse/**/*Mapper.xml"));
log.info("[初始化clickhouse数据源 - clickHouseSqlSessionFactory]");
return bean.getObject();
}
@Bean("clickHouseSqlSessionTemplate")
public SqlSessionTemplate clickHouseSqlSessionTemplate(
@Qualifier("clickHouseSqlSessionFactory") SqlSessionFactory sessionFactory) {
log.info("[初始化clickhouse数据源 - clickHouseSqlSessionTemplate]");
return new SqlSessionTemplate(sessionFactory);
}
}
package com.pcloud.book.group.biz;
import com.pcloud.book.group.entity.WeworkTeacherFriendRecord;
import com.pcloud.common.page.PageBeanNew;
import java.util.List;
/**
* 点击加老师好友记录表(WeworkTeacherFriendRecord)表服务接口
*
* @author makejava
* @since 2020-12-25 20:01:43
*/
public interface WeworkTeacherFriendRecordBiz {
/**
* 通过ID查询单条数据
*
* @param id 主键
* @return 实例对象
*/
WeworkTeacherFriendRecord getById(Long id);
/**
* 分页查询
*/
PageBeanNew getList(Integer currentPage, Integer numPerPage);
/**
* 新增数据
*
* @param weworkTeacherFriendRecord 实例对象
* @return 主键
*/
Long insert(WeworkTeacherFriendRecord weworkTeacherFriendRecord);
/**
* 修改数据
*
* @param weworkTeacherFriendRecord 实例对象
*/
void update(WeworkTeacherFriendRecord weworkTeacherFriendRecord);
/**
* 通过主键删除数据
*
* @param id 主键
* @return 是否成功
*/
void deleteById(Long id);
}
\ No newline at end of file
package com.pcloud.book.group.biz.impl;
import com.pcloud.book.group.entity.WeworkTeacherFriendRecord;
import com.pcloud.book.group.dao.WeworkTeacherFriendRecordDao;
import com.pcloud.book.group.biz.WeworkTeacherFriendRecordBiz;
import com.pcloud.common.core.aspect.ParamLog;
import com.pcloud.common.page.PageBeanNew;
import com.pcloud.common.page.PageParam;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.utils.ListUtils;
import com.pcloud.common.utils.NumberUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 点击加老师好友记录表(WeworkTeacherFriendRecord)表服务实现类
*
* @author makejava
* @since 2020-12-25 20:01:43
*/
@Service("weworkTeacherFriendRecordBiz")
public class WeworkTeacherFriendRecordBizImpl implements WeworkTeacherFriendRecordBiz {
private static final Logger LOGGER = LoggerFactory.getLogger(WeworkTeacherFriendRecordBizImpl.class);
@Autowired
private WeworkTeacherFriendRecordDao weworkTeacherFriendRecordDao;
@Override
@ParamLog("通过ID查询单条数据")
public WeworkTeacherFriendRecord getById(Long id) {
return weworkTeacherFriendRecordDao.getById(id);
}
@Override
@ParamLog("查询多条数据")
public PageBeanNew getList(Integer currentPage, Integer numPerPage) {
PageBeanNew pageBeanNew = weworkTeacherFriendRecordDao.listPageNew(new PageParam(currentPage, numPerPage), null, "getList");
List recordList = pageBeanNew.getRecordList();
if (ListUtils.isEmpty(recordList)){
return pageBeanNew;
}
// 加载其它数据
return pageBeanNew;
}
@Override
@ParamLog("新增")
public Long insert(WeworkTeacherFriendRecord weworkTeacherFriendRecord) {
weworkTeacherFriendRecordDao.insert(weworkTeacherFriendRecord);
return weworkTeacherFriendRecord.getId();
}
@Override
@ParamLog("修改")
public void update(WeworkTeacherFriendRecord weworkTeacherFriendRecord) {
if(weworkTeacherFriendRecord == null || !NumberUtil.isNumber(weworkTeacherFriendRecord.getId())){
throw BizException.PARAM_IS_NULL;
}
weworkTeacherFriendRecordDao.update(weworkTeacherFriendRecord);
}
@Override
@ParamLog("删除")
public void deleteById(Long id) {
weworkTeacherFriendRecordDao.deleteById(id);
}
}
\ No newline at end of file
package com.pcloud.book.group.dao;
import com.pcloud.book.applet.dto.AppletRecordDTO;
import com.pcloud.book.group.entity.WeworkTeacherFriendRecord;
import com.pcloud.common.core.dao.BaseDao;
import java.util.HashMap;
import java.util.List;
/**
* 点击加老师好友记录表(WeworkTeacherFriendRecord)表数据库访问层
*
* @author makejava
* @since 2020-12-25 20:01:43
*/
public interface WeworkTeacherFriendRecordDao extends BaseDao<WeworkTeacherFriendRecord> {
List<AppletRecordDTO> getAggrStatis(HashMap<String, Object> paramMap);
}
package com.pcloud.book.group.dao.impl;
import com.pcloud.book.applet.dto.AppletRecordDTO;
import com.pcloud.book.group.entity.WeworkTeacherFriendRecord;
import com.pcloud.book.group.dao.WeworkTeacherFriendRecordDao;
import com.pcloud.common.core.dao.BaseDaoImpl;
import org.springframework.stereotype.Repository;
import org.apache.ibatis.annotations.Param;
import java.util.HashMap;
import java.util.List;
/**
* 点击加老师好友记录表(WeworkTeacherFriendRecord)表数据库访问层
*
* @author makejava
* @since 2020-12-25 20:01:43
*/
@Repository("weworkTeacherFriendRecordDaoImpl")
public class WeworkTeacherFriendRecordDaoImpl extends BaseDaoImpl<WeworkTeacherFriendRecord> implements WeworkTeacherFriendRecordDao {
@Override
public List<AppletRecordDTO> getAggrStatis(HashMap<String, Object> paramMap) {
return this.sqlSessionTemplate.selectList(getStatement("getAggrStatis"), paramMap);
}
}
package com.pcloud.book.group.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.Date;
@Data
public class WxWorkTeacherDTO {
@ApiModelProperty("id")
private Long id;
/**
* 企业微信二维码
*/
@ApiModelProperty("企业微信二维码")
private String qrcode;
/**
* 真实姓名
*/
@ApiModelProperty("真实姓名")
private String realName;
/**
* 昵称
*/
@ApiModelProperty("昵称")
private String nickname;
/**
* 头像地址
*/
@ApiModelProperty("头像地址")
private String avatar;
/**
* 描述
*/
@ApiModelProperty("描述")
private String desc;
/**
* 图文素材标题名称
*/
@ApiModelProperty("图文素材标题名称")
private String title;
/**
* 客服类型:1:苏老师 2:张哥哥
*/
@ApiModelProperty("客服类型:1:苏老师 2:张哥哥")
private Integer teacherType;
/**
* 开关状态
*/
@ApiModelProperty("开关状态")
private Integer isOpen;
/**
* 图文素材地址
*/
@ApiModelProperty("图文素材地址")
private String materialUrl;
/**
* 图文素材媒体ID
*/
@ApiModelProperty("图文素材媒体ID")
private String mediaId;
/**
* 公众号ID
*/
@ApiModelProperty("公众号ID")
private Long accountId;
/**
* 创建时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ApiModelProperty("创建时间")
private Date createTime;
/**
* 更新时间
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@ApiModelProperty("更新时间")
private Date updateTime;
}
package com.pcloud.book.group.entity;
import java.util.Date;
import java.math.BigDecimal;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.pcloud.common.entity.BaseEntity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 点击加老师好友记录表(WeworkTeacherFriendRecord)实体类
*
* @author makejava
* @since 2020-12-25 20:01:43
*/
@Data
public class WeworkTeacherFriendRecord extends BaseEntity {
private static final long serialVersionUID = 326531946857412022L;
@ApiModelProperty("点击加老师好友记录表id")
private Long id;
@ApiModelProperty("用户id")
private Long wechatUserId;
@ApiModelProperty("老师id")
private Long weworkTeacherId;
@ApiModelProperty("添加时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
@ApiModelProperty("添加日期")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createDate;
}
package com.pcloud.book.group.facade.impl;
import com.pcloud.book.group.entity.WeworkTeacherFriendRecord;
import com.pcloud.book.group.biz.WeworkTeacherFriendRecordBiz;
import com.pcloud.book.base.exception.BookBizException;
import com.pcloud.common.dto.ResponseDto;
import com.pcloud.common.exceptions.BizException;
import com.pcloud.common.permission.PermissionException;
import com.pcloud.common.utils.SessionUtil;
import com.pcloud.common.utils.cookie.Cookie;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import io.swagger.annotations.ApiOperation;
/**
* 点击加老师好友记录表(WeworkTeacherFriendRecord)表控制层
*
* @author makejava
* @since 2020-12-25 20:01:43
*/
@RestController("weworkTeacherFriendRecordFacade")
@RequestMapping("weworkTeacherFriendRecord")
public class WeworkTeacherFriendRecordFacade {
@Autowired
private WeworkTeacherFriendRecordBiz weworkTeacherFriendRecordBiz;
@ApiOperation("通过主键查询单条数据")
@GetMapping("getById")
public ResponseDto<?> getById(@RequestHeader("token") String token, @RequestParam Long id) throws BizException, PermissionException {
SessionUtil.getToken4Redis(token);
return new ResponseDto<>(weworkTeacherFriendRecordBiz.getById(id));
}
@ApiOperation("分页查询")
@GetMapping("getList")
public ResponseDto<?> getList(@RequestHeader("token") String token,
@RequestParam(value = "currentPage", defaultValue = "0") Integer currentPage,
@RequestParam(value = "numPerPage", defaultValue = "10") Integer numPerPage)
throws BizException, PermissionException {
SessionUtil.getToken4Redis(token);
return new ResponseDto<>(weworkTeacherFriendRecordBiz.getList(currentPage, numPerPage));
}
@ApiOperation("新增")
@PostMapping("insert")
public ResponseDto<?> insert(@CookieValue("userInfo") String userInfo, @RequestBody WeworkTeacherFriendRecord weworkTeacherFriendRecord)
throws BizException, PermissionException {
Long wechatUserId = Cookie.getId(userInfo,Cookie._WECHAT_USER_ID);
weworkTeacherFriendRecord.setWechatUserId(wechatUserId);
return new ResponseDto<>(weworkTeacherFriendRecordBiz.insert(weworkTeacherFriendRecord));
}
@ApiOperation("更新")
@PostMapping("update")
public ResponseDto<?> update(@RequestHeader("token") String token,@RequestBody WeworkTeacherFriendRecord weworkTeacherFriendRecord) throws BizException, PermissionException {
SessionUtil.getToken4Redis(token);
weworkTeacherFriendRecordBiz.update(weworkTeacherFriendRecord);
return new ResponseDto<>();
}
@ApiOperation("删除")
@GetMapping("deleteById")
public ResponseDto<?> deleteById(@RequestHeader("token") String token, @RequestParam Long id) throws BizException, PermissionException {
SessionUtil.getToken4Redis(token);
if (null == id) {
throw BookBizException.PARAM_DELETION;
}
weworkTeacherFriendRecordBiz.deleteById(id);
return new ResponseDto<>();
}
}
...@@ -42,4 +42,4 @@ public interface WeworkTeacherMapper { ...@@ -42,4 +42,4 @@ public interface WeworkTeacherMapper {
@MapKey("id") @MapKey("id")
Map<Long, WxWorkTeacherDTO> getWxWorkTeacherByIds(@Param("ids") List<Long> teacherIds); Map<Long, WxWorkTeacherDTO> getWxWorkTeacherByIds(@Param("ids") List<Long> teacherIds);
} }
\ No newline at end of file
package com.pcloud.book.mapper.clickhouse;
import com.pcloud.book.applet.dto.AppletRecordDTO;
import com.pcloud.book.applet.entity.AppletRecord;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Mapper
@Component
public interface AppletRecordCHMapper {
void batchInsert(List<AppletRecord> list);
List<AppletRecordDTO> getAggrStatis(Map<String, Object> paramMap);
void optimize();
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pcloud.book.mapper.clickhouse.AppletRecordCHMapper">
<insert id="batchInsert">
INSERT INTO applet_record (
id,
wechat_user_id,
record_type,
rights_setting_id,
book_id,
channel_id,
adviser_id,
from_id,
from_name,
type_code,
account_setting_id,
create_time,
create_date,
is_delete,
link_url
) VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.id},
#{item.wechatUserId},
#{item.recordType},
#{item.rightsSettingId},
#{item.bookId},
#{item.channelId},
#{item.adviserId},
#{item.fromId},
#{item.fromName},
#{item.typeCode},
#{item.accountSettingId},
#{item.createTime},
#{item.createDate},
#{item.isDelete},
#{item.linkUrl}
)
</foreach>
</insert>
<select id="getAggrStatis" resultType="com.pcloud.book.applet.dto.AppletRecordDTO">
SELECT record_type recordType, from_id fromId, any(from_name) fromName, any(link_url) linkUrl,
COUNT(id) clickCount, COUNT(DISTINCT wechat_user_id) userCount
FROM applet_record
<where>
<if test="recordTypes != null and recordTypes.size() > 0">
(
</if>
<foreach collection="recordTypes" item="item" separator=" OR " open="(" close=")">
<if test="item.recordType != null">
record_type = #{item.recordType}
</if>
<if test="item.typeCodes != null and item.typeCodes.size() > 0">
AND type_code IN
<foreach collection="item.typeCodes" item="typeCode" separator="," open="(" close=")">
#{typeCode}
</foreach>
</if>
</foreach>
<if test="recordTypes != null and recordTypes.size() > 0">
)
</if>
<if test="beginDate != null">
AND creaete_time BETWEEN #{beginDate} AND #{endDate}
</if>
</where>
GROUP BY record_type, from_id
ORDER BY userCount DESC
LIMIT #{offset},#{limit}
</select>
<update id="optimize">
optimize table applet_record
</update>
</mapper>
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
<result column="adviser_id" property="adviserId" jdbcType="BIGINT"/> <result column="adviser_id" property="adviserId" jdbcType="BIGINT"/>
<result column="from_id" property="fromId" jdbcType="BIGINT"/> <result column="from_id" property="fromId" jdbcType="BIGINT"/>
<result column="from_name" property="fromName" jdbcType="VARCHAR"/> <result column="from_name" property="fromName" jdbcType="VARCHAR"/>
<result column="type_code" property="typeCode" jdbcType="VARCHAR"/>
<result column="account_setting_id" property="accountSettingId" jdbcType="BIGINT"/> <result column="account_setting_id" property="accountSettingId" jdbcType="BIGINT"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/> <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
<result column="create_date" property="createDate" jdbcType="DATE"/> <result column="create_date" property="createDate" jdbcType="DATE"/>
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
<result column="adviser_id" property="adviserId" jdbcType="BIGINT"/> <result column="adviser_id" property="adviserId" jdbcType="BIGINT"/>
<result column="from_id" property="fromId" jdbcType="BIGINT"/> <result column="from_id" property="fromId" jdbcType="BIGINT"/>
<result column="from_name" property="fromName" jdbcType="VARCHAR"/> <result column="from_name" property="fromName" jdbcType="VARCHAR"/>
<result column="type_code" property="typeCode" jdbcType="VARCHAR"/>
<result column="account_setting_id" property="accountSettingId" jdbcType="BIGINT"/> <result column="account_setting_id" property="accountSettingId" jdbcType="BIGINT"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/> <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
<result column="create_date" property="createDate" jdbcType="DATE"/> <result column="create_date" property="createDate" jdbcType="DATE"/>
...@@ -37,7 +39,7 @@ ...@@ -37,7 +39,7 @@
</resultMap> </resultMap>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, wechat_user_id, record_type, rights_setting_id, book_id, channel_id, adviser_id, from_id, from_name, account_setting_id, id, wechat_user_id, record_type, rights_setting_id, book_id, channel_id, adviser_id, from_id, from_name, type_code, account_setting_id,
create_time, create_date, is_delete, link_url create_time, create_date, is_delete, link_url
</sql> </sql>
...@@ -335,4 +337,41 @@ ...@@ -335,4 +337,41 @@
from_id from_id
</select> </select>
<select id="fixAppletRecordDataSync4CH" parameterType="map" resultMap="BaseResultMap">
SELECT * FROM applet_record WHERE create_date = #{createDate}
</select>
<select id="getHandleAppletRecordTypeCode" resultMap="BaseResultMap4DTO">
SELECT id, record_type, from_id
FROM applet_record
WHERE id > #{lastAppletRecordId}
<if test="recordTypes != null and recordTypes.size() > 0">
AND record_type IN
<foreach collection="recordTypes" item="recordType" open="(" close=")" separator=",">
#{recordType}
</foreach>
</if>
ORDER BY id
LIMIT #{offset},#{limit}
</select>
<update id="batchUpdateTypeCode" parameterType="list">
update
applet_record
<trim prefix="set" suffixOverrides=",">
<trim prefix="type_code =case" suffix="end,">
<foreach collection="list" item="item">
<if test="item.typeCode!=null">
when id=#{item.id} then #{item.typeCode}
</if>
</foreach>
</trim>
</trim>
<where>
<foreach collection="list" separator="or" item="item">
id = #{item.id}
</foreach>
</where>
</update>
</mapper> </mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pcloud.book.group.dao.impl.WeworkTeacherFriendRecordDaoImpl">
<resultMap id="BaseResultMap" type="com.pcloud.book.group.entity.WeworkTeacherFriendRecord">
<id column="id" property="id" jdbcType="BIGINT"/>
<result column="wechat_user_id" property="wechatUserId" jdbcType="BIGINT"/>
<result column="wework_teacher_id" property="weworkTeacherId" jdbcType="BIGINT"/>
<result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
<result column="create_date" property="createDate" jdbcType="DATE"/>
</resultMap>
<sql id="Base_Column_List">
id, wechat_user_id, wework_teacher_id, create_time, create_date
</sql>
<select id="getById" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM wework_teacher_friend_record
WHERE id = #{id}
</select>
<select id="getList" resultMap="BaseResultMap">
SELECT
<include refid="Base_Column_List"/>
FROM wework_teacher_friend_record
</select>
<select id="getAggrStatis" resultType="com.pcloud.book.applet.dto.AppletRecordDTO">
SELECT #{recordType} recordType, wework_teacher_id fromId, COUNT(id) clickCount, COUNT(DISTINCT wechat_user_id) userCount
FROM wework_teacher_friend_record
<where>
<if test="beginDate != null">
create_date BETWEEN #{beginDate} AND #{endDate}
</if>
</where>
GROUP BY wework_teacher_id
ORDER BY clickCount DESC
LIMIT #{offset},#{limit}
</select>
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
INSERT INTO wework_teacher_friend_record(
wechat_user_id,
wework_teacher_id,
create_time,
create_date
) VALUES (
#{wechatUserId, jdbcType=BIGINT},
#{weworkTeacherId, jdbcType=BIGINT},
NOW(),
NOW()
)
</insert>
<insert id="batchInsert">
INSERT INTO wework_teacher_friend_record (
wechat_user_id,
wework_teacher_id,
create_time,
create_date
) VALUES
<foreach collection="list" item="item" separator=",">
(
#{item.wechatUserId, jdbcType=BIGINT},
#{item.weworkTeacherId, jdbcType=BIGINT},
NOW(),
NOW()
)
</foreach>
</insert>
<!--通过主键修改数据-->
<update id="update">
UPDATE wework_teacher_friend_record
<set>
<if test="wechatUserId != null">
wechat_user_id = #{wechatUserId},
</if>
<if test="weworkTeacherId != null">
wework_teacher_id = #{weworkTeacherId},
</if>
<if test="createTime != null">
create_time = #{createTime},
</if>
<if test="createDate != null">
create_date = #{createDate},
</if>
</set>
WHERE id = #{id}
</update>
<!--通过主键删除-->
<delete id="deleteById">
DELETE FROM wework_teacher_friend_record where id = #{id}
</delete>
</mapper>
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
<result column="create_time" jdbcType="TIMESTAMP" property="createTime" /> <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime" /> <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
</resultMap> </resultMap>
<resultMap id="BaseResultMap4DTO" type="com.pcloud.book.group.dto.WxWorkTeacherDTO" extends="BaseResultMap"> <resultMap id="BaseResultMap4DTO" type="com.pcloud.book.group.dto.WxWorkTeacherDTO" extends="BaseResultMap">
</resultMap> </resultMap>
...@@ -295,4 +295,4 @@ ...@@ -295,4 +295,4 @@
</foreach> </foreach>
</select> </select>
</mapper> </mapper>
\ No newline at end of file
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