@sjtdev/koishi-plugin-dota2tracker 1.2.16-pre.1 → 1.2.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +99 -37
- package/package.json +1 -1
- package/template/images/bei.jpg +0 -0
- package/template/images/xi.jpg +0 -0
- package/template/rank/rank.ejs +35 -0
- package/template/rank/rank2temp.html +109 -0
- package/template/rank/rank_fun.ejs +108 -0
package/lib/index.js
CHANGED
|
@@ -73,9 +73,10 @@ __export(queries_exports, {
|
|
|
73
73
|
MATCHES_FOR_DAILY: () => MATCHES_FOR_DAILY,
|
|
74
74
|
MATCH_INFO: () => MATCH_INFO,
|
|
75
75
|
PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD: () => PLAYERS_INFO_WITH_10_MATCHES_FOR_GUILD,
|
|
76
|
+
PLAYERS_LASTMATCH_RANKINFO: () => PLAYERS_LASTMATCH_RANKINFO,
|
|
76
77
|
PLAYER_EXTRA_INFO: () => PLAYER_EXTRA_INFO,
|
|
77
78
|
PLAYER_INFO_WITH_25_MATCHES: () => PLAYER_INFO_WITH_25_MATCHES,
|
|
78
|
-
|
|
79
|
+
REQUEST_MATCH_DATA_ANALYSIS: () => REQUEST_MATCH_DATA_ANALYSIS,
|
|
79
80
|
VERIFYING_PLAYER: () => VERIFYING_PLAYER
|
|
80
81
|
});
|
|
81
82
|
var dotaconstants = __toESM(require("dotaconstants"));
|
|
@@ -257,29 +258,33 @@ function VERIFYING_PLAYER(steamAccountId) {
|
|
|
257
258
|
`;
|
|
258
259
|
}
|
|
259
260
|
__name(VERIFYING_PLAYER, "VERIFYING_PLAYER");
|
|
260
|
-
function
|
|
261
|
+
function PLAYERS_LASTMATCH_RANKINFO(steamAccountIds) {
|
|
261
262
|
return `
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
steamAccount {
|
|
263
|
+
{
|
|
264
|
+
players(steamAccountIds:${JSON.stringify(steamAccountIds)}) {
|
|
265
|
+
steamAccount{
|
|
266
|
+
id
|
|
267
|
+
name
|
|
268
|
+
avatar
|
|
269
|
+
seasonRank
|
|
270
|
+
seasonLeaderboardRank
|
|
271
|
+
}
|
|
272
|
+
matches(request:{take:1}){
|
|
273
273
|
id
|
|
274
|
+
parsedDateTime
|
|
275
|
+
startDateTime
|
|
276
|
+
players{
|
|
277
|
+
steamAccount{
|
|
278
|
+
id
|
|
279
|
+
}
|
|
280
|
+
}
|
|
274
281
|
}
|
|
275
282
|
}
|
|
276
283
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
`;
|
|
284
|
+
|
|
285
|
+
`;
|
|
281
286
|
}
|
|
282
|
-
__name(
|
|
287
|
+
__name(PLAYERS_LASTMATCH_RANKINFO, "PLAYERS_LASTMATCH_RANKINFO");
|
|
283
288
|
function PLAYER_INFO_WITH_25_MATCHES(steamAccountId, heroId) {
|
|
284
289
|
return `
|
|
285
290
|
{
|
|
@@ -517,6 +522,10 @@ function HERO_MATCHUP_WINRATE(heroId) {
|
|
|
517
522
|
`;
|
|
518
523
|
}
|
|
519
524
|
__name(HERO_MATCHUP_WINRATE, "HERO_MATCHUP_WINRATE");
|
|
525
|
+
function REQUEST_MATCH_DATA_ANALYSIS(matchId) {
|
|
526
|
+
return `stratz{matchRetry(id:${matchId})}`;
|
|
527
|
+
}
|
|
528
|
+
__name(REQUEST_MATCH_DATA_ANALYSIS, "REQUEST_MATCH_DATA_ANALYSIS");
|
|
520
529
|
|
|
521
530
|
// src/utils.ts
|
|
522
531
|
var CONFIGS = { STRATZ_API: { URL: "https://api.stratz.com/graphql", TOKEN: "" } };
|
|
@@ -566,7 +575,7 @@ function getImageUrl(image, type = "local" /* Local */, format = "png" /* png */
|
|
|
566
575
|
if (type === "local" /* Local */) {
|
|
567
576
|
try {
|
|
568
577
|
if (format === "svg" /* svg */) return import_fs.default.readFileSync(`./node_modules/@sjtdev/koishi-plugin-dota2tracker/template/images/${image}.svg`);
|
|
569
|
-
const imageData = import_fs.default.readFileSync(`./node_modules/@sjtdev/koishi-plugin-dota2tracker/template/images/${image}
|
|
578
|
+
const imageData = import_fs.default.readFileSync(`./node_modules/@sjtdev/koishi-plugin-dota2tracker/template/images/${image}.${format}`);
|
|
570
579
|
const base64Data = imageData.toString("base64");
|
|
571
580
|
return `data:image/png;base64,${base64Data}`;
|
|
572
581
|
} catch (error) {
|
|
@@ -1235,6 +1244,20 @@ var Config = import_koishi.Schema.intersect([
|
|
|
1235
1244
|
])
|
|
1236
1245
|
).role("checkbox").description("在消息中附带链接,<br/>请选择消息类型:")
|
|
1237
1246
|
}).description("基础设置"),
|
|
1247
|
+
import_koishi.Schema.intersect([
|
|
1248
|
+
import_koishi.Schema.object({
|
|
1249
|
+
rankBroadSwitch: import_koishi.Schema.boolean().default(false).description("段位变动播报")
|
|
1250
|
+
}),
|
|
1251
|
+
import_koishi.Schema.union([
|
|
1252
|
+
import_koishi.Schema.object({
|
|
1253
|
+
rankBroadSwitch: import_koishi.Schema.const(true).required(),
|
|
1254
|
+
rankBroadStar: import_koishi.Schema.boolean().default(true).description("星级变动播报"),
|
|
1255
|
+
rankBroadLeader: import_koishi.Schema.boolean().default(true).description("名词变动播报"),
|
|
1256
|
+
rankBroadFun: import_koishi.Schema.boolean().default(false).description("整活播报模板")
|
|
1257
|
+
}),
|
|
1258
|
+
import_koishi.Schema.object({})
|
|
1259
|
+
])
|
|
1260
|
+
]),
|
|
1238
1261
|
import_koishi.Schema.intersect([
|
|
1239
1262
|
import_koishi.Schema.object({
|
|
1240
1263
|
dailyReportSwitch: import_koishi.Schema.boolean().default(false).description("日报功能")
|
|
@@ -1444,7 +1467,7 @@ async function apply(ctx, config) {
|
|
|
1444
1467
|
let lastMatchId = 0;
|
|
1445
1468
|
try {
|
|
1446
1469
|
session.send("正在搜索对局详情,请稍后...");
|
|
1447
|
-
lastMatchId = (await query(
|
|
1470
|
+
lastMatchId = (await query(PLAYERS_LASTMATCH_RANKINFO(parseInt(flagBindedPlayer?.steamId ?? input_data)))).data.player.matches[0].id;
|
|
1448
1471
|
} catch {
|
|
1449
1472
|
session.send("获取玩家最近比赛失败。");
|
|
1450
1473
|
return;
|
|
@@ -1669,19 +1692,10 @@ async function apply(ctx, config) {
|
|
|
1669
1692
|
}
|
|
1670
1693
|
__name(findingHero, "findingHero");
|
|
1671
1694
|
ctx.on("ready", async () => {
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
}
|
|
1676
|
-
if (!("dt_subscribed_players" in tables)) {
|
|
1677
|
-
ctx.model.extend("dt_subscribed_players", { id: "unsigned", userId: "string", guildId: "string", platform: "string", steamId: "integer", nickName: "string" }, { autoInc: true });
|
|
1678
|
-
}
|
|
1679
|
-
if (!("dt_sended_match_id" in tables)) {
|
|
1680
|
-
ctx.model.extend("dt_sended_match_id", { matchId: "unsigned", sendTime: "timestamp" }, { primary: "matchId" });
|
|
1681
|
-
}
|
|
1682
|
-
if (!("dt_previous_query_results" in tables)) {
|
|
1683
|
-
ctx.model.extend("dt_previous_query_results", { matchId: "unsigned", data: "json", queryTime: "timestamp" }, { primary: "matchId" });
|
|
1684
|
-
}
|
|
1695
|
+
ctx.model.extend("dt_subscribed_guilds", { id: "unsigned", guildId: "string", platform: "string" }, { autoInc: true });
|
|
1696
|
+
ctx.model.extend("dt_subscribed_players", { id: "unsigned", userId: "string", guildId: "string", platform: "string", steamId: "integer", nickName: "string", rank: "json" }, { autoInc: true });
|
|
1697
|
+
ctx.model.extend("dt_sended_match_id", { matchId: "unsigned", sendTime: "timestamp" }, { primary: "matchId" });
|
|
1698
|
+
ctx.model.extend("dt_previous_query_results", { matchId: "unsigned", data: "json", queryTime: "timestamp" }, { primary: "matchId" });
|
|
1685
1699
|
ctx.cron("0 */6 * * *", () => {
|
|
1686
1700
|
const oneMonthAgo = (0, import_moment.default)().subtract(1, "months").toDate();
|
|
1687
1701
|
ctx.database.remove("dt_sended_match_id", { sendTime: { $lt: oneMonthAgo } });
|
|
@@ -1706,10 +1720,7 @@ async function apply(ctx, config) {
|
|
|
1706
1720
|
const subscribedPlayersSteamIds = subscribedPlayersInGuild.map((player) => player.steamId).filter(function(value, index, self) {
|
|
1707
1721
|
return self.indexOf(value) === index;
|
|
1708
1722
|
});
|
|
1709
|
-
const players =
|
|
1710
|
-
for (let id of subscribedPlayersSteamIds) {
|
|
1711
|
-
players.push((await query(PLAYER_LASTMATCH(id))).data.player);
|
|
1712
|
-
}
|
|
1723
|
+
const players = (await query(PLAYERS_LASTMATCH_RANKINFO(subscribedPlayersSteamIds))).data.players;
|
|
1713
1724
|
const lastMatches = players.map((player) => player.matches[0]).filter((item, index, self) => index === self.findIndex((t) => t.id === item.id)).filter((match) => import_moment.default.unix(match.startDateTime).isAfter((0, import_moment.default)().subtract(1, "days"))).filter((match) => !pendingMatches.some((pendingMatch) => pendingMatch.matchId == match.id));
|
|
1714
1725
|
const sendedMatchesIds = (await ctx.database.get("dt_sended_match_id", { matchId: lastMatches.map((match) => match.id) }, ["matchId"])).map((match) => match.matchId);
|
|
1715
1726
|
lastMatches.filter((match) => !sendedMatchesIds.includes(match.id)).forEach((match) => {
|
|
@@ -1724,10 +1735,61 @@ async function apply(ctx, config) {
|
|
|
1724
1735
|
});
|
|
1725
1736
|
});
|
|
1726
1737
|
pendingMatches.push({ matchId: match.id, guilds: tempGuilds });
|
|
1738
|
+
query(REQUEST_MATCH_DATA_ANALYSIS(match.id));
|
|
1727
1739
|
ctx.logger.info(
|
|
1728
1740
|
tempGuilds.map((guild) => `追踪到来自群组${guild.platform}:${guild.guildId}的用户${guild.players.map((player) => `[${player.nickName ?? ""}(${player.steamId})]`).join("、")}的尚未播报过的最新比赛 ${match.id}。`).join("")
|
|
1729
1741
|
);
|
|
1730
1742
|
});
|
|
1743
|
+
const rankMap = players.reduce((map, player) => {
|
|
1744
|
+
map[player.steamAccount.id] = { rank: player.steamAccount.seasonRank, leader: player.steamAccount.seasonLeaderboardRank };
|
|
1745
|
+
return map;
|
|
1746
|
+
}, {});
|
|
1747
|
+
for (let subPlayer of subscribedPlayersInGuild) {
|
|
1748
|
+
if (subPlayer.rank.rank !== rankMap[subPlayer.steamId].rank || subPlayer.rank.leader !== rankMap[subPlayer.steamId].board) {
|
|
1749
|
+
if (Object.keys(subPlayer.rank).length != 0) {
|
|
1750
|
+
if (config.rankBroadSwitch) {
|
|
1751
|
+
const ranks = ["prevRank", "currRank"].reduce((acc, key) => {
|
|
1752
|
+
const source = key === "prevRank" ? subPlayer.rank : rankMap[subPlayer.steamId];
|
|
1753
|
+
acc[key] = {
|
|
1754
|
+
medal: parseInt(source.rank?.toString().split("")[0] ?? "0"),
|
|
1755
|
+
star: parseInt(source.rank?.toString().split("")[1] ?? "0"),
|
|
1756
|
+
leader: source.leader,
|
|
1757
|
+
inTop100: source.leader ? source.leader <= 10 ? "8c" : source.leader <= 100 ? "8b" : void 0 : void 0
|
|
1758
|
+
};
|
|
1759
|
+
return acc;
|
|
1760
|
+
}, {});
|
|
1761
|
+
const prevRank = ranks["prevRank"];
|
|
1762
|
+
const currRank = ranks["currRank"];
|
|
1763
|
+
if (prevRank.medal !== currRank.medal || prevRank.star !== currRank.star && config.rankBroadStar || prevRank.leader !== currRank.leader && config.rankBroadLeader) {
|
|
1764
|
+
const guildMember = await ctx.bots.find((bot) => bot.platform == subPlayer.platform)?.getGuildMember?.(subPlayer.guildId, subPlayer.userId);
|
|
1765
|
+
const name2 = subPlayer.nickName ?? guildMember?.nick ?? players.find((player) => player.steamAccount.id == subPlayer.steamId)?.steamAccount.name ?? subPlayer.steamId;
|
|
1766
|
+
const message = `群友 ${name2} 段位变动:${rank[prevRank.medal]}${prevRank.star} → ${rank[currRank.medal]}${currRank.star} `;
|
|
1767
|
+
if (config.rankBroadFun === true) {
|
|
1768
|
+
const img = await ctx.puppeteer.render(
|
|
1769
|
+
genImageHTML(
|
|
1770
|
+
{
|
|
1771
|
+
name: name2,
|
|
1772
|
+
avatar: guildMember?.avatar ?? players.find((player) => subPlayer.steamId == player.steamAccount.id).steamAccount.avatar,
|
|
1773
|
+
isRising: rankMap[subPlayer.steamId].rank > subPlayer.rank.rank || rankMap[subPlayer.steamId].rank == subPlayer.rank.rank && rankMap[subPlayer.steamId].leader < subPlayer.rank.leader || rankMap[subPlayer.steamId].leader > 0 && subPlayer.rank.leader == null,
|
|
1774
|
+
prevRank,
|
|
1775
|
+
currRank
|
|
1776
|
+
},
|
|
1777
|
+
"rank" + (config.rankBroadFun ? "_fun" : ""),
|
|
1778
|
+
"rank" /* Rank */
|
|
1779
|
+
)
|
|
1780
|
+
);
|
|
1781
|
+
await ctx.broadcast([`${subPlayer.platform}:${subPlayer.guildId}`], img);
|
|
1782
|
+
} else {
|
|
1783
|
+
const img = await ctx.puppeteer.render(genImageHTML(currRank, "rank" + (config.rankBroadFun ? "2" : ""), "rank" /* Rank */));
|
|
1784
|
+
await ctx.broadcast([`${subPlayer.platform}:${subPlayer.guildId}`], message + img);
|
|
1785
|
+
}
|
|
1786
|
+
ctx.logger.info(`向${subPlayer.platform}:${subPlayer.guildId}发布段位变动播报信息。`);
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
ctx.database.set("dt_subscribed_players", subPlayer.id, { rank: rankMap[subPlayer.steamId] });
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1731
1793
|
}
|
|
1732
1794
|
if (pendingMatches.length > 0) {
|
|
1733
1795
|
const now = (0, import_moment.default)();
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<% const rank = data; %>
|
|
2
|
+
<head>
|
|
3
|
+
<style>
|
|
4
|
+
html,
|
|
5
|
+
body {
|
|
6
|
+
width: 128px;
|
|
7
|
+
height: 128px;
|
|
8
|
+
margin: 0;
|
|
9
|
+
padding: 0;
|
|
10
|
+
background-color: #0000;
|
|
11
|
+
}
|
|
12
|
+
div {
|
|
13
|
+
width: 128px;
|
|
14
|
+
height: 128px;
|
|
15
|
+
position: relative;
|
|
16
|
+
}
|
|
17
|
+
div > * {
|
|
18
|
+
position: absolute;
|
|
19
|
+
width: 100%;
|
|
20
|
+
}
|
|
21
|
+
p {
|
|
22
|
+
margin: 0;
|
|
23
|
+
text-align: center;
|
|
24
|
+
color: #fff;
|
|
25
|
+
bottom: 8px;
|
|
26
|
+
font-size: 20px;
|
|
27
|
+
text-shadow: -2px -2px 0 rgba(0, 0, 0, 0.5), 2px -2px 0 rgba(0, 0, 0, 0.5), -2px 2px 0 rgba(0, 0, 0, 0.5), 2px 2px 0 rgba(0, 0, 0, 0.5); /* 描边效果 */
|
|
28
|
+
}
|
|
29
|
+
</style>
|
|
30
|
+
</head>
|
|
31
|
+
<div>
|
|
32
|
+
<img src="<%= utils.getImageUrl('medal_' + (rank.inTop100 ?? rank.medal)) %>" />
|
|
33
|
+
<img src="<%= utils.getImageUrl("star_" + rank.star) %>" />
|
|
34
|
+
<p><%= rank.leader %></p>
|
|
35
|
+
</div>
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Document</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
}
|
|
12
|
+
html {
|
|
13
|
+
width: 1024px;
|
|
14
|
+
height: 768px;
|
|
15
|
+
}
|
|
16
|
+
body.xi {
|
|
17
|
+
background: url(../images/xi.jpg) no-repeat center center / cover;
|
|
18
|
+
}
|
|
19
|
+
body.bei {
|
|
20
|
+
background: url(../images/bei.jpg) no-repeat center center / cover;
|
|
21
|
+
}
|
|
22
|
+
.wrapper {
|
|
23
|
+
padding: 80px;
|
|
24
|
+
padding-top: 180px;
|
|
25
|
+
}
|
|
26
|
+
.wrapper > p {
|
|
27
|
+
font-size: 32px;
|
|
28
|
+
line-height: 48px;
|
|
29
|
+
height: 48px;
|
|
30
|
+
text-align: center;
|
|
31
|
+
}
|
|
32
|
+
body.xi p.bei,
|
|
33
|
+
body.bei p.xi {
|
|
34
|
+
display: none;
|
|
35
|
+
}
|
|
36
|
+
.wrapper > p > span {
|
|
37
|
+
margin: 0 10px;
|
|
38
|
+
}
|
|
39
|
+
.wrapper > p > span.prev {
|
|
40
|
+
color: gray;
|
|
41
|
+
}
|
|
42
|
+
.wrapper > p > span.curr {
|
|
43
|
+
font-weight: bold;
|
|
44
|
+
color: red;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.wrapper > p > img {
|
|
48
|
+
width: 48px;
|
|
49
|
+
height: 48px;
|
|
50
|
+
vertical-align: middle;
|
|
51
|
+
line-height: 48px;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.ranks {
|
|
55
|
+
margin-top: 40px;
|
|
56
|
+
display: flex;
|
|
57
|
+
width: 100%;
|
|
58
|
+
height: 256px;
|
|
59
|
+
justify-content: space-evenly;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
div.rank {
|
|
63
|
+
position: relative;
|
|
64
|
+
width: 256px;
|
|
65
|
+
height: 256px;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
div.rank > img {
|
|
69
|
+
position: absolute;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
div.rank.prev {
|
|
73
|
+
filter: grayscale(1);
|
|
74
|
+
}
|
|
75
|
+
div.rank.curr {
|
|
76
|
+
transform: scale(1.25);
|
|
77
|
+
}
|
|
78
|
+
div.rank p {
|
|
79
|
+
font-size: 36px;
|
|
80
|
+
bottom: 20px;
|
|
81
|
+
width: 100%;
|
|
82
|
+
text-align: center;
|
|
83
|
+
color: #fff;
|
|
84
|
+
position: absolute;
|
|
85
|
+
}
|
|
86
|
+
</style>
|
|
87
|
+
</head>
|
|
88
|
+
<body class="bei">
|
|
89
|
+
<div class="wrapper">
|
|
90
|
+
<p class="xi">热烈祝贺群友 <img src="" alt="" />12414124141 在天梯中再获进步,</p>
|
|
91
|
+
<p class="xi">由<span class="rank prev">先锋2</span>升为<span class="rank curr">先锋2</span>,再接再厉,再创辉煌!</p>
|
|
92
|
+
<p class="bei"><img src="" alt="" /></p>
|
|
93
|
+
<p class="bei">寄</p>
|
|
94
|
+
<div class="ranks">
|
|
95
|
+
<div class="rank prev">
|
|
96
|
+
<img src="../images/medal_8.png" alt="" />
|
|
97
|
+
<img src="../images/star_2.png" alt="" />
|
|
98
|
+
<p>1111</p>
|
|
99
|
+
</div>
|
|
100
|
+
<div class="rank curr">
|
|
101
|
+
<img src="../images/medal_8.png" alt="" />
|
|
102
|
+
<img src="../images/star_1.png" alt="" />
|
|
103
|
+
<p>1111</p>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
<p style="text-align: right; margin-top: 40px;">—— 2024/11/11 00点00分</p>
|
|
107
|
+
</div>
|
|
108
|
+
</body>
|
|
109
|
+
</html>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Document</title>
|
|
7
|
+
<style>
|
|
8
|
+
* {
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 0;
|
|
11
|
+
}
|
|
12
|
+
html {
|
|
13
|
+
width: 1024px;
|
|
14
|
+
height: 768px;
|
|
15
|
+
}
|
|
16
|
+
<%= ["xi","bei"].map(kind=>`body.${kind} {background: url(${utils.getImageUrl(kind, undefined, "jpg")}) no-repeat center center / cover;}`).join("\n") %>
|
|
17
|
+
.wrapper {
|
|
18
|
+
padding: 80px;
|
|
19
|
+
padding-top: 180px;
|
|
20
|
+
}
|
|
21
|
+
.wrapper > p {
|
|
22
|
+
font-size: 32px;
|
|
23
|
+
line-height: 48px;
|
|
24
|
+
height: 48px;
|
|
25
|
+
text-align: center;
|
|
26
|
+
}
|
|
27
|
+
body.xi p.bei,
|
|
28
|
+
body.bei p.xi {
|
|
29
|
+
display: none;
|
|
30
|
+
}
|
|
31
|
+
.wrapper > p > span {
|
|
32
|
+
margin: 0 10px;
|
|
33
|
+
}
|
|
34
|
+
.wrapper > p > span.prev {
|
|
35
|
+
color: gray;
|
|
36
|
+
}
|
|
37
|
+
.wrapper > p > span.curr {
|
|
38
|
+
font-weight: bold;
|
|
39
|
+
color: red;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.wrapper > p > img {
|
|
43
|
+
width: 48px;
|
|
44
|
+
height: 48px;
|
|
45
|
+
vertical-align: middle;
|
|
46
|
+
line-height: 48px;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.ranks {
|
|
50
|
+
margin-top: 40px;
|
|
51
|
+
display: flex;
|
|
52
|
+
width: 100%;
|
|
53
|
+
height: 256px;
|
|
54
|
+
justify-content: space-evenly;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
div.rank {
|
|
58
|
+
position: relative;
|
|
59
|
+
width: 256px;
|
|
60
|
+
height: 256px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
div.rank > img {
|
|
64
|
+
position: absolute;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
div.rank.prev {
|
|
68
|
+
filter: grayscale(1);
|
|
69
|
+
}
|
|
70
|
+
div.rank.curr {
|
|
71
|
+
transform: scale(1.25);
|
|
72
|
+
}
|
|
73
|
+
div.rank p {
|
|
74
|
+
font-size: 36px;
|
|
75
|
+
bottom: 20px;
|
|
76
|
+
width: 100%;
|
|
77
|
+
text-align: center;
|
|
78
|
+
color: #fff;
|
|
79
|
+
position: absolute;
|
|
80
|
+
}
|
|
81
|
+
</style>
|
|
82
|
+
</head>
|
|
83
|
+
<% const {name, avatar, isRising, prevRank, currRank} = data; %>
|
|
84
|
+
<body class="<%= isRising ? "xi" : "bei" %>">
|
|
85
|
+
<div class="wrapper">
|
|
86
|
+
<p class="xi">热烈祝贺群友 <img src="<%= avatar %>" /><%= name %> 在天梯中再获进步,</p>
|
|
87
|
+
<p class="xi">由
|
|
88
|
+
<span class="rank prev"><%= d2a.rank[prevRank.medal] %><%= prevRank.leader ?? prevRank.star %></span>升为
|
|
89
|
+
<span class="rank curr"><%= d2a.rank[currRank.medal] %><%= currRank.leader ?? currRank.star %></span>,再接再厉,再创辉煌!
|
|
90
|
+
</p>
|
|
91
|
+
<p class="bei"><img src="<%= avatar %>" /></p>
|
|
92
|
+
<p class="bei">寄</p>
|
|
93
|
+
<div class="ranks">
|
|
94
|
+
<div class="rank prev">
|
|
95
|
+
<img src="<%= utils.getImageUrl('medal_' +(prevRank.inTop100 ?? prevRank.medal)) %>" alt="" />
|
|
96
|
+
<img src="<%= utils.getImageUrl('star_' + prevRank.star) %>" alt="" />
|
|
97
|
+
<p><%= prevRank.leader ?? "" %></p>
|
|
98
|
+
</div>
|
|
99
|
+
<div class="rank curr">
|
|
100
|
+
<img src="<%= utils.getImageUrl('medal_' +(currRank.inTop100 ?? currRank.medal)) %>" alt="" />
|
|
101
|
+
<img src="<%= utils.getImageUrl('star_' + currRank.star) %>" alt="" />
|
|
102
|
+
<p><%= currRank.leader ?? "" %></p>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
<p style="text-align: right; margin-top: 40px;">—— <%= moment().format('YYYY/MM/DD HH点mm分') %></p>
|
|
106
|
+
</div>
|
|
107
|
+
</body>
|
|
108
|
+
</html>
|