admin
2024-08-09 27c6695551c7229786ef2cf7dae722886c9edf53
代理新功能完善
19个文件已修改
2个文件已添加
696 ■■■■■ 已修改文件
src/main/java/com/taoke/autopay/controller/WebApiController.java 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/admin/AdminOrderController.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/admin/AdminSettingsController.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/agent/AgentController.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/client/OrderController.java 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/exception/KeyVerifyException.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/manager/OrderPayFailProcessor.java 58 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/KeyOrderService.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/KeyOrderServiceImpl.java 107 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/WxUserOrderCountServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/agent/ChannelAgentSettleServiceImpl.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/task/KeyOrderDistributeTask.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/utils/AlipayOrderUtil.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/utils/ClientDistributeUtil.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/utils/Constant.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/index.html 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/settings_timeout_device.html 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/AutopayApplicationTests.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/ClientTest.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/KeyTest.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/WebApiController.java
@@ -48,37 +48,6 @@
    @Resource
    private SystemConfigService systemConfigService;
    @ResponseBody
    @RequestMapping(value = "submitKey")
    public String submitKey(String key) {
        if (1 > 0) {
            return JsonUtil.loadFalseResult(0, "接口已关闭");
        }
        if (StringUtil.isNullOrEmpty(key)) {
            return JsonUtil.loadFalseResult(0, "请上传key");
        }
        List<String> urllist = UrlUtils.parseUrlsFromText(key);
        if (urllist.isEmpty() || !urllist.get(0).contains("ur.alipay.com")) {
            return JsonUtil.loadFalseResult("支付宝口令不正确");
        }
        try {
            KeyOrder order = keyOrderService.addKeyOrder(new SubmitKeyInfo(key), null, TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyyMMdd"));
            Long uid = keyOrderService.getCanDistributeUid();
            if (uid != null) {
                KeyOrder orderUpdate = new KeyOrder();
                orderUpdate.setId(order.getId());
                orderUpdate.setDistributeClientUid(uid);
                orderUpdate.setDistributeTime(new Date());
                keyOrderService.update(orderUpdate);
            }
            return JsonUtil.loadTrueResult("");
        } catch (KeyOrderException e) {
            e.printStackTrace();
            return JsonUtil.loadFalseResult(e.getMessage());
        } catch (WxOrderCountException e) {
            return JsonUtil.loadFalseResult("今日超过最大提交次数");
        }
    }
    private void addKey(SubmitKeyInfo keyInfo, Long wxUid) throws KeyVerifyException, KeyOrderException, WxOrderCountException {
        // 解析链接
@@ -86,6 +55,8 @@
        String verifyAlipayKey = systemConfigService.getValueCache(SystemConfigKeyEnum.ALIPAY_KEY_VERIFY);
        DYOrderDto orderDto =null;
        int orderType = Constant.ORDER_TYPE_UNKNOWN;
        if (verifyAlipayKey != null && verifyAlipayKey.trim().equalsIgnoreCase("1")) {
            try {
                // 需要验证支付宝口令
@@ -108,8 +79,9 @@
                if (tradeInfo == null) {
                    throw new Exception("口令内容获取失败");
                }
                orderType = AlipayOrderUtil.getOrderType(tradeInfo.getGoodsTitle());
                // 验证内容
                DYOrderDto dto = keyOrderService.verifyKey(tradeInfo.getGoodsTitle(), orderStatus, tradeInfo.getItemRealAmount(), wxUid);
                orderDto = keyOrderService.verifyKey(tradeInfo.getGoodsTitle(), orderStatus, tradeInfo.getItemRealAmount(), wxUid, null);
            } catch (KeyVerifyException ee) {
                try {
                    verifyLogger.warn("校验不通过:【{}】-{}", keyInfo.getKey(), ee.getMessage());
@@ -122,8 +94,8 @@
        }
        KeyOrder order = keyOrderService.addKeyOrder(keyInfo, wxUid, TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyyMMdd"));
        Long uid = keyOrderService.getCanDistributeUid();
        KeyOrder order = keyOrderService.addKeyOrder(keyInfo, wxUid, TimeUtil.getGernalTime(System.currentTimeMillis(), Constant.DB_DAY_FORMAT),orderType, orderDto);
        Long uid = keyOrderService.getCanDistributeUid(Constant.MAX_PAY_ACCOUNT_QUEUE_SIZE);
        if (uid != null) {
            KeyOrder orderUpdate = new KeyOrder();
            orderUpdate.setId(order.getId());
@@ -142,126 +114,6 @@
        }
        if (!key.contains("支付宝")) {
            throw new Exception("没包含支付宝汉字");
        }
    }
    @ResponseBody
    @RequestMapping(value = "submitKeyV2")
    public String submitKeyV2(SubmitKeyInfo keyInfo, HttpSession session) {
        WxUserInfo user = (WxUserInfo) session.getAttribute(Constant.SESSION_KEY_USER);
        if (StringUtil.isNullOrEmpty(keyInfo.getKey())) {
            return JsonUtil.loadFalseResult("请上传key");
        }
        try {
            verifySubmitKey(keyInfo.getKey());
        } catch (Exception e) {
            return JsonUtil.loadFalseResult("支付宝口令不正确");
        }
        if (user == null) {
            // 先保存KEY
//            SESSION_KEY_TEMP_ALIPAY_KEY
            session.setAttribute(Constant.SESSION_KEY_TEMP_ALIPAY_KEY, keyInfo);
            wxLogger.info("微信没有授权:" + session.getId());
            String redictLink = systemConfigService.getValueCache(SystemConfigKeyEnum.WX_REDIRECT_LINK);
            if (StringUtil.isNullOrEmpty(redictLink)) {
                return JsonUtil.loadFalseResult("无法获取到授权链接");
            }
            // 没有登录,返回登录链接
            JSONObject root = new JSONObject();
            root.put("link", redictLink);
            return JsonUtil.loadTrueResult(Constant.RESULT_CODE_NEED_LOGIN, root);
        }
        wxLogger.info("微信有授权:" + session.getId());
        try {
            addKey(keyInfo, user.getId());
            return JsonUtil.loadTrueResult("");
        } catch (KeyOrderException e) {
            e.printStackTrace();
            return JsonUtil.loadFalseResult(e.getMessage());
        } catch (WxOrderCountException e) {
            return JsonUtil.loadFalseResult(e.getMessage());
        } catch (KeyVerifyException e) {
            switch (e.getCode()) {
                case KeyVerifyException.CODE_KEY_MONEY_NOT_MATCH:
                    return JsonUtil.loadFalseResult("该笔订单有误,不予提交");
                case KeyVerifyException.CODE_ORDER_MONEY_NOT_MATCH:
                    return JsonUtil.loadFalseResult("提交金额不匹配");
            }
            logger.debug("口令验证结果异常:{}-{}", keyInfo.getKey(), e.getMessage());
            return JsonUtil.loadFalseResult(e.getMessage());
        }
    }
    /**
     * @return java.lang.String
     * @author hxh
     * @description 带口令与金额的口令提交接口
     * @date 0:12 2024/7/9
     * @param: keyInfo
     * @param: session
     **/
    @ResponseBody
    @RequestMapping(value = "submitKeyV3")
    public String submitKeyV3(SubmitKeyInfo keyInfo, HttpSession session, HttpServletRequest request) {
        String referer = request.getHeader("Referer");
        keyInfo.setReferer(referer);
        WxUserInfo user = (WxUserInfo) session.getAttribute(Constant.SESSION_KEY_USER);
        if (StringUtil.isNullOrEmpty(keyInfo.getKey())) {
            return JsonUtil.loadFalseResult("请上传key");
        }
//        if (StringUtil.isNullOrEmpty(keyInfo.getMoney())) {
//            return JsonUtil.loadFalseResult("请上传money");
//        }
        try {
            verifySubmitKey(keyInfo.getKey());
        } catch (Exception e) {
            return JsonUtil.loadFalseResult("支付宝口令不正确");
        }
        // 验证提交时间
        String timeStr = systemConfigService.getValueCache(SystemConfigKeyEnum.KEY_SUBMIT_TIME_RANGE);
        if (StringUtil.isNullOrEmpty(timeStr)) {
            return JsonUtil.loadFalseResult("尚未配置生效时间");
        }
        String startTime = timeStr.split(",")[0].trim().replace(":", "");
        String endTime = timeStr.split(",")[1].trim().replace(":", "");
        String now = TimeUtil.getGernalTime(System.currentTimeMillis(), "HHmmss");
        if (Integer.parseInt(now) < Integer.parseInt(startTime) || Integer.parseInt(now) > Integer.parseInt(endTime)) {
            return JsonUtil.loadFalseResult(String.format("口令提交时间段为:%s-%s", timeStr.split(",")[0], timeStr.split(",")[1]));
        }
        if (user == null) {
            // 先保存KEY
//            SESSION_KEY_TEMP_ALIPAY_KEY
            session.setAttribute(Constant.SESSION_KEY_TEMP_ALIPAY_KEY, keyInfo);
            wxLogger.info("微信没有授权:" + session.getId());
            String redictLink = systemConfigService.getValueCache(SystemConfigKeyEnum.WX_REDIRECT_LINK);
            if (StringUtil.isNullOrEmpty(redictLink)) {
                return JsonUtil.loadFalseResult("无法获取到授权链接");
            }
            // 没有登录,返回登录链接
            JSONObject root = new JSONObject();
            root.put("link", redictLink);
            return JsonUtil.loadTrueResult(Constant.RESULT_CODE_NEED_LOGIN, root);
        }
        wxLogger.info("微信有授权:" + session.getId());
        try {
            addKey(keyInfo, user.getId());
            return JsonUtil.loadTrueResult("");
        } catch (KeyOrderException e) {
            e.printStackTrace();
            return JsonUtil.loadFalseResult(e.getMessage());
        } catch (WxOrderCountException e) {
            return JsonUtil.loadFalseResult(e.getMessage());
        } catch (KeyVerifyException e) {
            logger.debug("口令校验失败:{}-{}-{}", keyInfo.getKey(), e.getCode(), e.getMessage());
            switch (e.getCode()) {
                case KeyVerifyException.CODE_KEY_MONEY_NOT_MATCH:
                    return JsonUtil.loadFalseResult("该笔订单有误,不予提交");
                case KeyVerifyException.CODE_ORDER_MONEY_NOT_MATCH:
                    return JsonUtil.loadFalseResult("提交金额不匹配");
            }
            return JsonUtil.loadFalseResult(e.getMessage());
        }
    }
@@ -323,6 +175,8 @@
                    return JsonUtil.loadFalseResult("该笔订单有误,不予提交");
                case KeyVerifyException.CODE_ORDER_MONEY_NOT_MATCH:
                    return JsonUtil.loadFalseResult("提交金额不匹配");
                case KeyVerifyException.CODE_ORDER_NO_REPEAT:
                    return JsonUtil.loadFalseResult("重复提交订单");
            }
            return JsonUtil.loadFalseResult(e.getMessage());
        }
src/main/java/com/taoke/autopay/controller/admin/AdminOrderController.java
@@ -89,12 +89,14 @@
                case 2:
                    // 订单号
                    query.orderNo = vo.getKey().trim();
                    break;
                case 3:
                    // 支付设备ID
                    if (!NumberUtil.isNumeric(vo.getKey().trim())) {
                        throw new Exception("支付设备ID必须为数字");
                    }
                    query.distributeClientUid = Long.parseLong(vo.getKey().trim());
                    break;
            }
        }
