wjj 6 дней назад
Родитель
Сommit
f139008cce

+ 307 - 21
fs-admin/src/main/java/com/fs/his/task/Task.java

@@ -6,6 +6,7 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.json.JSONUtil;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.fs.app.domain.FsAppRole;
 import com.fs.app.mapper.FsAppRoleMapper;
@@ -15,11 +16,9 @@ import com.fs.company.service.ICompanyMiniappService;
 import com.fs.company.service.ICompanySmsService;
 import com.fs.core.config.WxMaConfiguration;
 import com.fs.core.utils.OrderCodeUtils;
-import com.fs.course.domain.FsCourseLink;
-import com.fs.course.domain.FsCourseRealLink;
-import com.fs.course.domain.FsCourseWatchLog;
-import com.fs.course.mapper.FsCourseLinkMapper;
-import com.fs.course.mapper.FsCourseWatchLogMapper;
+import com.fs.course.domain.*;
+import com.fs.course.mapper.*;
+import com.fs.course.service.IFsCoursePlaySourceConfigService;
 import com.fs.doctor.service.IFsDoctorOnlineService;
 import com.fs.fastGpt.domain.FastgptChatVoiceHomo;
 import com.fs.fastGpt.mapper.FastgptChatVoiceHomoMapper;
@@ -40,6 +39,7 @@ import com.fs.jd.http.IJdHttpService;
 import com.fs.qw.domain.QwExternalContact;
 import com.fs.qw.domain.QwUser;
 import com.fs.qw.mapper.FsSopCompanyUserTaskMapper;
+import com.fs.qw.mapper.QwCompanyMapper;
 import com.fs.qw.mapper.QwExternalContactMapper;
 import com.fs.qw.vo.QwSopCourseFinishTempSetting;
 import com.fs.sop.domain.QwSopLogs;
@@ -60,7 +60,6 @@ import com.fs.company.service.ICompanyUserService;
 import com.fs.company.vo.QwIpadTotalVo;
 import com.fs.company.vo.RedPacketMoneyVO;
 import com.fs.course.dto.BatchSendCourseAllDTO;
-import com.fs.course.mapper.FsCourseRedPacketLogMapper;
 import com.fs.course.service.IFsCourseWatchLogService;
 import com.fs.course.service.ITencentCloudCosService;
 import com.fs.erp.domain.ErpDeliverys;
