mirror of
https://github.com/yoimiya-kokomi/miao-plugin.git
synced 2024-11-21 22:48:13 +00:00
* 增加#喵喵日历
功能
* 【!请注意!】此功能需要安装moment库,请在Yunzai安装目录下运行`npm install moment`后再进行升级 * 展示当前活动内容,包括深渊更新信息
This commit is contained in:
parent
1c7795f97b
commit
0e4905accd
@ -1,9 +1,8 @@
|
||||
# 1.4.2
|
||||
# 1.4.3
|
||||
|
||||
* 增加`#喵喵日历` 功能
|
||||
* 【!!请注意!!】此功能需要安装 moment,不建议使用`#喵喵更新` 自动更新,否则可能重启错误
|
||||
* 请在Yunzai安装目录下运行`npm install moment`后再进行升级!
|
||||
* 功能尚未完全完成,深渊信息及部分样式仍然在调整中
|
||||
* 【!请注意!】此功能需要安装moment库,请在Yunzai安装目录下运行`npm install moment`后再进行升级
|
||||
* 展示当前活动内容,包括深渊更新信息
|
||||
* `#角色面板` 伤害计算新增部分角色
|
||||
* 目前支持:雷神、胡桃、魈、神子、甘雨、宵宫、公子、绫人、绫华、心海、钟离、刻晴、阿贝多、香菱
|
||||
|
||||
|
136
apps/wiki.js
136
apps/wiki.js
@ -3,8 +3,8 @@ import fs from "fs";
|
||||
import { Character } from "../components/models.js";
|
||||
import lodash from "lodash";
|
||||
import { Cfg } from "../components/index.js";
|
||||
import fetch from "node-fetch";
|
||||
import moment from "moment";
|
||||
import Cal from "../components/Calcendar.js";
|
||||
import Calcendar from "../components/Calcendar.js";
|
||||
|
||||
//import {wikiCharacter} from "../modules/wiki.js";
|
||||
|
||||
@ -99,140 +99,12 @@ async function wikiCache(e) {
|
||||
}
|
||||
|
||||
export async function calendar(e, { render }) {
|
||||
let listApi = "https://hk4e-api.mihoyo.com/common/hk4e_cn/announcement/api/getAnnList?game=hk4e&game_biz=hk4e_cn&lang=zh-cn&bundle_id=hk4e_cn&platform=pc®ion=cn_gf01&level=55&uid=100000000";
|
||||
|
||||
let request = await fetch(listApi);
|
||||
let calendarData = await request.json();
|
||||
|
||||
moment.locale("zh-cn");
|
||||
|
||||
let today = moment(), now = moment();
|
||||
let temp = today.add(-7, 'days');
|
||||
let dateList = [], month = 0, date = [];
|
||||
|
||||
let startDate, endDate;
|
||||
|
||||
const ignoreIds = [495,// 有奖问卷调查开启!
|
||||
1263, // 米游社《原神》专属工具一览
|
||||
423, // 《原神》玩家社区一览
|
||||
422, // 《原神》防沉迷系统说明
|
||||
762, // 《原神》公平运营声明
|
||||
762, // 《原神》公平运营声明
|
||||
]
|
||||
const ignoreReg = /(内容专题页|版本更新说明|调研|防沉迷|米游社|专项意见|更新修复与优化)/;
|
||||
|
||||
|
||||
for (let idx = 0; idx < 13; idx++) {
|
||||
let temp = today.add(1, 'days'),
|
||||
m = temp.month() + 1, d = temp.date();
|
||||
if (month === 0) {
|
||||
startDate = temp.format("YYYY-MM-DD");
|
||||
month = m;
|
||||
}
|
||||
if (month !== m && date.length > 0) {
|
||||
dateList.push({
|
||||
month,
|
||||
date
|
||||
})
|
||||
date = [];
|
||||
month = m;
|
||||
}
|
||||
date.push(d);
|
||||
if (idx === 12) {
|
||||
dateList.push({
|
||||
month,
|
||||
date
|
||||
})
|
||||
|
||||
endDate = temp.format("YYYY-MM-DD");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let startTime = moment(startDate + " 00:00:00"),
|
||||
endTime = moment(endDate + " 23:59:59");
|
||||
|
||||
let totalRange = endTime - startTime;
|
||||
|
||||
let list = [];
|
||||
let getList = (ds, isAct = false) => {
|
||||
let type = isAct ? "activity" : "normal",
|
||||
id = ds.ann_id,
|
||||
title = ds.title,
|
||||
banner = isAct ? ds.banner : '',
|
||||
extra = { sort: isAct ? 5 : 10 };
|
||||
|
||||
if (ignoreIds.includes(id) || ignoreReg.test(title)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (/神铸赋形/.test(title)) {
|
||||
type = "weapon";
|
||||
title = title.replace(/(单手剑|双手剑|长柄武器|弓|法器|·)/g, "");
|
||||
extra.sort = 2;
|
||||
} else if (/祈愿/.test(title)) {
|
||||
type = "character";
|
||||
let regRet = /·(.*)\(/.exec(title);
|
||||
if (regRet[1]) {
|
||||
let char = Character.get(regRet[1]);
|
||||
extra.banner2 = `/meta/character/${regRet[1]}/party.png`;
|
||||
extra.character = regRet[1];
|
||||
extra.elem = char.elem;
|
||||
extra.sort = 1;
|
||||
} else if (/纪行/.test(title)) {
|
||||
type = "pass"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let sDate = moment(ds.start_time),
|
||||
eDate = moment(ds.end_time);
|
||||
let sTime = moment.max(sDate, startTime),
|
||||
eTime = moment.min(eDate, endTime);
|
||||
|
||||
let sRange = sTime - startTime,
|
||||
eRange = eTime - startTime;
|
||||
|
||||
let left = sRange / totalRange * 100,
|
||||
width = eRange / totalRange * 100 - left;
|
||||
|
||||
let label = "";
|
||||
if (now > sDate && eDate > now) {
|
||||
label = eDate.format("MM-DD HH:mm") + " (" + moment.duration(eDate - now).humanize() + "后结束)"
|
||||
if (width > (isAct ? 38 : 55)) {
|
||||
label = sDate.format("MM-DD HH:mm") + " ~ " + label;
|
||||
}
|
||||
} else if (sDate > now) {
|
||||
label = sDate.format("MM-DD HH:mm") + " (" + moment.duration(sDate - now).humanize() + "后开始)"
|
||||
}
|
||||
|
||||
list.push({
|
||||
...extra,
|
||||
id,
|
||||
title,
|
||||
type,
|
||||
banner,
|
||||
icon: ds.tag_icon,
|
||||
left,
|
||||
width,
|
||||
label,
|
||||
|
||||
duration: eTime - sTime,
|
||||
start: sDate.format("MM-DD HH:mm"),
|
||||
end: eDate.format("MM-DD HH:mm")
|
||||
})
|
||||
};
|
||||
lodash.forEach(calendarData.data.list[1].list, (ds) => getList(ds, true))
|
||||
lodash.forEach(calendarData.data.list[0].list, (ds) => getList(ds, false));
|
||||
|
||||
list = lodash.sortBy(list, ["sort", 'duration', 'start']);
|
||||
let calData = await Calcendar.get();
|
||||
|
||||
let base64 = await render("wiki", "calendar", {
|
||||
list,
|
||||
dateList,
|
||||
now: (now - startTime) / totalRange * 100,
|
||||
nowTime: now.format("YYYY-MM-DD HH:mm"),
|
||||
...calData,
|
||||
cfgScale: Cfg.scale(1.1)
|
||||
});
|
||||
|
||||
|
209
components/Calcendar.js
Normal file
209
components/Calcendar.js
Normal file
@ -0,0 +1,209 @@
|
||||
import fetch from "node-fetch";
|
||||
import moment from "moment";
|
||||
import { Character } from "./models.js";
|
||||
import lodash from "lodash";
|
||||
|
||||
const ignoreIds = [495,// 有奖问卷调查开启!
|
||||
1263, // 米游社《原神》专属工具一览
|
||||
423, // 《原神》玩家社区一览
|
||||
422, // 《原神》防沉迷系统说明
|
||||
762, // 《原神》公平运营声明
|
||||
762, // 《原神》公平运营声明
|
||||
]
|
||||
|
||||
const ignoreReg = /(内容专题页|版本更新说明|调研|防沉迷|米游社|专项意见|更新修复与优化|问卷调查)/;
|
||||
const fulltimeReg = /(魔神任务)/;
|
||||
|
||||
let Cal = {
|
||||
async reqCalData() {
|
||||
let listApi = "https://hk4e-api.mihoyo.com/common/hk4e_cn/announcement/api/getAnnList?game=hk4e&game_biz=hk4e_cn&lang=zh-cn&bundle_id=hk4e_cn&platform=pc®ion=cn_gf01&level=55&uid=100000000";
|
||||
|
||||
let request = await fetch(listApi);
|
||||
let calendarData = await request.json();
|
||||
|
||||
return calendarData;
|
||||
|
||||
|
||||
},
|
||||
|
||||
getDateList() {
|
||||
let today = moment();
|
||||
let temp = today.add(-7, 'days');
|
||||
let dateList = [], month = 0, date = [];
|
||||
|
||||
let startDate, endDate;
|
||||
|
||||
for (let idx = 0; idx < 13; idx++) {
|
||||
let temp = today.add(1, 'days'),
|
||||
m = temp.month() + 1, d = temp.date();
|
||||
if (month === 0) {
|
||||
startDate = temp.format("YYYY-MM-DD");
|
||||
month = m;
|
||||
}
|
||||
if (month !== m && date.length > 0) {
|
||||
dateList.push({
|
||||
month,
|
||||
date
|
||||
})
|
||||
date = [];
|
||||
month = m;
|
||||
}
|
||||
date.push(d);
|
||||
if (idx === 12) {
|
||||
dateList.push({
|
||||
month,
|
||||
date
|
||||
})
|
||||
endDate = temp.format("YYYY-MM-DD");
|
||||
}
|
||||
}
|
||||
|
||||
let startTime = moment(startDate + " 00:00:00"),
|
||||
endTime = moment(endDate + " 23:59:59");
|
||||
|
||||
let totalRange = endTime - startTime
|
||||
return {
|
||||
dateList,
|
||||
startTime,
|
||||
endTime,
|
||||
totalRange,
|
||||
nowLeft: (moment() - startTime) / totalRange * 100
|
||||
}
|
||||
},
|
||||
|
||||
getAbyssCal(s1, e1) {
|
||||
let now = moment();
|
||||
let check = [], f = "YYYY-MM";
|
||||
let last = now.add(-1, 'M').format(f),
|
||||
lastM = now.format("MMMM"),
|
||||
curr = now.add(1, "M").format(f),
|
||||
currM = now.format("MMMM"),
|
||||
next = now.add(1, "M").format(f),
|
||||
nextM = now.format("MMMM");
|
||||
|
||||
check.push([moment(`${last}-16 04:00`), moment(`${curr}-01 03:59`), lastM + "下半"]);
|
||||
check.push([moment(`${curr}-01 04:00`), moment(`${curr}-16 03:59`), currM + "上半"]);
|
||||
check.push([moment(`${curr}-16 04:00`), moment(`${next}-01 03:59`), currM + "下半"]);
|
||||
check.push([moment(`${next}-01 04:00`), moment(`${next}-16 03:59`), nextM + "上半"]);
|
||||
|
||||
let ret = [];
|
||||
lodash.forEach(check, (ds) => {
|
||||
let [s2, e2] = ds;
|
||||
if ((s2 <= s1 && s1 <= e2) || (s2 <= e1 && e1 <= e2)) {
|
||||
ret.push(ds)
|
||||
}
|
||||
})
|
||||
return ret;
|
||||
},
|
||||
|
||||
getList(ds, target, { startTime, endTime, totalRange, now }, isAct = false,) {
|
||||
let type = isAct ? "activity" : "normal",
|
||||
id = ds.ann_id,
|
||||
title = ds.title,
|
||||
banner = isAct ? ds.banner : '',
|
||||
extra = { sort: isAct ? 5 : 10 };
|
||||
|
||||
if (ignoreIds.includes(id) || ignoreReg.test(title)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (/神铸赋形/.test(title)) {
|
||||
type = "weapon";
|
||||
title = title.replace(/(单手剑|双手剑|长柄武器|弓|法器|·)/g, "");
|
||||
extra.sort = 2;
|
||||
} else if (/祈愿/.test(title)) {
|
||||
type = "character";
|
||||
let regRet = /·(.*)\(/.exec(title);
|
||||
if (regRet[1]) {
|
||||
let char = Character.get(regRet[1]);
|
||||
extra.banner2 = `/meta/character/${regRet[1]}/party.png`;
|
||||
extra.character = regRet[1];
|
||||
extra.elem = char.elem;
|
||||
extra.sort = 1;
|
||||
} else if (/纪行/.test(title)) {
|
||||
type = "pass"
|
||||
} else if ('深渊' === title) {
|
||||
type = "abyss";
|
||||
}
|
||||
}
|
||||
|
||||
let sDate = moment(ds.start_time),
|
||||
eDate = moment(ds.end_time);
|
||||
let sTime = moment.max(sDate, startTime),
|
||||
eTime = moment.min(eDate, endTime);
|
||||
|
||||
let sRange = sTime - startTime,
|
||||
eRange = eTime - startTime;
|
||||
|
||||
let left = sRange / totalRange * 100,
|
||||
width = eRange / totalRange * 100 - left;
|
||||
|
||||
let label = "";
|
||||
if (fulltimeReg.test(title)) {
|
||||
left = 0;
|
||||
width = 100;
|
||||
label = "永久有效";
|
||||
} else if (now > sDate && eDate > now) {
|
||||
label = eDate.format("MM-DD HH:mm") + " (" + moment.duration(eDate - now).humanize() + "后结束)"
|
||||
if (width > (isAct ? 38 : 55)) {
|
||||
label = sDate.format("MM-DD HH:mm") + " ~ " + label;
|
||||
}
|
||||
} else if (sDate > now) {
|
||||
label = sDate.format("MM-DD HH:mm") + " (" + moment.duration(sDate - now).humanize() + "后开始)"
|
||||
}
|
||||
|
||||
target.push({
|
||||
...extra,
|
||||
id,
|
||||
title,
|
||||
type,
|
||||
banner,
|
||||
icon: ds.tag_icon,
|
||||
left,
|
||||
width,
|
||||
label,
|
||||
duration: eTime - sTime,
|
||||
start: sDate.format("MM-DD HH:mm"),
|
||||
end: eDate.format("MM-DD HH:mm")
|
||||
});
|
||||
},
|
||||
|
||||
async get() {
|
||||
|
||||
moment.locale("zh-cn");
|
||||
|
||||
let now = moment();
|
||||
|
||||
let calendarData = await Cal.reqCalData();
|
||||
|
||||
let dl = Cal.getDateList();
|
||||
|
||||
|
||||
let list = [], abyss = [];
|
||||
|
||||
lodash.forEach(calendarData.data.list[1].list, (ds) => Cal.getList(ds, list, { ...dl, now }, true))
|
||||
lodash.forEach(calendarData.data.list[0].list, (ds) => Cal.getList(ds, list, { ...dl, now }, false));
|
||||
|
||||
let abyssCal = Cal.getAbyssCal(dl.startTime, dl.endTime);
|
||||
lodash.forEach(abyssCal, (t) => {
|
||||
Cal.getList({
|
||||
title: `「深境螺旋」· ${t[2]}`,
|
||||
start_time: t[0].format("YYYY-MM-DD HH:mm"),
|
||||
end_time: t[1].format("YYYY-MM-DD HH:mm")
|
||||
}, abyss, { ...dl, now }, true)
|
||||
});
|
||||
|
||||
list = lodash.sortBy(list, ["sort", 'duration', 'start']);
|
||||
|
||||
return {
|
||||
...dl,
|
||||
list,
|
||||
abyss,
|
||||
nowTime: now.format("YYYY-MM-DD HH:mm"),
|
||||
nowDate: now.date(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default Cal;
|
@ -28,7 +28,7 @@ body {
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-size: 24px;
|
||||
font-size: 18px;
|
||||
font-family: "tttgbnumber";
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
@ -68,6 +68,11 @@ body {
|
||||
.cal-bg .tr.thead {
|
||||
background: rgba(0, 0, 0, .8);
|
||||
height: 40px;
|
||||
|
||||
}
|
||||
|
||||
.cal-bg .tr.thead td {
|
||||
font-family: Number, YS;
|
||||
}
|
||||
|
||||
.cal-bg td {
|
||||
@ -75,13 +80,25 @@ body {
|
||||
}
|
||||
|
||||
.cal-bg td.date {
|
||||
width: 7.692%
|
||||
width: 7.692%;
|
||||
|
||||
}
|
||||
|
||||
.cal-bg td.date.current-date {
|
||||
background: #d3bc8e;
|
||||
border: 1px solid #d3bc8e;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
|
||||
.cal-bg td.line {
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.cal-bg td.line.current-date {
|
||||
background: rgba(211, 188, 142, .4)
|
||||
}
|
||||
|
||||
.cal-list {
|
||||
position: relative;
|
||||
padding-top: 80px;
|
||||
@ -107,13 +124,14 @@ body {
|
||||
right: 4px;
|
||||
bottom: 4px;
|
||||
box-shadow: 0 0 1px 0 #000 inset, 0 0 2px 0 #222a3b;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.cal-list .cal-item .info {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding: 15px 50px 15px 55px;
|
||||
min-width: calc(100% - 480px);
|
||||
min-width: calc(100% - 400px);
|
||||
border-radius: 5px;
|
||||
background-image: linear-gradient(to right, rgba(232, 226, 216, 1), rgba(232, 226, 216, 1) 80%, rgba(232, 226, 216, 0) 100%);
|
||||
}
|
||||
@ -132,7 +150,6 @@ body {
|
||||
|
||||
.cal-list .cal-item strong {
|
||||
display: block;
|
||||
margin-left: -5px;
|
||||
font-family: YS;
|
||||
font-weight: normal;
|
||||
}
|
||||
@ -176,7 +193,7 @@ body {
|
||||
}
|
||||
|
||||
.cal-list .cal-item.type-normal:last-child {
|
||||
margin-bottom: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.cal-list .cal-item.type-normal:after {
|
||||
@ -225,26 +242,80 @@ body {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.cal-list .cal-item.type-normal.small-mode span {
|
||||
display: block;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
|
||||
.calendar .now-line {
|
||||
position: absolute;
|
||||
top: 84px;
|
||||
bottom: -18px;
|
||||
width: 1px;
|
||||
width: 2px;
|
||||
box-shadow: 0 0 5px 0 #fff;
|
||||
background: #fff;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
.calendar .now-line:after {
|
||||
content: "";
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-bottom: 20px solid #fff;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: -9px;
|
||||
transform: scaleY(.7);
|
||||
transform-origin: bottom center;
|
||||
}
|
||||
|
||||
.calendar .now-line.line2 {
|
||||
z-index: 3;
|
||||
opacity: .5;
|
||||
background: rgb(211, 188, 141);
|
||||
width: 2px;
|
||||
box-shadow: none;
|
||||
|
||||
}
|
||||
|
||||
.calendar .now-line.line2:after {
|
||||
}
|
||||
|
||||
.now-time {
|
||||
text-align: center;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.now-time span {
|
||||
|
||||
color: #fff;
|
||||
font-family: Number;
|
||||
font-family: Number, YS;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
border-radius: 30px;
|
||||
padding: 10px 15px;
|
||||
border:1px solid #fff;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
.cal-abyss-cont {
|
||||
padding-top: 15px;
|
||||
height: 80px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cal-abyss-cont .cal-item {
|
||||
border-radius: 0;
|
||||
background: url("./imgs/abyss.jpg") #333465 top right no-repeat;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.cal-abyss-cont .cal-item .info {
|
||||
background: none;
|
||||
color: rgba(211, 188, 141, 1);
|
||||
}
|
||||
|
||||
.cal-list .cal-abyss-cont .cal-item:after {
|
||||
box-shadow: 0 0 1px 0 #fff;
|
||||
}
|
@ -18,19 +18,30 @@
|
||||
</tr>
|
||||
<tr class="tr thead">
|
||||
{{each dateList d}}{{each d.date dn}}
|
||||
<td class="td date">{{dn}}日</td>
|
||||
<td class="td date {{dn === nowDate ? 'current-date':''}}">{{dn}}日</td>
|
||||
{{/each}} {{/each}}
|
||||
</tr>
|
||||
<tr class="tr">
|
||||
{{each dateList d}}{{each d.date dn}}
|
||||
<td class="line"></td>
|
||||
<td class="line {{dn === nowDate ? 'current-date':''}}"></td>
|
||||
{{/each}} {{/each}}
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="cal-list">
|
||||
<div class="cal-abyss-cont">
|
||||
{{each abyss li}}
|
||||
<div class="cal-item type-abyss" style="{{`left:${li.left}%;width:${li.width}%`}}">
|
||||
<div class="info">
|
||||
<img src="{{_res_path}}/wiki/imgs/abyss-icon.png" class="cal-icon"/>
|
||||
<strong>{{li.title}}</strong>
|
||||
<span>{{li.label}}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{each list li}}
|
||||
<div class="cal-item type-{{li.type}} {{li.elem?'elem-'+li.elem:''}}"
|
||||
<div class="cal-item type-{{li.type}} {{li.elem?'elem-'+li.elem:''}} {{li.width<20 ? 'small-mode':''}}"
|
||||
style="{{`margin-left:${li.left}%;width:${li.width}%`}}"
|
||||
data-id="{{li.id}}"
|
||||
data-type="{{li.type}}">
|
||||
@ -52,8 +63,8 @@
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
<div class="now-line" style="left:{{now}}%"></div>
|
||||
<div class="now-line" style="left:{{nowLeft}}%"></div>
|
||||
<div class="now-line line2" style="left:{{nowLeft}}%"></div>
|
||||
</div>
|
||||
<div class="now-time">
|
||||
<span>当前时间:{{nowTime}}</span>
|
||||
|
BIN
resources/wiki/imgs/abyss-icon.png
Normal file
BIN
resources/wiki/imgs/abyss-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 49 KiB |
BIN
resources/wiki/imgs/abyss.jpg
Normal file
BIN
resources/wiki/imgs/abyss.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
Loading…
Reference in New Issue
Block a user