src/main/java/com/taoke/autopay/controller/admin/AdminSettingsController.java
@@ -122,6 +122,7 @@
    @Resource
    private UserSettingService userSettingService;
    @ResponseBody
    @RequestMapping("getUserSubmitKeyCountSetting")
    public String getUserSubmitKeyCountSetting() {
@@ -133,10 +134,38 @@
    @ResponseBody
    @RequestMapping("setUserSubmitKeyCount")
    public String setUserSubmitKeyCount(String value) {
        List<UserSubmitKeyLimitDto> list =   new Gson().fromJson(value, new TypeToken<List<UserSubmitKeyLimitDto>>() {
        List<UserSubmitKeyLimitDto> list = new Gson().fromJson(value, new TypeToken<List<UserSubmitKeyLimitDto>>() {
        }.getType());
        userSettingService.setUserSubmitKeyCount(list);
        return JsonUtil.loadTrueResult(new Gson().toJson(list));
    }
    @ResponseBody
    @RequestMapping("getTimeoutPayDevices")
    public String getTimeoutPayDevices() {
        String value = systemConfigService.getValue(SystemConfigKeyEnum.RE_EXCUTE_PAY_CLIENTS);
        JSONObject data = new JSONObject();
        data.put("timeout_devices", value);
        return JsonUtil.loadTrueResult(data);
    }
    @ResponseBody
    @RequestMapping("setTimeoutPayDevices")
    public String setTimeoutPayDevices(String timeout_devices) {
        timeout_devices = timeout_devices.trim();
        List<Long> idList = new ArrayList<>();
        String[] sts = timeout_devices.split(",");
        for (String st : sts) {
            st = st.trim();
            if (!StringUtil.isNullOrEmpty(st)) {
                idList.add(Long.parseLong(st));
            }
        }
        String st = StringUtil.concat(idList, ",");
        systemConfigService.setValue(SystemConfigKeyEnum.RE_EXCUTE_PAY_CLIENTS, st);
        return JsonUtil.loadTrueResult("");
    }
}
src/main/java/com/taoke/autopay/controller/agent/AgentController.java
@@ -135,6 +135,7 @@
                break;
            case 2:
                query.oMinCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now - 24 * 60 * 60 * 1000L * 3, "yyyy-MM-dd"), "yyyy-MM-dd"));
                break;
            case 3:
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(new Date(now));
@@ -202,6 +203,7 @@
        }
        ChannelAgentSettleRecordMapper.DaoQuery daoQuery = new ChannelAgentSettleRecordMapper.DaoQuery();
        daoQuery.agentId = agent.getId();
        daoQuery.statusList = Arrays.asList(new Integer[]{ChannelAgentSettleRecord.STATUS_SETTLED, ChannelAgentSettleRecord.STATUS_WITHDRAWING, ChannelAgentSettleRecord.STATUS_WITHDRAW_SUCCESS, ChannelAgentSettleRecord.STATUS_WITHDRAW_REJECTED});
        daoQuery.sortList = Arrays.asList(new String[]{"_update_time desc"});
        daoQuery.count = 20;
