Bladeren bron

feat:定时任务退回红包-添加到缓存余额、同步余额到公司表添加流水记录

caoliqin 1 week geleden
bovenliggende
commit
6ed2032cea

+ 51 - 25
fs-admin/src/main/java/com/fs/task/FsCompanyTask.java

@@ -3,6 +3,8 @@ package com.fs.task;
 import com.fs.common.constant.FsConstants;
 import com.fs.common.core.redis.RedisCache;
 import com.fs.company.domain.Company;
+import com.fs.company.domain.CompanyMoneyLogs;
+import com.fs.company.mapper.CompanyMoneyLogsMapper;
 import com.fs.company.service.ICompanyService;
 import com.fs.company.vo.RedPacketMoneyVO;
 import com.fs.course.mapper.FsCourseRedPacketLogMapper;
@@ -29,6 +31,9 @@ public class FsCompanyTask {
     @Autowired
     private RedisTemplate<String, Object> redisTemplate;
 
+    @Autowired
+    private CompanyMoneyLogsMapper moneyLogsMapper;
+
     public void refreshCompanyMoney() {
         LocalDateTime now = LocalDateTime.now();
         // 获取上一个小时的开始时间
@@ -49,38 +54,59 @@ public class FsCompanyTask {
      * 同步公司缓存余额到公司数据表
      */
     public void syncRedisCompanyMoneyToDB(){
-            // 获取所有的公司余额key
-            String companyMoneyKeyAll = FsConstants.COMPANY_MONEY_KEY + "*";
-            Collection<String> keys = redisCache.keys(companyMoneyKeyAll);
+        // 获取所有的公司余额key
+        String companyMoneyKeyAll = FsConstants.COMPANY_MONEY_KEY + "*";
+        Collection<String> keys = redisCache.keys(companyMoneyKeyAll);
 
-            if (keys != null && !keys.isEmpty()) {
-                log.info("同步缓存余额到公司表,keys:{}", keys);
-                List<Object> values = redisTemplate.opsForValue().multiGet(keys);
-                Iterator<String> keyIterator = keys.iterator();
-                if(values != null && !values.isEmpty()){
-                    Iterator<Object> valueIterator = values.iterator();
-                    List<Company> companies = companyService.selectCompanyList(new Company());
+        if (keys != null && !keys.isEmpty()) {
+            log.info("同步缓存余额到公司表,keys:{}", keys);
+            List<Object> values = redisTemplate.opsForValue().multiGet(keys);
+            Iterator<String> keyIterator = keys.iterator();
+            if(values != null && !values.isEmpty()){
+                Iterator<Object> valueIterator = values.iterator();
+                List<Company> companies = companyService.selectCompanyList(new Company());
+
+                Map<Long, BigDecimal> moneyMap = new HashMap<>();
+                while (keyIterator.hasNext() && valueIterator.hasNext()) {
+                    String next = keyIterator.next();
+                    String[] keySplit = next.split(":");
+                    Long companyId = Long.parseLong(keySplit[2]);
+                    String value = valueIterator.next().toString();
+                    moneyMap.put(companyId, new BigDecimal(value));
+                }
 
-                    Map<Long, BigDecimal> moneyMap = new HashMap<>();
-                    while (keyIterator.hasNext() && valueIterator.hasNext()) {
-                        String next = keyIterator.next();
-                        String[] keySplit = next.split(":");
-                        Long companyId = Long.parseLong(keySplit[2]);
-                        String value = valueIterator.next().toString();
-                        moneyMap.put(companyId, new BigDecimal(value));
+                // 新增账户流水
+                // 直接循环保存,由于是定时任务执行,暂时不优化
+                for (Company company : companies) {
+                    if(moneyMap.containsKey(company.getCompanyId()) && !(moneyMap.get(company.getCompanyId()).compareTo(company.getMoney()) == 0)){
+                        CompanyMoneyLogs log = new CompanyMoneyLogs();
+                        log.setCompanyId(company.getCompanyId());
+                        log.setRemark("扣除红包金额-同步");
+                        // 让减出来的金额为负数
+                        if(moneyMap.get(company.getCompanyId()).compareTo(company.getMoney()) <= 0 ){
+                            log.setMoney(moneyMap.get(company.getCompanyId()).subtract(company.getMoney()));
+                        } else {
+                            log.setMoney(company.getMoney().subtract(moneyMap.get(company.getCompanyId())));
+                        }
+                        log.setLogsType(15);
+                        log.setBalance(moneyMap.get(company.getCompanyId()));
+                        log.setCreateTime(new Date());
+                        moneyLogsMapper.insertCompanyMoneyLogs(log);
                     }
+                }
 
-                    // 使用Stream进行匹配赋值
-                    List<Company> collect = companies.stream()
-                            .filter(company -> moneyMap.containsKey(company.getCompanyId()))
-                            .peek(company -> company.setMoney(moneyMap.get(company.getCompanyId()))).collect(Collectors.toList());
+                // 使用Stream进行匹配赋值
+                List<Company> collect = companies.stream()
+                        .filter(company -> moneyMap.containsKey(company.getCompanyId()))
+                        .peek(company -> company.setMoney(moneyMap.get(company.getCompanyId()))).collect(Collectors.toList());
 
-                    // 保存公司余额
-                    if(!collect.isEmpty()){
-                        companyService.batchUpdateCompany(collect);
-                    }
+                // 保存公司余额
+                if(!collect.isEmpty()){
+                    companyService.batchUpdateCompany(collect);
                 }
+
             }
+        }
 
     }
 }

+ 48 - 11
fs-service/src/main/java/com/fs/company/service/impl/CompanyServiceImpl.java

@@ -3,6 +3,7 @@ package com.fs.company.service.impl;
 import java.math.BigDecimal;
 import java.time.LocalTime;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 import cn.hutool.core.util.ObjectUtil;
@@ -42,6 +43,8 @@ import com.github.pagehelper.PageHelper;
 import com.google.gson.Gson;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.ObjectUtils;
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -107,6 +110,9 @@ public class CompanyServiceImpl implements ICompanyService
     @Autowired
     private TransactionTemplate transactionTemplate;
 
+    @Autowired
+    private RedissonClient redissonClient;
+
     @Override
     public List<OptionsVO> selectAllCompanyList(Long deptId) {
         return companyMapper.selectAllCompanyList(deptId);
@@ -1245,17 +1251,48 @@ public class CompanyServiceImpl implements ICompanyService
         if(companyId!=null&&companyId>0){
             Company company=companyMapper.selectCompanyByIdForUpdate(companyId);
             if(company!=null){
-                logger.info("退回红包金额:"+money);
-                company.setMoney(company.getMoney().add(money));
-                companyMapper.updateCompany(company);
-                CompanyMoneyLogs log=new CompanyMoneyLogs();
-                log.setCompanyId(company.getCompanyId());
-                log.setRemark("退回红包金额");
-                log.setMoney(money);
-                log.setLogsType(16);
-                log.setBalance(company.getMoney());
-                log.setCreateTime(new Date());
-                moneyLogsMapper.insertCompanyMoneyLogs(log);
+                String companyMoneyKey = FsConstants.COMPANY_MONEY_KEY + company.getCompanyId();
+                // 加锁,与看课发放红包的加锁保持一致
+                RLock lock = redissonClient.getLock(FsConstants.COMPANY_MONEY_LOCK + company.getCompanyId());
+                boolean lockAcquired = false;
+                try {
+                    lockAcquired = lock.tryLock(3, 10, TimeUnit.SECONDS);
+                    if (lockAcquired) {
+                        BigDecimal redisMoney;
+                        // 获取当前余额
+                        String moneyStr = redisCache.getCacheObject(companyMoneyKey);
+                        if (StringUtils.isNotEmpty(moneyStr)) {
+                            redisMoney = new BigDecimal(moneyStr);
+                        } else {
+                            redisMoney = company.getMoney();
+                        }
+                        BigDecimal newMoney = redisMoney.add(money);
+                        logger.info("退回红包金额:"+money);
+                        company.setMoney(newMoney);
+                        companyMapper.updateCompany(company);
+                        CompanyMoneyLogs log=new CompanyMoneyLogs();
+                        log.setCompanyId(company.getCompanyId());
+                        log.setRemark("退回红包金额");
+                        log.setMoney(money);
+                        log.setLogsType(16);
+                        log.setBalance(newMoney);
+                        log.setCreateTime(new Date());
+                        moneyLogsMapper.insertCompanyMoneyLogs(log);
+
+                        redisCache.setCacheObject(companyMoneyKey, newMoney.toString());
+                    }
+                } catch (Exception e) {
+                    logger.error("退回的红包同步增加到缓存和数据表,参数错误,请求异常,异常信息:{}", e.getMessage(), e);
+                } finally {
+                    if (lockAcquired && lock.isHeldByCurrentThread()) {
+                        try {
+                            lock.unlock();
+                        } catch (IllegalMonitorStateException e) {
+                            logger.warn("尝试释放非当前线程持有的锁: companyId:{}", company.getCompanyId());
+                        }
+                    }
+                }
+
             }
         }
     }