|
@@ -3,6 +3,7 @@ package com.fs.course.service.impl;
|
|
|
import cn.hutool.core.util.NumberUtil;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.fs.common.BeanCopyUtils;
|
|
|
import com.fs.common.core.domain.R;
|
|
@@ -29,10 +30,12 @@ import com.fs.course.vo.FsUserCourseVideoVO;
|
|
|
import com.fs.course.vo.newfs.*;
|
|
|
import com.fs.his.param.WxSendRedPacketParam;
|
|
|
import com.fs.his.vo.OptionsVO;
|
|
|
+import com.fs.qw.domain.QwCompany;
|
|
|
import com.fs.qw.domain.QwExternalContact;
|
|
|
import com.fs.qw.domain.QwUser;
|
|
|
import com.fs.qw.mapper.QwExternalContactMapper;
|
|
|
import com.fs.qw.mapper.QwUserMapper;
|
|
|
+import com.fs.qw.service.IQwCompanyService;
|
|
|
import com.fs.qwApi.Result.QwAddContactWayResult;
|
|
|
import com.fs.qwApi.param.QwAddContactWayParam;
|
|
|
import com.fs.qwApi.service.QwApiService;
|
|
@@ -49,6 +52,7 @@ import com.fs.store.service.IFsStorePaymentService;
|
|
|
import com.fs.store.service.IFsUserService;
|
|
|
import com.fs.store.service.cache.IFsUserCourseCacheService;
|
|
|
import com.fs.system.service.ISysConfigService;
|
|
|
+import com.fs.voice.utils.StringUtil;
|
|
|
import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
import org.slf4j.Logger;
|
|
@@ -61,11 +65,14 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
import java.math.BigDecimal;
|
|
|
import java.math.RoundingMode;
|
|
|
import java.time.LocalDateTime;
|
|
|
+import java.time.ZoneId;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
+import static com.fs.course.utils.LinkUtil.generateRandomStringWithLock;
|
|
|
+
|
|
|
/**
|
|
|
* 课堂视频Service业务层处理
|
|
|
*
|
|
@@ -77,6 +84,11 @@ import java.util.stream.Collectors;
|
|
|
public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
{
|
|
|
private static final Logger logger = LoggerFactory.getLogger(FsUserCourseVideoServiceImpl.class);
|
|
|
+
|
|
|
+ private static final String miniappRealLink = "/pages_course/video.html?course=";
|
|
|
+ private static final String REAL_LINK_PREFIX = "/courseH5/pages/course/learning?course=";
|
|
|
+ private static final String SHORT_LINK_PREFIX = "/courseH5/pages/course/learning?s=";
|
|
|
+
|
|
|
@Autowired
|
|
|
private FsUserCourseVideoMapper fsUserCourseVideoMapper;
|
|
|
@Autowired
|
|
@@ -153,6 +165,12 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
private FsUserCompanyUserMapper fsUserCompanyUserMapper;
|
|
|
@Autowired
|
|
|
private IFsUserCourseCacheService fsUserCourseCacheService;
|
|
|
+ @Autowired
|
|
|
+ private IQwCompanyService qwCompanyService;
|
|
|
+ @Autowired
|
|
|
+ private FsCourseWatchLogMapper fsCourseWatchLogMapper;
|
|
|
+ @Autowired
|
|
|
+ private FsCourseLinkMapper fsCourseLinkMapper;
|
|
|
|
|
|
/**
|
|
|
* 查询课堂视频
|
|
@@ -1198,6 +1216,125 @@ public class FsUserCourseVideoServiceImpl implements IFsUserCourseVideoService
|
|
|
return fsUserCourseVideoMapper.getFsCourseVideoListBySidebar(param);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public R createMiniLink(FsCourseLinkMiniParam param) {
|
|
|
+ QwExternalContact qwExternalContact = qwExternalContactMapper.selectById(param.getExtId());
|
|
|
+ if (Objects.isNull(qwExternalContact)) {
|
|
|
+ return R.error("客户不存在");
|
|
|
+ }
|
|
|
+ QwUser qwUser = qwUserMapper.selectById(qwExternalContact.getQwUserId());
|
|
|
+ if (Objects.isNull(qwUser) || Objects.isNull(qwUser.getCompanyId()) || Objects.isNull(qwUser.getCompanyUserId())){
|
|
|
+ return R.error("员工未绑定 销售公司 或 销售 请先绑定");
|
|
|
+ }
|
|
|
+
|
|
|
+ QwCompany qwCompany = qwCompanyService.selectQwCompanyByCorpId(qwUser.getCorpId());
|
|
|
+ if (Objects.isNull(qwCompany)) {
|
|
|
+ return R.error().put("msg","企业不存在,请联系管理员");
|
|
|
+ }
|
|
|
+
|
|
|
+ //看课记录
|
|
|
+ addWatchLogIfNeeded(param.getVideoId(), param.getCourseId(), qwExternalContact.getFsUserId(), qwUser, qwExternalContact.getId());
|
|
|
+
|
|
|
+ //生成小程序链接
|
|
|
+ String linkByMiniApp = createLinkByMiniApp(new Date(), param.getCourseId(), param.getVideoId(), qwUser, qwExternalContact.getId(),2,null);
|
|
|
+
|
|
|
+ JSONObject news = new JSONObject(true);
|
|
|
+ news.put("miniprogramAppid", qwCompany.getMiniAppId());
|
|
|
+ news.put("miniprogramTitle", param.getTitle());
|
|
|
+ news.put("miniprogramPicUrl", "https://cos.his.cdwjyyh.com/fs/20250523/9c8af5735d784847818cada7fa776a7b.jpg");
|
|
|
+ news.put("miniprogramPage", linkByMiniApp);
|
|
|
+
|
|
|
+ return R.ok().put("data",news);
|
|
|
+ }
|
|
|
+
|
|
|
+ private String createLinkByMiniApp(Date sendTime, Long courseId, Long videoId,
|
|
|
+ QwUser qwUser, Long externalId,int type,String domainName) {
|
|
|
+ FsCourseLink link = new FsCourseLink();
|
|
|
+ link.setCompanyId(qwUser.getCompanyId());
|
|
|
+ link.setQwUserId(String.valueOf(qwUser.getId()));
|
|
|
+ link.setCompanyUserId(qwUser.getCompanyUserId());
|
|
|
+ link.setVideoId(videoId);
|
|
|
+ link.setCorpId(qwUser.getCorpId());
|
|
|
+ link.setCourseId(courseId);
|
|
|
+ link.setQwExternalId(externalId);
|
|
|
+
|
|
|
+ if (type == 1) {
|
|
|
+ link.setLinkType(0);
|
|
|
+ }else {
|
|
|
+ link.setLinkType(3);
|
|
|
+ }
|
|
|
+
|
|
|
+ String randomString = generateRandomStringWithLock();
|
|
|
+ if (StringUtil.strIsNullOrEmpty(randomString)){
|
|
|
+ link.setLink(UUID.randomUUID().toString().replace("-", ""));
|
|
|
+ }else {
|
|
|
+ link.setLink(randomString);
|
|
|
+ }
|
|
|
+
|
|
|
+ link.setCreateTime(sendTime);
|
|
|
+
|
|
|
+ FsCourseRealLink courseMap = new FsCourseRealLink();
|
|
|
+ BeanUtils.copyProperties(link,courseMap);
|
|
|
+
|
|
|
+ String courseJson = JSON.toJSONString(courseMap);
|
|
|
+
|
|
|
+ String realLinkFull;
|
|
|
+
|
|
|
+ if (type == 1) {
|
|
|
+ realLinkFull = REAL_LINK_PREFIX + courseJson;
|
|
|
+ }else {
|
|
|
+ realLinkFull = miniappRealLink + courseJson;
|
|
|
+ }
|
|
|
+
|
|
|
+ link.setRealLink(realLinkFull);
|
|
|
+
|
|
|
+ // 使用 Java 8 时间 API 计算过期时间
|
|
|
+ LocalDateTime sendDateTime = sendTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
|
|
+ LocalDateTime expireDateTime = sendDateTime.plusDays(0);
|
|
|
+ expireDateTime = expireDateTime.toLocalDate().atTime(23, 59, 59);
|
|
|
+ Date updateTime = Date.from(expireDateTime.atZone(ZoneId.systemDefault()).toInstant());
|
|
|
+ link.setUpdateTime(updateTime);
|
|
|
+
|
|
|
+ //存短链-
|
|
|
+ fsCourseLinkMapper.insertFsCourseLink(link);
|
|
|
+
|
|
|
+ if (type==1){
|
|
|
+ return domainName + SHORT_LINK_PREFIX + link.getLink();
|
|
|
+ }else {
|
|
|
+ return link.getRealLink();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 插入观看记录
|
|
|
+ private void addWatchLogIfNeeded(Long videoId, Long courseId,
|
|
|
+ Long fsUserId, QwUser qwUser,Long externalId) {
|
|
|
+
|
|
|
+ try {
|
|
|
+ FsCourseWatchLog watchLog = new FsCourseWatchLog();
|
|
|
+ watchLog.setVideoId(videoId);
|
|
|
+ watchLog.setQwExternalContactId(externalId);
|
|
|
+ watchLog.setSendType(2);
|
|
|
+ watchLog.setQwUserId(String.valueOf(qwUser.getId()));
|
|
|
+ watchLog.setDuration(0L);
|
|
|
+ watchLog.setCourseId(courseId);
|
|
|
+ watchLog.setCompanyUserId(qwUser.getCompanyUserId());
|
|
|
+ watchLog.setCompanyId(qwUser.getCompanyId());
|
|
|
+ watchLog.setCreateTime(new Date());
|
|
|
+ watchLog.setUpdateTime(new Date());
|
|
|
+ watchLog.setLogType(3);
|
|
|
+
|
|
|
+ if (fsUserId == null) {
|
|
|
+ fsUserId=0L;
|
|
|
+ }
|
|
|
+ watchLog.setUserId(fsUserId);
|
|
|
+
|
|
|
+ //存看课记录
|
|
|
+ fsCourseWatchLogMapper.insertOrUpdateFsCourseWatchLog(watchLog);
|
|
|
+ }catch (Exception e){
|
|
|
+ logger.error("一键群发失败-插入观看记录失败:"+e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
//会员-更新心跳时间
|
|
|
public void updateHeartbeatWx(FsUserCourseVideoUParam param) {
|
|
|
String redisKey = "h5wxuser:watch:heartbeat:" + param.getUserId() + ":" + param.getVideoId() + ":" + param.getCompanyUserId();
|