@@ -256,8 +258,7 @@
            return JsonUtil.loadFalseResult("尚未登录");
        }
        if(StringUtil.isNullOrEmpty(agent.getAlipayName())||StringUtil.isNullOrEmpty(agent.getAlipayAccount()))
        {
        if (StringUtil.isNullOrEmpty(agent.getAlipayName()) || StringUtil.isNullOrEmpty(agent.getAlipayAccount())) {
            return JsonUtil.loadFalseResult("尚未设置支付宝信息");
        }
src/main/java/com/taoke/autopay/controller/client/OrderController.java
@@ -232,7 +232,7 @@
            }
            if (order.getUid() != null) {
                WxUserOrderCount countInfo = wxUserOrderCountService.get(order.getUid(), OrderCountTypeEnum.DY_ORDER_PAY, TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyyMMdd"));
                WxUserOrderCount countInfo = wxUserOrderCountService.get(order.getUid(), OrderCountTypeEnum.DY_ORDER_PAY, TimeUtil.getGernalTime(System.currentTimeMillis(), Constant.DB_DAY_FORMAT));
                if (countInfo != null) {
                    WxUserSettings settings = wxUserSettingService.getUserSettings(order.getUid());
                    if (settings.getDyOrderCountPerDay() <= countInfo.getOrderCount()) {
@@ -310,7 +310,7 @@
            DYOrderDto dyOrderDto =null;
            try {
                dyOrderDto = keyOrderService.verifyKey(orderNoDesc, orderStatus, money, null);
                dyOrderDto = keyOrderService.verifyKey(orderNoDesc, orderStatus, money, null, null);
            }catch(KeyVerifyException ve){
                throw new KeyOrderException("口令验证失败:" + ve.getMessage());
            }
@@ -336,7 +336,7 @@
                        break;
                }
                WxUserOrderCount countInfo = wxUserOrderCountService.get(order.getUid(), orderCountType, TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyyMMdd"));
                WxUserOrderCount countInfo = wxUserOrderCountService.get(order.getUid(), orderCountType, TimeUtil.getGernalTime(System.currentTimeMillis(), Constant.DB_DAY_FORMAT));
                if (countInfo != null) {
                    WxUserSettings settings = wxUserSettingService.getUserSettings(order.getUid());
                    int maxOrderCount = settings.getDyOrderCountPerDay();
@@ -420,7 +420,7 @@
                loggerPay.info("处理支付失败完成");
            } else {
                try {
                    keyOrderService.paySuccess(id, "支付成功", TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyyMMdd"));
                    keyOrderService.paySuccess(id, "支付成功", TimeUtil.getGernalTime(System.currentTimeMillis(), Constant.DB_DAY_FORMAT));
                    loggerPay.info("处理支付成功完成");
                } catch (WxOrderCountException e) {
                    loggerPay.error(e.getMessage());
src/main/java/com/taoke/autopay/exception/KeyVerifyException.java
@@ -12,6 +12,8 @@
    public final static int CODE_KEY_MONEY_NOT_MATCH = 11;
    public final static int CODE_ORDER_STATUS_ERROR = 12;
    public final static int CODE_ORDER_TYPE_ERROR = 13;
    // 订单号重复提交
    public final static int CODE_ORDER_NO_REPEAT = 14;
    private int code;
src/main/java/com/taoke/autopay/manager/OrderPayFailProcessor.java
@@ -1,5 +1,7 @@
package com.taoke.autopay.manager;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.entity.ClientInfo;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.entity.SystemConfigKeyEnum;
import com.taoke.autopay.service.ClientInfoService;
@@ -53,13 +55,50 @@
        orderQueues.clear();
    }
    private Long getTargetClientId() {
        List<Long> clientIds = clientInfoService.getRePayClientIds();
        if (clientIds != null && clientIds.size() > 0) {
            // 查询设备未执行的数量
            List<List<Long>> clist=new ArrayList<>();
            for (Long cuid : clientIds) {
                KeyOrderMapper.DaoQuery daoQuery = new KeyOrderMapper.DaoQuery();
                daoQuery.distributeClientUid =cuid;
                daoQuery.state =  KeyOrder.STATE_NOT_PAY;
                daoQuery.minCreateTime=new Date(System.currentTimeMillis() - 1000*60*30L);
                long count =  keyOrderService.count(daoQuery);
                clist.add(Arrays.asList(new Long[]{cuid,count}));
            }
            clist.sort(new Comparator<List<Long>>() {
                @Override
                public int compare(List<Long> o1, List<Long> o2) {
                    return (int)(o1.get(1)-o2.get(1));
                }
            });
            if(clist.size()>1) {
                for (int i = 1; i < clist.size(); i++) {
                    if (clist.get(i).get(1).longValue() != clist.get(i - 1).get(1)) {
                        clist = clist.subList(0, i);
                        break;
                    }
                }
            }
            Collections.shuffle(clist);
            return clist.get(0).get(0);
        }
        return null;
    }
    @Transactional(rollbackFor = Exception.class)
    public void processFromQueue() {
        if (orderQueues.isEmpty()) {
            return;
        }
        Long targetCUID = getTargetClientId();
        if (targetCUID == null) {
            return;
        }
        OrderQueue queue = orderQueues.peek();
        if (queue != null && System.currentTimeMillis() > queue.expireTime) {
        if (queue != null && System.currentTimeMillis() >= queue.expireTime) {
            queue = orderQueues.poll();
            KeyOrder order = keyOrderService.selectById(queue.getId());
            if (order == null || order.getState() != KeyOrder.STATE_REJECT_PAY) {
@@ -70,29 +109,23 @@
            }
            // 超时30分钟不执行
            if(System.currentTimeMillis() - order.getCreateTime().getTime()> 30*60*1000L){
            if (System.currentTimeMillis() - order.getCreateTime().getTime() > 30 * 60 * 1000L) {
                return;
            }
            if (!reProcessCountMap.containsKey(queue.getId())) {
                reProcessCountMap.put(queue.getId(), 0);
            }
            reProcessCountMap.put(queue.getId(), reProcessCountMap.get(queue.getId()) + 1);
            keyOrderService.removeDistributedClient(queue.getId());
            List<Long> clientIds = clientInfoService.getRePayClientIds();
            // 移除已经分配的设备,改变状态为未分配
            KeyOrder update = new KeyOrder();
            update.setId(queue.getId());
            update.setState(KeyOrder.STATE_NOT_PROCESS);
            update.setStateDesc("重新分配");
            if (clientIds!=null&&clientIds.size()>0) {
                int index = (int) Math.round(Math.random() *clientIds.size());
                if (index + 1 > clientIds.size()) {
                    index = clientIds.size() - 1;
                }
                update.setDistributeClientUid(clientIds.get(index));
            }
            update.setDistributeClientUid(targetCUID);
            update.setDistributeTime(new Date());
            keyOrderService.update(update);
        }
    }
@@ -111,12 +144,13 @@
            return;
        }
        //加入重试队列
        orderQueues.add(OrderQueue.builder().id(id).expireTime(System.currentTimeMillis() + 1 * 60 * 1000).build());
        orderQueues.add(OrderQueue.builder().id(id).expireTime(System.currentTimeMillis()).build());
        KeyOrder update = new KeyOrder();
        update.setId(id);
        update.setState(KeyOrder.STATE_REJECT_PAY);
        update.setStateDesc(msg);
        keyOrderService.update(update);
        processFromQueue();
    }
    public static void main(String[] args) {
src/main/java/com/taoke/autopay/service/KeyOrderService.java
@@ -36,7 +36,7 @@
     * @date 19:19 2024/6/14
     * @param: key
     **/
    public KeyOrder addKeyOrder(SubmitKeyInfo keyInfo, Long uid, String day) throws KeyOrderException, WxOrderCountException;
    public KeyOrder addKeyOrder(SubmitKeyInfo keyInfo, Long uid, String day,Integer orderType, DYOrderDto orderDto) throws KeyOrderException, WxOrderCountException;
    /**
     * @return void
@@ -89,7 +89,7 @@
     * @description 获取可用于分配的设备ID信息
     * @date 16:41 2024/6/17
     **/
    public Long getCanDistributeUid();
    public Long getCanDistributeUid(int maxQueueSize);
    /**
     * @return java.util.List<com.taoke.autopay.entity.KeyOrder>
@@ -121,7 +121,7 @@
     * @param: money
     * @return void
     **/
    public DYOrderDto verifyKey(String orderNoDesc, String orderStatus, String money, Long uid) throws KeyVerifyException;
    public DYOrderDto verifyKey(String orderNoDesc, String orderStatus, String money, Long uid, String keyId) throws KeyVerifyException;
    /**
     * @author hxh 
src/main/java/com/taoke/autopay/service/impl/KeyOrderServiceImpl.java
@@ -65,11 +65,12 @@
    @Transactional(rollbackFor = Exception.class)
    @Override
    public KeyOrder addKeyOrder(SubmitKeyInfo keyInfo, Long uid, String day) throws KeyOrderException, WxOrderCountException {
    public KeyOrder addKeyOrder(SubmitKeyInfo keyInfo, Long uid, String day, Integer orderType, DYOrderDto orderDto) throws KeyOrderException, WxOrderCountException {
        // 判断提交次数是否过量
        if (uid != null) {
            WxUserSettings settings = wxUserSettingService.getUserSettings(uid);
            wxUserOrderCountService.addOrderCount(uid, OrderCountTypeEnum.SUBMIT_TOKEN_COUNT, day, 1, settings.getTotalOrderCountPerDay());
            OrderCountTypeEnum countType = OrderCountTypeEnum.SUBMIT_TOKEN_COUNT;
            wxUserOrderCountService.addOrderCount(uid, countType, day, 1, settings.getTotalOrderCountPerDay());
        }
        String id = OrderFactory.createId(keyInfo.getKey());
        KeyOrder order = keyOrderMapper.selectById(id);
@@ -104,6 +105,13 @@
        order.setState(KeyOrder.STATE_NOT_PROCESS);
        order.setStateDesc("尚未处理");
        order.setCreateTime(new Date());
        if(orderType!=Constant.ORDER_TYPE_UNKNOWN){
            order.setOrderType(orderType);
        }
        if (orderDto != null) {
            order.setOrderNo(orderDto.getOrder_id());
        }
        keyOrderMapper.insertSelective(order);
@@ -137,7 +145,8 @@
            return;
        }
        if (old.getUid() != null) {
            wxUserOrderCountService.addOrderCount(old.getUid(), OrderCountTypeEnum.DY_ORDER_PAY, day, 1, null);
            Integer orderType = old.getOrderType();
            wxUserOrderCountService.addOrderCount(old.getUid(), (orderType==null||orderType==Constant.ORDER_TYPE_DY)? OrderCountTypeEnum.DY_ORDER_PAY:OrderCountTypeEnum.KS_ORDER_PAY, day, 1, null);
        }
        KeyOrder orderUpdate = new KeyOrder();
        orderUpdate.setId(id);
@@ -193,7 +202,7 @@
        Map<OrderChannelEnum, BigDecimal> shareMoneyMap = channelAgentSharingRatioService.getShareMoneyMap(query.agentId);
        List<ChannelOrderStatistic> channelOrderStatisticList = keyOrderMapper.statisticChannelOrders(query);
        BigDecimal totalMoney = new BigDecimal(0);
        long totalOrderCount=0;
        long totalOrderCount = 0;
        for (ChannelOrderStatistic s : channelOrderStatisticList) {
            for (OrderChannelEnum channel : OrderChannelEnum.values()) {
@@ -205,7 +214,7 @@
                    break;
                }
            }
            totalOrderCount+=s.getCount();
            totalOrderCount += s.getCount();
        }
        long userCount = keyOrderMapper.countUser(query);
        ChannelOrderStatistic statistic = new ChannelOrderStatistic();
@@ -217,66 +226,45 @@
    @Override
    public List<ChannelOrderStatistic> statisticChannelOrders(Long agentId, Date startTime, Date endTime) {
        KeyOrderMapper.DaoQuery daoQuery=new KeyOrderMapper.DaoQuery();
        daoQuery.oMinCreateTime=startTime;
        daoQuery.oMaxCreateTime=endTime;
        KeyOrderMapper.DaoQuery daoQuery = new KeyOrderMapper.DaoQuery();
        daoQuery.oMinCreateTime = startTime;
        daoQuery.oMaxCreateTime = endTime;
        daoQuery.agentId = agentId;
        daoQuery.state =KeyOrder.STATE_PAY;
        daoQuery.hasPayTime=true;
        daoQuery.state = KeyOrder.STATE_PAY;
        daoQuery.hasPayTime = true;
        return keyOrderMapper.statisticChannelOrders(daoQuery);
    }
    @Override
    public Long getCanDistributeUid() {
    public Long getCanDistributeUid(int maxQueueSize) {
        // 最近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;
        }
        // 排除重新分配的设备
        List<Long> excludeIds =   clientInfoService.getRePayClientIds();
        for(int i=0;i<list.size();i++){
            if(excludeIds.contains(list.get(i).getUid())){
        List<Long> excludeIds = clientInfoService.getRePayClientIds();
        for (int i = 0; i < list.size(); i++) {
            if (excludeIds.contains(list.get(i).getUid())) {
                list.remove(i);
                i--;
            }
        }
        List<OrderDistributeCountInfo> filterList = new ArrayList<>();
        // count小于2直接视为0
        for (OrderDistributeCountInfo info : list) {
            if (info.getCount() < 2) {
                info.setCount(0);
            if (info.getCount() >= maxQueueSize) {
                continue;
            }
            filterList.add(info);
        }
        if (filterList.size() <= 0) {
            return null;
        }
        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();
        return ClientDistributeUtil.computeDistributeClient(filterList);
    }
    @Override
@@ -290,34 +278,30 @@
    }
    @Override
    public DYOrderDto verifyKey(String orderNoDesc, String orderStatus, String money, Long uid) throws KeyVerifyException {
        int orderType = Constant.ORDER_TYPE_UNKNOWN;
        if (orderNoDesc.contains("抖音")||orderNoDesc.contains("上海格物致品")) {
            orderType = Constant.ORDER_TYPE_DY;
        } else if (orderNoDesc.contains("快手")) {
            orderType = Constant.ORDER_TYPE_KS;
        }
    public DYOrderDto verifyKey(String orderNoDesc, String orderStatus, String money, Long uid, String keyId) throws KeyVerifyException {
        int orderType = AlipayOrderUtil.getOrderType(orderNoDesc);
        if (uid != null) {
            WxUserSettings settings = wxUserSettingService.getUserSettings(uid);
            OrderCountTypeEnum orderCountType=OrderCountTypeEnum.SUBMIT_TOKEN_COUNT;
            switch (orderType){
                case  Constant.ORDER_TYPE_DY:
            OrderCountTypeEnum orderCountType = OrderCountTypeEnum.SUBMIT_TOKEN_COUNT;
            int maxCount = settings.getTotalOrderCountPerDay();
            switch (orderType) {
                case Constant.ORDER_TYPE_DY:
                    orderCountType = OrderCountTypeEnum.DY_ORDER_PAY;
                    maxCount = settings.getDyOrderCountPerDay();
                    break;
                case Constant.ORDER_TYPE_KS:
                    orderCountType = OrderCountTypeEnum.KS_ORDER_PAY;
                    maxCount = settings.getKsOrderCountPerDay();
                    break;
            }
            try {
                wxUserOrderCountService.isOrderCountLimit(uid, orderCountType, TimeUtil.getGernalTime(System.currentTimeMillis(),"yyyy-MM-dd"), 1, settings.getTotalOrderCountPerDay());
                wxUserOrderCountService.isOrderCountLimit(uid, orderCountType, TimeUtil.getGernalTime(System.currentTimeMillis(), Constant.DB_DAY_FORMAT), 1, maxCount);
            } catch (WxOrderCountException e) {
                e.printStackTrace();
                throw new KeyVerifyException(KeyVerifyException.CODE_COMMON, "今日提交超过" +maxCount + "次");
            }
        }
        String orderNo = "";
@@ -345,11 +329,18 @@
        try {
            if (orderType == Constant.ORDER_TYPE_DY && !StringUtil.isNullOrEmpty(orderNo)) {
                dyOrderDto = DYOrderApi.getOrderDetail(orderNo);
                if (dyOrderDto != null) {
                if (dyOrderDto != null && false) {
                    // 验证金额
                    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()));
                    }
                    // 验证订单号是否已经存在
                    KeyOrderMapper.DaoQuery query = new KeyOrderMapper.DaoQuery();
                    query.orderNo = orderNo;
                    query.orderType = orderType;
                    if (count(query) > 1) {
                        throw new KeyVerifyException(KeyVerifyException.CODE_ORDER_NO_REPEAT, "订单号重复提交");
                    }
                }
            } else {
                throw new KeyOrderException("抖音订单获取失败");
src/main/java/com/taoke/autopay/service/impl/WxUserOrderCountServiceImpl.java
@@ -1,12 +1,15 @@
package com.taoke.autopay.service.impl;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.dao.WxUserOrderCountMapper;
import com.taoke.autopay.entity.OrderCountTypeEnum;
import com.taoke.autopay.entity.WxUserOrderCount;
import com.taoke.autopay.exception.WxOrderCountException;
import com.taoke.autopay.factory.OrderFactory;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.service.UserSettingService;
import com.taoke.autopay.service.WxUserOrderCountService;
import com.taoke.autopay.utils.TimeUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -28,6 +31,9 @@
    @Resource
    private UserSettingService userSettingService;
    @Resource
    private KeyOrderMapper keyOrderMapper;
    @Transactional(rollbackFor = Exception.class)
@@ -95,20 +101,19 @@
            maxCount =Integer.MAX_VALUE;
        }
        maxCount = Math.min(submitCount, maxCount);
        WxUserOrderCount info = new WxUserOrderCount();
        info.setDay(day);
        info.setOrderType(orderType.getType());
        info.setUid(uid);
        info.setId(OrderFactory.createId(info));
        // 判断是否存在
        WxUserOrderCount old = wxUserOrderCountMapper.selectByPrimaryKeyForUpdate(info.getId());
        if (old != null) {
            if (maxCount != null && maxCount < count + old.getOrderCount()) {
                throw new WxOrderCountException(String.format("今日超过最大提交次数(%s次)", maxCount));
            }
        // 统计今天的提交次数
        KeyOrderMapper.DaoQuery orderQuery=new KeyOrderMapper.DaoQuery();
        orderQuery.uid = uid;
        orderQuery.minCreateTime =new Date( TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(System.currentTimeMillis(),"yyyyMMdd"),"yyyyMMdd"));
        if(orderType!=null&&orderType!=OrderCountTypeEnum.SUBMIT_TOKEN_COUNT){
            orderQuery.orderType=orderType.getType();
        }
       long todayCount = keyOrderMapper.count(orderQuery);
       if (maxCount != null && maxCount < count + todayCount) {
        throw new WxOrderCountException(String.format("今日超过最大提交次数(%s次)", maxCount));
       }
    }
    @Override
src/main/java/com/taoke/autopay/service/impl/agent/ChannelAgentSettleServiceImpl.java
@@ -103,14 +103,16 @@
            }
            ChannelAgent agent = channelAgentService.selectByPrimaryKey(agentId);
            settle(ChannelAgentSettleRecord.builder()
                    .agentId(agentId)
                    .settleDay(day)
                    .settleMoney(totalMoney)
                    .alipayAccount(agent.getAlipayAccount())
                    .alipayName(agent.getAlipayName())
                    .detailList(detailList)
                    .build());
            if(agent!=null) {
                settle(ChannelAgentSettleRecord.builder()
                        .agentId(agentId)
                        .settleDay(day)
                        .settleMoney(totalMoney)
                        .alipayAccount(agent.getAlipayAccount())
                        .alipayName(agent.getAlipayName())
                        .detailList(detailList)
                        .build());
            }
        }
    }
src/main/java/com/taoke/autopay/task/KeyOrderDistributeTask.java
@@ -6,6 +6,7 @@
import com.taoke.autopay.exception.KeyOrderException;
import com.taoke.autopay.manager.OrderPayFailProcessor;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.utils.Constant;
import com.taoke.autopay.utils.StringUtil;
import com.taoke.autopay.utils.order.DYOrderApi;
import org.springframework.context.annotation.Configuration;
@@ -32,7 +33,7 @@
                    if (order.getDistributeClientUid() != null) {
                        continue;
                    }
                    Long uid = keyOrderService.getCanDistributeUid();
                    Long uid = keyOrderService.getCanDistributeUid(Constant.MAX_PAY_ACCOUNT_QUEUE_SIZE);
                    if (uid != null) {
                        KeyOrder orderUpdate = new KeyOrder();
                        orderUpdate.setId(order.getId());
src/main/java/com/taoke/autopay/utils/AlipayOrderUtil.java
@@ -180,6 +180,16 @@
        return null;
    }
    public static int getOrderType(String orderNoDesc){
        int orderType = Constant.ORDER_TYPE_UNKNOWN;
        if (orderNoDesc.contains("抖音") || orderNoDesc.contains("上海格物致品")) {
            orderType = Constant.ORDER_TYPE_DY;
        } else if (orderNoDesc.contains("快手")) {
            orderType = Constant.ORDER_TYPE_KS;
        }
        return orderType;
    }
    public static void main(String[] args) throws Exception {
    String url = getLocationUrl("https://ur.alipay.com/_5MDnsPbo8TAsDNtNB9Tfia");
    if(url!=null){
src/main/java/com/taoke/autopay/utils/ClientDistributeUtil.java
New file
@@ -0,0 +1,39 @@
package com.taoke.autopay.utils;
import com.taoke.autopay.entity.OrderDistributeCountInfo;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
 * @author hxh
 * @title: ClientDistributeUtil
 * @description: TODO
 * @date 2024/8/8 23:36
 */
public class ClientDistributeUtil {
    public static Long computeDistributeClient(List<OrderDistributeCountInfo> infoList){
        if(infoList.size()<1){
            return null;
        }
        infoList.sort(new Comparator<OrderDistributeCountInfo>() {
            @Override
            public int compare(OrderDistributeCountInfo o1,OrderDistributeCountInfo o2) {
                return (int)(o1.getCount()-o2.getCount());
            }
        });
        if(infoList.size()>1) {
            for (int i = 1; i < infoList.size(); i++) {
                if (infoList.get(i).getCount() != infoList.get(i - 1).getCount()) {
                    infoList = infoList.subList(0, i);
                    break;
                }
            }
        }
        Collections.shuffle(infoList);
        return infoList.get(0).getUid();
    }
}
src/main/java/com/taoke/autopay/utils/Constant.java
@@ -33,6 +33,10 @@
    // 根据金额支付
    public final static int PAY_TYPE_WITH_MONEY = 2;
    public final static int MAX_PAY_ACCOUNT_QUEUE_SIZE = 4;
    public final static  String DB_DAY_FORMAT="yyyyMMdd";
}
src/main/resources/application.yml
@@ -1,3 +1,3 @@
spring:
  profiles:
    active: pro
    active: dev
src/main/resources/static/admin/index.html
@@ -51,6 +51,7 @@
                      <dd><a href="javascript:;" data-url="pay_settings.html" data-id='40' data-text="付款金额设置"><span class="l-line"></span>付款金额设置</a></dd>
                      <dd><a href="javascript:;" data-url="settings_edit.html" data-id='41' data-text="默认参数设置"><span class="l-line"></span>默认参数设置</a></dd>
                      <dd><a href="javascript:;" data-url="user-actioncount-limit.html" data-id='42' data-text="限制代付单数"><span class="l-line"></span>限制代付单数</a></dd>
                      <dd><a href="javascript:;" data-url="settings_timeout_device.html" data-id='43' data-text="重新支付设备"><span class="l-line"></span>重新支付设备</a></dd>
                    </dl>
                  </li>
                  <li class="layui-nav-item">
src/main/resources/static/admin/settings_timeout_device.html
New file
@@ -0,0 +1,91 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
            content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>支付超时执行设备管理</title>
        <link rel="stylesheet" type="text/css" href="layui/css/layui.css" />
        <style>
            body {
                padding: 10px;
            }
            input {
                width: 200px !important;
            }
        </style>
    </head>
    <body>
        <form class="layui-form" lay-filter="edit">
            <div class="layui-form-item">
                <label class="layui-form-label">设备ID集合</label>
                <div class="layui-input-block">
                    <input type="text" name="timeout_devices" required lay-verify="required|num"
                        placeholder="请输入设备ID" autocomplete="off" class="layui-input">
                    <div class="layui-form-mid layui-word-aux">设备ID间采用英文逗号分隔</div>
                </div>
            </div>
            <div class="layui-input-block">
                <button class="layui-btn layui-btn-normal" lay-submit lay-filter="sure" id="sure">确定</button>
            </div>
        </form>
        <script src="layui/layui.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/jquery.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/http_api.js"></script>
        <script>
            layui.use(['form', 'layedit', 'laydate'], function() {
                var form = layui.form,
                    layer = layui.layer;
                //自定义验证规则
                form.verify({
                    num: [/^(\d|,)+$/, "只能包含数字或者英文逗号"]
                });
                let index = layer.load(1);
                $.post("/admin/api/settings/getTimeoutPayDevices", {},
                    function(response) {
                        layer.close(index);
                        if (response.code == 0) {
                            form.val("edit", response.data);
                        } else {
                            layer.msg(response.msg);
                        }
                    }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                    layer.msg("网络请求失败");
                    layer.close(index);
                });
                //监听提交
                form.on('submit(sure)', function(data) {
                    var params = data.field;
                    if(params.alipay_key_verify_state==undefined){
                        params.alipay_key_verify_state = "0";
                    }
                    console.log(params);
                    $.post("/admin/api/settings/setTimeoutPayDevices", params,
                        function(response) {
                            if (response.code == 0) {
                                layer.msg("修改成功");
                            } else {
                                layer.msg(response.msg);
                            }
                        }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                        layer.msg("网络请求失败");
                    });
                    return false;
                });
            });
        </script>
    </body>
</html>
src/test/java/com/taoke/autopay/AutopayApplicationTests.java
@@ -9,6 +9,7 @@
import com.taoke.autopay.exception.KeyOrderException;
import com.taoke.autopay.service.ClientInfoService;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.utils.Constant;
import com.taoke.autopay.utils.StringUtil;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@@ -54,7 +55,7 @@
    @Test
    void test3() throws Exception {
        for (int i = 0; i < 100; i++) {
            Long uid = keyOrderService.getCanDistributeUid();
            Long uid = keyOrderService.getCanDistributeUid(Constant.MAX_PAY_ACCOUNT_QUEUE_SIZE);
            System.out.println(uid);
        }
    }
src/test/java/com/taoke/autopay/ClientTest.java
@@ -1,14 +1,16 @@
package com.taoke.autopay;
import com.taoke.autopay.dao.ClientInfoMapper;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.entity.ClientInfo;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.service.ClientInfoService;
import com.taoke.autopay.service.KeyOrderService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.*;
/**
 * @author hxh
@@ -22,6 +24,9 @@
    @Resource
    private ClientInfoService clientInfoService;
    @Resource
    private KeyOrderService keyOrderService;
    @Test
    public void add(){
        ClientInfoMapper.DaoQuery query = new ClientInfoMapper.DaoQuery();
@@ -30,4 +35,43 @@
        List<ClientInfo> list = clientInfoService.list(query);
    }
    private Long getTargetClientId() {
        List<Long> clientIds = clientInfoService.getRePayClientIds();
        if (clientIds != null && clientIds.size() > 0) {
            // 查询设备未执行的数量
            List<List<Long>> clist=new ArrayList<>();
            for (Long cuid : clientIds) {
                KeyOrderMapper.DaoQuery daoQuery = new KeyOrderMapper.DaoQuery();
                daoQuery.distributeClientUid =cuid;
                daoQuery.state =  KeyOrder.STATE_NOT_PAY;
                daoQuery.minCreateTime=new Date(System.currentTimeMillis() - 1000*60*30L);
                long count =  keyOrderService.count(daoQuery);
                clist.add(Arrays.asList(new Long[]{cuid,count}));
            }
            clist.sort(new Comparator<List<Long>>() {
                @Override
                public int compare(List<Long> o1, List<Long> o2) {
                    return (int)(o1.get(1)-o2.get(1));
                }
            });
            if(clist.size()>1) {
                for (int i = 1; i < clist.size(); i++) {
                    if (clist.get(i).get(1).longValue() != clist.get(i - 1).get(1)) {
                        clist = clist.subList(0, i);
                        break;
                    }
                }
            }
            Collections.shuffle(clist);
            return clist.get(0).get(0);
        }
        return null;
    }
    @Test
    public void testTargetUid(){
        getTargetClientId();
    }
}
src/test/java/com/taoke/autopay/KeyTest.java
@@ -5,13 +5,14 @@
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.entity.OrderCountTypeEnum;
import com.taoke.autopay.entity.SystemConfigKeyEnum;
import com.taoke.autopay.entity.WxUserSettings;
import com.taoke.autopay.exception.KeyOrderException;
import com.taoke.autopay.exception.KeyVerifyException;
import com.taoke.autopay.exception.WxOrderCountException;
import com.taoke.autopay.manager.OrderPayFailProcessor;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.service.SystemConfigService;
import com.taoke.autopay.service.*;
import com.taoke.autopay.utils.AlipayOrderUtil;
import com.taoke.autopay.utils.Constant;
import com.taoke.autopay.utils.TimeUtil;
import com.taoke.autopay.vo.SubmitKeyInfo;
import org.junit.jupiter.api.Test;
@@ -19,6 +20,7 @@
import org.yeshi.utils.UrlUtils;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@@ -72,7 +74,7 @@
                    throw new Exception("口令内容获取失败");
                }
                // 验证内容
                DYOrderDto dto = keyOrderService.verifyKey(tradeInfo.getGoodsTitle(), orderStatus, tradeInfo.getItemRealAmount());
                DYOrderDto dto = keyOrderService.verifyKey(tradeInfo.getGoodsTitle(), orderStatus, tradeInfo.getItemRealAmount(),null, null);
            } catch (KeyVerifyException ee) {
                throw ee;
            } catch (Exception e) {
@@ -135,5 +137,64 @@
    }
    @Resource
    private ClientInfoService clientInfoService;
    @Test
    public void test2(){
        List<Long> clientIds = clientInfoService.getRePayClientIds();
        if (clientIds!=null&&clientIds.size()>0) {
            Collections.shuffle(clientIds);
            // 查询设备未执行的数量
            for(Long cuid:clientIds) {
                KeyOrderMapper.DaoQuery daoQuery = new KeyOrderMapper.DaoQuery();
                daoQuery.distributeClientUid =cuid;
                daoQuery.state =  KeyOrder.STATE_NOT_PAY;
                daoQuery.minCreateTime=new Date(System.currentTimeMillis() - 1000*60*30L);
                long count =  keyOrderService.count(daoQuery);
                if(count <=1){
                    // 分配
                    System.out.println( cuid);
                }
            }
        }
    }
    @Resource
    private WxUserSettingService wxUserSettingService;
    @Resource
    private WxUserOrderCountService wxUserOrderCountService;
    @Test
    public void testCount() throws Exception{
        Long uid = 5413L;
        int orderType = Constant.ORDER_TYPE_DY;
        WxUserSettings settings = wxUserSettingService.getUserSettings(uid);
        OrderCountTypeEnum orderCountType = OrderCountTypeEnum.SUBMIT_TOKEN_COUNT;
        int maxCount = settings.getTotalOrderCountPerDay();
        switch (orderType) {
            case Constant.ORDER_TYPE_DY:
                orderCountType = OrderCountTypeEnum.DY_ORDER_PAY;
                maxCount = settings.getDyOrderCountPerDay();
                break;
            case Constant.ORDER_TYPE_KS:
                orderCountType = OrderCountTypeEnum.KS_ORDER_PAY;
                maxCount = settings.getKsOrderCountPerDay();
                break;
        }
        try {
            wxUserOrderCountService.isOrderCountLimit(uid, orderCountType, TimeUtil.getGernalTime(System.currentTimeMillis(), "yyyy-MM-dd"), 1, maxCount);
        } catch (WxOrderCountException e) {
            e.printStackTrace();
            throw new KeyVerifyException(KeyVerifyException.CODE_COMMON, "今日提交超过" + maxCount + "次");
        }
    }
}