|
|
@@ -21,13 +21,17 @@ import com.fs.config.cloud.CloudHostProper;
|
|
|
import com.fs.course.domain.FsCourseSop;
|
|
|
import com.fs.course.domain.FsCourseSopLogs;
|
|
|
import com.fs.course.domain.FsCourseWatchLog;
|
|
|
+import com.fs.course.domain.FsUserCourse;
|
|
|
import com.fs.course.mapper.FsCourseLinkMapper;
|
|
|
import com.fs.course.mapper.FsCourseSopLogsMapper;
|
|
|
import com.fs.course.mapper.FsCourseSopMapper;
|
|
|
import com.fs.course.mapper.FsCourseWatchLogMapper;
|
|
|
+import com.fs.course.mapper.FsUserCourseMapper;
|
|
|
import com.fs.course.param.FsCourseLinkCreateParam;
|
|
|
import com.fs.course.param.FsCourseListBySidebarParam;
|
|
|
import com.fs.course.service.IFsCourseLinkService;
|
|
|
+import com.fs.course.service.IFsUserCourseVideoService;
|
|
|
+import com.fs.course.vo.FsUserCourseVideoQVO;
|
|
|
import com.fs.crm.domain.CrmCustomer;
|
|
|
import com.fs.crm.mapper.CrmCustomerMapper;
|
|
|
import com.fs.his.domain.FsUser;
|
|
|
@@ -78,12 +82,15 @@ import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.context.annotation.Lazy;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.io.IOException;
|
|
|
import java.math.BigDecimal;
|
|
|
+import java.net.URLDecoder;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
import java.text.ParseException;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.time.*;
|
|
|
@@ -107,6 +114,10 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
|
|
|
|
|
|
private static final String miniappRealLink = "/pages_course/video.html?course=";
|
|
|
|
|
|
+ /** 欢迎语补发 SOP 日志中小程序卡片封面兜底图(解析课程图失败时使用) */
|
|
|
+ private static final String DEFAULT_REISSUE_MINIPROGRAM_PIC =
|
|
|
+ "https://cos.his.cdwjyyh.com/fs/20250331/ec2b4e73be8048afbd526124a655ad56.png";
|
|
|
+
|
|
|
@Autowired
|
|
|
private QwExternalContactMapper qwExternalContactMapper;
|
|
|
@Autowired
|
|
|
@@ -199,6 +210,13 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
|
|
|
@Autowired
|
|
|
private IFsCourseLinkService iFsCourseLinkService;
|
|
|
|
|
|
+ @Lazy
|
|
|
+ @Autowired
|
|
|
+ private IFsUserCourseVideoService fsUserCourseVideoService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private FsUserCourseMapper fsUserCourseMapper;
|
|
|
+
|
|
|
@Autowired
|
|
|
private IQwExternalErrRetryService errRetryService;
|
|
|
|
|
|
@@ -2971,7 +2989,7 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
|
|
|
settingItem.setContentType("4");
|
|
|
settingItem.setMiniprogramAppid(item.getMiniprogram().getAppid());
|
|
|
settingItem.setMiniprogramPage(item.getMiniprogram().getPage());
|
|
|
- settingItem.setMiniprogramPicUrl("https://cos.his.cdwjyyh.com/fs/20250331/ec2b4e73be8048afbd526124a655ad56.png");
|
|
|
+ settingItem.setMiniprogramPicUrl(resolveMiniprogramCoverPicUrlForSopLog(item.getMiniprogram()));
|
|
|
settingItem.setMiniprogramTitle(item.getMiniprogram().getTitle());
|
|
|
break;
|
|
|
default:
|
|
|
@@ -2986,6 +3004,73 @@ public class QwExternalContactServiceImpl extends ServiceImpl<QwExternalContactM
|
|
|
return setting;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 补发欢迎语写入 SOP 日志时:小程序卡片封面优先取课节缩略图 thumbnail,
|
|
|
+ * 与后台 {@code FsUserCourseVideoController#getInfo} 中 {@code selectFsUserCourseVideoByVideoIdVO(videoId, null)} 一致;
|
|
|
+ * 若无 thumbnail 再尝试课程封面;videoId/courseId 可从附件或 page 上 {@code ?course=} JSON 解析。
|
|
|
+ */
|
|
|
+ private String resolveMiniprogramCoverPicUrlForSopLog(SendWelcomeMsgParam.Attachment.MiniProgramAttachment miniprogram) {
|
|
|
+ if (miniprogram == null) {
|
|
|
+ return DEFAULT_REISSUE_MINIPROGRAM_PIC;
|
|
|
+ }
|
|
|
+ Long videoId = null;
|
|
|
+ Long courseId = null;
|
|
|
+ if (!StringUtil.strIsNullOrEmpty(miniprogram.getVideoId())) {
|
|
|
+ try {
|
|
|
+ videoId = Long.valueOf(miniprogram.getVideoId());
|
|
|
+ } catch (NumberFormatException ignored) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!StringUtil.strIsNullOrEmpty(miniprogram.getCourseId())) {
|
|
|
+ try {
|
|
|
+ courseId = Long.valueOf(miniprogram.getCourseId());
|
|
|
+ } catch (NumberFormatException ignored) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (videoId == null && courseId == null && !StringUtil.strIsNullOrEmpty(miniprogram.getPage())) {
|
|
|
+ String page = miniprogram.getPage();
|
|
|
+ int q = page.indexOf("?course=");
|
|
|
+ if (q >= 0) {
|
|
|
+ String jsonPart = page.substring(q + "?course=".length());
|
|
|
+ try {
|
|
|
+ if (jsonPart.contains("%")) {
|
|
|
+ jsonPart = URLDecoder.decode(jsonPart, StandardCharsets.UTF_8.name());
|
|
|
+ }
|
|
|
+ com.alibaba.fastjson.JSONObject obj = JSON.parseObject(jsonPart);
|
|
|
+ if (obj != null) {
|
|
|
+ if (obj.containsKey("videoId") && obj.get("videoId") != null) {
|
|
|
+ try {
|
|
|
+ videoId = obj.getLong("videoId");
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (obj.containsKey("courseId") && obj.get("courseId") != null) {
|
|
|
+ try {
|
|
|
+ courseId = obj.getLong("courseId");
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.debug("解析欢迎语小程序 path 中的 course 参数失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (videoId != null) {
|
|
|
+ FsUserCourseVideoQVO videoQvo = fsUserCourseVideoService.selectFsUserCourseVideoByVideoIdVO(videoId, null);
|
|
|
+ if (videoQvo != null && StringUtils.isNotEmpty(videoQvo.getThumbnail())) {
|
|
|
+ return videoQvo.getThumbnail();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (courseId != null) {
|
|
|
+ FsUserCourse course = fsUserCourseMapper.selectFsUserCourseByCourseId(courseId);
|
|
|
+ if (course != null && StringUtils.isNotEmpty(course.getImgUrl())) {
|
|
|
+ return course.getImgUrl();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return DEFAULT_REISSUE_MINIPROGRAM_PIC;
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public void insertQwExternalContactByExternalUserId2(String externalUserID, String userID, Long companyId, String corpId, String state, String welcomeCode) throws ParseException {
|
|
|
|