|
|
@@ -0,0 +1,197 @@
|
|
|
+package com.fs.qw.service.impl;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.fs.common.core.domain.R;
|
|
|
+import com.fs.common.exception.CustomException;
|
|
|
+import com.fs.common.service.ISmsService;
|
|
|
+import com.fs.common.utils.DateUtils;
|
|
|
+import com.fs.common.utils.StringUtils;
|
|
|
+import com.fs.company.domain.CompanySmsTemp;
|
|
|
+import com.fs.company.service.ICompanySmsTempService;
|
|
|
+import com.fs.course.config.CourseConfig;
|
|
|
+import com.fs.his.dto.SendResultDetailDTO;
|
|
|
+import com.fs.his.mapper.FsUserMapper;
|
|
|
+import com.fs.his.utils.PhoneUtil;
|
|
|
+import com.fs.qw.domain.QwUser;
|
|
|
+import com.fs.qw.dto.SmsLinkRemindCourseDTO;
|
|
|
+import com.fs.qw.enums.SmsLogType;
|
|
|
+import com.fs.his.domain.FsUser;
|
|
|
+import com.fs.qw.mapper.QwUserMapper;
|
|
|
+import com.fs.qw.service.ISmsLinkRemindCourseService;
|
|
|
+import com.fs.qw.vo.QwSopCourseFinishTempSetting;
|
|
|
+import com.fs.sop.service.ISopUserLogsInfoService;
|
|
|
+import com.fs.system.service.ISysConfigService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * 企微-短信发送看课链接服务实现类
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class SmsLinkRemindCourseServiceImpl implements ISmsLinkRemindCourseService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ISmsService smsService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ISysConfigService configService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ICompanySmsTempService smsTempService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ISopUserLogsInfoService sopUserLogsInfoService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private QwUserMapper qwUserMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private FsUserMapper fsUserMapper;
|
|
|
+
|
|
|
+ //看课短信模板code
|
|
|
+ private static final String SMS_COURSE_TEMPLATE_CODE = "看课发送短信模板";
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public SendResultDetailDTO sendMessageLinkRemindCourse(SmsLinkRemindCourseDTO smsLinkRemindCourseDto) {
|
|
|
+
|
|
|
+ // ========== 第一阶段:基础参数校验与配置加载 ==========
|
|
|
+ // 1.1 加载课程配置
|
|
|
+ CourseConfig config = loadCourseConfig();
|
|
|
+
|
|
|
+ // ========== 第二阶段:短信模板处理 ==========
|
|
|
+ // 2.1 获取短信模板
|
|
|
+ CompanySmsTemp temp = smsTempService.selectCompanySmsTempByCode(SMS_COURSE_TEMPLATE_CODE);
|
|
|
+ if (temp == null) {
|
|
|
+ log.error("发送课程链接短信-未找到短信模板:{}", SMS_COURSE_TEMPLATE_CODE);
|
|
|
+ throw new CustomException("发送课程链接短信-未找到短信模板");
|
|
|
+ }
|
|
|
+
|
|
|
+ // ========== 第三阶段:准备基础数据 ==========
|
|
|
+ QwUser qwUser = qwUserMapper.selectQwUserByCorpIdAndUserId(smsLinkRemindCourseDto.getCorpId(), smsLinkRemindCourseDto.getUserId());
|
|
|
+ if (qwUser == null) {
|
|
|
+ log.error("发送课程链接短信-未找到企微用户corpId:{},userId:{}", smsLinkRemindCourseDto.getCorpId(), smsLinkRemindCourseDto.getUserId());
|
|
|
+ throw new CustomException("发送课程链接短信-未找到企微用户");
|
|
|
+ }
|
|
|
+ FsUser fsUser = fsUserMapper.selectFsUserById(smsLinkRemindCourseDto.getFsUserId());
|
|
|
+ if (fsUser == null) {
|
|
|
+ log.error("发送课程链接短信-未找到用户fsUserId:{}", smsLinkRemindCourseDto.getFsUserId());
|
|
|
+ throw new CustomException("发送课程链接短信-未找到用户");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (StringUtils.isBlank(fsUser.getPhone())){
|
|
|
+ log.error("发送课程链接短信-未找到用户手机号fsUserId:{}", smsLinkRemindCourseDto.getFsUserId());
|
|
|
+ throw new CustomException("发送课程链接短信-未找到用户手机号");
|
|
|
+ }
|
|
|
+ //处理手机号(存在部分加密、未加密的情况)
|
|
|
+ String phone =decryptSendLinkPhone(fsUser.getPhone());
|
|
|
+ String companyUserId = String.valueOf(qwUser.getCompanyUserId()).trim();
|
|
|
+ String companyId = String.valueOf(qwUser.getCompanyId()).trim();
|
|
|
+ String qwUserTableId = String.valueOf(qwUser.getId());
|
|
|
+ Integer videoId = smsLinkRemindCourseDto.getVideoId();
|
|
|
+ Integer courseId = smsLinkRemindCourseDto.getCourseId();
|
|
|
+ Long externalId = smsLinkRemindCourseDto.getExternalId();
|
|
|
+ Long fsUserId = smsLinkRemindCourseDto.getFsUserId();
|
|
|
+
|
|
|
+ String startTime = DateUtils.getTime();
|
|
|
+ Date createTime = DateUtils.getNowDate();
|
|
|
+
|
|
|
+ // ========== 第四阶段:添加看课记录(未走sop逻辑,无sopId) ==========
|
|
|
+ sopUserLogsInfoService.addWatchLog(
|
|
|
+ null,
|
|
|
+ videoId,
|
|
|
+ courseId,
|
|
|
+ fsUserId,
|
|
|
+ qwUserTableId,
|
|
|
+ companyUserId,
|
|
|
+ companyId,
|
|
|
+ externalId,
|
|
|
+ startTime,
|
|
|
+ createTime
|
|
|
+ );
|
|
|
+
|
|
|
+ // ========== 第五阶段:生成看课短链 ==========
|
|
|
+ QwSopCourseFinishTempSetting.Setting setting = new QwSopCourseFinishTempSetting.Setting();
|
|
|
+ String link = sopUserLogsInfoService.createSmsCourseLink(
|
|
|
+ setting,
|
|
|
+ smsLinkRemindCourseDto.getCorpId(),
|
|
|
+ createTime,
|
|
|
+ courseId,
|
|
|
+ videoId,
|
|
|
+ qwUserTableId,
|
|
|
+ companyUserId,
|
|
|
+ companyId,
|
|
|
+ externalId,
|
|
|
+ config
|
|
|
+ );
|
|
|
+
|
|
|
+ // ========== 第六阶段:校验短链生成结果 ==========
|
|
|
+ if (StringUtils.isBlank(link)) {
|
|
|
+ log.error("生成看课短链失败, phone:{}, link:{}", phone, link);
|
|
|
+ throw new CustomException("生成看课短链失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ // ========== 第七阶段:发送短信 ==========
|
|
|
+ String tempContent = temp.getContent();
|
|
|
+ if (StringUtils.isBlank(tempContent) || !tempContent.contains("${sms.courseUrl}")) {
|
|
|
+ log.error("生成看课短链时检测到短信模板选择错误,跳过设置 URL。");
|
|
|
+ throw new CustomException("短信模板内容异常");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 7.1 构建短信内容
|
|
|
+ String messageContent = tempContent
|
|
|
+ .replaceAll("【(.*?)】", "【" + config.getSmsDomain() + "】")
|
|
|
+ .replace("${sms.courseUrl}", link);
|
|
|
+
|
|
|
+ // 7.2 发送短信
|
|
|
+ try {
|
|
|
+ R result = smsService.simpleSmsSend(phone, messageContent, temp, SmsLogType.COURSE_LINK, externalId);
|
|
|
+ if (result != null && "200".equals(String.valueOf(result.get("code")))) {
|
|
|
+ return new SendResultDetailDTO(true, null, null);
|
|
|
+ } else {
|
|
|
+ String msg = result != null && result.get("msg") != null ? result.get("msg").toString() : "未知错误";
|
|
|
+ log.error("短信发送失败 , phone={}, 发送结果={}", phone, msg);
|
|
|
+ return new SendResultDetailDTO(false, msg, null);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发送异常 phone=" + phone, e);
|
|
|
+ return new SendResultDetailDTO(false, e.getMessage(), null);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 加载课程配置
|
|
|
+ */
|
|
|
+ private CourseConfig loadCourseConfig() {
|
|
|
+ String json = configService.selectConfigByKey("course.config");
|
|
|
+ CourseConfig config = JSON.parseObject(json, CourseConfig.class);
|
|
|
+ if (config == null) {
|
|
|
+ throw new CustomException("课程默认配置为空,请联系管理员");
|
|
|
+ }
|
|
|
+ return config;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解密手机号
|
|
|
+ * */
|
|
|
+ private String decryptSendLinkPhone(String phone) {
|
|
|
+ try {
|
|
|
+ if (phone.length() > 11){
|
|
|
+ return PhoneUtil.decryptPhone(phone);
|
|
|
+ } else if (phone.length()<11) {
|
|
|
+ throw new CustomException("发送课程链接短信-手机号长度异常");
|
|
|
+ }
|
|
|
+ return phone;
|
|
|
+ }catch (Exception e){
|
|
|
+ log.error("发送课程链接短信-解密手机号异常", e);
|
|
|
+ throw new CustomException("发送课程链接短信-解密手机号异常");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|