@@ -141,6 +140,8 @@ import static com.fs.course.utils.LinkUtil.generateRandomStringWithLock;
 @Slf4j
 @Component("task")
 public class Task {
+
+    private static final String courseRealLink = "/pages_course/video.html?course=";
     private static final String miniappRealLink = "pages_user/answerQues.html";
     //商城小程序appId配置常量
     private static final String APP_ID_CONFIG_KEY = "appStore.appId.config";
@@ -358,6 +359,9 @@ public class Task {
     @Autowired
     private FsCourseLinkMapper fsCourseLinkMapper;
 
+    @Autowired
+    private IFsCoursePlaySourceConfigService fsCoursePlaySourceConfigService;
+
     public static final String SOP_TEMP_VOICE_KEY = "sop:tempVoice";
 
     // sop升单客户类型
@@ -372,6 +376,14 @@ public class Task {
 
     @Autowired
     private FsAppRoleMapper fsAppRoleMapper;
+    @Autowired
+    private QwCompanyMapper qwCompanyMapper;
+
+    @Autowired
+    private FsUserCourseMapper userCourseMapper;
+
+    @Autowired
+    private FsUserCourseVideoMapper courseVideoMapper;
 
     public void syncExpressToWx() {
         List<FsWxExpressTask> fsWxExpressTasks = fsWxExpressTaskMapper.selectPendingData();
@@ -2850,28 +2862,302 @@ public class Task {
         return link.getRealLink();
 
     }
-    private String getAppIdFromMiniMap(Map<Long, Map<Integer, List<CompanyMiniapp>>> miniMap,
-                                       String companyId, int sendMsgType) {
-        if (miniMap.isEmpty() || sendMsgType != 1) {
-            return null;
+    public void checkQwCompanyMainAppId(){
+        List<FsCoursePlaySourceConfig> banConfigs = new ArrayList<>();
+        List<FsCoursePlaySourceConfig> normalConfigs = new ArrayList<>();
+        String normalAppId = null;
+        //查询小程序所有配置
+        LambdaQueryWrapper<FsCoursePlaySourceConfig> queryWrapper = Wrappers.<FsCoursePlaySourceConfig>lambdaQuery()
+                .eq(FsCoursePlaySourceConfig::getStatus, 0)
+                .eq(FsCoursePlaySourceConfig::getReplaceStatus, 1)
+                .eq(FsCoursePlaySourceConfig::getIsDel, 0)
+                .eq(FsCoursePlaySourceConfig::getType, 1);
+        List<FsCoursePlaySourceConfig> configs = fsCoursePlaySourceConfigService.list(queryWrapper);
+
+        if (CollectionUtils.isNotEmpty(configs)) {
+            for (FsCoursePlaySourceConfig config : configs) {
+                String appId = config.getAppid();
+                boolean result = checkQwCompanyMainAppId(appId);
+                if (result) {
+                    normalConfigs.add(config);
+                } else {
+                    banConfigs.add(config);
+                }
+            }
+        }
+        List<QwCompany> qwCompanies = qwCompanyMapper.selectQwCompanyList(new QwCompany());
+        if (CollectionUtils.isNotEmpty(qwCompanies)) {
+            if (CollectionUtils.isNotEmpty(banConfigs)) {
+                //批量更新已封禁的小程序
+                Set<String> banAppIds = banConfigs.stream()
+                        .map(FsCoursePlaySourceConfig::getAppid)
+                        .collect(Collectors.toSet());
+
+                List<QwCompany> filteredCompanies = qwCompanies.stream()
+                        .filter(qwCompany -> qwCompany.getMiniAppId() != null && banAppIds.contains(qwCompany.getMiniAppId()))
+                        .collect(Collectors.toList());
+                if (CollectionUtils.isEmpty(filteredCompanies)) {
+                    return;
+                }
+                if (CollectionUtils.isNotEmpty(normalConfigs)) {
+                    normalAppId = normalConfigs.get(0).getAppid();
+                }
+                if (StringUtil.strIsNullOrEmpty(normalAppId)) {
+                    logger.error("未找到可用的课程小程序配置");
+                    return;
+                }
+
+                for (QwCompany qwCompany : filteredCompanies) {
+                    qwCompany.setMiniAppId(normalAppId);
+                }
+
+                //批量更新filteredCompanies
+                qwCompanyMapper.batchUpdateQwCompanyMiniAppId(filteredCompanies);
+
+                //批量更新已封禁的小程序 status=1, replace_status=0
+                banConfigs.forEach(config -> {
+                    config.setStatus(1);
+                    config.setReplaceStatus(0);
+                });
+                fsCoursePlaySourceConfigService.updateBatchById(banConfigs);
+
+                //作废sopLos
+                qwSopLogsMapper.wasteQwSopLogs();
+                //查询看课中断记录
+                List<FsCourseWatchLog> watchLogs = watchLogMapper.selectTodayWatchLogs(4);
+                List<QwSopLogs> interruptionSopLogsList = new ArrayList<>();
+                if (CollectionUtils.isNotEmpty(watchLogs)) {
+                    for (FsCourseWatchLog watchLog : watchLogs) {
+                        try {
+                            FsUserCourse userCourse = userCourseMapper.selectFsUserCourseByCourseId(watchLog.getCourseId());
+                            if (userCourse==null) {
+                                throw new CustomException("课程不存在,请检查");
+                            }
+
+                            FsUserCourseVideo courseVideo = courseVideoMapper.selectFsUserCourseVideoByVideoId(watchLog.getVideoId());
+                            if (courseVideo==null) {
+                                throw new CustomException("视频不存在,请检查");
+                            }
+
+                            QwUser qwUser = qwUserService.selectQwUserById(watchLog.getQwUserId());
+
+                            if (qwUser==null||qwUser.getCompanyId()==null||qwUser.getCompanyUserId()==null){
+                                throw new CustomException("员工未绑定 客服公司 或 客服 请先绑定");
+                            }
+
+                            QwCompany qwCompany = qwCompanyService.getQwCompanyByRedis(qwUser.getCorpId());
+                            if ( qwCompany==null ) {
+                                throw new CustomException("企业不存在,请联系管理员");
+                            }
+                            String linkByMiniApp = createCourseLinkByMiniApp(new Date(), watchLog.getCourseId(), watchLog.getVideoId(), qwUser, watchLog.getQwExternalContactId());
+
+                            QwExternalContact qwExternalContact = qwExternalContactService.selectQwExternalContactById(watchLog.getQwExternalContactId());
+                            if (qwExternalContact==null) {
+                                throw new CustomException("客户不存在");
+                            }
+                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+                            QwSopLogs sopLogs = new QwSopLogs();
+                            sopLogs.setQwUserid(qwUser.getQwUserId());
+                            sopLogs.setExternalUserId(qwExternalContact.getExternalUserId());
+                            sopLogs.setExternalId(qwExternalContact.getId());
+                            sopLogs.setLogType(2);
+                            sopLogs.setSendStatus(3L);
+                            sopLogs.setSendTime(sdf.format(new Date()));
+                            sopLogs.setCompanyId(qwUser.getCompanyId());
+                            sopLogs.setReceivingStatus(0L);
+                            sopLogs.setSopId("miniSidebar");
+                            sopLogs.setCorpId(qwUser.getCorpId());
+                            sopLogs.setFsUserId(watchLog.getUserId());
+                            sopLogs.setSort(99999999);
+                            sopLogs.setSendType(3);
+                            sopLogs.setExternalUserName(qwExternalContact.getName());
+                            sopLogs.setQwUserKey(qwUser.getId());
+
+                            QwSopCourseFinishTempSetting setting = new QwSopCourseFinishTempSetting();
+                            List<QwSopCourseFinishTempSetting.Setting> list = new ArrayList<>();
+                            QwSopCourseFinishTempSetting.Setting st = new QwSopCourseFinishTempSetting.Setting();
+                            st.setContentType("4");
+                            st.setVideoId(watchLog.getVideoId());
+                            st.setMiniprogramAppid(normalAppId);
+                            st.setMiniprogramTitle(courseVideo.getTitle());
+                            st.setMiniprogramPicUrl(userCourse.getImgUrl());
+                            st.setMiniprogramPage(linkByMiniApp);
+
+                            list.add(st);
+                            setting.setSetting(list);
+                            setting.setType(2);
+                            setting.setCourseType(0);
+                            setting.setCourseId(watchLog.getCourseId().intValue());
+                            setting.setVideoId(watchLog.getVideoId().intValue());
+
+                            sopLogs.setSendMiniAppId(normalAppId);
+                            sopLogs.setContentJson(JSON.toJSONString(setting));
+                            interruptionSopLogsList.add(sopLogs);
+                        } catch (CustomException e) {
+                            log.error("创建SOP失败,原因:{}", e.getMessage());
+                        }
+                    }
+                    if (CollectionUtils.isNotEmpty(interruptionSopLogsList)) {
+                        qwSopLogsMapper.batchInsertQwSopLogs(interruptionSopLogsList);
+                    }
+                }
+
+                //查询看课中断记录
+                List<FsCourseWatchLog> waitWatchLogs = watchLogMapper.selectTodayWatchLogs(3);
+                List<QwSopLogs> waitSopLogsList = new ArrayList<>();
+                if (CollectionUtils.isNotEmpty(waitWatchLogs)) {
+                    for (FsCourseWatchLog waitWatchLog : waitWatchLogs) {
+                        try {
+                            FsUserCourse userCourse = userCourseMapper.selectFsUserCourseByCourseId(waitWatchLog.getCourseId());
+                            if (userCourse==null) {
+                                throw new CustomException("课程不存在,请检查");
+                            }
+
+                            FsUserCourseVideo courseVideo = courseVideoMapper.selectFsUserCourseVideoByVideoId(waitWatchLog.getVideoId());
+                            if (courseVideo==null) {
+                                throw new CustomException("视频不存在,请检查");
+                            }
+
+                            QwUser qwUser = qwUserService.selectQwUserById(waitWatchLog.getQwUserId());
+
+                            if (qwUser==null||qwUser.getCompanyId()==null||qwUser.getCompanyUserId()==null){
+                                throw new CustomException("员工未绑定 客服公司 或 客服 请先绑定");
+                            }
+
+                            QwCompany qwCompany = qwCompanyService.getQwCompanyByRedis(qwUser.getCorpId());
+                            if ( qwCompany==null ) {
+                                throw new CustomException("企业不存在,请联系管理员");
+                            }
+                            String linkByMiniApp = createCourseLinkByMiniApp(new Date(), waitWatchLog.getCourseId(), waitWatchLog.getVideoId(), qwUser, waitWatchLog.getQwExternalContactId());
+
+                            QwExternalContact qwExternalContact = qwExternalContactService.selectQwExternalContactById(waitWatchLog.getQwExternalContactId());
+                            if (qwExternalContact==null) {
+                                throw new CustomException("客户不存在");
+                            }
+                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+                            QwSopLogs sopLogs = new QwSopLogs();
+                            sopLogs.setQwUserid(qwUser.getQwUserId());
+                            sopLogs.setExternalUserId(qwExternalContact.getExternalUserId());
+                            sopLogs.setExternalId(qwExternalContact.getId());
+                            sopLogs.setLogType(2);
+                            sopLogs.setSendStatus(3L);
+                            sopLogs.setSendTime(sdf.format(new Date()));
+                            sopLogs.setCompanyId(qwUser.getCompanyId());
+                            sopLogs.setReceivingStatus(0L);
+                            sopLogs.setSopId("miniSidebar");
+                            sopLogs.setCorpId(qwUser.getCorpId());
+                            sopLogs.setFsUserId(waitWatchLog.getUserId());
+                            sopLogs.setSort(99999999);
+                            sopLogs.setSendType(3);
+                            sopLogs.setExternalUserName(qwExternalContact.getName());
+                            sopLogs.setQwUserKey(qwUser.getId());
+
+                            QwSopCourseFinishTempSetting setting = new QwSopCourseFinishTempSetting();
+                            List<QwSopCourseFinishTempSetting.Setting> list = new ArrayList<>();
+                            QwSopCourseFinishTempSetting.Setting st = new QwSopCourseFinishTempSetting.Setting();
+                            st.setContentType("4");
+                            st.setVideoId(waitWatchLog.getVideoId());
+                            st.setMiniprogramAppid(normalAppId);
+                            st.setMiniprogramTitle(courseVideo.getTitle());
+                            st.setMiniprogramPicUrl(userCourse.getImgUrl());
+                            st.setMiniprogramPage(linkByMiniApp);
+
+                            list.add(st);
+                            setting.setSetting(list);
+                            setting.setType(2);
+                            setting.setCourseType(0);
+                            setting.setCourseId(waitWatchLog.getCourseId().intValue());
+                            setting.setVideoId(waitWatchLog.getVideoId().intValue());
+
+                            sopLogs.setSendMiniAppId(normalAppId);
+                            sopLogs.setContentJson(JSON.toJSONString(setting));
+                            waitSopLogsList.add(sopLogs);
+                        } catch (CustomException e) {
+                            log.error("创建待看课SOP失败,原因:{}", e.getMessage());
+                        }
+                    }
+                    if (CollectionUtils.isNotEmpty(waitSopLogsList)) {
+                        qwSopLogsMapper.batchInsertQwSopLogs(waitSopLogsList);
+                    }
+                }
+            }
         }
+    }
 
-        Map<Integer, List<CompanyMiniapp>> gradeMap = miniMap.get(Long.valueOf(companyId));
-        if (gradeMap == null) {
-            return null;
+    private boolean checkQwCompanyMainAppId(String appId) {
+        boolean result = false;
+        final WxMaService wxMaService = WxMaConfiguration.getMaService(appId);
+        String scene="collectionId";
+        try {
+            wxMaService.getQrcodeService().createWxaCodeUnlimitBytes(
+                    scene,
+                    "pages_course/customerStatistics",
+                    true,
+                    "release",//trial - 体验版  release - 正式版  develop - 开发版
+                    430,
+                    true,
+                    null,
+                    false);
+            result = true;
+        } catch (WxErrorException e) {
+            int errorCode = e.getError().getErrorCode();
+            if (errorCode == 50002) {
+                logger.info("生成二维码失败,mainAppId: {}, 错误码: {}, 错误信息: {}", appId, errorCode, e.getMessage());
+            }
+        } catch (Exception e) {
+            result = true;
+            logger.info("生成二维码失败,mainAppId: {}, 错误信息: {}", appId, e.getMessage());
         }
-        int listIndex =  5;
+        return result;
+    }
 
-        List<CompanyMiniapp> miniapps = gradeMap.get(listIndex);
+    private String createCourseLinkByMiniApp(Date sendTime, Long courseId, Long videoId,
+                                       QwUser qwUser, Long externalId) {
+        FsCourseLink link = new FsCourseLink();
+        link.setCompanyId(qwUser.getCompanyId());
+        link.setQwUserId(qwUser.getId());
+        link.setCompanyUserId(qwUser.getCompanyUserId());
+        link.setVideoId(videoId);
+        link.setCorpId(qwUser.getCorpId());
+        link.setCourseId(courseId);
+        link.setQwExternalId(externalId);
+        link.setIsRoom(1);
+        link.setUNo(UUID.randomUUID().toString());
+        link.setLinkType(3);
 
-        if (miniapps == null || miniapps.isEmpty()) {
-            return null;
+        String randomString = generateRandomStringWithLock();
+        if (StringUtil.strIsNullOrEmpty(randomString)){
+            link.setLink(UUID.randomUUID().toString().replace("-", ""));
+        }else {
+            link.setLink(randomString);
         }
 
-        CompanyMiniapp companyMiniapp = miniapps.get(0);
-        return (companyMiniapp != null && !StringUtil.strIsNullOrEmpty(companyMiniapp.getAppId()))
-                ? companyMiniapp.getAppId()
-                : null;
+        link.setCreateTime(sendTime);
+
+        FsCourseRealLink courseMap = new FsCourseRealLink();
+        BeanUtils.copyProperties(link,courseMap);
+
+        String courseJson = JSON.toJSONString(courseMap);
+
+        String realLinkFull = courseRealLink + 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);
+
+
+        return link.getRealLink();
     }
 
 }

+ 5 - 0
fs-service/src/main/java/com/fs/course/domain/FsCoursePlaySourceConfig.java

@@ -100,4 +100,9 @@ public class FsCoursePlaySourceConfig {
      * 状态 0-未封禁 1-已封禁
      */
     private Integer status;
+
+    /**
+     * 是否替换 0-否 1-是
+     */
+    private Integer replaceStatus;
 }

+ 9 - 0
fs-service/src/main/java/com/fs/course/mapper/FsCourseWatchLogMapper.java

@@ -620,4 +620,13 @@ public interface FsCourseWatchLogMapper extends BaseMapper<FsCourseWatchLog> {
 
     void batchUpdateAnswerSendStatus(@Param("list") List<FsCourseWatchLog> list);
 
+    @Select("SELECT *\n" +
+            "FROM fs_course_watch_log\n" +
+            "WHERE log_type = #{logType}  \n" +
+            "  AND (\n" +
+            "      DATE(update_time) = CURDATE()  \n" +
+            "      OR \n" +
+            "      (update_time IS NULL AND DATE(create_time) = CURDATE())  \n" +
+            "  );")
+    List<FsCourseWatchLog> selectTodayWatchLogs(@Param("logType") Integer logType);
 }

+ 10 - 0
fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigCreateParam.java

@@ -48,4 +48,14 @@ public class FsCoursePlaySourceConfigCreateParam {
 
     @ApiModelProperty("是否是互医/商城小程序")
     private Integer isMall;
+
+
+    @NotNull(message = "状态不能为空")
+    @ApiModelProperty("状态 0未封禁 1已封禁")
+    private Integer status;
+
+
+    @NotNull(message = "是否替换不能为空")
+    @ApiModelProperty("是否替换 0-否 1-是")
+    private Integer replaceStatus;
 }

+ 6 - 0
fs-service/src/main/java/com/fs/course/param/FsCoursePlaySourceConfigEditParam.java

@@ -45,4 +45,10 @@ public class FsCoursePlaySourceConfigEditParam {
 
     @ApiModelProperty("是否是互医/商城小程序")
     private Integer isMall;
+
+    @ApiModelProperty("状态 0未封禁 1已封禁")
+    private Integer status;
+
+    @ApiModelProperty("是否替换 0-否 1-是")
+    private Integer replaceStatus;
 }

+ 2 - 0
fs-service/src/main/java/com/fs/qw/mapper/QwCompanyMapper.java

@@ -47,6 +47,8 @@ public interface QwCompanyMapper
      */
     public int updateQwCompany(QwCompany qwCompany);
 
+    void batchUpdateQwCompanyMiniAppId(@Param("list") List<QwCompany> list);
+
     /**
      * 删除企微主体
      *

+ 4 - 0
fs-service/src/main/java/com/fs/sop/mapper/QwSopLogsMapper.java

@@ -365,4 +365,8 @@ public interface QwSopLogsMapper extends BaseMapper<QwSopLogs> {
                                          @Param("oldAppId") String oldAppId);
     @DataSource(DataSourceType.SOP)
     int batchUpdateQwSopLogsByIdInMiniAppId(@Param("list") List<QwSopLogs> preparedBatch);
+
+    @DataSource(DataSourceType.SOP)
+    @Select("UPDATE qw_sop_logs  SET send_status = 5 WHERE send_status = 3")
+    void wasteQwSopLogs();
 }

+ 14 - 0
fs-service/src/main/resources/mapper/qw/QwCompanyMapper.xml

@@ -157,6 +157,20 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         where id = #{id}
     </update>
 
+    <update id="batchUpdateQwCompanyMiniAppId" parameterType="java.util.List">
+        UPDATE qw_company
+        SET mini_app_id = CASE
+        <foreach collection="list" item="item">
+            WHEN id = #{item.id} THEN #{item.miniAppId}
+        </foreach>
+        ELSE mini_app_id
+        END
+        WHERE id IN
+        <foreach collection="list" item="item" open="(" separator="," close=")">
+            #{item.id}
+        </foreach>
+    </update>
+
     <delete id="deleteQwCompanyById" parameterType="Long">
         delete from qw_company where id = #{id}
     </delete>