|
@@ -5,6 +5,7 @@ import java.util.Collections;
|
|
|
import java.util.Date;
|
|
|
import java.util.List;
|
|
|
|
|
|
+import cn.hutool.json.JSONUtil;
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.utils.DateUtils;
|
|
@@ -12,6 +13,7 @@ import com.fs.company.domain.Company;
|
|
|
import com.fs.company.domain.CompanyMoneyLogs;
|
|
|
import com.fs.company.mapper.CompanyMapper;
|
|
|
import com.fs.company.mapper.CompanyMoneyLogsMapper;
|
|
|
+import com.fs.course.config.CourseConfig;
|
|
|
import com.fs.course.domain.FsCourseWatchLog;
|
|
|
import com.fs.course.mapper.FsCourseWatchLogMapper;
|
|
|
import com.fs.course.param.FsCourseRedPacketLogParam;
|
|
@@ -20,7 +22,10 @@ import com.fs.his.domain.FsUser;
|
|
|
import com.fs.his.mapper.FsUserMapper;
|
|
|
import com.fs.his.param.WxSendRedPacketParam;
|
|
|
import com.fs.his.service.IFsStorePaymentService;
|
|
|
+import com.fs.system.service.ISysConfigService;
|
|
|
import com.github.binarywang.wxpay.bean.transfer.TransferBillsResult;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import com.fs.course.mapper.FsCourseRedPacketLogMapper;
|
|
@@ -37,10 +42,14 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
@Service
|
|
|
public class FsCourseRedPacketLogServiceImpl implements IFsCourseRedPacketLogService
|
|
|
{
|
|
|
+ private static final Logger logger = LoggerFactory.getLogger(FsCourseRedPacketLogServiceImpl.class);
|
|
|
@Autowired
|
|
|
private FsCourseRedPacketLogMapper fsCourseRedPacketLogMapper;
|
|
|
@Autowired
|
|
|
private CompanyMapper companyMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ISysConfigService configService;
|
|
|
/**
|
|
|
* 查询短链课程看课记录
|
|
|
*
|
|
@@ -236,4 +245,137 @@ public class FsCourseRedPacketLogServiceImpl implements IFsCourseRedPacketLogSer
|
|
|
return R.ok("成功:"+suc+" 失败:"+err);
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public void sendRedPacketBf() {
|
|
|
+ try {
|
|
|
+ logger.info("【红包发放】开始执行红包发放任务");
|
|
|
+
|
|
|
+ // 初始化查询对象
|
|
|
+ FsCourseRedPacketLog query = new FsCourseRedPacketLog();
|
|
|
+ query.setStatus(2); // 状态2表示待处理红包
|
|
|
+
|
|
|
+ // 获取红包配置
|
|
|
+ String json = configService.selectConfigByKey("course.config");
|
|
|
+ CourseConfig config = JSONUtil.toBean(json, CourseConfig.class);
|
|
|
+ logger.info("【红包发放】当前红包发放模式:{}", config.getRedPacketMode());
|
|
|
+
|
|
|
+ // 获取待处理红包列表
|
|
|
+ List<FsCourseRedPacketLog> pendingPackets = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogList(query);
|
|
|
+ if (pendingPackets == null || pendingPackets.isEmpty()) {
|
|
|
+ logger.info("【红包发放】没有待处理的红包记录");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("【红包发放】共发现{}条待处理红包记录", pendingPackets.size());
|
|
|
+
|
|
|
+ // 处理每条红包记录
|
|
|
+ for (FsCourseRedPacketLog redPacket : pendingPackets) {
|
|
|
+ try {
|
|
|
+ logger.info("【红包处理】开始处理红包记录ID:{},用户ID:{},金额:{}元",
|
|
|
+ redPacket.getLogId(), redPacket.getUserId(), redPacket.getAmount());
|
|
|
+
|
|
|
+ processRedPacket(redPacket, config);
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("【红包处理】处理红包记录ID:{}时发生异常", redPacket.getLogId(), e);
|
|
|
+ // 即使一条记录失败也继续处理下一条
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("【红包发放】红包发放任务执行完成");
|
|
|
+ } catch (Exception e) {
|
|
|
+ logger.error("【红包发放】红包发放任务执行过程中发生未预期异常", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void processRedPacket(FsCourseRedPacketLog redPacket, CourseConfig config) {
|
|
|
+ // 获取用户信息
|
|
|
+ FsUser user = fsUserMapper.selectFsUserByUserId(redPacket.getUserId());
|
|
|
+ if (user == null || user.getMpOpenId() == null) {
|
|
|
+ logger.error("【红包处理】错误:未找到用户ID:{}或用户缺少openId", redPacket.getUserId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("【红包处理】准备为用户{}发放红包,openId:{}", user.getUserId(), user.getMpOpenId());
|
|
|
+
|
|
|
+ // 准备红包参数
|
|
|
+ WxSendRedPacketParam packetParam = new WxSendRedPacketParam();
|
|
|
+ packetParam.setOpenId(user.getMpOpenId());
|
|
|
+ packetParam.setAmount(redPacket.getAmount());
|
|
|
+ packetParam.setSource(2);
|
|
|
+ packetParam.setAppId(redPacket.getAppId());
|
|
|
+ packetParam.setRedPacketMode(config.getRedPacketMode());
|
|
|
+ packetParam.setCompanyId(redPacket.getCompanyId());
|
|
|
+
|
|
|
+ // 处理企业资金(使用悲观锁)
|
|
|
+ Company company = companyMapper.selectCompanyByIdForUpdate(redPacket.getCompanyId());
|
|
|
+ if (company == null) {
|
|
|
+ logger.error("【红包处理】错误:未找到企业ID:{}", redPacket.getCompanyId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ BigDecimal remainingBalance = company.getMoney().subtract(redPacket.getAmount());
|
|
|
+ if (remainingBalance.compareTo(BigDecimal.ZERO) < 0) {
|
|
|
+ logger.warn("【红包处理】企业{}余额不足(当前余额:{}元,需要扣除:{}元)",
|
|
|
+ company.getCompanyId(), company.getMoney(), redPacket.getAmount());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ logger.info("【红包处理】企业{}当前余额:{}元,发放后余额:{}元",
|
|
|
+ company.getCompanyId(), company.getMoney(), remainingBalance);
|
|
|
+
|
|
|
+ // 发送红包
|
|
|
+ R sendRedPacketResult = paymentService.sendRedPacket(packetParam);
|
|
|
+ if (sendRedPacketResult == null) {
|
|
|
+ logger.error("【红包处理】红包接口返回空结果");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!sendRedPacketResult.get("code").equals(200)) {
|
|
|
+ logger.error("【红包处理】红包发放失败,错误码:{},错误信息:{}",
|
|
|
+ sendRedPacketResult.get("code"), sendRedPacketResult.get("msg"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理成功结果
|
|
|
+ logger.info("【红包处理】红包发放成功");
|
|
|
+
|
|
|
+ // 更新红包记录
|
|
|
+ if (sendRedPacketResult.get("isNew").equals(1)) {
|
|
|
+ TransferBillsResult transferBillsResult = (TransferBillsResult)sendRedPacketResult.get("data");
|
|
|
+ redPacket.setResult(JSON.toJSONString(sendRedPacketResult));
|
|
|
+ redPacket.setOutBatchNo(transferBillsResult.getOutBillNo());
|
|
|
+ logger.info("【红包处理】新批次红包,批次号:{}", transferBillsResult.getOutBillNo());
|
|
|
+ } else {
|
|
|
+ redPacket.setOutBatchNo(sendRedPacketResult.get("orderCode").toString());
|
|
|
+ logger.info("【红包处理】已有批次红包,订单号:{}", redPacket.getOutBatchNo());
|
|
|
+ }
|
|
|
+
|
|
|
+ fsCourseRedPacketLogMapper.updateFsCourseRedPacketLog(redPacket);
|
|
|
+
|
|
|
+ // 更新观看记录
|
|
|
+ FsCourseWatchLog watchLog = courseWatchLogMapper.selectFsCourseWatchLogByLogId(redPacket.getLogId());
|
|
|
+ if (watchLog != null) {
|
|
|
+ watchLog.setRewardType(config.getRewardType());
|
|
|
+ courseWatchLogMapper.updateFsCourseWatchLog(watchLog);
|
|
|
+ logger.info("【红包处理】更新观看记录{}的奖励类型为{}", watchLog.getLogId(), config.getRewardType());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更新企业余额
|
|
|
+ company.setMoney(remainingBalance);
|
|
|
+ companyMapper.updateCompany(company);
|
|
|
+
|
|
|
+ // 记录资金流水
|
|
|
+ CompanyMoneyLogs moneyLog = new CompanyMoneyLogs();
|
|
|
+ moneyLog.setCompanyId(company.getCompanyId());
|
|
|
+ moneyLog.setRemark("扣除红包金额");
|
|
|
+ moneyLog.setMoney(redPacket.getAmount().multiply(new BigDecimal(-1)));
|
|
|
+ moneyLog.setLogsType(15);
|
|
|
+ moneyLog.setBalance(company.getMoney());
|
|
|
+ moneyLog.setCreateTime(new Date());
|
|
|
+ moneyLogsMapper.insertCompanyMoneyLogs(moneyLog);
|
|
|
+
|
|
|
+ logger.info("【红包处理】企业资金流水记录成功,企业ID:{},变动金额:{}元",
|
|
|
+ company.getCompanyId(), moneyLog.getMoney());
|
|
|
+ }
|
|
|
+
|
|
|
}
|