home.html 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470
  1. <html style="width:100%; height:100%;" lang="zh">
  2. <head>
  3. <title>主页</title>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  6. <script src="jquery.min.js"></script>
  7. <script src="vue.js"></script>
  8. <script src="elementui.js"></script>
  9. <script src="js.cookie.min.js"></script>
  10. <link rel="stylesheet" type="text/css" href="elementui.css">
  11. <style>
  12. * {
  13. margin: 0;
  14. padding: 0;
  15. }
  16. .font {
  17. font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
  18. }
  19. .right {
  20. float: left;
  21. padding: 20px;
  22. width: calc(100% - 240px);
  23. overflow: auto;
  24. height: calc(100% - 40px);
  25. }
  26. .box-card {
  27. width: 450px;
  28. }
  29. </style>
  30. </head>
  31. <body style="width:100%; height:100%;">
  32. <div id="app" style="width:100%; height:100%;">
  33. <div style="float:left; width:200px; height: 100%;">
  34. <!-- 菜单项 -->
  35. <el-menu style="height:100%;" :default-active="activeIndex" class="el-menu-vertical-demo" @select="handleSelect">
  36. <el-menu-item index="1">
  37. <i class="el-icon-menu"></i>
  38. <span slot="title">帮助</span>
  39. </el-menu-item>
  40. <el-menu-item index="2">
  41. <i class="el-icon-document"></i>
  42. <span slot="title">提交</span>
  43. </el-menu-item>
  44. <el-menu-item index="3">
  45. <i class="el-icon-coin"></i>
  46. <span slot="title">日志</span>
  47. </el-menu-item>
  48. <el-menu-item index="4">
  49. <i class="el-icon-zoom-in"></i>
  50. <span slot="title">详情</span>
  51. </el-menu-item>
  52. <li style="padding: 0 20px;box-sizing: border-box;text-align: center;">
  53. <el-popconfirm title="确定要退出登录吗?" @confirm="logout">
  54. <el-button slot="reference" style="margin-top: 20px;">退出登录</el-button>
  55. </el-popconfirm>
  56. </li>
  57. <!--<el-menu-item index="4">-->
  58. <!--<i class="el-icon-setting"></i>-->
  59. <!--<span @click="logout" slot="title">退出登录</span>-->
  60. <!--</el-menu-item>-->
  61. </el-menu>
  62. </div>
  63. <!-- 页面 -->
  64. <!--help-->
  65. <div v-show="activeIndex==='1'" class="right">
  66. <p style="margin-bottom: 20px;">当前用户:{{name}}</p>
  67. <p>干就完事</p>
  68. </div>
  69. <!--submit-->
  70. <div v-show="activeIndex==='2'" class="right" v-loading="!submit.urlOK || !submit.keyOK">
  71. <p style="margin-bottom: 20px;">当前用户:{{name}}</p>
  72. <el-card class="box-card">
  73. <div slot="header">
  74. <span>提交URL</span>
  75. </div>
  76. <p style="margin-bottom: 10px;">提交的URL:</p>
  77. <el-input @keydown.native.enter="submitSetUrl" v-model="submit.url" placeholder="e.g. http://123.123.123.123/"></el-input>
  78. <p style="margin-top: 20px;">状态:<span :style="'color:'+statusColor+';font-weight:bold;'">{{statusTxt}}</span></p>
  79. <p style="margin-top: 20px; word-wrap: break-word; word-break: break-all;" v-show="submit.urlMsg!==''">消息:{{submit.urlMsg}}</p>
  80. <el-button style="margin-top: 20px;" type="primary" @click="submitSetUrl" :disabled="submit.submitUrlDelay">提交</el-button>
  81. </el-card>
  82. <el-card style="margin-top: 30px;" class="box-card">
  83. <!--v-if="submit.reqStatus===1 || submit.ak !== ''"-->
  84. <div slot="header">
  85. <span>提交实验账号密码</span>
  86. </div>
  87. <p style="margin-bottom: 10px;">提交的实验邮箱:</p>
  88. <el-input @keydown.native.enter="submitSetKey" v-model="submit.ak" placeholder="e.g. abcdef@ghijk.com"></el-input>
  89. <p style="margin: 10px 0;">提交的实验密码:</p>
  90. <el-input type="password" @keydown.native.enter="submitSetKey" v-model="submit.sk" placeholder="e.g. abcdefABCDEFabcdef"></el-input>
  91. <el-button style="margin-top: 20px;" type="primary" @click="submitSetKey" :disabled="submit.submitKeyDelay">提交</el-button>
  92. </el-card>
  93. </div>
  94. <!--scoreboard-->
  95. <div v-show="activeIndex==='3'" class="right">
  96. <p style="margin-bottom: 20px;">当前用户:{{name}}</p>
  97. <!-- v-loading="!log.reqOK"-->
  98. <el-table :data="logData" stripe style="width: 100%;">
  99. <el-table-column prop="name" label="姓名" width="300">
  100. </el-table-column>
  101. <el-table-column prop="time" label="时间" width="180">
  102. </el-table-column>
  103. <el-table-column prop="type" label="操作">
  104. </el-table-column>
  105. </el-table>
  106. </div>
  107. <!--details-->
  108. <div v-show="activeIndex==='4'" class="right">
  109. <p style="margin-bottom: 20px;">当前用户:{{name}}</p>
  110. <el-table :data="detailsData" stripe style="width: 100%;">
  111. <el-table-column prop="name" label="姓名" width="300">
  112. </el-table-column>
  113. <el-table-column prop="time" label="首次完成时间" width="180">
  114. </el-table-column>
  115. <el-table-column prop="fail" label="失败提交次数">
  116. </el-table-column>
  117. </el-table>
  118. </div>
  119. </div>
  120. <script>
  121. var app;
  122. var vue = new Vue({
  123. el: '#app',
  124. data: {
  125. apiUrl: '/api',
  126. needLogout: false,
  127. name: "",
  128. activeIndex: "",
  129. currentPage: "-1",
  130. submit: {
  131. url: "",
  132. reqStatus: -1,
  133. urlInterval: -1,
  134. urlMsg: "",
  135. ak: "",
  136. sk: "",
  137. urlOK: false,
  138. keyOK: false,
  139. submitUrlDelay: false,
  140. submitKeyDelay: false
  141. },
  142. log: {
  143. data: [],
  144. interval: -1
  145. },
  146. details: {
  147. data: [],
  148. interval: -1
  149. }
  150. },
  151. computed: {
  152. logData: function() {
  153. for (var i = 0, j = this.log.data.length; i < j; i++) {
  154. this.log.data[i]["time"] = this.formatDate(this.log.data[i]["time"]);
  155. switch (this.log.data[i]["type"]) {
  156. case 1:
  157. this.log.data[i]["type"] = "URL结果匹配成功!!";
  158. break;
  159. case 2:
  160. this.log.data[i]["type"] = "URL结果匹配失败";
  161. break;
  162. default:
  163. this.log.data[i]["type"] = "";
  164. break;
  165. }
  166. }
  167. return this.log.data;
  168. },
  169. detailsData: function() {
  170. for (var i = 0, j = this.details.data.length; i < j; i++) {
  171. if (this.details.data[i]["time"] === 0) {
  172. this.details.data[i]["time"] = "";
  173. }
  174. else {
  175. this.details.data[i]["time"] = this.formatDate(this.details.data[i]["time"]);
  176. }
  177. }
  178. return this.details.data;
  179. },
  180. statusTxt: function() {
  181. switch (this.submit.reqStatus) {
  182. case 0:
  183. return "请求中,请等待至多10秒"
  184. case 1:
  185. return "成功"
  186. case 2:
  187. return "失败"
  188. default:
  189. return "未提交"
  190. }
  191. },
  192. statusColor: function() {
  193. switch (this.submit.reqStatus) {
  194. case 1:
  195. return "green"
  196. case 2:
  197. return "red"
  198. default:
  199. return "black"
  200. }
  201. }
  202. },
  203. methods: {
  204. req(url, method, data) {
  205. data = data ? JSON.stringify(data) : "";
  206. return new Promise(function(resolve, reject) {
  207. $.ajax({
  208. type: method,
  209. url: url,
  210. data: data ? data : "",
  211. contentType: data ? "application/json" : "",
  212. success: function(data) {
  213. resolve(data);
  214. },
  215. error: function(err) {
  216. reject(err);
  217. }
  218. });
  219. });
  220. },
  221. getUser() {
  222. this.req(this.apiUrl + "/user/get", "GET", null).then((data) => {
  223. if (!data["msg"]) {
  224. this.$message.closeAll();
  225. this.$message({
  226. type: 'error',
  227. showClose: true,
  228. message: "未知错误3"
  229. });
  230. }
  231. else {
  232. if (typeof data["msg"] === "string") {
  233. this.logoutAlert(data["msg"]);
  234. // this.$message.closeAll();
  235. // this.$message({
  236. // type: 'error',
  237. // showClose: true,
  238. // message: data["msg"]
  239. // });
  240. }
  241. else {
  242. this.name = data["msg"]["name"];
  243. }
  244. }
  245. }).catch(() => {
  246. this.logoutAlert("服务器错误3");
  247. // this.$message.closeAll();
  248. // this.$message({
  249. // type: 'error',
  250. // showClose: true,
  251. // message: "服务器错误3"
  252. // });
  253. });
  254. },
  255. logoutAlert(msg) {
  256. this.$alert(msg, '错误', {
  257. showClose: false,
  258. confirmButtonText: '重新登录',
  259. callback: action => {
  260. this.logout();
  261. }
  262. });
  263. },
  264. handleSelect(index) {
  265. if (index === this.activeIndex) {
  266. return;
  267. }
  268. Cookies.set("page", index);
  269. this.activeIndex = index;
  270. if (index === "2") { // submit
  271. this.submitGetUrl();
  272. this.submitGetKey();
  273. }
  274. else {
  275. clearInterval(this.submit.timeInterval);
  276. }
  277. if (index === "3") { // log
  278. var self = this;
  279. this.log.interval = setInterval(function() { self.getLog(); }, 3000);
  280. this.getLog();
  281. }
  282. else {
  283. clearInterval(this.log.interval);
  284. }
  285. if (index === "4") { // details
  286. var self = this;
  287. this.details.interval = setInterval(function() { self.getDetails(); }, 3000);
  288. this.getDetails();
  289. }
  290. else {
  291. clearInterval(this.details.interval);
  292. }
  293. },
  294. logout() {
  295. Cookies.set("token", "");
  296. Cookies.set("page", "");
  297. location.href = "/";
  298. },
  299. submitGetUrl(statusOnly) {
  300. if (!statusOnly) {
  301. this.submit.urlOK = false;
  302. this.submit.url = "";
  303. this.submit.reqStatus = "";
  304. }
  305. this.req(this.apiUrl + "/url/get", "GET", null).then((data) => {
  306. this.submit.urlOK = true;
  307. if (data["success"] === 1 && typeof data["msg"] === 'object' && typeof data["msg"]["url"] === 'string' && typeof data["msg"]["status"] === 'number') {
  308. this.submit.reqStatus = data["msg"]["status"];
  309. this.submit.urlMsg = data["msg"]["msg"];
  310. if (!statusOnly) {
  311. this.submit.url = data["msg"]["url"];
  312. }
  313. if (this.submit.reqStatus === 0 && !statusOnly) {
  314. var self = this;
  315. this.submit.timeInterval = setInterval(function() { self.submitGetUrl(true); }, 3000);
  316. }
  317. if (this.submit.reqStatus !== 0) {
  318. clearInterval(this.submit.timeInterval);
  319. }
  320. }
  321. }).catch((err) => {
  322. this.logoutAlert("服务器错误4");
  323. });
  324. },
  325. submitGetKey() {
  326. this.submit.keyOK = false;
  327. this.submit.ak = "";
  328. this.submit.sk = "";
  329. this.req(this.apiUrl + "/key/get", "GET", null).then((data) => {
  330. this.submit.keyOK = true;
  331. if (data["success"] === 1 && typeof data["msg"] === 'object' && typeof data["msg"]["ak"] === 'string' && typeof data["msg"]["sk"] === 'string') {
  332. this.submit.ak = data["msg"]["ak"];
  333. this.submit.sk = data["msg"]["sk"];
  334. }
  335. }).catch((err) => {
  336. this.submit.keyOK = true;
  337. console.log(err);
  338. this.$message.closeAll();
  339. this.$message({
  340. type: 'error',
  341. showClose: true,
  342. message: "未知错误4"
  343. });
  344. });
  345. },
  346. submitSetUrl() {
  347. if (this.submit.url === "") {
  348. this.$message.closeAll();
  349. this.$message({
  350. type: 'error',
  351. showClose: true,
  352. message: "请输入URL"
  353. });
  354. return;
  355. }
  356. this.submit.submitUrlDelay = true;
  357. var self = this;
  358. setTimeout(function() { self.submit.submitUrlDelay = false; }, 3000);
  359. this.req(this.apiUrl + "/url/set", "POST", { "url": this.submit.url }).then((data) => {
  360. if (data["success"] === 1) {
  361. this.$message.closeAll();
  362. this.$message({
  363. type: 'success',
  364. showClose: true,
  365. message: "提交成功"
  366. });
  367. var self = this;
  368. this.submitGetUrl(true);
  369. this.submit.timeInterval = setInterval(function() { self.submitGetUrl(true); }, 3000);
  370. }
  371. else {
  372. this.$message.closeAll();
  373. this.$message({
  374. type: 'error',
  375. showClose: true,
  376. message: data["msg"]
  377. });
  378. }
  379. }).catch((err) => {
  380. this.logoutAlert("服务器错误5");
  381. });
  382. },
  383. submitSetKey() {
  384. if (this.submit.ak === "") {
  385. this.$message.closeAll();
  386. this.$message({
  387. type: 'error',
  388. showClose: true,
  389. message: "请输入邮箱"
  390. });
  391. return;
  392. }
  393. if (this.submit.sk === "") {
  394. this.$message.closeAll();
  395. this.$message({
  396. type: 'error',
  397. showClose: true,
  398. message: "请输入密码"
  399. });
  400. return;
  401. }
  402. this.submit.submitKeyDelay = true;
  403. var self = this;
  404. setTimeout(function() { self.submit.submitKeyDelay = false; }, 3000);
  405. this.req(this.apiUrl + "/key/set", "POST", { ak: this.submit.ak, sk: this.submit.sk }).then((data) => {
  406. if (data && (data["success"] === 1 || data["success"] === -1)) {
  407. this.$message.closeAll();
  408. this.$message({
  409. type: 'success',
  410. showClose: true,
  411. message: "提交成功"
  412. });
  413. }
  414. }).catch((err) => {
  415. this.logoutAlert("服务器错误6");
  416. });
  417. },
  418. getLog() {
  419. // this.log.data = [];
  420. this.req(this.apiUrl + "/log/get", "GET", null).then((data) => {
  421. this.log.data = data;
  422. }).catch((err) => {
  423. this.logoutAlert("服务器错误7");
  424. });
  425. },
  426. getDetails() {
  427. this.req(this.apiUrl + "/log/get/details", "GET", null).then((data) => {
  428. this.details.data = data;
  429. }).catch((err) => {
  430. this.logoutAlert("服务器错误8");
  431. });
  432. },
  433. formatDate: function(timestamp) {
  434. var d = new Date(timestamp * 1000);
  435. return d.getFullYear() + "-" + ((d.getMonth() + 1 >= 10) ? (d.getMonth() + 1) : "0" + (d.getMonth() + 1)) + "-" + ((d.getDate() >= 10) ? d.getDate() + "" : "0" + d.getDate()) + " " + ((d.getHours() >= 10) ? d.getHours() + "" : "0" + d.getHours()) + ":" + ((d.getMinutes() >= 10) ? d.getMinutes() + "" : "0" + d.getMinutes()) + ":" + ((d.getSeconds() >= 10) ? d.getSeconds() + "" : "0" + d.getSeconds());
  436. }
  437. },
  438. mounted: function() {
  439. app = this;
  440. var page = Cookies.get("page")
  441. if (page) {
  442. this.handleSelect(page);
  443. }
  444. else {
  445. this.handleSelect("2");
  446. }
  447. this.getUser();
  448. // this.getLog();
  449. }
  450. });
  451. </script>
  452. </body>
  453. </html>