|
|
@@ -12,16 +12,18 @@ import com.alibaba.fastjson.JSON;
|
|
|
import com.fs.common.constant.FsConstants;
|
|
|
import com.fs.common.core.domain.R;
|
|
|
import com.fs.common.core.redis.RedisCache;
|
|
|
+import com.fs.common.exception.CustomException;
|
|
|
import com.fs.common.utils.DateUtils;
|
|
|
import com.fs.common.utils.SecurityUtils;
|
|
|
import com.fs.common.utils.StringUtils;
|
|
|
import com.fs.company.domain.*;
|
|
|
import com.fs.company.mapper.*;
|
|
|
import com.fs.company.param.CompanyParam;
|
|
|
-import com.fs.company.service.ICompanyMiniappService;
|
|
|
-import com.fs.company.service.ICompanyProfitService;
|
|
|
-import com.fs.company.service.ICompanyRoleService;
|
|
|
+import com.fs.company.service.*;
|
|
|
import com.fs.company.vo.*;
|
|
|
+import com.fs.course.config.CourseConfig;
|
|
|
+import com.fs.course.config.RedPacketConfig;
|
|
|
+import com.fs.course.domain.FsCourseRedPacketLog;
|
|
|
import com.fs.course.mapper.FsCourseRedPacketLogMapper;
|
|
|
import com.fs.his.config.StoreConfig;
|
|
|
import com.fs.his.domain.FsInquiryOrder;
|
|
|
@@ -37,6 +39,14 @@ import com.fs.store.config.CompanyMenuConfig;
|
|
|
import com.fs.system.domain.SysConfig;
|
|
|
import com.fs.system.mapper.SysConfigMapper;
|
|
|
import com.fs.system.service.ISysConfigService;
|
|
|
+import com.github.binarywang.wxpay.bean.transfer.QueryTransferBatchesRequest;
|
|
|
+import com.github.binarywang.wxpay.bean.transfer.QueryTransferBatchesResult;
|
|
|
+import com.github.binarywang.wxpay.bean.transfer.TransferBillsGetResult;
|
|
|
+import com.github.binarywang.wxpay.config.WxPayConfig;
|
|
|
+import com.github.binarywang.wxpay.exception.WxPayException;
|
|
|
+import com.github.binarywang.wxpay.service.TransferService;
|
|
|
+import com.github.binarywang.wxpay.service.WxPayService;
|
|
|
+import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
|
|
|
import com.github.pagehelper.PageHelper;
|
|
|
import com.google.gson.Gson;
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
@@ -45,10 +55,10 @@ import org.redisson.api.RLock;
|
|
|
import org.redisson.api.RedissonClient;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
-import com.fs.company.service.ICompanyService;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.transaction.support.TransactionTemplate;
|
|
|
|
|
|
@@ -114,6 +124,156 @@ public class CompanyServiceImpl implements ICompanyService
|
|
|
@Autowired
|
|
|
private TransactionTemplate transactionTemplate;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private CompanyRedPacketBalanceLogsMapper companyRedPacketBalanceLogsMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private ICompanyConfigService companyConfigService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String checkMchTransferStatus(String outBatchNo,Long companyId) {
|
|
|
+
|
|
|
+ // 查看红包发送配置
|
|
|
+ String json = configService.selectConfigByKey("course.config");
|
|
|
+ CourseConfig courseConfig = JSONUtil.toBean(json, CourseConfig.class);
|
|
|
+ RedPacketConfig config;
|
|
|
+ switch (courseConfig.getRedPacketMode()){// 1-总配置 2- 分公司配置
|
|
|
+ case 1:
|
|
|
+ json = configService.selectConfigByKey("redPacket.config");
|
|
|
+ config = JSONUtil.toBean(json, RedPacketConfig.class);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ json = companyConfigService.selectRedPacketConfigByKey(companyId);
|
|
|
+ //如果分公司配置为空就走总后台的配置
|
|
|
+ if (StringUtils.isEmpty(json)){
|
|
|
+ json = configService.selectConfigByKey("redPacket.config");
|
|
|
+ }
|
|
|
+ config = JSONUtil.toBean(json, RedPacketConfig.class);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new UnsupportedOperationException("当前红包模式不支持!");
|
|
|
+ }
|
|
|
+
|
|
|
+ WxPayConfig payConfig = new WxPayConfig();
|
|
|
+ BeanUtils.copyProperties(config, payConfig);
|
|
|
+
|
|
|
+ WxPayService wxPayService = new WxPayServiceImpl();
|
|
|
+ wxPayService.setConfig(payConfig);
|
|
|
+
|
|
|
+ TransferService transferService = wxPayService.getTransferService();
|
|
|
+
|
|
|
+ if (Objects.isNull(config.getIsNew()) || !Arrays.asList(0,1).contains(config.getIsNew())) {
|
|
|
+ logger.error("红包配置错误 isNew is err");
|
|
|
+ throw new CustomException("红包配置错误 isNew is err ");
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ if (config.getIsNew() == 0) {
|
|
|
+ QueryTransferBatchesRequest request = new QueryTransferBatchesRequest();
|
|
|
+ request.setOutBatchNo(outBatchNo);
|
|
|
+ request.setNeedQueryDetail(true);
|
|
|
+ request.setOffset(0);
|
|
|
+ request.setLimit(20);
|
|
|
+ request.setDetailStatus("ALL");
|
|
|
+ QueryTransferBatchesResult result = transferService.transferBatchesOutBatchNo(request);
|
|
|
+ List<QueryTransferBatchesResult.TransferDetail> detailList = result.getTransferDetailList();
|
|
|
+ boolean isSuccess = detailList.stream().anyMatch(d -> "SUCCESS".equals(d.getDetailStatus()));
|
|
|
+ if (isSuccess) {
|
|
|
+ return result.getTransferBatch().getBatchId();
|
|
|
+ }
|
|
|
+
|
|
|
+ boolean isFail = detailList.stream().anyMatch(d -> "FAIL".equals(d.getDetailStatus()));
|
|
|
+ if (isFail) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ TransferBillsGetResult result = transferService.getBillsByOutBillNo(outBatchNo);
|
|
|
+ if ("SUCCESS".equals(result.getState())) {
|
|
|
+ return result.getTransferBillNo();
|
|
|
+ } else if ("FAIL".equals(result.getState())) {
|
|
|
+ return "";
|
|
|
+ } else if ("CANCELLED".equals(result.getState())) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (WxPayException e) {
|
|
|
+ logger.error("查询转账单失败 err: {}", e.getMessage(), e);
|
|
|
+ throw new CustomException("查询转账单失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ throw new CustomException("转账处理中");
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R checkMchTransferStatusByBatchID(String batchId, Long companyId) {
|
|
|
+ // 获取配置信息
|
|
|
+ CourseConfig courseConfig = JSONUtil.toBean(configService.selectConfigByKey("course.config"), CourseConfig.class);
|
|
|
+
|
|
|
+ String json;
|
|
|
+ RedPacketConfig config = new RedPacketConfig();
|
|
|
+ // 根据红包模式获取配置
|
|
|
+ switch (courseConfig.getRedPacketMode()){
|
|
|
+ case 1:
|
|
|
+ json = configService.selectConfigByKey("redPacket.config");
|
|
|
+ config = JSONUtil.toBean(json, RedPacketConfig.class);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ json = companyConfigService.selectRedPacketConfigByKey(companyId);
|
|
|
+ //如果分公司配置为空就走总后台的配置
|
|
|
+ if (StringUtils.isEmpty(json)){
|
|
|
+ json = configService.selectConfigByKey("redPacket.config");
|
|
|
+ }
|
|
|
+ config = JSONUtil.toBean(json, RedPacketConfig.class);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new UnsupportedOperationException("当前红包模式不支持!");
|
|
|
+ }
|
|
|
+
|
|
|
+ //创建微信订单
|
|
|
+ WxPayConfig payConfig = new WxPayConfig();
|
|
|
+ BeanUtils.copyProperties(config,payConfig);
|
|
|
+ WxPayService wxPayService = new WxPayServiceImpl();
|
|
|
+ wxPayService.setConfig(payConfig);
|
|
|
+ TransferService transferService=wxPayService.getTransferService();
|
|
|
+
|
|
|
+ Map<String,Object> map = new HashMap<>();
|
|
|
+ map.put("status","待确认"); //
|
|
|
+ if (config.getIsNew() != null && config.getIsNew() == 1) {
|
|
|
+ try {
|
|
|
+ TransferBillsGetResult queryRedPacketResult = transferService.getBillsByTransferBillNo(batchId);
|
|
|
+ logger.info("FsCourseRedPacketLog-batchId:{},【红包处理】查询批次结果:{}",batchId,queryRedPacketResult.toString());
|
|
|
+ if(("SUCCESS").equals(queryRedPacketResult.getState())){
|
|
|
+ map.put("status","success");
|
|
|
+ }else if(("FAIL").equals(queryRedPacketResult.getState())){
|
|
|
+ map.put("status","fail");
|
|
|
+ }
|
|
|
+ return R.ok(map);
|
|
|
+ } catch (WxPayException e) {
|
|
|
+ logger.error(e.getMessage());
|
|
|
+ return R.error(e.getMessage());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ QueryTransferBatchesRequest request = new QueryTransferBatchesRequest();
|
|
|
+ request.setBatchId(batchId);
|
|
|
+ request.setNeedQueryDetail(false);
|
|
|
+
|
|
|
+ try {
|
|
|
+ QueryTransferBatchesResult queryTransferBatchesResult = transferService.transferBatchesBatchId(request);
|
|
|
+ logger.info("FsCourseRedPacketLog-batchId,【红包处理】查询批次结果:{}",batchId,queryTransferBatchesResult.toString());
|
|
|
+ if(("FINISHED").equals(queryTransferBatchesResult.getTransferBatch().getBatchStatus())){
|
|
|
+ map.put("status","success");
|
|
|
+ }else if(("CLOSED").equals(queryTransferBatchesResult.getTransferBatch().getBatchStatus())){
|
|
|
+ map.put("status","fail");
|
|
|
+ }
|
|
|
+ return R.ok(map);
|
|
|
+ } catch (WxPayException e) {
|
|
|
+ logger.error(e.getMessage());
|
|
|
+ return R.error(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
@Override
|
|
|
public List<OptionsVO> selectAllCompanyList(Long deptId) {
|
|
|
return companyMapper.selectAllCompanyList(deptId);
|
|
|
@@ -1380,7 +1540,7 @@ public class CompanyServiceImpl implements ICompanyService
|
|
|
// 记录余额变更日志
|
|
|
String remark = "同步公司余额,差额: " + amount+"(正数为增加,负数为扣减)";
|
|
|
// 实际不发生交易只是从缓存同步金额到数据库中 交易金额登记为0,备注清楚同步的金额
|
|
|
- asyncRecordBalanceLog(company.getCompanyId(),new BigDecimal(0),17,redisMoney,remark);
|
|
|
+ asyncRecordBalanceLog(company.getCompanyId(),new BigDecimal(0),17,redisMoney,remark, null);
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
@@ -1433,7 +1593,7 @@ public class CompanyServiceImpl implements ICompanyService
|
|
|
redisCache.setCacheObject(companyMoneyKey, newMoney.toString());
|
|
|
|
|
|
// 异步登记余额添加日志
|
|
|
- asyncRecordBalanceLog(companyId,money,16,newMoney,"红包充值(负数为扣款)");
|
|
|
+ asyncRecordBalanceLog(companyId,money,16,newMoney,"红包充值(负数为扣款)", null);
|
|
|
|
|
|
} else {
|
|
|
logger.error("获取redis锁失败,异常请求参数companyId:{},money:{},type:{}",companyId,money, type);
|
|
|
@@ -1459,28 +1619,29 @@ public class CompanyServiceImpl implements ICompanyService
|
|
|
|
|
|
/**
|
|
|
* 异步登记余额添加日志 xgb
|
|
|
+ *
|
|
|
* @param companyId 公司ID
|
|
|
- * @param money 变更金额
|
|
|
- * @param balance 当前余额
|
|
|
- * @param remark 备注信息
|
|
|
- * @param logType 16-红包余额充值 15-红包余额扣除 17-同步公司余额
|
|
|
+ * @param money 变更金额
|
|
|
+ * @param logType 16-红包余额充值 15-红包余额扣除 17-同步公司余额
|
|
|
+ * @param balance 当前余额
|
|
|
+ * @param remark 备注信息
|
|
|
+ * @param logId
|
|
|
*/
|
|
|
@Async
|
|
|
@Override
|
|
|
- public void asyncRecordBalanceLog(Long companyId, BigDecimal money,Integer logType, BigDecimal balance, String remark) {
|
|
|
+ public void asyncRecordBalanceLog(Long companyId, BigDecimal money, Integer logType, BigDecimal balance, String remark, Long logId) {
|
|
|
try {
|
|
|
- CompanyMoneyLogs log = new CompanyMoneyLogs();
|
|
|
+ CompanyRedPacketBalanceLogs log = new CompanyRedPacketBalanceLogs();
|
|
|
log.setCompanyId(companyId);
|
|
|
log.setRemark(remark);
|
|
|
log.setMoney(money);
|
|
|
log.setLogsType(logType); // 同步余额
|
|
|
log.setBalance(balance);
|
|
|
log.setCreateTime(new Date());
|
|
|
- moneyLogsMapper.insertCompanyMoneyLogs(log);
|
|
|
- logger.info("异步登记余额日志成功 - 公司ID: {}, 金额: {}, 余额: {}, 备注: {}",
|
|
|
- companyId, money, balance, remark);
|
|
|
+ log.setRedPacketId(logId);
|
|
|
+ companyRedPacketBalanceLogsMapper.insertCompanyRedPacketBalanceLogs(log);
|
|
|
} catch (Exception e) {
|
|
|
- logger.error("异步登记余额日志失败 - 公司ID: {}, 金额: {}, 余额: {}, 备注: {}",
|
|
|
+ logger.error("异步登记红包余额日志失败 - 公司ID: {}, 金额: {}, 余额: {}, 备注: {}",
|
|
|
companyId, money, balance, remark, e);
|
|
|
}
|
|
|
}
|
|
|
@@ -1508,7 +1669,7 @@ public class CompanyServiceImpl implements ICompanyService
|
|
|
// 实际不发生交易只是从缓存获取当天余额报错25小时 交易金额登记为0,备注清楚同步的金额
|
|
|
String remark = "时间:" + time +",当前公司余额,金额: " + moneyStr;
|
|
|
BigDecimal money = new BigDecimal(moneyStr);
|
|
|
- asyncRecordBalanceLog(company.getCompanyId(),new BigDecimal(0),18,money,remark);
|
|
|
+ asyncRecordBalanceLog(company.getCompanyId(),new BigDecimal(0),18,money,remark, null);
|
|
|
}
|
|
|
return null;
|
|
|
});
|
|
|
@@ -1530,20 +1691,67 @@ public class CompanyServiceImpl implements ICompanyService
|
|
|
* @Param:
|
|
|
* @Return:
|
|
|
* @Author xgb
|
|
|
- * @Date 2025/11/7 9:53
|
|
|
+ * @Date 2025/12/25 9:32
|
|
|
*/
|
|
|
@Override
|
|
|
- public void rollbackRedPacketMoney() {
|
|
|
- List<RedPacketMoneyVO> redPacketMoneyVOS = fsCourseRedPacketLogMapper.selectFsCourseAddRedPacketLogByCompany();
|
|
|
- for(RedPacketMoneyVO company:redPacketMoneyVOS){
|
|
|
- logger.info("红包余额回滚开始:{}",company);
|
|
|
- }
|
|
|
- Optional.ofNullable(redPacketMoneyVOS).ifPresent(list -> list.forEach(company -> {
|
|
|
+ public void rollbackRedPacketMoney(String createSTime, String createETime) {
|
|
|
+ // 回滚前查询一下红包记录
|
|
|
+ List<CompanyRedPacketBalanceLogs> companyRedPacketBalanceLogsList = companyRedPacketBalanceLogsMapper.selectCompanyRedPacketBalanceLogsListByStatus(createSTime, createETime);
|
|
|
+
|
|
|
+ Optional.ofNullable(companyRedPacketBalanceLogsList).ifPresent(list -> list.forEach(company -> {
|
|
|
+
|
|
|
+ if(company.getRedPacketId()==null){// 无数据跳过
|
|
|
+ logger.info("红包记录未登记,流水{}",company.getLogsId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询红包记录
|
|
|
+ FsCourseRedPacketLog redLogs = fsCourseRedPacketLogMapper.selectFsCourseRedPacketLogByLogId(company.getRedPacketId());
|
|
|
+ if(redLogs==null){
|
|
|
+ logger.error("未查询到红包记录,流水{}",company.getLogsId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
if(company.getCompanyId()==null){
|
|
|
- logger.error("红包记录表中存在公司id为null的异常数据");
|
|
|
+ logger.error("红包记录表中存在公司id为null的异常数据,流水{}",company.getLogsId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(!StringUtils.isEmpty(redLogs.getBatchId())){
|
|
|
+ R result=checkMchTransferStatusByBatchID(redLogs.getBatchId(),redLogs.getCompanyId());
|
|
|
+ if("200".equals(result.get("code"))){
|
|
|
+ FsCourseRedPacketLog update = new FsCourseRedPacketLog();
|
|
|
+ update.setUpdateTime(new Date());
|
|
|
+ update.setLogId(redLogs.getLogId());
|
|
|
+
|
|
|
+ // 更新扣减状态
|
|
|
+ CompanyRedPacketBalanceLogs redBalanceLogs = new CompanyRedPacketBalanceLogs();
|
|
|
+ redBalanceLogs.setRedPacketId(company.getRedPacketId());
|
|
|
+
|
|
|
+ if("success".equals(result.get("status"))){
|
|
|
+ update.setStatus(1);
|
|
|
+ fsCourseRedPacketLogMapper.updateFsCourseRedPacketLog(update);
|
|
|
+
|
|
|
+ redBalanceLogs.setStatus(1L);
|
|
|
+ companyRedPacketBalanceLogsMapper.updateCompanyRedPacketBalanceLogsByRedPacketId(redBalanceLogs);
|
|
|
+ return;
|
|
|
+ }else if("fail".equals(result.get("status"))){// 只对失败的部分进行回滚
|
|
|
+ // 更新支付状态
|
|
|
+ update.setStatus(2); // 已退回
|
|
|
+ fsCourseRedPacketLogMapper.updateFsCourseRedPacketLog(update);
|
|
|
+
|
|
|
+ redBalanceLogs.setStatus(2L);
|
|
|
+ companyRedPacketBalanceLogsMapper.updateCompanyRedPacketBalanceLogsByRedPacketId(redBalanceLogs);
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ logger.info("商户转账状态查询失败,流水{}",company.getLogsId());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ logger.error("红包记录表中存在商户批次号为null的异常数据,流水{}",company.getLogsId());
|
|
|
return;
|
|
|
}
|
|
|
+
|
|
|
String companyMoneyKey = FsConstants.COMPANY_MONEY_KEY + company.getCompanyId();
|
|
|
// 加锁,与看课发放红包的加锁保持一致
|
|
|
RLock lock = redissonClient.getLock(FsConstants.COMPANY_MONEY_LOCK + company.getCompanyId());
|
|
|
@@ -1557,14 +1765,14 @@ public class CompanyServiceImpl implements ICompanyService
|
|
|
if (StringUtils.isNotEmpty(moneyStr)) {
|
|
|
redisMoney = new BigDecimal(moneyStr);
|
|
|
}else {
|
|
|
- logger.error("缓存公司id:{}的余额不存在,回滚金额{}",company.getCompanyId(),company.getMoney());
|
|
|
+ logger.error("缓存公司id:{}的余额不存在,回滚金额{}",company.getCompanyId(),redLogs.getAmount());
|
|
|
return;
|
|
|
}
|
|
|
- BigDecimal newMoney = redisMoney.add(company.getMoney());
|
|
|
+ BigDecimal newMoney = redisMoney.add(redLogs.getAmount());
|
|
|
redisCache.setCacheObject(companyMoneyKey, newMoney.toString());
|
|
|
|
|
|
- String remark = "执行时间:"+DateUtils.getTime()+",T2天客户未领取红包退回,金额: " + company.getMoney();
|
|
|
- asyncRecordBalanceLog(company.getCompanyId(),company.getMoney(),16,newMoney,remark);
|
|
|
+ String remark = "执行时间:"+DateUtils.getTime()+",T2天客户未领取红包退回,金额: " + redLogs.getAmount();
|
|
|
+ asyncRecordBalanceLog(company.getCompanyId(),redLogs.getAmount(),19,newMoney,remark, redLogs.getLogId());
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
logger.error("退回的红包同步增加到缓存和数据表,参数错误,请求异常,异常信息:{}", e.getMessage(), e);
|
|
|
@@ -1579,8 +1787,5 @@ public class CompanyServiceImpl implements ICompanyService
|
|
|
}
|
|
|
}));
|
|
|
}
|
|
|
- @Override
|
|
|
- public Company selectCompanyByStoreId(Long storeId) {
|
|
|
- return companyMapper.selectCompanyByStoreId(storeId);
|
|
|
- }
|
|
|
+
|
|
|
}
|