123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>剑鱼访问控制台</title>
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css"
- integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
- crossorigin="anonymous">
- </head>
- <style>
- body, html {
- margin: 0;
- padding: 0;
- background: #eee;
- min-height: 100vh;
- }
- .main {
- width: 1000px;
- margin: 0 auto;
- min-height: 100vh;
- background-color: #f9f9f9;
- }
- .main .title {
- text-align: center;
- }
- .query {
- display: flex;
- justify-content: space-around;
- }
- .query .item {
- display: flex;
- flex-direction: row;
- }
- .query .item .left {
- line-height: 46px;
- height: 46px;
- margin: 0 5px;
- font-size: 20px;
- }
- #login {
- width: 500px;
- height: 270px;
- position: absolute;
- top: 50%;
- left: 50%;
- margin-top: -200px;
- margin-left: -250px;
- padding: 20px;
- }
- #login .input-group {
- margin: 20px 10px;
- }
- #login .btns {
- display: flex;
- flex-direction: row;
- justify-content: space-around;
- }
- #login .btns button {
- width: 120px;
- height: 35px;
- }
- .btns .submit {
- background-color: #2196f3a1;
- }
- .btns .cancel {
- background-color: #9e9e9e6e;
- }
- #content {
- display: flex;
- flex-direction: column;
- padding: 20px 100px;
- }
- .line {
- display: flex;
- flex-direction: row;
- line-height: 50px;
- margin-top: 1px;
- }
- .line-title {
- width: 170px;
- padding: 0 20px;
- background: #91d3cd;
- }
- .line-content {
- width: 100%;
- padding: 0 20px;
- background: #b7d9f4;
- margin-left: 1px;
- }
- .line-opera {
- background: #b7d9f4;
- width: 30px;
- text-align: center;
- line-height: 30px;
- }
- .line-opera span {
- background: #FF5722;
- padding: 2px;
- border-radius: 5px;
- }
- .line-content .row_30 {
- display: flex;
- flex-direction: row;
- line-height: 30px;
- }
- .line-content .row_normal {
- display: flex;
- flex-direction: row;
- }
- .line-content div.min {
- margin-right: 20px;
- width: 60px;
- }
- .line-content div.min_2 {
- margin-right: 20px;
- width: 120px;
- }
- .line-content div.min_4 {
- margin-right: 20px;
- width: 240px;
- }
- .alias-title {
- margin-top: 10px;
- text-align: center;
- background-color: #68e3f0d1;
- color: #a94442;
- height: 20px;
- line-height: 20px;
- border-radius: 12px;
- }
- .alias-title-head {
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- }
- .alias-title-head .line-opera {
- padding-top: 10px;
- }
- </style>
- <body>
- <div class="main">
- <div class="panel panel-default">
- <div class="panel-body title">
- <h3>用户访问状态查询</h3>
- </div>
- </div>
- <div class="tip">
- </div>
- <nav class="navbar navbar-default">
- <div class="container-fluid">
- <!-- Collect the nav links, forms, and other content for toggling -->
- <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
- <input id="appid" type="text" style="display:none">
- <ul class="nav navbar-nav">
- <li class="dropdown">
- <a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
- aria-expanded="false"><span
- id="userSelect">选择应用</span>
- <span class="caret"></span></a>
- <ul class="dropdown-menu">
- <li><a onclick="ShowLogin()">请登录</a></li>
- </ul>
- </li>
- </ul>
- <div class="navbar-form navbar-right">
- <div class="form-group">
- <input type="text" id="queryValue" class="form-control" style="width: 500px;"
- placeholder="输入用户openid/userid/手机号进行查询">
- </div>
- <button onclick="doSearch()" class="btn btn-default">查询</button>
- </div>
- </div><!-- /.navbar-collapse -->
- </div><!-- /.container-fluid -->
- </nav>
- <!--内容展示-->
- <div id="content" style="display: none">
- <div class="line" v-if="status">
- <div class="line-title">用户状态</div>
- <div v-if="status.flag === 1" class="line-content">
- <div class="row_normal">
- <div class="min">验证码</div>
- <div class="min_4">{{fotmatData(status.flush)}}</div>
- </div>
- </div>
- <div v-else-if="status.flag === 2" class="line-content">
- <div class="row_normal">
- <div class="min">黑名单</div>
- <div class="min_4">{{fotmatData(status.flush)}}</div>
- </div>
- </div>
- <div v-else class="line-content">
- 正常
- </div>
- <div class="line-opera" title="清除账户异常状态" onclick="doClear('1')">
- <span class="glyphicon glyphicon glyphicon-remove"></span>
- </div>
- </div>
- <div class="line" v-if="aliasReq">
- <div class="line-title">请求频率</div>
- <div class="line-content">
- <div class="one" v-for="(alias, i) in aliasReq" v-bind:key="i">
- <div class="alias-title">{{i}}</div>
- <div>
- <div class="alias-title-head">
- <div class="">验证码阀值</div>
- <div class="line-opera" title="清除验证码阀值" v-on:click="doClear('2',i)">
- <span class="glyphicon glyphicon glyphicon-remove"></span>
- </div>
- </div>
- <div>
- <div class="row_30">
- <div class="min">时间</div>
- <div class="min">限制</div>
- <div class="min">当前次数</div>
- <div class="min_4">清除时间</div>
- </div>
- <div class="row_30" v-for="(item, i) in alias.allRates" v-bind:key="i">
- <div class="min">{{item.k}}</div>
- <div class="min">{{item.v}}</div>
- <div class="min">{{item.times}}</div>
- <div class="min_4">{{fotmatData(item.flush)}}</div>
- </div>
- </div>
- </div>
- <div>
- <div class="alias-title-head">
- <div class="">超出最大阈值次数</div>
- <div class="line-opera" title="清除最大请求次数" v-on:click="doClear('6',i)">
- <span class="glyphicon glyphicon glyphicon-remove"></span>
- </div>
- </div>
- <div>
- <div class="row_30">
- <div class="min_2">id超出最大阈值</div>
- <div class="min">当前次数</div>
- <div class="min_4">清除时间</div>
- </div>
- <div class="row_30">
- <div class="min_2">每{{alias.exceedTime.v}}次</div>
- <div class="min">{{alias.exceedTime.times}}</div>
- <div class="min_4">{{fotmatData(alias.exceedTime.flush)}}</div>
- </div>
- </div>
- </div>
- <div>
- <div class="alias-title-head">
- <div class="">最大请求次数</div>
- <div class="line-opera" title="清除最大请求次数" v-on:click="doClear('3',i)">
- <span class="glyphicon glyphicon glyphicon-remove"></span>
- </div>
- </div>
- <div>
- <div class="row_30">
- <div class="min">时间</div>
- <div class="min">限制</div>
- <div class="min">当前次数</div>
- <div class="min_4">清除时间</div>
- </div>
- <div class="row_30">
- <div class="min">{{alias.maxRate.k}}</div>
- <div class="min">{{alias.maxRate.v}}</div>
- <div class="min">{{alias.maxRate.times}}</div>
- <div class="min_4">{{fotmatData(alias.maxRate.flush)}}</div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="line-opera">
- </div>
- </div>
- <div class="line" v-if="verifyErr">
- <div class="line-title">验证码错误次数</div>
- <div class="line-content">
- <div class="row_30">
- <div class="min">时间</div>
- <div class="min">限制</div>
- <div class="min">当前次数</div>
- <div class="min_4">清除时间</div>
- </div>
- <div class="row_30">
- <div class="min">{{verifyErr.k}}</div>
- <div class="min">{{verifyErr.v}}</div>
- <div class="min">{{verifyErr.times}}</div>
- <div class="min_4">{{fotmatData(verifyErr.flush)}}</div>
- </div>
- </div>
- <div class="line-opera" title="清除错误验证码次数" onclick="doClear('4')">
- <span class="glyphicon glyphicon glyphicon-remove"></span>
- </div>
- </div>
- <div class="line" v-if="blackTmpTimes">
- <div class="line-title">临时黑名单次数</div>
- <div class="line-content">
- <div class="row_30">
- <div class="min">时间</div>
- <div class="min">限制</div>
- <div class="min">当前次数</div>
- <div class="min_4">清除时间</div>
- </div>
- <div class="row_30">
- <div class="min">{{blackTmpTimes.k}}</div>
- <div class="min">{{blackTmpTimes.v}}</div>
- <div class="min">{{blackTmpTimes.times}}</div>
- <div class="min_4">{{fotmatData(blackTmpTimes.flush)}}</div>
- </div>
- </div>
- <div class="line-opera" title="清除临时黑名单次数" onclick="doClear('5')">
- <span class="glyphicon glyphicon glyphicon-remove"></span>
- </div>
- </div>
- </div>
- <div id="login" class="panel panel-default" style="display:none">
- <button type="button" class="close cancel" data-dismiss="alert" aria-label="Close"><span
- aria-hidden="true">×</span></button>
- <div class="panel-body ">
- 身份验证
- </div>
- <div class="input-group">
- <span class="input-group-addon">账 户:</span>
- <input type="text" class="form-control" placeholder="请输入账户" id="userName">
- </div>
- <div class="input-group">
- <span class="input-group-addon">密 码:</span>
- <input type="password" class="form-control" placeholder="请输入密码" id="passWord">
- </div>
- <div class="btns">
- <button type="button" class="btn btn-default cancel">取消</button>
- <button type="button" class="btn btn-default submit">登录</button>
- </div>
- </div>
- </div>
- </body>
- <script src="https://cdn.bootcss.com/vue/2.6.11/vue.min.js"></script>
- <script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.js"></script>
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"
- integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
- crossorigin="anonymous"></script>
- <script type="text/javascript">
- Date.prototype.pattern = function (fmt) {
- var o = {
- "y+": this.getFullYear(),
- "M+": this.getMonth() + 1, //月份
- "d+": this.getDate(), //日
- "h+": this.getHours() % 12 === 0 ? 12 : this.getHours() % 12, //小时
- "H+": this.getHours(), //小时
- "m+": this.getMinutes(), //分
- "s+": this.getSeconds(), //秒
- "q+": Math.floor((this.getMonth() + 3) / 3), //季度
- "S": this.getMilliseconds() //毫秒
- };
- var week = {
- "0": "日",
- "1": "一",
- "2": "二",
- "3": "三",
- "4": "四",
- "5": "五",
- "6": "六"
- };
- if (/(y+)/.test(fmt)) {
- fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
- }
- if (/(E+)/.test(fmt)) {
- fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? "星期" : "周") : "") + week[this.getDay() +
- ""]);
- }
- for (var k in o) {
- if (new RegExp("(" + k + ")").test(fmt)) {
- fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
- }
- }
- return fmt;
- }
- var Control = new Vue({
- el: '#content',
- data: {
- "allRates": false,
- "blackTmpTimes": false,
- "aliasReq": false,
- //"maxRate": false,
- "verifyErr": false
- },
- methods: {
- fotmatData: function (time) {
- if (time === 0) {
- return ""
- } else if (time === -1) {
- return "永久"
- }
- return new Date(time * 1000).pattern('yyyy-MM-dd HH.mm.ss')
- }
- }
- });
- $(function () {
- $("#login .cancel").on("click", function () {
- $("#login").hide();
- });
- $("#login .submit").on("click", function () {
- var userName = $("#userName").val();
- var passWord = $("#passWord").val();
- if (userName !== "" && passWord !== "") {
- localStorage.UserName = userName;
- localStorage.Password = passWord;
- $(".tip").html("");
- getAppList();
- $("#login").hide();
- } else {
- tipMsg("输入不能为空")
- }
- });
- if (!localStorage.UserName || !localStorage.UserName) {
- ShowLogin()
- } else {
- getAppList()
- }
- });
- function ShowLogin() {
- $("#login").show();
- }
- function getAppList() {
- var param = {};
- addAuthentication(param);
- $.post("/antiControl/getAppList", param, function (r) {
- if (!r.errMsg) {
- if (r.appList.length > 0) {
- var dropdown_mune = "";
- for (var i = 0; i < r.appList.length; i++) {
- dropdown_mune += "<li data_id=" + r.appList[i] + " onclick='updataSelect(this)'><a>" + r.appList[i] + "</a></li>"
- }
- $(".dropdown .dropdown-menu").html(dropdown_mune)
- }
- } else {
- tipMsg(r.errMsg)
- }
- }, "json")
- }
- var Reqing = false;
- //查询
- function doSearch() {
- var param = {
- "appName": $("#appid").val(),
- "searchV": $("#queryValue").val(),
- };
- if (!param.appName) {
- tipMsg("请选择应用");
- return
- }
- if (!(param.searchV.split(".").length === 4 || param.searchV.length === 11 || param.searchV.length === 24 || param.searchV.length === 28)) {
- tipMsg("查询内容有误");
- return
- }
- addAuthentication(param);
- if (Reqing) {
- return
- }
- $(".tip").html("");
- Reqing = true;
- $.post("/antiControl/query", param, function (r) {
- Reqing = false;
- if (!r.errMsg) {
- $("#content").css("display", "");
- Control.aliasReq = r.rateData;
- // Control.allRates = r.allRates;
- //Control.maxRate = r.maxRate;
- Control.blackTmpTimes = r.blackTmpTimes;
- Control.verifyErr = r.verifyErr;
- Control.status = r.status;
- } else {
- tipMsg(r.errMsg)
- }
- }, "json")
- }
- //清除 -1清除所有;1用户状态 2验证码阀值 3最大请求次数 4验证码错误次数 5临时黑名单次数
- function doClear(flag, other) {
- var param = {
- "appName": $("#appid").val(),
- "searchV": $("#queryValue").val(),
- "flag": flag,
- };
- if (other) {
- param["alias"] = other
- }
- addAuthentication(param);
- if (Reqing) {
- return
- }
- Reqing = true;
- $.post("/antiControl/clear", param, function (r) {
- Reqing = false;
- if (!r.errMsg) {
- doSearch()
- } else {
- tipMsg(r.err)
- }
- }, "json")
- }
- function addAuthentication(param) {
- if (!localStorage.UserName || !localStorage.UserName) {
- ShowLogin()
- } else {
- param["userName"] = localStorage.UserName;
- param["passWord"] = localStorage.Password;
- }
- }
- function updataSelect(demo) {
- var name = $(demo).find("a").text();
- var appid = $(demo).attr("data_id");
- $("#userSelect").text(name);
- $("#appid").val(appid);
- }
- function tipMsg(type) {
- var addHtml = "";
- if (type === "用户校验失败") {
- addHtml = '身份验证异常 <span style="color:#000;cursor: pointer;" onclick="ShowLogin()">点击重新验证</span>'
- } else {
- addHtml = type
- }
- var tipHtml = '<div class="alert alert-warning alert-dismissible" role="alert">' +
- '<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>' +
- '<strong>Warning!</strong> <em>' + addHtml + '</em>' +
- '</div>';
- $(".tip").html(tipHtml);
- }
- </script>
- </html>
|