admin
2024-06-24 5d3b3b74afd2ac4cf21697fc38367b2f88170e9f
功能完善
23个文件已修改
542 ■■■■ 已修改文件
src/main/java/com/taoke/autopay/controller/WebApiController.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/client/OrderController.java 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/client/UserController.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dao/ClientInfoMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dao/KeyOrderMapper.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/dto/DYOrderDto.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/entity/KeyOrder.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/factory/OrderFactory.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/ClientInfoService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/KeyOrderService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/ClientInfoServiceImpl.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/KeyOrderServiceImpl.java 64 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/task/KeyOrderDistributeTask.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/utils/order/DYOrderApi.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/vo/KeyOrderVO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/vo/OrderFilter.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-dev.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application-pro.yml 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/logback.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/ClientInfoMapper.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/KeyOrderMapper.xml 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/AutopayApplicationTests.java 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/MapperTest.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/WebApiController.java
@@ -11,10 +11,12 @@
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.yeshi.utils.UrlUtils;
import javax.annotation.Resource;
import java.io.PrintWriter;
import java.util.Date;
import java.util.List;
@Controller
@RequestMapping("webapi")
@@ -25,12 +27,16 @@
    private KeyOrderService keyOrderService;
    @ResponseBody
    @RequestMapping(value = "submitKey")
    public void push(String  key, PrintWriter out) {
    public String submitKey(String  key) {
        if(StringUtil.isNullOrEmpty(key)){
            out.print(JsonUtil.loadFalseResult(0,"请上传key"));
            return;
           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(key);
@@ -42,18 +48,11 @@
                orderUpdate.setDistributeTime(new Date());
                keyOrderService.update(orderUpdate);
            }
            out.print(JsonUtil.loadTrueResult(""));
            return JsonUtil.loadTrueResult("");
        } catch (KeyOrderException e) {
            e.printStackTrace();
            out.print(JsonUtil.loadFalseResult(e.getMessage()));
           return JsonUtil.loadFalseResult(e.getMessage());
        }
    }
    @ResponseBody
    @RequestMapping(value = "test")
    public String test(String  key) {
      return "123123";
    }
}
src/main/java/com/taoke/autopay/controller/client/OrderController.java
@@ -18,6 +18,7 @@
import com.taoke.autopay.utils.JsonUtil;
import com.taoke.autopay.utils.StringUtil;
import com.taoke.autopay.utils.TimeUtil;
import com.taoke.autopay.utils.order.DYOrderApi;
import com.taoke.autopay.vo.AcceptData;
import com.taoke.autopay.vo.KeyOrderVO;
import com.taoke.autopay.vo.OrderFilter;
@@ -42,15 +43,15 @@
@RequestMapping("api/order")
public class OrderController {
    private Logger loggerPay= LoggerFactory.getLogger("payLogger");
    private Logger loggerPay = LoggerFactory.getLogger("payLogger");
    private Gson gson=new GsonBuilder().registerTypeAdapter(Date.class, new TypeAdapter<Date>() {
    private Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new TypeAdapter<Date>() {
        @Override
        public void write(JsonWriter out, Date value) throws IOException {
            String desc = "";
            if (value != null) {
                // 判断是否是同一天
                desc = TimeUtil.getGernalTime(value.getTime(),"yyyy-MM-dd HH:mm:ss");
                desc = TimeUtil.getGernalTime(value.getTime(), "yyyy-MM-dd HH:mm:ss");
                out.value(desc);
            } else
                out.value("");
@@ -70,28 +71,28 @@
    @ResponseBody
    @RequestMapping("listOrder")
    public String listOrder(AcceptData acceptData, OrderFilter filter){
        KeyOrderMapper.DaoQuery query=new KeyOrderMapper.DaoQuery();
    public String listOrder(AcceptData acceptData, OrderFilter filter) {
        KeyOrderMapper.DaoQuery query = new KeyOrderMapper.DaoQuery();
        Long uid = filter.getUid();
        ClientInfo info = clientInfoService.selectByPrimaryKey(uid);
        query.distributeClientUid = filter.getUid();
       if(info==null){
        if (info == null) {
            return JsonUtil.loadFalseResult("客户端ID不存在");
       }
       if(info.getRule()==1){
           // 超级管理员
           query.distributeClientUid = null;
       }
        clientInfoService.setActiveTime(filter.getUid(),new Date());
        query.start = (filter.getPage()-1)*filter.getPageSize();
        }
        if (info.getRule() == 1) {
            // 超级管理员
            query.distributeClientUid = null;
        }
        clientInfoService.setActiveTime(filter.getUid(), new Date());
        query.start = (filter.getPage() - 1) * filter.getPageSize();
        query.count = filter.getPageSize();
        if(filter.getState()!=null) {
        if (filter.getState() != null) {
            switch (filter.getState()) {
                case OrderFilter.STATE_NOT_PROCESS:
                    query.stateList = Arrays.asList(new Integer[]{KeyOrder.STATE_NOT_PROCESS});
                    break;
                case OrderFilter.STATE_PROCESSED:
                    query.stateList = Arrays.asList(new Integer[]{KeyOrder.STATE_PAY});
                    query.stateList = Arrays.asList(new Integer[]{KeyOrder.STATE_PAY, KeyOrder.STATE_REJECT_PAY});
                    break;
                case OrderFilter.STATE_PROCESS_ERROR:
                    query.stateList = Arrays.asList(new Integer[]{KeyOrder.STATE_NOT_PAY});
@@ -99,65 +100,75 @@
            }
        }
        if(filter.getTimeType()!=null){
        if (filter.getTimeType() != null) {
            long now = System.currentTimeMillis();
            String nowDay = TimeUtil.getGernalTime(now,"yyyy-MM-dd");
            switch(filter.getTimeType()){
            String nowDay = TimeUtil.getGernalTime(now, "yyyy-MM-dd");
            switch (filter.getTimeType()) {
                case OrderFilter.TIME_TYPE_TODAY:
                    query.minCreateTime = new Date(TimeUtil.convertToTimeTemp(nowDay,"yyyy-MM-dd"));
                    query.minCreateTime = new Date(TimeUtil.convertToTimeTemp(nowDay, "yyyy-MM-dd"));
                    break;
                case OrderFilter.TIME_TYPE_YESTERDAY:
                    query.maxCreateTime = new Date(TimeUtil.convertToTimeTemp(nowDay,"yyyy-MM-dd"));
                    query.minCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now - 24*60*60*1000L,"yyyy-MM-dd"),"yyyy-MM-dd"));
                    query.maxCreateTime = new Date(TimeUtil.convertToTimeTemp(nowDay, "yyyy-MM-dd"));
                    query.minCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now - 24 * 60 * 60 * 1000L, "yyyy-MM-dd"), "yyyy-MM-dd"));
                    break;
                case OrderFilter.TIME_TYPE_WEEK:
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(new Date(now));
                    int day = calendar.get(Calendar.DAY_OF_WEEK);
                    day-=1;
                    if(day==0){
                    day -= 1;
                    if (day == 0) {
                        // 星期天
                        day=7;
                        day = 7;
                    }
                    query.minCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now - 24*60*60*1000L*(day-1),"yyyy-MM-dd"),"yyyy-MM-dd"));
                    query.minCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now - 24 * 60 * 60 * 1000L * (day - 1), "yyyy-MM-dd"), "yyyy-MM-dd"));
                    break;
                case OrderFilter.TIME_TYPE_MONTH:
                    query.minCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now,"yyyy-MM"),"yyyy-MM"));
                    query.minCreateTime = new Date(TimeUtil.convertToTimeTemp(TimeUtil.getGernalTime(now, "yyyy-MM"), "yyyy-MM"));
                    break;
            }
        }
        if(filter.getSort()==0) {
        if (filter.getSort() == 0) {
            query.sortList = Arrays.asList(new String[]{"create_time asc"});
        }else{
        } else {
            query.sortList = Arrays.asList(new String[]{"create_time desc"});
        }
        List<KeyOrder> list = keyOrderService.list(query);
        List<KeyOrderVO> voList=new ArrayList<>();
        for(KeyOrder order:list){
        List<KeyOrderVO> voList = new ArrayList<>();
        for (KeyOrder order : list) {
            voList.add(OrderFactory.create(order));
        }
        long count = keyOrderService.count(query);
        JSONObject data=new JSONObject();
        data.put("count",count);
        data.put("list",gson.toJson(voList));
        JSONObject data = new JSONObject();
        data.put("count", count);
        data.put("list", gson.toJson(voList));
        return JsonUtil.loadTrueResult(data);
    }
    /**
     * @author hxh
     * @description 设置订单号
     * @date 23:08 2024/6/24
     * @param: acceptData
     * @param: id 订单ID
     * @param: orderNo 订单号
     * @param: orderStatus 订单状态:订单已取消/已支付
     * @return java.lang.String
     **/
    @ResponseBody
    @RequestMapping("setOrderNo")
    public String setOrderNo(AcceptData acceptData, String id,String orderNo){
        loggerPay.info("setOrderNo: {}-{}",id,orderNo);
        if(StringUtil.isNullOrEmpty(id)){
    public String setOrderNo(AcceptData acceptData, String id, String orderNo, String orderStatus) {
        loggerPay.info("setOrderNo: {}-{}-{}", id, orderNo, orderStatus);
        if (StringUtil.isNullOrEmpty(id)) {
            return JsonUtil.loadFalseResult("请上传id");
        }
        if(StringUtil.isNullOrEmpty(orderNo)){
        if (StringUtil.isNullOrEmpty(orderNo)) {
            return JsonUtil.loadFalseResult("orderNo");
        }
        KeyOrder order = keyOrderService.selectById(id);
        if(order==null){
        if (order == null) {
            return JsonUtil.loadFalseResult("口令不存在");
        }
@@ -165,32 +176,38 @@
            if (order.getOrderNo() != null && !order.getOrderNo().equalsIgnoreCase(orderNo)) {
                throw new KeyOrderException("已经处理过,与之前处理的订单号不一致");
            }
        }catch(KeyOrderException e){
        } catch (KeyOrderException e) {
            return JsonUtil.loadFalseResult(e.getMessage());
        }
        try {
            DYOrderDto dto = new DYOrderDto(); // DYOrderApi.getOrderDetail(orderNo);
            dto.setOrder_status(1);
            if(dto.getOrder_status() !=DYOrderDto.ORDER_STATUS_NOT_PAY){
                KeyOrder orderUpdate=new KeyOrder();
            DYOrderDto dto = DYOrderApi.getOrderDetail(orderNo);
//            dto.setOrder_status(1);
            if (dto.getOrder_status() != DYOrderDto.ORDER_STATUS_NOT_PAY) {
                // 订单不处于尚未付款状态
                KeyOrder orderUpdate = new KeyOrder();
                orderUpdate.setId(id);
                orderUpdate.setOrderState(dto.getOrder_status());
                orderUpdate.setOrderType(1);
                orderUpdate.setOrderNo(orderNo);
                if(order.getState() == KeyOrder.STATE_NOT_PROCESS){
                    orderUpdate.setState(KeyOrder.STATE_NOT_PAY);
                    orderUpdate.setStateDesc("订单不处于待付款状态");
                if (order.getState() == KeyOrder.STATE_NOT_PROCESS) {
                     if (dto.getOrder_status() == DYOrderDto.ORDER_STATUS_CANCELED) {
                        orderUpdate.setState(KeyOrder.STATE_PAY);
                        orderUpdate.setStateDesc(dto.getOrder_status_desc());
                    } else {
                        orderUpdate.setState(KeyOrder.STATE_PAY);
                        orderUpdate.setStateDesc(dto.getOrder_status_desc());
                    }
                }
                keyOrderService.update(orderUpdate);
                if(dto.getOrder_status() ==DYOrderDto.ORDER_STATUS_CANCELED){
                if (dto.getOrder_status() == DYOrderDto.ORDER_STATUS_CANCELED) {
                    throw new Exception("订单已取消");
                }else {
                } else {
                    throw new Exception("订单已支付");
                }
            }
            // 设置进入
            KeyOrder orderUpdate=new KeyOrder();
            KeyOrder orderUpdate = new KeyOrder();
            orderUpdate.setId(id);
            orderUpdate.setOrderType(1);
            orderUpdate.setOrderState(dto.getOrder_status());
@@ -198,6 +215,16 @@
            keyOrderService.update(orderUpdate);
            order = keyOrderService.selectById(id);
            return JsonUtil.loadTrueResult(gson.toJson(OrderFactory.create(order)));
        } catch (KeyOrderException e) {
            KeyOrder orderUpdate = new KeyOrder();
            orderUpdate.setId(id);
            orderUpdate.setOrderType(1);
            orderUpdate.setOrderState(0);
            orderUpdate.setOrderNo(orderNo);
            orderUpdate.setState(KeyOrder.STATE_REJECT_PAY);
            orderUpdate.setStateDesc(e.getMessage());
            keyOrderService.update(orderUpdate);
            return JsonUtil.loadFalseResult(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return JsonUtil.loadFalseResult(e.getMessage());
@@ -206,53 +233,93 @@
    @ResponseBody
    @RequestMapping("setPayResult")
    public String setPayResult(AcceptData acceptData, String id,boolean paySuccess,String msg){
        loggerPay.info("setPayResult: {}-{}",id,paySuccess);
        if(StringUtil.isNullOrEmpty(id)){
    public String setPayResult(AcceptData acceptData, String id, boolean paySuccess, String msg) {
        loggerPay.info("setPayResult: {}-{}", id, paySuccess);
        if (StringUtil.isNullOrEmpty(id)) {
            return JsonUtil.loadFalseResult("请上传id");
        }
        KeyOrder order = keyOrderService.selectById(id);
        if(order==null){
        if (order == null) {
            return JsonUtil.loadFalseResult("口令不存在");
        }
        if(StringUtil.isNullOrEmpty(order.getOrderNo())){
        if (StringUtil.isNullOrEmpty(order.getOrderNo())) {
            return JsonUtil.loadFalseResult("没有匹配到订单号");
        }
        if(!paySuccess){
          // 支付失败
            KeyOrder orderUpdate=new KeyOrder();
            orderUpdate.setId(id);
            orderUpdate.setState(KeyOrder.STATE_NOT_PAY);
            orderUpdate.setStateDesc("支付失败");
            keyOrderService.update(orderUpdate);
        } else {
            KeyOrder orderUpdate=new KeyOrder();
            orderUpdate.setId(id);
            orderUpdate.setState(KeyOrder.STATE_PAY);
            orderUpdate.setStateDesc("支付成功");
            keyOrderService.update(orderUpdate);
        if(order.getState()==KeyOrder.STATE_NOT_PROCESS) {
            if (!paySuccess) {
                // 支付失败
                KeyOrder orderUpdate = new KeyOrder();
                orderUpdate.setId(id);
                orderUpdate.setState(KeyOrder.STATE_NOT_PAY);
                orderUpdate.setStateDesc("支付失败");
                keyOrderService.update(orderUpdate);
            } else {
                KeyOrder orderUpdate = new KeyOrder();
                orderUpdate.setId(id);
                orderUpdate.setState(KeyOrder.STATE_PAY);
                orderUpdate.setStateDesc("支付成功");
                keyOrderService.update(orderUpdate);
            }
        }
        return JsonUtil.loadTrueResult("");
    }
    @ResponseBody
    @RequestMapping("rejectPay")
    public String rejectPay(AcceptData acceptData, Long uid, String id) {
        loggerPay.info("rejectPay: {}-{}", uid, id);
        if (StringUtil.isNullOrEmpty(id)) {
            return JsonUtil.loadFalseResult("请上传id");
        }
        KeyOrder order = keyOrderService.selectById(id);
        if (order == null) {
            return JsonUtil.loadFalseResult("口令不存在");
        }
        if (order.getState() != KeyOrder.STATE_NOT_PROCESS) {
            return JsonUtil.loadFalseResult("只能驳回未执行状态的口令");
        }
        KeyOrder orderUpdate = new KeyOrder();
        orderUpdate.setId(id);
        orderUpdate.setState(KeyOrder.STATE_REJECT_PAY);
        orderUpdate.setStateDesc("人工驳回");
        keyOrderService.update(orderUpdate);
        return JsonUtil.loadTrueResult("");
    }
    @ResponseBody
    @RequestMapping("deleteAll")
    public String deleteAll(AcceptData acceptData){
    public String deleteAll(AcceptData acceptData,Long uid) {
     ClientInfo user=   clientInfoService.selectByPrimaryKey(uid);
     if(user==null){
         return JsonUtil.loadFalseResult("用户不存在");
     }
     if(user.getRule() != ClientInfo.RULE_ADMIN){
         return JsonUtil.loadFalseResult("只有管理员才能删除");
     }
        // 删除24小时之前的数据
//        keyOrderService.deleteAll(new Date(System.currentTimeMillis() - 24*60*60*1000L));
        keyOrderService.deleteAll(new Date(System.currentTimeMillis()));
        // 刪除所有數據
        return JsonUtil.loadTrueResult("");
    }
    public static void main(String[] args){
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        for(int i=0;i<7;i++) {
            calendar.setTime(new Date(System.currentTimeMillis() - 24*60*60*1000L*i));
        for (int i = 0; i < 7; i++) {
            calendar.setTime(new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000L * i));
            int day = calendar.get(Calendar.DAY_OF_WEEK);
            System.out.println(day-1);
            System.out.println(day - 1);
        }
    }
}
src/main/java/com/taoke/autopay/controller/client/UserController.java
@@ -5,6 +5,7 @@
import com.taoke.autopay.service.ClientInfoService;
import com.taoke.autopay.utils.JsonUtil;
import com.taoke.autopay.vo.AcceptData;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@@ -37,4 +38,17 @@
        }
    }
    @ResponseBody
    @RequestMapping("logout")
    public String logout(AcceptData acceptData,Long uid){
        try {
            clientInfoService.logout(uid);
            return JsonUtil.loadTrueResult(new JSONObject());
        } catch (Exception e) {
            e.printStackTrace();
            return JsonUtil.loadFalseResult(1,e.getMessage());
        }
    }
}
src/main/java/com/taoke/autopay/dao/ClientInfoMapper.java
@@ -18,6 +18,8 @@
    long count(@Param("query") DaoQuery query);
    int clearActiveTime(@Param("id") Long uid);
    public static class DaoQuery{
        public Long id;
        public String name;
src/main/java/com/taoke/autopay/dao/KeyOrderMapper.java
@@ -21,10 +21,12 @@
    long count(@Param("query") DaoQuery query);
    List<OrderDistributeCountInfo> listDistributeUids();
    List<OrderDistributeCountInfo> listDistributeUids(@Param("minActiveTime") Date minActiveTime);
    List<KeyOrder>  listNotDistributed(@Param("start") int start,@Param("count") int count);
    int deleteAll(@Param("maxCreateTime") Date maxCreateTime);
    public static class DaoQuery{
        public String id;
        public String key;
src/main/java/com/taoke/autopay/dto/DYOrderDto.java
@@ -12,7 +12,7 @@
    // 订单未支付
    public final static int ORDER_STATUS_NOT_PAY = 1;
    // 订单取消
    public final static int ORDER_STATUS_CANCELED= 2;
    public final static int ORDER_STATUS_CANCELED= 4;
    /**
src/main/java/com/taoke/autopay/entity/KeyOrder.java
@@ -20,6 +20,8 @@
    public final static int STATE_NOT_PAY = 1;
    // 已支付
    public final static int STATE_PAY = 2;
    // 已支付
    public final static int STATE_REJECT_PAY = 3;
    @Id
src/main/java/com/taoke/autopay/factory/OrderFactory.java
@@ -26,13 +26,16 @@
        vo.setKey(order.getKey());
        switch (order.getState()){
            case KeyOrder.STATE_NOT_PROCESS:
                vo.setState(OrderFilter.STATE_NOT_PROCESS);
                vo.setState(KeyOrderVO.STATE_NOT_PROCESS);
                break;
            case KeyOrder.STATE_NOT_PAY:
                vo.setState(OrderFilter.STATE_PROCESS_ERROR);
                vo.setState(KeyOrderVO.STATE_PROCESS_ERROR);
                break;
            case KeyOrder.STATE_PAY:
                vo.setState(OrderFilter.STATE_PROCESSED);
                vo.setState(KeyOrderVO.STATE_PROCESSED);
                break;
            case KeyOrder.STATE_REJECT_PAY:
                vo.setState(KeyOrderVO.STATE_PROCESSED);
                break;
        }
        return vo;
src/main/java/com/taoke/autopay/service/ClientInfoService.java
@@ -24,6 +24,17 @@
     **/
    public ClientInfo login(String account, String pwd) throws LoginException;
    /**
     * @author hxh
     * @description 退出登录
     * @date 16:49 2024/6/18
     * @param: uid
     * @return com.taoke.autopay.entity.ClientInfo
     **/
    public void logout(Long uid);
    /**
     * @author hxh 
     * @description /根据主键查询
src/main/java/com/taoke/autopay/service/KeyOrderService.java
@@ -4,6 +4,7 @@
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.exception.KeyOrderException;
import java.util.Date;
import java.util.List;
/**
@@ -57,8 +58,31 @@
    public long count(KeyOrderMapper.DaoQuery query);
    /**
     * @author hxh
     * @description 获取可用于分配的设备ID信息
     * @date 16:41 2024/6/17
     * @return java.lang.Long
     **/
    public Long getCanDistributeUid();
    /**
     * @author hxh
     * @description 查询还没分配设备ID的数据
     * @date 16:40 2024/6/17
     * @param: page
     * @param: pageSize
     * @return java.util.List<com.taoke.autopay.entity.KeyOrder>
     **/
    public List<KeyOrder> listNotDistributed(int page,int pageSize);
    /**
     * @author hxh
     * @description 删除所有数据
     * @date 16:40 2024/6/17
     * @param: maxCreateTime
     * @return void
     **/
    public void deleteAll(Date maxCreateTime);
}
src/main/java/com/taoke/autopay/service/impl/ClientInfoServiceImpl.java
@@ -39,6 +39,11 @@
    }
    @Override
    public void logout(Long uid) {
        clientInfoMapper.clearActiveTime(uid);
    }
    @Override
    public ClientInfo selectByPrimaryKey(Long id) {
        return clientInfoMapper.selectByPrimaryKey(id);
    }
src/main/java/com/taoke/autopay/service/impl/KeyOrderServiceImpl.java
@@ -10,9 +10,7 @@
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.*;
/**
 * @author hxh
@@ -34,12 +32,12 @@
    @Override
    public KeyOrder addKeyOrder(String key) throws KeyOrderException {
        String id =   OrderFactory.createId(key);
        KeyOrder order =   keyOrderMapper.selectById(id);
        if(order!=null){
           throw  new KeyOrderException("请勿重复提交口令");
        String id = OrderFactory.createId(key);
        KeyOrder order = keyOrderMapper.selectById(id);
        if (order != null) {
            throw new KeyOrderException("请勿重复提交口令");
        }
        order =new KeyOrder();
        order = new KeyOrder();
        order.setId(id);
        order.setKey(key);
        order.setState(KeyOrder.STATE_NOT_PROCESS);
@@ -67,12 +65,12 @@
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setOrderInfo(String id,String orderNo, int orderState)  throws  KeyOrderException{
    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 +94,53 @@
    @Override
    public Long getCanDistributeUid() {
        List<OrderDistributeCountInfo>  list =   keyOrderMapper.listDistributeUids();
        if(list==null||list.size()==0){
        // 最近1小时有活跃
        List<OrderDistributeCountInfo> list = keyOrderMapper.listDistributeUids(new Date(System.currentTimeMillis() - 1000 * 60 * 60L));
        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);
    }
}
src/main/java/com/taoke/autopay/task/KeyOrderDistributeTask.java
@@ -1,12 +1,18 @@
package com.taoke.autopay.task;
import com.taoke.autopay.dao.KeyOrderMapper;
import com.taoke.autopay.dto.DYOrderDto;
import com.taoke.autopay.entity.KeyOrder;
import com.taoke.autopay.exception.KeyOrderException;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.utils.StringUtil;
import com.taoke.autopay.utils.order.DYOrderApi;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -17,7 +23,7 @@
    private KeyOrderService keyOrderService;
    @Scheduled(cron = "0/5 * * * * ? ")
    private void distribute(){
    private void distribute() {
        try {
            List<KeyOrder> results = keyOrderService.listNotDistributed(1, 20);
            if (results != null) {
@@ -35,9 +41,66 @@
                    }
                }
            }
        }catch(Exception e){
        } catch (Exception e) {
        }
    }
    /**
     * @return void
     * @author hxh
     * @description 修正已经处理的订单
     * @date 17:53 2024/6/20
     **/
    @Scheduled(cron = "0/5 * * * * ? ")
    private void repaireProcessedOrders() {
        // TODO 待完成
        KeyOrderMapper.DaoQuery query = new KeyOrderMapper.DaoQuery();
        // 修正1分钟到1小时的数据之前执行的数据
        query.maxUpdateTime = new Date(System.currentTimeMillis() - 1000 * 60 * 1L);
        query.minUpdateTime = new Date(System.currentTimeMillis() - 1000 * 60 * 60L);
        query.sortList = Arrays.asList(new String[]{"update_time asc"});
        query.stateList = Arrays.asList(new Integer[]{KeyOrder.STATE_NOT_PAY, KeyOrder.STATE_PAY});
        query.orderState = DYOrderDto.ORDER_STATUS_NOT_PAY;
        query.start = 0;
        query.count = 20;
        List<KeyOrder> list = keyOrderService.list(query);
        if (list != null && list.size() > 0) {
            for (KeyOrder order : list) {
                // 如果没有拿到订单就不做处理
                if (StringUtil.isNullOrEmpty(order.getOrderNo())) {
                    continue;
                }
                // 查询结果
                DYOrderDto dto = null;
                try {
                    dto = DYOrderApi.getOrderDetail(order.getOrderNo());
                    if (dto.getOrder_status() != DYOrderDto.ORDER_STATUS_NOT_PAY) {
                        // 订单不处于尚未付款状态
                        KeyOrder orderUpdate = new KeyOrder();
                        orderUpdate.setId(order.getId());
                        orderUpdate.setOrderState(dto.getOrder_status());
                        orderUpdate.setState(KeyOrder.STATE_PAY);
                        orderUpdate.setStateDesc(dto.getOrder_status_desc());
                        keyOrderService.update(orderUpdate);
                    } else {
                        KeyOrder update = new KeyOrder();
                        update.setId(order.getId());
                        update.setState(KeyOrder.STATE_NOT_PROCESS);
                        update.setStateDesc("重置未分配");
                        update.setOrderState(dto.getOrder_status());
                        keyOrderService.update(update);
                    }
                } catch (KeyOrderException e) {
                    e.printStackTrace();
                    KeyOrder orderUpdate = new KeyOrder();
                    orderUpdate.setId(order.getId());
                    orderUpdate.setState(KeyOrder.STATE_PAY);
                    orderUpdate.setStateDesc(e.getMessage());
                    keyOrderService.update(orderUpdate);
                }
            }
        }
    }
}
src/main/java/com/taoke/autopay/utils/order/DYOrderApi.java
@@ -1,6 +1,7 @@
package com.taoke.autopay.utils.order;
import com.taoke.autopay.dto.DYOrderDto;
import com.taoke.autopay.exception.KeyOrderException;
import com.taoke.autopay.utils.HttpUtil;
import com.taoke.autopay.utils.JsonUtil;
import net.sf.json.JSONObject;
@@ -22,19 +23,20 @@
        return result;
    }
    public static DYOrderDto getOrderDetail(String orderNo) throws Exception {
    public static DYOrderDto getOrderDetail(String orderNo) throws KeyOrderException {
        String result = requestByOrderNo1(orderNo);
        JSONObject root = JSONObject.fromObject(result);
        if (root.optInt("code") != 1000) {
            logger.error(String.format("抖音订单查询出错:%s - %s",orderNo, result));
            throw new Exception(root.optString("message"));
            throw new KeyOrderException(root.optString("message"));
        }
       JSONObject data = root.optJSONObject("data");
       return  JsonUtil.getSimpleGson().fromJson(data.toString(),DYOrderDto.class);
    }
    public static void main(String[] args) throws Exception {
        DYOrderDto dto = (DYOrderApi.getOrderDetail("6930867557709059751"));
        DYOrderDto dto = (DYOrderApi.getOrderDetail("6931134387948820382"));
        System.out.println("123123");
    }
}
src/main/java/com/taoke/autopay/vo/KeyOrderVO.java
@@ -3,6 +3,10 @@
import java.util.Date;
public class KeyOrderVO {
    public final static int STATE_NOT_PROCESS = 0;
    public final static int STATE_PROCESSED = 1;
    public final static int STATE_PROCESS_ERROR = 2;
    private String id;
    private String key;
    private int state;
src/main/java/com/taoke/autopay/vo/OrderFilter.java
@@ -17,9 +17,9 @@
    public static final int TIME_TYPE_MONTH=3;
    public static final int STATE_NOT_PROCESS=0;
    public static final int STATE_PROCESSED=1;
    public static final int STATE_PROCESS_ERROR=2;
    public static final int STATE_NOT_PROCESS=1;
    public static final int STATE_PROCESSED=2;
    public static final int STATE_PROCESS_ERROR=3;
src/main/resources/application-dev.yml
@@ -1,5 +1,5 @@
server:
  port: 8080
  port: 9010
  tomcat:
    uri-encoding: UTF-8
spring:
src/main/resources/application-pro.yml
@@ -1,5 +1,5 @@
server:
  port: 9010
  port: 9011
  tomcat:
    uri-encoding: UTF-8
spring:
@@ -11,9 +11,15 @@
      charset: UTF-8
      enabled: true
  datasource:
    url: jdbc:mysql://172.16.16.17:3306/taoke_autopay?serverTimezone=GMT%2B8
    username: root
    password: Yeshi2016@
# 测试
#    url: jdbc:mysql://172.16.16.17:3306/taoke_autopay?serverTimezone=GMT%2B8
#    username: root
#    password: Yeshi2016@
# XCP
    url: jdbc:mysql://127.0.0.1:3306/taoke_autopay?serverTimezone=GMT%2B8
    username: taoke_autopay
    password: xcp123123
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
src/main/resources/logback.xml
@@ -13,7 +13,7 @@
    <property name="log.maxHistory" value="30"/>
    <!--日志存储的根路径 ${catalina.base}指向每个Tomcat目录私有信息的位置,
             就是conf、logs、temp、webapps和work的父目录-->
    <property name="log.filePath" value="/tmp/logs"/>
    <property name="log.filePath" value="/var/logs/taoke"/>
    <!--日志展示的格式-->
    <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
src/main/resources/mapper/ClientInfoMapper.xml
@@ -72,4 +72,14 @@
      <if test="rule != null">rule=#{rule,jdbcType=INTEGER},</if>
    </set> where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="clearActiveTime" parameterType="java.lang.Long">update table_user
    <set>
      active_time = NULL
    </set> where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
src/main/resources/mapper/KeyOrderMapper.xml
@@ -111,8 +111,12 @@
    </set> where id = #{id,jdbcType=VARCHAR}
  </update>
  
  <select id="listDistributeUids" resultMap="DistributeResultMap">
     SELECT u.`id` as uid, IF( a.count IS NULL,0,a.count) AS `count` FROM `table_user` u LEFT JOIN  (SELECT o.`distribute_client_uid` AS uid,COUNT(*) AS `count` FROM `table_order` o WHERE o.`state` = 0 GROUP BY o.`distribute_client_uid`) a ON a.uid = u.`id` WHERE rule=0
  <select id="listDistributeUids" resultMap="DistributeResultMap" parameterType="java.util.Date">
     SELECT u.`id` as uid, IF( a.count IS NULL,0,a.count) AS `count` FROM `table_user` u LEFT JOIN  (SELECT o.`distribute_client_uid` AS uid,COUNT(*) AS `count` FROM `table_order` o WHERE o.`state` = 0 GROUP BY o.`distribute_client_uid`) a ON a.uid = u.`id` WHERE rule=0 <if test="minActiveTime!=null">
    and active_time >=#{minActiveTime}
  </if>
  </select>
@@ -121,4 +125,9 @@
  </select>
  <delete id="deleteAll"  parameterType="java.util.Date">
    delete from table_order where  #{maxCreateTime} >= create_time
  </delete>
</mapper>
src/test/java/com/taoke/autopay/AutopayApplicationTests.java
@@ -5,6 +5,7 @@
import com.taoke.autopay.entity.ClientInfo;
import com.taoke.autopay.entity.OrderDistributeCountInfo;
import com.taoke.autopay.exception.KeyOrderException;
import com.taoke.autopay.service.ClientInfoService;
import com.taoke.autopay.service.KeyOrderService;
import com.taoke.autopay.utils.StringUtil;
import org.junit.jupiter.api.Test;
@@ -14,11 +15,14 @@
import java.util.Date;
import java.util.List;
//@SpringBootTest
@SpringBootTest
class AutopayApplicationTests {
    @Resource
    private ClientInfoMapper mapper;
    @Resource
    private ClientInfoService clientInfoService;
    @Resource
    private KeyOrderService keyOrderService;
@@ -27,16 +31,32 @@
    private KeyOrderMapper keyOrderMapper;
    @Test
    void addClientInfo(){
        for(int i=4;i<50;i++) {
            ClientInfo info=new ClientInfo();
            info.setRule(0);
            info.setAccount("c"+i);
            info.setPwd("e10adc3949ba59abbe56e057f20f883e");
            info.setCreateTime(new Date());
            info.setName("客户端"+i);
            mapper.insertSelective(info);
        }
    }
    @Test
    void test2() throws KeyOrderException {
        keyOrderService.addKeyOrder("【\uD83D\uDC4D z h`i付宝\uD83D\uDC4D】亲,复制 T:/TQEx7jy96Gr  o:/b CA5742 2020/12/07打开支付宝就可以帮我\uD83C\uDFEE付款啦\uD83D\uDCAAhttps://ur.alipay.com/_72G9ZwXA6jz28jdJUNhUx7");
    }
    @Test
    void test3() throws Exception {
    void test4(){
        clientInfoService.logout(3L);
    }
        Long uid =  keyOrderService.getCanDistributeUid();
        System.out.println(uid);
    @Test
    void test3() throws Exception {
        keyOrderService.deleteAll(new Date(System.currentTimeMillis() - 1000*60*60*24L *5));
    }
    @Test
src/test/java/com/taoke/autopay/MapperTest.java
@@ -4,6 +4,9 @@
import org.junit.jupiter.api.Test;
import org.yeshi.utils.generater.mybatis.MyBatisMapperUtil;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @author hxh
 * @title: MapperTest
@@ -15,7 +18,19 @@
    @Test
    public void test() {
//        MyBatisMapperUtil.createMapper(ClientInfo.class);
        MyBatisMapperUtil.createMapper(KeyOrder.class);
//        MyBatisMapperUtil.createMapper(KeyOrder.class);
        String orderNoStr = "抖音电商商家 即时到账--抖音电商-订单编号6931067415405008690";
        Pattern pattern = Pattern.compile("\\d+"); // 匹配连续的数字
        Matcher matcher = pattern.matcher(orderNoStr);
        while (matcher.find()) {
            String number = matcher.group(); // 获取匹配到的数字字符串
            if(number.length()>10){
                orderNoStr = number;
                break;
            }
        }
        System.out.println(orderNoStr);
    }