admin
2024-07-27 65aaf1c05bd06cefa82ebc40cc3e01cf4ac233c0
代理新功能完善
3个文件已添加
9个文件已修改
614 ■■■■■ 已修改文件
src/main/java/com/taoke/autopay/controller/WebApiController.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/factory/WxUserFactory.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/WxUserService.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/service/impl/WxUserServiceImpl.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/utils/WxApiUtil.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/vo/WxUserVO.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/agent-add.html 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/agent-list.html 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/admin/user-list.html 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/static/index3.html 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/KeyTest.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/test/java/com/taoke/autopay/WxUserTests.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/taoke/autopay/controller/WebApiController.java
@@ -1,5 +1,6 @@
package com.taoke.autopay.controller;
import com.google.gson.Gson;
import com.taoke.autopay.dto.DYOrderDto;
import com.taoke.autopay.dto.WXAppInfoDto;
import com.taoke.autopay.entity.KeyOrder;
@@ -268,7 +269,7 @@
    }
    @ResponseBody
    @RequestMapping(value = "submitKeyV3")
    @RequestMapping(value = "submitKeyV4")
    public String submitKeyV4(SubmitKeyInfo keyInfo, HttpSession session, HttpServletRequest request) {
        String referer = request.getHeader("Referer");
        keyInfo.setReferer(referer);
@@ -276,6 +277,7 @@
        if (StringUtil.isNullOrEmpty(keyInfo.getKey())) {
            return JsonUtil.loadFalseResult( "请上传key");
        }
        if(1<0) {
        try{
            verifySubmitKey(keyInfo.getKey());
        }catch (Exception e){
@@ -292,6 +294,7 @@
        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
@@ -302,7 +305,7 @@
                return JsonUtil.loadFalseResult("无法获取到授权链接");
            }
            redictLink=redictLink.replace("","");
            redictLink=redictLink.replace("snsapi_base","snsapi_userinfo");
            // 没有登录,返回登录链接
            JSONObject root = new JSONObject();
            root.put("link", redictLink);
@@ -349,7 +352,20 @@
            WxApiUtil.WXAccessTokenInfo tokenInfo = WxApiUtil.getAcessTokenInfo(code, wxApp);
            if (tokenInfo != null && !StringUtil.isNullOrEmpty(tokenInfo.getOpenid())) {
                WxUserInfo user = wxUserService.login(tokenInfo.getOpenid());
                WxApiUtil.WXUserInfo wxUserInfo =null;
                if(tokenInfo.getScope()!=null&&tokenInfo.getScope().contains("snsapi_userinfo")){
                    try {
                       wxUserInfo = WxApiUtil.getUserInfo(tokenInfo.getAccess_token(), tokenInfo.getOpenid());
                        wxLogger.info("解析结果",new Gson().toJson(wxUserInfo));
                    }catch(Exception e){
                        wxLogger.error("解析出错",e);
                    }
                }
                if(wxUserInfo==null){
                    wxUserInfo=new  WxApiUtil.WXUserInfo();
                    wxUserInfo.setOpenid(tokenInfo.getOpenid());
                }
                WxUserInfo user = wxUserService.login(wxUserInfo);
                session.setAttribute(Constant.SESSION_KEY_USER, user);
                wxLogger.info("微信保存用户信息:{} id-{}", session.getId(), user.getId());
src/main/java/com/taoke/autopay/factory/WxUserFactory.java
@@ -18,6 +18,8 @@
        vo.setId(user.getId());
        vo.setCreateTime(user.getCreateTime());
        vo.setLoginTime(user.getLoginTime());
        vo.setNickName(user.getNickName());
        vo.setPortrait(user.getPortrait());
        WxUserOrderSettingVO settingVO = new WxUserOrderSettingVO(settings.getDyOrderCountPerDay(), settings.getKsOrderCountPerDay(), settings.getTotalOrderCountPerDay());
        vo.setOrderSetting(settingVO);
        return vo;
src/main/java/com/taoke/autopay/service/WxUserService.java
@@ -2,6 +2,7 @@
import com.taoke.autopay.dao.WxUserInfoMapper;
import com.taoke.autopay.entity.WxUserInfo;
import com.taoke.autopay.utils.WxApiUtil;
import java.util.List;
@@ -13,7 +14,7 @@
 */
public interface WxUserService {
    public WxUserInfo login(String openid);
    public WxUserInfo login(WxApiUtil.WXUserInfo wxUserInfo);
    public WxUserInfo selectById(Long id);
src/main/java/com/taoke/autopay/service/impl/WxUserServiceImpl.java
@@ -8,6 +8,7 @@
import com.taoke.autopay.service.WxUserService;
import com.taoke.autopay.service.WxUserSettingService;
import com.taoke.autopay.utils.StringUtil;
import com.taoke.autopay.utils.WxApiUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -36,17 +37,19 @@
    @Transactional(rollbackFor = Exception.class)
    @Override
    public WxUserInfo login(String openid) {
    public WxUserInfo login(WxApiUtil.WXUserInfo wxUserInfo) {
        // 查询用户是否存在
        WxUserInfoMapper.DaoQuery query = new WxUserInfoMapper.DaoQuery();
        query.openId = openid;
        query.openId = wxUserInfo.getOpenid();
        query.count = 1;
        query.start = 0;
        List<WxUserInfo> list = wxUserInfoMapper.list(query);
        if (list.size() == 0) {
            // 没有数据,需要注册
            WxUserInfo user = new WxUserInfo();
            user.setOpenId(openid);
            user.setOpenId(wxUserInfo.getOpenid());
            user.setNickName(wxUserInfo.getNickname());
            user.setPortrait(wxUserInfo.getHeadimgurl());
            user.setLoginTime(new Date());
            user.setCreateTime(new Date());
            wxUserInfoMapper.insertSelective(user);
@@ -54,6 +57,8 @@
        } else {
            WxUserInfo update = new WxUserInfo();
            update.setId(list.get(0).getId());
            update.setNickName(wxUserInfo.getNickname());
            update.setPortrait(wxUserInfo.getHeadimgurl());
            update.setLoginTime(new Date());
            update.setUpdateTime(new Date());
            wxUserInfoMapper.updateByPrimaryKeySelective(update);
src/main/java/com/taoke/autopay/utils/WxApiUtil.java
@@ -2,9 +2,14 @@
import com.google.gson.Gson;
import com.taoke.autopay.dto.WXAppInfoDto;
import lombok.Data;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yeshi.utils.HttpUtil;
import org.yeshi.utils.entity.wx.WXAPPInfo;
import java.net.URLEncoder;
/**
 * @author hxh
@@ -13,6 +18,8 @@
 * @date 2024/6/28 17:27
 */
public class WxApiUtil {
   private static Logger wxLogger = LoggerFactory.getLogger("wxLogger");
    public class WXAccessTokenInfo {
        private String access_token;
@@ -80,11 +87,25 @@
        }
    }
    @Data
  public static  class WXUserInfo{
        private String  openid;//    用户的唯一标识
        private String    nickname    ;//    用户昵称
        private Integer  sex;//        用户的性别,值为1时是男性,值为2时是女性,值为0时是未知
        private String    province;//        用户个人资料填写的省份
        private String    city    ;//    普通用户个人资料填写的城市
        private String    country;//        国家,如中国为CN
        private String      headimgurl;//        用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空。若用户更换头像,原有头像URL将失效。
        private String     unionid;//        只有在用户将公众号绑定到微信开放平台账号后,才会出现该字段。
    }
    public static WXAccessTokenInfo getAcessTokenInfo(String code, WXAppInfoDto app) throws Exception {
        String tokenUrl = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", app.getAppId(), app.getAppSecret(), code);
        String result = HttpUtil.get(tokenUrl);
        System.out.println(result);
        wxLogger.info(result);
        JSONObject root = JSONObject.fromObject(result);
        if (root.optInt("errcode", 0) != 0) {
            throw new Exception(root.optString("errmsg"));
@@ -92,6 +113,19 @@
        return JsonUtil.getSimpleGson().fromJson(result, WXAccessTokenInfo.class);
    }
    public static WXUserInfo getUserInfo(String accessToken,String openid) throws Exception {
        String tokenUrl = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN", URLEncoder.encode(accessToken,"UTF-8"),openid);
        String result = HttpUtil.get(tokenUrl);
        result = new String(result.getBytes("ISO-8859-1"),"UTF-8");
        System.out.println(result);
        wxLogger.info(result);
        JSONObject root = JSONObject.fromObject(result);
        if (root.optInt("errcode", 0) != 0) {
            throw new Exception(root.optString("errmsg"));
        }
        return JsonUtil.getSimpleGson().fromJson(result, WXUserInfo.class);
    }
    public static void main(String[] args) throws Exception {
        getAcessTokenInfo("061KT5ll2vgWHd4VyIll2UVQZV0KT5lP", new WXAppInfoDto("wx6217429129959b05", "14ae1808a271111954c509d8cb06df92"));
src/main/java/com/taoke/autopay/vo/WxUserVO.java
@@ -13,6 +13,8 @@
    private Date createTime;
    private Date loginTime;
    private WxUserOrderSettingVO orderSetting;
    private String nickName;
    private String portrait;
    public Long getId() {
        return id;
@@ -46,5 +48,19 @@
        this.orderSetting = orderSetting;
    }
    public String getNickName() {
        return nickName;
    }
    public void setNickName(String nickName) {
        this.nickName = nickName;
    }
    public String getPortrait() {
        return portrait;
    }
    public void setPortrait(String portrait) {
        this.portrait = portrait;
    }
}
src/main/resources/static/admin/agent-add.html
New file
@@ -0,0 +1,149 @@
<!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;
            }
            .layui-form-label{
                width: 200px;
            }
            .layui-input-block{
                margin-left: 240px;
                max-width: 500px;
            }
            .layui-input-block input{
                    max-width: 150px;
            }
             .small{
                max-width: 75px !important;
            }
        </style>
    </head>
    <body>
        <form class="layui-form" lay-filter="edit">
             <input type="hidden" name="id" />
             <div class="layui-form-item">
                <label class="layui-form-label">渠道代理名称:</label>
                <div class="layui-input-block">
                 <input type="text" name="dyPayCount" required lay-verify="required|num" placeholder="代理名称"
                     autocomplete="off" class="layui-input">
                </div>
              </div>
              <div class="layui-form-item">
                 <label class="layui-form-label">单日代付总频次限制:</label>
                 <div class="layui-input-block">
                  <input type="text" name="dyPayCount" required lay-verify="required|num" placeholder="口令提交总次数"
                      autocomplete="off" class="layui-input">
                 </div>
               </div>
               <div class="layui-form-item">
                  <label class="layui-form-label">单日代付总金额限制:</label>
                  <div class="layui-input-block">
                   <input type="text" name="dyPayCount" required lay-verify="required|num" placeholder="单位:元"
                       autocomplete="off" class="layui-input">
                  </div>
                </div>
                <div class="layui-form-item">
                   <label class="layui-form-label">提交口令时段:</label>
                   <div class="layui-input-inline" style="width: 100px;">
                        <input type="text" name="price_min" placeholder="¥" autocomplete="off" class="layui-input">
                      </div>
                      <div class="layui-form-mid">-</div>
                      <div class="layui-input-inline" style="width: 100px;">
                        <input type="text" name="price_max" placeholder="¥" autocomplete="off" class="layui-input">
                      </div>
                      <div class="layui-form-mid layui-word-aux">如不填写就采用系统默认</div>
                 </div>
              <div class="layui-form-item">
                 <label class="layui-form-label">登录渠道代理后台账号:</label>
                 <div class="layui-input-block">
                  <input type="text" name="ksPayCount" required lay-verify="required|num" placeholder="账号"
                      autocomplete="off" class="layui-input">
                 </div>
               </div>
               <div class="layui-form-item">
                  <label class="layui-form-label">登录渠道代理后台密码:</label>
                  <div class="layui-input-block">
                   <input type="password" name="ksPayCount" required lay-verify="required|num" placeholder="密码"
                       autocomplete="off" class="layui-input">
                  </div>
                </div>
                <div class="layui-form-item">
                   <label class="layui-form-label">分成设置</label>
                   <div class="layui-input-block">
                      <div class="layui-form-mid layui-word-aux">如不填写就采用系统默认</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>
            var listener;
            function submit(callback) {
                //暂存回调方法
                listener = callback;
                //表单提交按钮
                $("#sure").click();
            }
            layui.use(['form', 'layedit', 'laydate'], function() {
                var form = layui.form,
                    layer = layui.layer;
                //自定义验证规则
                form.verify({
                    num: [/^\d+$/, "必须为正整数"]
                });
                var id = http_util.getQueryString("id");
                // 获取值
                $.post("/admin/api/wxuser/getOrderSettings", {"id":id}, function(response) {
                    if (response.code == 0) {
                        form.val("edit", response.data);
                    } else {
                        layer.msg(response.msg);
                    }
                }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                    layer.msg("网络请求失败");
                });
                //监听提交
                form.on('submit(sure)', function(data) {
                    listener(data.field);
                    return false;
                });
            });
        </script>
    </body>
</html>
src/main/resources/static/admin/agent-list.html
New file
@@ -0,0 +1,229 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="renderer" content="webkit">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <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" />
        <link rel="stylesheet" type="text/css" href="css/admin.css" />
        <style>
            #add_client{
                padding: 10px;
            }
        </style>
    </head>
    <body>
        <div class="page-content-wrap">
            <form class="layui-form" action="" lay-filter='search'>
                <div class="layui-form-item">
                    <div class="layui-inline">
                        <input type="text" name="key" id="key" placeholder="按渠道ID/名称搜索" autocomplete="off"
                            class="layui-input">
                    </div>
                    <button class="layui-btn layui-btn-normal" lay-submit lay-filter="search" id="search"><i class="layui-icon layui-icon-search"></i>搜索</button>
                    <a href="javascript:void();" class="layui-btn layui-btn-warm" onclick="add_agent()"><i class="layui-icon layui-icon-add-circle"></i> 创建代理</a>
                </div>
            </form>
            <div class="layui-form" id="table-list">
                <table class="layui-table" lay-even lay-skin="nob" id="table">
                </table>
            </div>
        </div>
        <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 src="js/common.js" type="text/javascript" charset="utf-8"></script> -->
        <script>
            function forbidden(id) {
                // 修改密码
                layer.prompt({
                  formType: 2,
                  value: '',
                  title: '请输入密码',
                  area: ['200px', '50px'] //自定义文本域宽高
                }, function(value, index, elem){
                    if(value.length < 6){
                        layer.msg("密码不能少于6位数");
                        return;
                    }
                    $.post("/admin/api//setpwd", {"id":id,"pwd":value}, function(response) {
                        if (response.code == 0) {
                             layer.close(index);
                            layer.msg("密码修改成功");
                        } else {
                            layer.msg(response.msg);
                        }
                    }, 'json').fail(function(jqXHR, textStatus, errorThrown) {
                        layer.msg("网络请求失败");
                    });
                });
            }
            function add_agent(){
                // 创建设备
                var index = layer.open({
                    type:1,
                    title:"设备账号创建",
                    content: $("#add_client"),
                    end:function(e){
                        $("#add_client").css("display","none");
                    }
                });
            }
            layui.use(['form', 'jquery', 'layer', 'table','laydate'], function() {
                var table = layui.table;
                var form = layui.form;
                var $ = layui.jquery;
                var  laydate = layui.laydate;
                let table_option = {
                    elem: '#table',
                    url: '/admin/api/agent/list', //数据接口
                    where: {
                        'key': $("#key").val()
                    },
                    parseData: function(res) { //res 即为原始返回的数据
                        let flist = new Array();
                        res.data.list.forEach(function(e) {
                            var fdata = {}
                            for (let key in e) {
                                // 判断属性是否是对象自身的属性而非继承的属性
                                if (e.hasOwnProperty(key)) {
                                    //console.log(key + ": " + json[key]);
                                    if (typeof e[key] == 'object') {
                                        for (let k1 in e[key]) {
                                            fdata[key + "." + k1] = e[key][k1];
                                        }
                                    } else {
                                        fdata[key] = e[key];
                                    }
                                }
                            }
                            console.log(fdata);
                            flist.push(fdata);
                        });
                        return {
                            "code": res.code, //解析接口状态
                            "msg": res.msg, //解析提示文本
                            "count": res.data.count, //解析数据长度
                            "data": flist //解析数据列表
                        }
                    },
                    page: true, //开启分页
                    cols: [
                        [ //表头
                            {
                                field: 'id',
                                title: 'ID',
                                width: 100,
                                fixed: 'left'
                            },
                            {
                                field: 'name',
                                title: '名称',
                                width: 120
                            },
                            {
                                field: 'alias',
                                title: '渠道标识',
                                width: 100,
                                sort: false,
                            },
                            {
                                field: 'link',
                                title: '口令提交链接',
                                width: 100,
                                sort: false,
                            },
                            {
                                field: 'rule',
                                title: '类型',
                                width: 100,
                                sort: false,
                                templet: function(d) {
                                    return d.rule == 1 ? '超级管理员' : '普通'
                                }
                            },
                            {
                                field: 'createTime',
                                title: '创建时间',
                                width: 180,
                            }, {
                                field: 'activeTime',
                                title: '活跃时间',
                                width: 180,
                                sort: false,
                            },
                            {
                                field: '',
                                title: '操作',
                                sort: false,
                                templet:'<div><a href="javascript:void" onclick="updatePwd({{d.id}})" class="layui-table-link">设置密码</a></div>'
                            }
                        ]
                    ]
                };
                var key = http_util.getQueryString("key");
                if (key != null && key != undefined) {
                    form.val("search", {
                        "key": key
                    });
                    table_option.data=[];
                    setTimeout(function() {
                        $("#search").click();
                    }, 100);
                }
                //第一个实例
                let tableIns = table.render(table_option);
                //监听提交
                form.on('submit(search)', function(data) {
                    tableIns.reload({
                        where: data.field,
                        page: {
                            curr: 1 //重新从第 1 页开始
                        }
                    });
                    return false;
                });
                form.on('submit(add-client)', function(data) {
                    $.post("/admin/api/clientinfo/add", data.field, 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/main/resources/static/admin/user-list.html
@@ -10,6 +10,11 @@
        <title>用户管理</title>
        <link rel="stylesheet" type="text/css" href="/admin/layui/css/layui.css" />
        <link rel="stylesheet" type="text/css" href="/admin/css/admin.css" />
        <style>
            .portrait{
                width: 30px;
            }
        </style>
    </head>
    <body>
@@ -127,7 +132,20 @@
                                title: '老铁ID',
                                sort: false,
                                fixed: 'left'
                            }, {
                            },
                            {
                                field: 'nickName',
                                title: '昵称',
                                sort: false
                            },
                            {
                                field: '',
                                title: '头像',
                                sort: false,
                                templet: function(d) {return "<img class='portrait' src='"+d.portrait+"' />";}
                            },
                            {
                                field: 'createTime',
                                title: '首次提交口令时间',
                            }, {
src/main/resources/static/index3.html
New file
@@ -0,0 +1,113 @@
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, viewport-fit=cover, 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" />
        <script src="js/jquery.min.js"></script>
        <script src="layui/layui.js"></script>
        <style>
            body{
                background: #FFF;
            }
            .container{
                display: flex;
                 align-items: center;
                 flex-direction: column;
            }
            .edit{
                border-radius: 1rem;
                width: 80%;
                margin-top: 3rem;
            }
            .money {
                border-radius: 0.5rem;
                width: 80%;
                margin-top: 2rem;
                display: none;
            }
            .btn{
                background-color: #FF2B4B;
                border-radius: 0.5rem;
                width: 80%;
                margin-top: 2rem;
                font-size: 1.2rem;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <img  src="img/icon.png" style="width: 40%;margin-top: 1rem;"/>
            <textarea class="layui-textarea edit" placeholder="长按粘贴口令"></textarea>
            <input class="layui-input money" placeholder="请输入付款金额" />
            <button class="layui-btn btn" >提交</button>
        </div>
        <script>
            $(function(){
               function  getQueryString(name) {
                    console.log(window.location.search)
                    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
                    var r = window.location.search.substr(1).match(reg);
                    if (r != null)
                        return unescape(decodeURI(r[2]));
                    return null;
                }
                var state = getQueryString("state");
                var msg = getQueryString("msg");
                if(state=="SUCCESS"){
                  layer.msg("提交成功");
                }else if(state =="FAIL"){
                    if(msg!=null&&msg!=undefined&&msg!=""){
                        layer.msg(msg);
                    }else {
                        layer.msg("提交失败");
                    }
                }
                $(".btn").click(function(){
                    var text = $(".edit").val();
                    var money = $(".money").val();
                    if (text.length <= 0) {
                        layer.msg("请输入口令");
                        return;
                    }
                    // const moneyRegex = /^\d+(\.\d{1,2})?$/;
                    // if (!moneyRegex.test(money)) {
                    //     layer.msg("付款金额输入错误");
                    //     return;
                    // }
                    var index = layer.load();
                    // 上传口令
                    $.post("/webapi/submitKeyV4",{"key":text,"money": money},function(response){
                        layer.close(index);
                        if(response.code==0){
                            layer.msg("提交成功");
                             $(".edit").val("");
                        } else if(response.code==1001){
                            window.location.replace(response.data.link);
                        }else{
                            layer.msg(response.msg);
                        }
                    },'json').fail(function(jqXHR, textStatus, errorThrown){
                        layer.close(index);
                        layer.msg("网络请求失败");
                    });
                });
            });
        </script>
    </body>
</html>
src/test/java/com/taoke/autopay/KeyTest.java
@@ -6,6 +6,7 @@
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.utils.AlipayOrderUtil;
@@ -34,6 +35,9 @@
    @Resource
    private KeyOrderService keyOrderService;
    @Resource
    private OrderPayFailProcessor orderPayFailProcessor;
    private void addKey(SubmitKeyInfo keyInfo, Long wxUid) throws KeyVerifyException, KeyOrderException, WxOrderCountException {
        // 解析链接
@@ -91,4 +95,13 @@
        }
    }
    @Test
    public void testRePay() throws InterruptedException {
        for(int i=0;i<10;i++) {
            orderPayFailProcessor.processPayFail("2c9d0dd55cd845819c8e6010fe10def4", "读取支付宝粘贴板超时");
            Thread.sleep(2000);
            orderPayFailProcessor.processFromQueue();
        }
    }
}
src/test/java/com/taoke/autopay/WxUserTests.java
@@ -22,7 +22,7 @@
    @Test
    public void addWxUser(){
        wxUserService.login("1231231231231234");
//        wxUserService.login("1231231231231234");
    }
}