admin
2024-07-27 65aaf1c05bd06cefa82ebc40cc3e01cf4ac233c0
src/main/java/com/taoke/autopay/service/impl/KeyOrderServiceImpl.java
@@ -1,18 +1,29 @@
package com.taoke.autopay.service.impl;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.entity.OrderDistributeCountInfo;
import com.taoke.autopay.dao.WxUserSettingsMapper;
import com.taoke.autopay.dto.DYOrderDto;
import com.taoke.autopay.entity.*;
import com.taoke.autopay.exception.KeyOrderException;
import com.taoke.autopay.exception.KeyVerifyException;
import com.taoke.autopay.exception.WxOrderCountException;
import com.taoke.autopay.factory.OrderFactory;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.service.SystemConfigService;
import com.taoke.autopay.service.WxUserOrderCountService;
import com.taoke.autopay.service.WxUserSettingService;
import com.taoke.autopay.utils.*;
import com.taoke.autopay.utils.order.DYOrderApi;
import com.taoke.autopay.vo.SubmitKeyInfo;
import net.sf.json.JSONArray;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author hxh
@@ -26,26 +37,47 @@
    @Resource
    private KeyOrderMapper keyOrderMapper;
    @Resource
    private WxUserSettingService wxUserSettingService;
    @Resource
    private WxUserOrderCountService wxUserOrderCountService;
    @Resource
    private SystemConfigService systemConfigService;
    @Override
    public KeyOrder selectById(String id) {
        return keyOrderMapper.selectById(id);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public KeyOrder addKeyOrder(String key) throws KeyOrderException {
        String id =   OrderFactory.createId(key);
        KeyOrder order =   keyOrderMapper.selectById(id);
        if(order!=null){
           throw  new KeyOrderException("请勿重复提交口令");
    public KeyOrder addKeyOrder(SubmitKeyInfo keyInfo, Long uid, String day) throws KeyOrderException, WxOrderCountException {
        // 判断提交次数是否过量
        if (uid != null) {
            WxUserSettings settings = wxUserSettingService.getUserSettings(uid);
            wxUserOrderCountService.addOrderCount(uid, OrderCountTypeEnum.SUBMIT_TOKEN_COUNT, day, 1, settings.getTotalOrderCountPerDay());
        }
        order =new KeyOrder();
        String id = OrderFactory.createId(keyInfo.getKey());
        KeyOrder order = keyOrderMapper.selectById(id);
        if (order != null) {
            throw new KeyOrderException("请勿重复提交口令");
        }
        order = new KeyOrder();
        order.setId(id);
        order.setKey(key);
        order.setKey(keyInfo.getKey());
        if(!StringUtil.isNullOrEmpty(keyInfo.getMoney())){
            order.setOrderMoney(new BigDecimal(keyInfo.getMoney()));
        }
        order.setUid(uid);
        order.setState(KeyOrder.STATE_NOT_PROCESS);
        order.setStateDesc("尚未处理");
        order.setCreateTime(new Date());
        keyOrderMapper.insertSelective(order);
        return order;
    }
@@ -67,12 +99,35 @@
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setOrderInfo(String id,String orderNo, int orderState)  throws  KeyOrderException{
    public void paySuccess(String id, String stateDesc,String day) throws WxOrderCountException {
        KeyOrder old = keyOrderMapper.selectByPrimaryKeyForUpdate(id);
        if(old==null){
           return;
        }
        if(old.getState() == KeyOrder.STATE_PAY){
            return;
        }
        if(old.getUid()!=null) {
            wxUserOrderCountService.addOrderCount(old.getUid(),OrderCountTypeEnum.DY_ORDER_PAY,day,1,null);
        }
        KeyOrder orderUpdate = new KeyOrder();
        orderUpdate.setId(id);
        orderUpdate.setState(KeyOrder.STATE_PAY);
        orderUpdate.setStateDesc(stateDesc);
        if(old.getPayTime()==null){
            orderUpdate.setPayTime(new Date());
        }
        update(orderUpdate);
    }
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setOrderInfo(String id, String orderNo, int orderState) throws KeyOrderException {
        KeyOrder old = keyOrderMapper.selectByPrimaryKeyForUpdate(id);
        if (old == null) {
           throw new  KeyOrderException("口令不存在");
            throw new KeyOrderException("口令不存在");
        }
        KeyOrder keyOrder=new KeyOrder();
        KeyOrder keyOrder = new KeyOrder();
        keyOrder.setId(id);
        // 默认1抖音
        keyOrder.setOrderType(1);
@@ -96,17 +151,122 @@
    @Override
    public Long getCanDistributeUid() {
        List<OrderDistributeCountInfo>  list =   keyOrderMapper.listDistributeUids();
        if(list==null||list.size()==0){
        // 最近1小时有活跃,且不算12以上未执行的数据
        List<OrderDistributeCountInfo> list = keyOrderMapper.listDistributeUids(new Date(System.currentTimeMillis() - 1000 * 60 * 60L),new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 12L));
        if (list == null || list.size() == 0) {
            return null;
        }
        Comparator<OrderDistributeCountInfo> cm = (OrderDistributeCountInfo o1, OrderDistributeCountInfo o2)-> o1.getCount()-o2.getCount();
        // count小于2直接视为0
        for (OrderDistributeCountInfo info : list) {
            if (info.getCount() < 2) {
                info.setCount(0);
            }
        }
        Comparator<OrderDistributeCountInfo> cm = new Comparator<OrderDistributeCountInfo>() {
            @Override
            public int compare(OrderDistributeCountInfo o1, OrderDistributeCountInfo o2) {
                return o1.getCount() - o2.getCount();
            }
        };
        list.sort(cm);
        if (list.get(0).getCount() == 0) {
            // 处理大多数设备都没有分配的情况
            // 将为0的数据随机分配
            List<OrderDistributeCountInfo> tempList = new ArrayList<>();
            for (OrderDistributeCountInfo info : list) {
                if (info.getCount() == 0) {
                    tempList.add(info);
                }
            }
            int index = new Random().nextInt(tempList.size());
            if (index < 0) {
                index = 0;
            }
            if (index >= tempList.size()) {
                index = tempList.size() - 1;
            }
            return tempList.get(index).getUid();
        }
        return list.get(0).getUid();
    }
    @Override
    public List<KeyOrder> listNotDistributed(int page, int pageSize) {
        return keyOrderMapper.listNotDistributed((page-1)*pageSize,pageSize);
        return keyOrderMapper.listNotDistributed((page - 1) * pageSize, pageSize);
    }
    @Override
    public void deleteAll(Date maxCreateTime) {
        keyOrderMapper.deleteAll(maxCreateTime);
    }
    @Override
    public DYOrderDto verifyKey(String orderNoDesc, String orderStatus, String money) throws  KeyVerifyException {
        int orderType= Constant.ORDER_TYPE_UNKNOWN;
        if(orderNoDesc.contains("抖音")){
            orderType = Constant.ORDER_TYPE_DY;
        }else  if(orderNoDesc.contains("快手")){
            orderType = Constant.ORDER_TYPE_KS;
        }
        String orderNo= "";
        // 匹配连续的数字
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(orderNoDesc);
        while (matcher.find()) {
            // 获取匹配到的数字字符串
            String number = matcher.group();
            if (number.length() > 10) {
                orderNo = number;
                break;
            }
        }
            if(orderType==Constant.ORDER_TYPE_UNKNOWN){
                throw new KeyVerifyException(KeyVerifyException.CODE_ORDER_TYPE_ERROR, "未定义的订单类型");
            }
            if (!StringUtil.isNullOrEmpty(orderStatus)&&!orderStatus.contains("未支付")) {
                throw new KeyVerifyException(KeyVerifyException.CODE_ORDER_STATUS_ERROR, "订单状态:"+orderStatus);
            }
            DYOrderDto dyOrderDto=null;
            // 先匹配订单
            try {
                if(orderType == Constant.ORDER_TYPE_DY&&!StringUtil.isNullOrEmpty(orderNo)){
                    dyOrderDto = DYOrderApi.getOrderDetail(orderNo);
                    if(dyOrderDto!=null){
                        // 验证金额
                        if( dyOrderDto.getPay_amount().intValue()!= new BigDecimal(money).multiply(new BigDecimal(100)).setScale(0).intValue()){
                            throw new KeyVerifyException(KeyVerifyException.CODE_ORDER_MONEY_NOT_MATCH ,String.format("支付金额与订单金额不一致:%s-%d",money,dyOrderDto.getPay_amount() ));
                        }
                    }
                }else{
                    throw new KeyOrderException("抖音订单获取失败");
                }
            }catch(KeyOrderException e){
                // 抖音订单未验证通过,匹配金额
                // 验证提交的金额是否正确
                String moneyStr =  systemConfigService.getValueCache(SystemConfigKeyEnum.PAY_MONEY_LIST);
                if(StringUtil.isNullOrEmpty(moneyStr)){
                    throw new KeyVerifyException(KeyVerifyException.CODE_KEY_MONEY_NOT_MATCH ,"尚未配置金额");
                }
                JSONArray array=JSONArray.fromObject(moneyStr);
                Set<String> moneySet=new HashSet<>();
                for(int i=0;i<array.size();i++){
                    moneySet.add(MoneyUtil.getMoneyStr(new BigDecimal(array.optString(i))));
                }
                // 匹配金额
                if(!moneySet.contains(money)){
                    throw new KeyVerifyException(KeyVerifyException.CODE_KEY_MONEY_NOT_MATCH, String.format("金额未在系统设置中:%s",money));
                }
            }
            return dyOrderDto;
    }
    @Override
    public void removeDistributedClient(String id) {
        keyOrderMapper.removeDistributedClient(id);
    }
}