├── favicon.ico ├── index.html └── index.js /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Kengxxiao/Kyouka/3089a1f3ffb4d5e664f0d6ce62c997bef74bfb28/favicon.ico -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 镜华 - 公会战排名查询 7 | 8 | 11 | 12 | 13 | 14 | 22 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 | 88 |
89 | 90 |
91 |
92 |
93 |
94 | 95 |
96 |
97 |
98 |
99 |
100 | 101 | 102 |
103 |
104 | 105 |
106 |
107 | 111 |
112 | 113 | 114 |

查询结果

115 |
{{showData.time}}
116 |
117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 129 | 132 | 133 | 134 |
{{item}}
{{idx == 'damage' ? Number(xd).toLocaleString() : xd}} 127 | 128 | 130 | 131 |
135 |
136 | 145 | 152 |
153 |
154 |
155 | 156 | 157 |
158 |
159 | 160 | 161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 | 181 |
182 |
183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var app = new Vue({ 2 | el: "#Kyouka", 3 | data: { 4 | showData: { 5 | header: ["排名", "公会名", "分数", "会长名", "收藏", "保存"], 6 | time: "", 7 | body: [], 8 | ts: 0, 9 | }, 10 | historyData: [], 11 | inputtype: "text", 12 | selected: 2, 13 | selectType: { 14 | "2": "按公会名", 15 | "1": "按排名", 16 | "3": "按会长名", 17 | "4": "按分数" 18 | }, 19 | selectdata: "", 20 | pageinfo: { 21 | page: 0, 22 | maxPage: 0, 23 | limit: 10, 24 | show: "", 25 | prevDis: "disabled", 26 | nextDis: "disabled", 27 | }, 28 | lastReq: JSON.stringify({ 29 | history: 0 30 | }), 31 | lastApi: "", 32 | mock: true, 33 | allow: true, 34 | waitTime: 1, 35 | nowHistoryTime: 0, 36 | bossData: { 37 | scoreRate: [ 38 | [1.2, 1.2, 1.3, 1.4, 1.5], 39 | [1.6, 1.6, 1.8, 1.9, 2.0], 40 | [2.0, 2.0, 2.4, 2.4, 2.6], 41 | [3.5, 3.5, 3.7, 3.8, 4.0] 42 | ], 43 | hp: [ 44 | [6000000, 8000000, 10000000, 12000000, 15000000], 45 | [6000000, 8000000, 10000000, 12000000, 15000000], 46 | [7000000, 9000000, 13000000, 15000000, 20000000], 47 | [15000000, 16000000, 18000000, 19000000, 20000000] 48 | ], 49 | phase: [1, 4, 11, 35], 50 | baseTime: 1593464400, 51 | endTime: 1593964800, 52 | }, 53 | //apiUrl: "http://127.0.0.1:5002/clan", 54 | apiUrl: "https://service-kjcbcnmw-1254119946.gz.apigw.tencentcs.com/", 55 | foot2show: false, 56 | foot2Info: { 57 | clanName: "", 58 | zminfo: "", 59 | per: "", 60 | perText: "", 61 | }, 62 | proTableData: [], 63 | favSelected: [], 64 | serverMsg: [], 65 | country: "", 66 | savedData: [], 67 | }, 68 | computed: { 69 | selectRange() { 70 | const { 71 | selected, 72 | selectdata 73 | } = this; 74 | return { 75 | selected, 76 | selectdata, 77 | }; 78 | }, 79 | }, 80 | watch: { 81 | proTableData: function(val) { 82 | $(".navbar-collapse").collapse("hide"); 83 | }, 84 | }, 85 | mounted() { 86 | let type = this.getUrlKey("type", window.location.href); 87 | let data = this.getUrlKey("data", window.location.href); 88 | if (type != null && data != null) { 89 | this.selected = type; 90 | this.selectdata = data; 91 | setTimeout(() => { 92 | this.search(); 93 | }, 300); 94 | return; 95 | } 96 | $(document).ajaxSend(function(ev, xhr, settings) { 97 | xhr.setRequestHeader("Custom-Source", "KyoukaOfficial"); 98 | }); 99 | if (!localStorage.hasOwnProperty("savedData")) { 100 | localStorage.setItem("savedData", "{}"); 101 | } 102 | this.checkGeo(); 103 | this.defaultPage(); 104 | }, 105 | methods: { 106 | getClanBattlePhase(zm) { 107 | for (let i = this.bossData.phase.length - 1; i >= 0; i--) { 108 | if (zm >= this.bossData.phase[i]) return i; 109 | } 110 | }, 111 | checkGeo() { 112 | var self = this; 113 | $.ajax({ 114 | url: "https://get.geojs.io/v1/ip/country.js", 115 | type: "GET", 116 | dataType: "JSONP", 117 | async: true, 118 | jsonp: "callback", 119 | success: function(data) { 120 | self.country = data.country; 121 | self.$forceUpdate(); 122 | }, 123 | }); 124 | }, 125 | async exportSavedData() { 126 | let wb = new ExcelJS.Workbook(); 127 | let ws = wb.addWorksheet("Kyouka"); 128 | let p2 = JSON.parse(localStorage.getItem("savedData")); 129 | wb.creator = "Kyouka Clan Data Maker"; 130 | ws.columns = [{ 131 | width: 24 132 | }, { 133 | width: 8 134 | }, { 135 | width: 24 136 | }, { 137 | width: 12 138 | }, { 139 | width: 24 140 | }]; 141 | for (let key in p2) { 142 | ws.addRow(["会长ID", key]); 143 | ws.addRow(["时间", "排名", "公会名", "分数", "会长名"]); 144 | let data = p2[key]; 145 | let sortedTime = {}; 146 | for (let i = 0; i < data.time.length; i++) { 147 | sortedTime[data.time[i]] = i; 148 | } 149 | let s2 = Object.keys(sortedTime).sort(); 150 | for (let i = 0; i < s2.length; i++) { 151 | ws.addRow([this.convertTime(data.time[sortedTime[s2[i]]]), data.data[sortedTime[s2[i]]].rank, data.data[sortedTime[s2[i]]].clan_name, data.data[sortedTime[s2[i]]].damage, data.data[sortedTime[s2[i]]].leader_name]); 152 | } 153 | ws.addRow([]); 154 | } 155 | let b = await wb.xlsx.writeBuffer(); 156 | saveAs(new Blob([b], { 157 | type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 158 | }), "Kyouka_" + Date.parse(new Date()) / 1000 + ".xlsx"); 159 | }, 160 | removeAllSavedData() { 161 | if (confirm("您确定要移除所有保存的数据吗?")) { 162 | localStorage.setItem("savedData", "{}"); 163 | this.$forceUpdate(); 164 | alert("移除已完成"); 165 | } 166 | }, 167 | resetSearch(val) { 168 | switch (parseInt(val)) { 169 | case 1: 170 | this.lastApi = "/rank/"; 171 | this.rank = parseInt(this.selectdata); 172 | this.lastReq = JSON.stringify({ 173 | history: parseInt(this.nowHistoryTime) 174 | }); 175 | this.inputtype = "number"; 176 | break; 177 | case 4: 178 | this.lastApi = "/score/"; 179 | this.rank = parseInt(this.selectdata); 180 | this.lastReq = JSON.stringify({ 181 | history: parseInt(this.nowHistoryTime) 182 | }); 183 | this.inputtype = "number"; 184 | break; 185 | case 2: 186 | this.lastApi = "/name/"; 187 | this.lastReq = JSON.stringify({ 188 | history: parseInt(this.nowHistoryTime), 189 | clanName: this.selectdata 190 | }); 191 | this.inputtype = "text"; 192 | break; 193 | case 3: 194 | this.lastApi = "/leader/"; 195 | this.lastReq = JSON.stringify({ 196 | history: parseInt(this.nowHistoryTime), 197 | leaderName: this.selectdata 198 | }); 199 | this.inputtype = "text"; 200 | break; 201 | default: 202 | return; 203 | } 204 | }, 205 | isAllowedToShow(im) { 206 | let a = JSON.parse(localStorage.getItem("disabledMsg")).indexOf(im.id) == -1; 207 | let b = im.regionLimit == undefined || im.regionLimit == this.country; 208 | return a & b; 209 | }, 210 | disableMsg(id) { 211 | let orig = JSON.parse(localStorage.getItem("disabledMsg")); 212 | if (orig.indexOf(id) == -1) { 213 | orig.push(id); 214 | localStorage.setItem("disabledMsg", JSON.stringify(orig)); 215 | this.$forceUpdate(); 216 | } 217 | }, 218 | convertTime(date) { 219 | return new Date(date * 1000).toLocaleString([], { 220 | minute: "numeric", 221 | hour: "numeric", 222 | day: "numeric", 223 | month: "narrow", 224 | year: "numeric" 225 | }); 226 | }, 227 | serverError(xhr, state, errorThrown) { 228 | $(".search").button("reset"); 229 | if (xhr.responseJSON == undefined) { 230 | alert("无法连接到服务器,请刷新后重试"); 231 | return; 232 | } 233 | alert(xhr.responseJSON.msg); 234 | }, 235 | transPage() { 236 | var p = prompt("请输入要跳转的页码"); 237 | if (p != null) { 238 | var g = parseInt(p); 239 | if (!isNaN(g)) { 240 | if (g <= 0 || g > this.pageinfo.maxPage) { 241 | alert("页码超出范围,请重试"); 242 | } else { 243 | this.pageinfo.page = g - 1; 244 | this.getPage(this.pageinfo.page); 245 | } 246 | } 247 | } 248 | }, 249 | processPage() { 250 | this.allow = false; 251 | setTimeout(() => { 252 | this.allow = true; 253 | }, this.waitTime * 1000); 254 | this.pageinfo.show = this.pageinfo.page + 1 + "/" + (this.pageinfo.maxPage == 0 ? 1 : this.pageinfo.maxPage); 255 | 256 | if (this.pageinfo.page <= 0) { 257 | this.pageinfo.prevDis = "disabled"; 258 | } else { 259 | this.pageinfo.prevDis = ""; 260 | } 261 | if (this.pageinfo.page + 1 >= this.pageinfo.maxPage) { 262 | this.pageinfo.nextDis = "disabled"; 263 | } else { 264 | this.pageinfo.nextDis = ""; 265 | } 266 | }, 267 | getPage(val) { 268 | if (!this.allow) { 269 | alert("休息一下再翻页吧"); 270 | return; 271 | } 272 | if (val < 0 || val >= this.pageinfo.maxPage) return; 273 | $(".search").button("loading"); 274 | $.ajax({ 275 | url: this.apiUrl + this.lastApi + val, 276 | type: "POST", 277 | dataType: "JSON", 278 | async: true, 279 | contentType: "application/json", 280 | data: this.lastReq, 281 | success: this.processData, 282 | error: this.serverError, 283 | }); 284 | this.pageinfo.page = val; 285 | }, 286 | reset() { 287 | this.pageinfo.page = 0; 288 | this.nowHistoryTime = 0; 289 | this.defaultPage(); 290 | }, 291 | showfoot() { 292 | this.foot2show = true; 293 | }, 294 | setFootPer(remainPer) { 295 | this.showfoot(); 296 | setTimeout( 297 | () => { 298 | this.foot2Info.per = "width: " + remainPer + "%"; 299 | this.foot2Info.perText = remainPer.toFixed(2) + "%"; 300 | }, 301 | this.foot2show ? 0 : 100 302 | ); 303 | }, 304 | calcHp(clan) { 305 | let clanName = clan.clan_name; 306 | let hpBase = clan.damage; 307 | if (hpBase > 100000000000) 308 | hpBase /= 100000; 309 | var zm = 1; 310 | var king = 1; 311 | var cc = 0.0; 312 | var remain = 0.0; 313 | var damage = 0; 314 | var remainHp = 0.0; 315 | var remainPer = 0.0; 316 | let phase = 0; 317 | while (true) { 318 | phase = this.getClanBattlePhase(zm); 319 | cc += this.bossData.scoreRate[phase][king - 1] * this.bossData.hp[phase][king - 1]; 320 | if (cc > hpBase) { 321 | cc -= this.bossData.scoreRate[phase][king - 1] * this.bossData.hp[phase][king - 1]; 322 | remain = (hpBase - cc) / this.bossData.scoreRate[phase][king - 1]; 323 | damage += remain; 324 | remainPer = 1.0 - remain / this.bossData.hp[phase][king - 1]; 325 | remainHp = this.bossData.hp[phase][king - 1] - remain; 326 | break; 327 | } 328 | damage += this.bossData.hp[phase][king - 1]; 329 | if (king == 5) { 330 | zm++; 331 | king = 1; 332 | continue; 333 | } 334 | king++; 335 | } 336 | remainPer *= 100; 337 | 338 | this.foot2Info.clanName = clanName; 339 | this.foot2Info.zminfo = zm + "周目" + king + "王 [" + parseInt(remainHp) + "/" + this.bossData.hp[phase][king - 1] + "]"; 340 | this.setFootPer(remainPer); 341 | }, 342 | searchFav() { 343 | $(".search").button("loading"); 344 | this.pageinfo.page = 0; 345 | var favc = JSON.parse(localStorage.getItem("fav")); 346 | for (var i = 0; i < favc.length; i++) { 347 | ga("send", "event", "kyouka", "fav", favc[i]); 348 | } 349 | $.ajax({ 350 | url: this.apiUrl + "/fav", 351 | type: "POST", 352 | dataType: "JSON", 353 | async: true, 354 | contentType: "application/json", 355 | data: JSON.stringify({ 356 | ids: JSON.parse(localStorage.getItem("fav")), 357 | history: parseInt(this.nowHistoryTime) 358 | }), 359 | success: this.processData, 360 | error: this.serverError, 361 | }); 362 | }, 363 | saveDataLocal(ts, id) { 364 | let sv = JSON.parse(localStorage.getItem("savedData")); 365 | let leader = this.proTableData[id].leader_viewer_id; 366 | if (sv[leader] == undefined) { 367 | sv[leader] = { 368 | time: [], 369 | data: [] 370 | }; 371 | } 372 | let indexA = sv[leader].time.indexOf(ts); 373 | if (indexA != -1) { 374 | sv[leader].time.splice(indexA, 1); 375 | sv[leader].data.splice(indexA, 1); 376 | if (sv[leader].time.length == 0) delete sv[leader]; 377 | } else { 378 | sv[leader].time.push(ts); 379 | sv[leader].data.push(this.proTableData[id]); 380 | } 381 | localStorage.setItem("savedData", JSON.stringify(sv)); 382 | this.$forceUpdate(); 383 | }, 384 | getDataLocal(ts, id) { 385 | if (!localStorage.hasOwnProperty("savedData")) return "glyphicon glyphicon-floppy-disk"; 386 | let sv = JSON.parse(localStorage.getItem("savedData")); 387 | let leader = this.proTableData[id].leader_viewer_id; 388 | if (sv[leader] != undefined) { 389 | if (sv[leader].time.indexOf(ts) != -1) { 390 | return "glyphicon glyphicon-floppy-saved"; 391 | } 392 | } 393 | return "glyphicon glyphicon-floppy-disk"; 394 | }, 395 | favLeader(id) { 396 | let leaderId = this.proTableData[id].leader_viewer_id; 397 | var fav = JSON.parse(localStorage.getItem("fav")); 398 | var idx = fav.indexOf(leaderId); 399 | if (idx == -1) { 400 | if (fav.length >= 10) { 401 | alert("收藏过多,请取消一些收藏的公会"); 402 | return; 403 | } 404 | fav.push(leaderId); 405 | this.favSelected[id] = "glyphicon glyphicon-heart"; 406 | } else { 407 | fav.splice(idx, 1); 408 | this.favSelected[id] = "glyphicon glyphicon-heart-empty"; 409 | } 410 | this.$forceUpdate(); 411 | localStorage.setItem("fav", JSON.stringify(fav)); 412 | }, 413 | setTableData(table) { 414 | this.favSelected = []; 415 | this.showData.body = []; 416 | for (let item of table) { 417 | if (item.clan_name == undefined) { 418 | item.clan_name = "该行会已解散"; 419 | } 420 | let tableData = { 421 | rank: item.rank, 422 | clan_name: item.clan_name, 423 | damage: item.damage, 424 | leader_name: item.leader_name, 425 | }; 426 | this.showData.body.push(tableData); 427 | this.favSelected.push("glyphicon glyphicon-heart-empty"); 428 | } 429 | 430 | if (!localStorage.hasOwnProperty("fav")) { 431 | localStorage.setItem("fav", "[]"); 432 | } 433 | var fav = JSON.parse(localStorage.getItem("fav")); 434 | for (let f of fav) { 435 | let xid = 0; 436 | for (let t of table) { 437 | if (t.leader_viewer_id == f) { 438 | this.favSelected[xid] = "glyphicon glyphicon-heart"; 439 | } 440 | xid = xid + 1; 441 | } 442 | } 443 | 444 | this.proTableData = table; 445 | $(".search").button("reset"); 446 | }, 447 | historyRank(time) { 448 | this.pageinfo.page = 0; 449 | this.nowHistoryTime = time; 450 | this.lastReq = JSON.stringify({ 451 | history: parseInt(time) 452 | }); 453 | this.defaultPage(); 454 | }, 455 | processHistory(historyV2) { 456 | $(".navbar-collapse").collapse("hide"); 457 | this.historyData = []; 458 | let data = Object.keys(historyV2); 459 | for (var i = 0; i < data.length; i++) { 460 | let his = { 461 | time: data[i], 462 | date: historyV2[data[i]] == "" ? this.convertTime(data[i]) : historyV2[data[i]] + "(" + this.convertTime(data[i]) + ")", 463 | }; 464 | this.historyData.push(his); 465 | } 466 | }, 467 | processData(data) { 468 | if (data.history != undefined) { 469 | this.processHistory(data.historyV2); 470 | } 471 | if (data.serverMsg != undefined && data.serverMsg.length) { 472 | if (!localStorage.hasOwnProperty("disabledMsg")) { 473 | localStorage.setItem("disabledMsg", "[]"); 474 | localStorage.setItem("savedMsg", "[]"); 475 | } 476 | let saved2 = JSON.parse(localStorage.getItem("savedMsg")); 477 | let msgArray = []; 478 | let defaultMsgArray = data.serverMsg; 479 | for (let i = 0; i < data.serverMsg.length; i++) { 480 | if (saved2.indexOf(data.serverMsg[i]) == -1) msgArray.push(data.serverMsg[i]); 481 | } 482 | if (msgArray.length) { 483 | var self = this; 484 | $.ajax({ 485 | url: this.apiUrl + "/serverMsg", 486 | type: "POST", 487 | dataType: "JSON", 488 | contentType: "application/json", 489 | data: JSON.stringify({ 490 | idList: msgArray 491 | }), 492 | async: true, 493 | success: function(data) { 494 | let saved = JSON.parse(localStorage.getItem("savedMsg")); 495 | for (let i = 0; i < saved.length; i++) { 496 | if (defaultMsgArray.indexOf(saved[i]) != -1) data.push(JSON.parse(localStorage.getItem("msg_" + saved[i]))); 497 | } 498 | self.serverMsg = data; 499 | for (let i = 0; i < data.length; i++) { 500 | if (data[i] == undefined) { 501 | continue; 502 | } 503 | if (saved.indexOf(data[i].id) == -1) { 504 | localStorage.setItem("msg_" + data[i].id, JSON.stringify(data[i])); 505 | saved.push(data[i].id); 506 | } 507 | } 508 | localStorage.setItem("savedMsg", JSON.stringify(saved)); 509 | }, 510 | }); 511 | } else { 512 | let saved = JSON.parse(localStorage.getItem("savedMsg")); 513 | this.serverMsg = []; 514 | for (let i = 0; i < saved.length; i++) { 515 | if (data.serverMsg.indexOf(saved[i]) != -1) { 516 | this.serverMsg.push(JSON.parse(localStorage.getItem("msg_" + saved[i]))); 517 | } 518 | } 519 | } 520 | } 521 | this.showData.time = this.convertTime(data.ts); 522 | this.showData.ts = data.ts; 523 | this.pageinfo.maxPage = Math.ceil((data.full * 1.0) / this.pageinfo.limit); 524 | this.setTableData(data.data); 525 | this.processPage(); 526 | }, 527 | defaultPage() { 528 | $(".search").button("loading"); 529 | this.pageinfo.page = 0; 530 | this.lastApi = "/page/"; 531 | if (this.nowHistoryTime == 0) { 532 | this.lastReq = JSON.stringify({ 533 | history: 0 534 | }); 535 | $.ajax({ 536 | url: this.apiUrl + "/default", 537 | type: "GET", 538 | dataType: "JSON", 539 | async: true, 540 | success: this.processData, 541 | error: this.serverError, 542 | }); 543 | } else { 544 | $.ajax({ 545 | url: this.apiUrl + "/page/0", 546 | type: "POST", 547 | dataType: "JSON", 548 | contentType: "application/json", 549 | async: true, 550 | data: JSON.stringify({ 551 | history: parseInt(this.nowHistoryTime) 552 | }), 553 | success: this.processData, 554 | error: this.serverError, 555 | }); 556 | } 557 | }, 558 | searchRank() { 559 | $(".search").button("loading"); 560 | this.pageinfo.page = 0; 561 | $.ajax({ 562 | url: this.apiUrl + "/line", 563 | type: "POST", 564 | dataType: "JSON", 565 | async: true, 566 | contentType: "application/json", 567 | data: JSON.stringify({ 568 | history: parseInt(this.nowHistoryTime) 569 | }), 570 | success: (data) => { 571 | this.showData.time = this.convertTime(data.ts); 572 | this.showData.ts = data.ts; 573 | this.processData(data); 574 | }, 575 | error: this.serverError, 576 | }); 577 | }, 578 | 579 | search() { 580 | if (this.selectdata == "") { 581 | this.defaultPage(); 582 | return; 583 | } 584 | if (!this.rank) { 585 | this.rank = -1; 586 | } 587 | this.resetSearch(this.selected); 588 | this.pageinfo.page = 0; 589 | 590 | $.ajax({ 591 | url: this.apiUrl + this.lastApi + (this.rank != -1 ? this.rank : 0), 592 | type: "POST", 593 | dataType: "JSON", 594 | async: true, 595 | contentType: "application/json", 596 | data: this.lastReq, 597 | success: this.processData, 598 | error: this.serverError, 599 | }); 600 | }, 601 | getUrlKey(name, url) { 602 | return decodeURIComponent((new RegExp("[?|&]" + name + "=" + "([^&;]+?)(&|#|;|$)").exec(url) || [, ""])[1].replace(/\+/g, "%20")) || null; 603 | }, 604 | }, 605 | }); --------------------------------------------------------------------------------