|
|
@@ -1,42 +1,61 @@
|
|
|
package com.fs.app.service;
|
|
|
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
import com.fs.common.core.redis.RedisCache;
|
|
|
import com.fs.common.exception.base.BaseException;
|
|
|
import com.fs.common.utils.StringUtils;
|
|
|
import com.fs.common.utils.date.DateUtil;
|
|
|
+import com.fs.company.domain.Company;
|
|
|
import com.fs.company.domain.CompanyMiniapp;
|
|
|
+import com.fs.company.mapper.CompanyMapper;
|
|
|
import com.fs.company.service.ICompanyMiniappService;
|
|
|
+import com.fs.course.config.CourseConfig;
|
|
|
import com.fs.course.domain.FsCoursePlaySourceConfig;
|
|
|
import com.fs.course.domain.FsCourseWatchLog;
|
|
|
import com.fs.course.service.IFsCourseWatchLogService;
|
|
|
+import com.fs.his.domain.FsUser;
|
|
|
+import com.fs.his.mapper.FsUserMapper;
|
|
|
import com.fs.ipad.IpadSendUtils;
|
|
|
import com.fs.ipad.vo.*;
|
|
|
+import com.fs.qw.domain.BindPhoneRedPacketRecord;
|
|
|
import com.fs.qw.domain.QwUser;
|
|
|
import com.fs.qw.domain.QwUserVideo;
|
|
|
+import com.fs.qw.domain.RedPacket;
|
|
|
+import com.fs.qw.mapper.BindPhoneRedPacketRecordMapper;
|
|
|
import com.fs.qw.mapper.QwExternalContactMapper;
|
|
|
import com.fs.qw.mapper.QwUserMapper;
|
|
|
import com.fs.qw.service.IQwUserService;
|
|
|
import com.fs.qw.service.IQwUserVideoService;
|
|
|
+import com.fs.qw.service.IRedPacketService;
|
|
|
import com.fs.qw.vo.QwSopCourseFinishTempSetting;
|
|
|
import com.fs.qwApi.param.QwExternalContactHParam;
|
|
|
import com.fs.sop.domain.QwSopLogs;
|
|
|
import com.fs.sop.service.IQwSopLogsService;
|
|
|
import com.fs.sop.service.impl.QwSopLogsServiceImpl;
|
|
|
+import com.fs.system.service.ISysConfigService;
|
|
|
import com.fs.wxwork.dto.*;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
+import java.time.ZoneId;
|
|
|
+import java.util.Date;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
|
|
|
@Slf4j
|
|
|
@Service
|
|
|
@AllArgsConstructor
|
|
|
public class IpadSendServer {
|
|
|
-
|
|
|
+ private static final Pattern LINK_PATTERN = Pattern.compile("link=([^&]+)");
|
|
|
private final QwUserMapper qwUserMapper;
|
|
|
private final IQwUserService qwUserService;
|
|
|
private final IpadSendUtils ipadSendUtils;
|
|
|
@@ -47,6 +66,21 @@ public class IpadSendServer {
|
|
|
private final RedisCache redisCache;
|
|
|
private final ICompanyMiniappService companyMiniappService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private ISysConfigService configService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private IRedPacketService redPacketService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private BindPhoneRedPacketRecordMapper bindPhoneRedPacketRecordMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private CompanyMapper companyMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private FsUserMapper fsUserMapper;
|
|
|
+
|
|
|
//private final LiveWatchLogMapper liveWatchLogMapper;
|
|
|
|
|
|
|
|
|
@@ -507,6 +541,31 @@ public class IpadSendServer {
|
|
|
// 语音
|
|
|
sendWxVideo(vo, content);
|
|
|
break;
|
|
|
+ case "14":
|
|
|
+ log.info("===============进入授权手机号红包=============");
|
|
|
+ // 记录授权手机号红包发送记录
|
|
|
+ RedPacket redPacket = redPacketService.selectRedPacketById(content.getRedPacketId());
|
|
|
+ if (ObjectUtil.isNotEmpty(redPacket) && redPacket.getStatus().equals("0")) {
|
|
|
+ qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(),"手机号授权红包已禁用");
|
|
|
+ } else if (ObjectUtil.isNotEmpty(qwSopLogs.getFsUserId())) {
|
|
|
+ //查询用户领取记录
|
|
|
+ BindPhoneRedPacketRecord record = new BindPhoneRedPacketRecord();
|
|
|
+ record.setUserId(qwSopLogs.getFsUserId());
|
|
|
+ record.setCollectType("1");
|
|
|
+ List<BindPhoneRedPacketRecord> records = bindPhoneRedPacketRecordMapper.selectBindPhoneRedPacketRecordList(record);
|
|
|
+ if (ObjectUtil.isNotEmpty(records)) {
|
|
|
+ qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(),"用户已领取过手机号授权红包");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ try{
|
|
|
+ Long businessId = addRedPacketCollectRecord(redPacket,qwUser, content,qwSopLogs);
|
|
|
+ content.setMiniprogramPage(quickProcess(content.getMiniprogramPage(),businessId));
|
|
|
+ //手机号授权红包
|
|
|
+ sendMiniProgram(vo, content, miniMap,qwUser.getCompanyId());
|
|
|
+ }catch (Exception e){
|
|
|
+ qwSopLogsService.updateQwSopLogsByWatchLogType(qwSopLogs.getId(), "手机号授权红包发放失败,请重新发送!");
|
|
|
+ }
|
|
|
+ break;
|
|
|
case "21":
|
|
|
content.setSendStatus(0);
|
|
|
content.setSendRemarks("短信待发送");
|
|
|
@@ -523,6 +582,257 @@ public class IpadSendServer {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ public Long addRedPacketCollectRecord(RedPacket redPacket, QwUser qwUser, QwSopCourseFinishTempSetting.Setting content, QwSopLogs qwSopLogs) {
|
|
|
+
|
|
|
+ try{
|
|
|
+ String json = configService.selectConfigByKey("course.config");
|
|
|
+ CourseConfig config = JSON.parseObject(json, CourseConfig.class);
|
|
|
+ Date updateTime = createUpdateTime(content, new Date(), config);
|
|
|
+ String companyUserId = String.valueOf(qwUser.getCompanyUserId()).trim();
|
|
|
+ String companyId = String.valueOf(qwUser.getCompanyId()).trim();
|
|
|
+ Long businessId = addRedPacketCollectRecord(qwUser,redPacket,content,qwSopLogs,updateTime,companyUserId,companyId,content.getChatId());
|
|
|
+ return businessId;
|
|
|
+ }catch (Exception e){
|
|
|
+ log.error("授权手机号红包创建失败:qwUser={},qwSopLogs={}",qwUser,qwSopLogs);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 优化版快速处理方法
|
|
|
+ */
|
|
|
+ public static String quickProcess(String miniprogramPage, Long businessId) {
|
|
|
+ if (miniprogramPage == null || businessId == null) {
|
|
|
+ return miniprogramPage;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ Matcher matcher = LINK_PATTERN.matcher(miniprogramPage);
|
|
|
+ if (matcher.find()) {
|
|
|
+ String encodedLink = matcher.group(1);
|
|
|
+
|
|
|
+ // 第一次URL解码
|
|
|
+ String decodedLink = java.net.URLDecoder.decode(encodedLink, "UTF-8");
|
|
|
+
|
|
|
+ // 处理多次转义的情况:如果解码后仍有转义字符,继续解码
|
|
|
+ String jsonStr = decodedLink;
|
|
|
+ while (jsonStr.contains("\\\"") || jsonStr.contains("\\\\")) {
|
|
|
+ // 检查是否是合法的JSON格式
|
|
|
+ if (jsonStr.trim().startsWith("{") && jsonStr.trim().endsWith("}")) {
|
|
|
+ break; // 已经是JSON对象字符串,不需要再解码
|
|
|
+ }
|
|
|
+ // 尝试再次解码
|
|
|
+ try {
|
|
|
+ jsonStr = java.net.URLDecoder.decode(jsonStr, "UTF-8");
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 如果解码失败,说明不是URL编码,跳出循环
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 清理JSON字符串中的转义字符
|
|
|
+ jsonStr = cleanJsonString(jsonStr);
|
|
|
+
|
|
|
+ // 解析JSON
|
|
|
+ JSONObject linkJson = JSON.parseObject(jsonStr);
|
|
|
+
|
|
|
+ // 检查并添加businessId
|
|
|
+ if (!linkJson.containsKey("businessId") ||
|
|
|
+ linkJson.getString("businessId") == null ||
|
|
|
+ linkJson.getString("businessId").isEmpty()) {
|
|
|
+
|
|
|
+ linkJson.put("businessId", businessId);
|
|
|
+
|
|
|
+ // 重新编码(只编码一次)
|
|
|
+ String updatedJson = linkJson.toJSONString();
|
|
|
+ String updatedEncoded = java.net.URLEncoder.encode(updatedJson, "UTF-8");
|
|
|
+
|
|
|
+ // 替换原link参数
|
|
|
+ return miniprogramPage.replace(
|
|
|
+ "link=" + encodedLink,
|
|
|
+ "link=" + updatedEncoded
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return miniprogramPage;
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 记录错误日志,这里可以替换为你的日志框架
|
|
|
+ System.err.println("处理小程序页面链接失败: " + e.getMessage());
|
|
|
+ e.printStackTrace();
|
|
|
+ // 根据业务需求,可以选择抛出异常或返回原字符串
|
|
|
+ // throw new RuntimeException("处理小程序页面链接失败", e);
|
|
|
+ return miniprogramPage; // 失败时返回原字符串,避免影响主流程
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清理JSON字符串中的多余转义
|
|
|
+ */
|
|
|
+ private static String cleanJsonString(String jsonStr) {
|
|
|
+ if (jsonStr == null || jsonStr.isEmpty()) {
|
|
|
+ return jsonStr;
|
|
|
+ }
|
|
|
+
|
|
|
+ String result = jsonStr;
|
|
|
+
|
|
|
+ // 移除多余的转义
|
|
|
+ result = result.replace("\\\"", "\"");
|
|
|
+ result = result.replace("\\\\", "\\");
|
|
|
+
|
|
|
+ // 处理开头和结尾的转义引号
|
|
|
+ if (result.startsWith("\"") && result.endsWith("\"")) {
|
|
|
+ result = result.substring(1, result.length() - 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 过期时间
|
|
|
+ *
|
|
|
+ * @param setting
|
|
|
+ * @param sendTime
|
|
|
+ * @param config
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private Date createUpdateTime(QwSopCourseFinishTempSetting.Setting setting, Date sendTime, CourseConfig config) {
|
|
|
+
|
|
|
+ Integer expireDays = (setting.getExpiresDays() == null || setting.getExpiresDays() == 0)
|
|
|
+ ? config.getVideoLinkExpireDate()
|
|
|
+ : setting.getExpiresDays();
|
|
|
+
|
|
|
+// 使用 Java 8 时间 API 计算过期时间
|
|
|
+ LocalDateTime sendDateTime = sendTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
|
|
+ LocalDateTime expireDateTime = sendDateTime.plusDays(expireDays - 1);
|
|
|
+ expireDateTime = expireDateTime.toLocalDate().atTime(23, 59, 59);
|
|
|
+ Date updateTime = Date.from(expireDateTime.atZone(ZoneId.systemDefault()).toInstant());
|
|
|
+
|
|
|
+ return updateTime;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 增加授权手机号红包发放记录、领取记录
|
|
|
+ *
|
|
|
+ * @param companyId
|
|
|
+ * @param qwUser
|
|
|
+ * @param redPacket
|
|
|
+ * @param content
|
|
|
+ * @param qwSopLogs
|
|
|
+ * @param sendTime
|
|
|
+ * @param companyUserId
|
|
|
+ * @param chatId
|
|
|
+ */
|
|
|
+ private Long addRedPacketCollectRecord(QwUser qwUser, RedPacket redPacket, QwSopCourseFinishTempSetting.Setting content,
|
|
|
+ QwSopLogs qwSopLogs,
|
|
|
+ Date sendTime,
|
|
|
+ String companyUserId,
|
|
|
+ String companyId,
|
|
|
+ String chatId) {
|
|
|
+ try {
|
|
|
+ // 参数校验
|
|
|
+ if (content == null || qwSopLogs == null || sendTime == null) {
|
|
|
+ log.error("添加授权手机号红包记录失败:必要参数为空 [content:{}, qwSopLogs:{}, sendTime:{}]",
|
|
|
+ content, qwSopLogs, sendTime);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 验证授权手机号红包ID
|
|
|
+ if (content.getRedPacketId() == null) {
|
|
|
+ log.error("授权手机号红包ID为空");
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询授权手机号红包信息
|
|
|
+ if (redPacket == null) {
|
|
|
+ log.error("未找到对应的授权手机号红包信息 [luckyBagId:{}]", content.getRedPacketId());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查授权手机号红包状态
|
|
|
+ if (redPacket.getStatus().equals("0")) {
|
|
|
+ log.error("授权手机号红包被禁用 [luckyBagId:{}]", content.getRedPacketId());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询公司信息
|
|
|
+ Company company = (Company)redisCache.getCacheObject("redPacketCompanyId:"+companyId);
|
|
|
+ if (company == null) {
|
|
|
+ company = companyMapper.selectCompanyById(Long.valueOf(companyId));
|
|
|
+ redisCache.setCacheObject("redPacketCompanyId:"+companyId, company, 1 , TimeUnit.DAYS);
|
|
|
+ log.error("未找到对应的公司信息 [companyId:{}]", companyId);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建授权手机号红包记录
|
|
|
+ BindPhoneRedPacketRecord bindPhoneRedPacketRecord = buildRePacketRecord(qwUser, content, qwSopLogs, sendTime,
|
|
|
+ companyUserId, companyId, chatId, company, redPacket);
|
|
|
+ bindPhoneRedPacketRecord.setSendTime(new Date());
|
|
|
+ bindPhoneRedPacketRecord.setCollectType("0");
|
|
|
+ // 插入记录并返回ID
|
|
|
+ int result = bindPhoneRedPacketRecordMapper.insertBindPhoneRedPacketRecord(bindPhoneRedPacketRecord);
|
|
|
+ if (result <= 0) {
|
|
|
+ log.error("授权手机号红包记录插入失败 [luckyBagId:{}]", content.getRedPacketId());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 返回新增记录的ID
|
|
|
+ Long recordId = bindPhoneRedPacketRecord.getId();
|
|
|
+ if (recordId == null) {
|
|
|
+ log.error("授权手机号红包记录插入成功但未返回ID [luckyBagId:{}]", content.getRedPacketId());
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ log.info("授权手机号红包记录添加成功 [recordId:{}, luckyBagId:{}]", recordId, content.getRedPacketId());
|
|
|
+ return recordId;
|
|
|
+
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ log.error("ID转换失败 [companyId:{}, companyUserId:{}]", companyId, companyUserId, e);
|
|
|
+ return null;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("ID:" + (content != null ? content.getRedPacketId() : "unknown") + "-添加授权手机号红包记录失败", e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构建授权手机号红包记录对象
|
|
|
+ */
|
|
|
+ private BindPhoneRedPacketRecord buildRePacketRecord(QwUser qwUser,QwSopCourseFinishTempSetting.Setting content,
|
|
|
+ QwSopLogs qwSopLogs,
|
|
|
+ Date sendTime,
|
|
|
+ String companyUserId,
|
|
|
+ String companyId,
|
|
|
+ String chatId,
|
|
|
+ Company company,
|
|
|
+ RedPacket redPacket) {
|
|
|
+ BindPhoneRedPacketRecord record = new BindPhoneRedPacketRecord();
|
|
|
+ record.setQwUserId(qwUser.getQwUserId());
|
|
|
+ record.setQwUserName(qwUser.getQwUserName());
|
|
|
+ record.setRedPacketId(content.getRedPacketId());
|
|
|
+ record.setCollectType("3");
|
|
|
+ record.setCompanyId(Long.valueOf(companyId));
|
|
|
+ record.setUserId(qwSopLogs.getFsUserId());
|
|
|
+ if (ObjectUtil.isNotEmpty(qwSopLogs.getFsUserId())){
|
|
|
+ FsUser fsUser = fsUserMapper.selectFsUserByUserId(qwSopLogs.getFsUserId());
|
|
|
+ record.setUserName(ObjectUtil.isNotEmpty(fsUser)?fsUser.getNickName():null);
|
|
|
+ }
|
|
|
+ record.setCompanyName(company.getCompanyName());
|
|
|
+ record.setCompanyUserId(Long.valueOf(companyUserId));
|
|
|
+ record.setSendLink(content.getMiniprogramPage());
|
|
|
+
|
|
|
+ // 设置奖励类型和聊天信息
|
|
|
+ if (StringUtils.isNotEmpty(chatId)) {
|
|
|
+ record.setRewardType(1L);
|
|
|
+ record.setChatId(chatId);
|
|
|
+ record.setExternalUserName(qwSopLogs.getExternalUserName());
|
|
|
+ } else {
|
|
|
+ record.setRewardType(2L);
|
|
|
+ }
|
|
|
+
|
|
|
+ record.setAmount(redPacket.getAmount());
|
|
|
+
|
|
|
+ return record;
|
|
|
+ }
|
|
|
+
|
|
|
public void loginOut(QwUser user) {
|
|
|
ipadSendUtils.loginOut(user.getUid(), user.getServerId());
|
|
|
}
|