mirror of
https://github.com/ZZZure/ZZZ-Plugin.git
synced 2025-12-16 13:17:32 +00:00
feat: 版本机制; fix: fix: 绑定设备提示
This commit is contained in:
parent
d34c1d8be1
commit
8425503797
16 changed files with 820 additions and 59 deletions
14
CHANGELOG.md
14
CHANGELOG.md
|
|
@ -1,40 +1,54 @@
|
|||
# 1.4.2
|
||||
* 版本机制
|
||||
|
||||
# 1.4.1
|
||||
|
||||
* 绑定设备
|
||||
* 优化部分代码
|
||||
|
||||
# 1.4
|
||||
|
||||
* 添加 `练度统计` 功能,发送 `%练度统计` 或 `%练度` 查看
|
||||
|
||||
# 1.3
|
||||
|
||||
* 添加驱动盘评分
|
||||
|
||||
# 1.2
|
||||
|
||||
* 添加伤害计算,支持目前为止所有 `驱动盘` 以及 `艾莲` 、 `朱鸢` 的伤害计算,`强攻武器` 支持 `B` 级以上。
|
||||
* 修复攻略问题,若有对不上的问题,请“刷新攻略”。
|
||||
|
||||
# 1.1
|
||||
|
||||
* 支持自定义面板图,详情请查看 `README`。
|
||||
|
||||
# 1.0
|
||||
|
||||
* 重构帮助指令,发送 `%帮助`
|
||||
|
||||
# 0.3
|
||||
|
||||
* 修复攻略图角色“本”图片错误
|
||||
* 将 `mysid` 比较转为字符串,解决部分适配问题
|
||||
|
||||
# 0.2
|
||||
|
||||
* 添加“式舆防卫战”查询,发送 `%式舆防卫战` 或者 `%深渊`
|
||||
|
||||
# 0.1
|
||||
|
||||
* 刷新角色面板图片版
|
||||
* 优化指令分配
|
||||
* 添加版本信息
|
||||
|
||||
# 0.05
|
||||
|
||||
* 支持查看角色面板,发送 `%角色名/别名+面板`
|
||||
* 修复一些问题
|
||||
|
||||
# 0.04
|
||||
|
||||
* 支持获取抽卡链接,发送 `%获取抽卡链接`
|
||||
* 支持面板刷新,发送 `%刷新面板`
|
||||
|
||||
|
|
|
|||
21
apps/help.js
21
apps/help.js
|
|
@ -189,6 +189,27 @@ const helpData = [
|
|||
needSK: false,
|
||||
commands: ['解绑设备'],
|
||||
},
|
||||
{
|
||||
title: '更新日志',
|
||||
desc: '查看插件的Commit日志',
|
||||
needCK: false,
|
||||
needSK: false,
|
||||
commands: ['[插件]更新日志'],
|
||||
},
|
||||
{
|
||||
title: '版本',
|
||||
desc: '查看插件版本日志',
|
||||
needCK: false,
|
||||
needSK: false,
|
||||
commands: ['[插件]版本'],
|
||||
},
|
||||
{
|
||||
title: '检查更新',
|
||||
desc: '检查插件是否更新',
|
||||
needCK: false,
|
||||
needSK: false,
|
||||
commands: ['[插件]检查更新'],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -60,6 +60,18 @@ export class Panel extends ZZZPlugin {
|
|||
reg: `${rulePrefix}删除(\\S+)(角色|面板)图(.+)$`,
|
||||
fnc: 'deleteCharacterImg',
|
||||
},
|
||||
{
|
||||
reg: `${rulePrefix}(插件)?版本$`,
|
||||
fnc: 'getChangeLog',
|
||||
},
|
||||
{
|
||||
reg: `^${rulePrefix}(插件)?更新日志$`,
|
||||
fnc: 'getCommitLog',
|
||||
},
|
||||
{
|
||||
reg: `^${rulePrefix}(插件)?检查更新$`,
|
||||
fnc: 'hasUpdate',
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
|
|
@ -75,5 +87,8 @@ export class Panel extends ZZZPlugin {
|
|||
this.uploadCharacterImg = manage.panel.uploadCharacterImg;
|
||||
this.getCharacterImages = manage.panel.getCharacterImages;
|
||||
this.deleteCharacterImg = manage.panel.deleteCharacterImg;
|
||||
this.getChangeLog = manage.version.getChangeLog;
|
||||
this.getCommitLog = manage.version.getCommitLog;
|
||||
this.hasUpdate = manage.version.hasUpdate;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,10 +8,13 @@ import * as alias from './alias.js';
|
|||
|
||||
import * as panel from './panel.js';
|
||||
|
||||
import * as version from './version.js';
|
||||
|
||||
export default {
|
||||
assets,
|
||||
guides,
|
||||
config,
|
||||
alias,
|
||||
panel,
|
||||
version,
|
||||
};
|
||||
|
|
|
|||
49
apps/manage/version.js
Normal file
49
apps/manage/version.js
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
import version from '../../lib/version.js';
|
||||
import render from '../../lib/render.js';
|
||||
import { ZZZUpdate } from '../../lib/update.js';
|
||||
import { pluginName } from '../../lib/path.js';
|
||||
|
||||
export async function getChangeLog() {
|
||||
const versionData = version.changelogs;
|
||||
await render(this.e, 'help/version.html', {
|
||||
versionData,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function getCommitLog() {
|
||||
if (!ZZZUpdate) return false;
|
||||
let updatePlugin = new ZZZUpdate();
|
||||
updatePlugin.e = this.e;
|
||||
updatePlugin.reply = this.reply;
|
||||
if (updatePlugin.getPlugin(pluginName)) {
|
||||
try {
|
||||
const commitData = await updatePlugin.getZZZAllLog();
|
||||
await render(this.e, 'help/commit.html', {
|
||||
commitData,
|
||||
});
|
||||
} catch (error) {
|
||||
this.reply(`[${pluginName}]获取更新日志失败\n${error.message}`);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function hasUpdate() {
|
||||
if (!ZZZUpdate) return false;
|
||||
let updatePlugin = new ZZZUpdate();
|
||||
updatePlugin.e = this.e;
|
||||
updatePlugin.reply = this.reply;
|
||||
if (updatePlugin.getPlugin(pluginName)) {
|
||||
const result = await updatePlugin.hasUpdate();
|
||||
if (result.hasUpdate) {
|
||||
await this.reply(`[${pluginName}]有${result.logs.length || 1}个更新`);
|
||||
await render(this.e, 'help/commit.html', {
|
||||
commitData: result.logs,
|
||||
});
|
||||
} else {
|
||||
await this.reply(`[${pluginName}]已是最新`);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,15 +1,8 @@
|
|||
import _ from 'lodash'
|
||||
import { rulePrefix } from '../lib/common.js'
|
||||
import { pluginName } from '../lib/path.js'
|
||||
import settings from '../lib/settings.js'
|
||||
|
||||
let Update = null
|
||||
try {
|
||||
Update = (await import("../../other/update.js").catch(e => null))?.update
|
||||
Update ||= (await import("../../system/apps/update.ts")).update
|
||||
} catch (e) {
|
||||
logger.error(`[${pluginName}]未获取到更新js ${logger.yellow("更新功能")} 将无法使用`)
|
||||
}
|
||||
import _ from 'lodash';
|
||||
import { rulePrefix } from '../lib/common.js';
|
||||
import { pluginName } from '../lib/path.js';
|
||||
import settings from '../lib/settings.js';
|
||||
import { ZZZUpdate } from '../lib/update.js';
|
||||
|
||||
export class update extends plugin {
|
||||
constructor() {
|
||||
|
|
@ -23,30 +16,15 @@ export class update extends plugin {
|
|||
reg: `^${rulePrefix}(插件)?(强制)?更新(插件)?$`,
|
||||
fnc: 'update',
|
||||
},
|
||||
{
|
||||
reg: `^${rulePrefix}(插件)?更新日志$`,
|
||||
fnc: 'update_log',
|
||||
}
|
||||
],
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
async update(e = this.e) {
|
||||
if (!e.isMaster) return
|
||||
e.msg = `#${e.msg.includes("强制") ? "强制" : ""}更新${pluginName}`
|
||||
const up = new Update(e)
|
||||
up.e = e
|
||||
return up.update()
|
||||
}
|
||||
|
||||
async update_log() {
|
||||
let Update_Plugin = new Update()
|
||||
Update_Plugin.e = this.e
|
||||
Update_Plugin.reply = this.reply
|
||||
|
||||
if (Update_Plugin.getPlugin(pluginName)) {
|
||||
this.e.reply(await Update_Plugin.getLog(pluginName))
|
||||
}
|
||||
return true
|
||||
if (!e.isMaster || !ZZZUpdate) return false;
|
||||
e.msg = `#${e.msg.includes('强制') ? '强制' : ''}更新${pluginName}`;
|
||||
const up = new ZZZUpdate(e);
|
||||
up.e = e;
|
||||
return up.update();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ export class Panel extends ZZZPlugin {
|
|||
'1. 使用抓包软件抓取米游社APP的请求',
|
||||
'2. 在请求头内找到【x-rpc-device_id】和【x-rpc-device_fp】',
|
||||
'3. 自行构造如下格式的信息:',
|
||||
' {device_id: "x-rpc-device_id的内容", device_fp: "x-rpc-device_fp的内容"}',
|
||||
' {"device_id": "x-rpc-device_id的内容", "device_fp": "x-rpc-device_fp的内容"}',
|
||||
'4. 给机器人发送"%绑定设备"指令',
|
||||
'5. 机器人会提示发送设备信息',
|
||||
'6. 粘贴自行构造的信息发送',
|
||||
|
|
|
|||
105
lib/update.js
Normal file
105
lib/update.js
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
import _ from 'lodash';
|
||||
import { pluginName } from '../lib/path.js';
|
||||
import { mdLogLineToHTML } from '../utils/data.js';
|
||||
|
||||
let Update = null;
|
||||
try {
|
||||
Update = (await import('../../other/update.js').catch(e => null))?.update;
|
||||
Update ||= (await import('../../system/apps/update.ts')).update;
|
||||
} catch (e) {
|
||||
logger.error(
|
||||
`[${pluginName}]未获取到更新js ${logger.yellow('更新功能')} 将无法使用`
|
||||
);
|
||||
}
|
||||
let ZZZUpdate = null;
|
||||
/**
|
||||
* @typedef {Object} CommitLog
|
||||
* @property {string} commit 提交ID
|
||||
* @property {string} date 提交时间
|
||||
* @property {string} msg 提交信息
|
||||
* @property {boolean} local 是否本地记录
|
||||
* @property {current} boolean 是否当前版本
|
||||
*/
|
||||
/**
|
||||
* @typedef {Object} UpdateInfo
|
||||
* @property {boolean} hasUpdate 是否有更新
|
||||
* @property {CommitLog[]} logs 更新日志
|
||||
*/
|
||||
if (Update) {
|
||||
ZZZUpdate = class ZZZUpdate extends Update {
|
||||
async handleLog(remote = false) {
|
||||
let cmdStr = 'git log -100 --pretty="%h||%cd||%s" --date=format:"%F %T"';
|
||||
if (remote) {
|
||||
cmdStr =
|
||||
'git log -100 --pretty="%h||%cd||%s" --date=format:"%F %T" origin/main';
|
||||
}
|
||||
const cm = await this.exec(cmdStr, pluginName);
|
||||
if (cm.error) {
|
||||
throw new Error(cm.error.message);
|
||||
}
|
||||
|
||||
const logAll = cm.stdout.split('\n');
|
||||
if (!logAll.length) {
|
||||
throw new Error('未获取到更新日志');
|
||||
}
|
||||
/** @type CommitLog[] */
|
||||
const log = [];
|
||||
let current = true;
|
||||
for (let str of logAll) {
|
||||
str = str.split('||');
|
||||
if (str[0] === this.oldCommitId) break;
|
||||
if (str[2].includes('Merge')) continue;
|
||||
/** @type CommitLog */
|
||||
const commit = {
|
||||
commit: str[0],
|
||||
date: str[1],
|
||||
msg: mdLogLineToHTML(str[2]),
|
||||
local: !remote,
|
||||
current: false,
|
||||
};
|
||||
if (!remote && current) {
|
||||
commit.current = true;
|
||||
current = false;
|
||||
}
|
||||
log.push(commit);
|
||||
}
|
||||
return log;
|
||||
}
|
||||
async getZZZLog() {
|
||||
const log = await this.handleLog();
|
||||
return log;
|
||||
}
|
||||
|
||||
async getZZZRemoteLog() {
|
||||
const log = await this.handleLog(true);
|
||||
return log;
|
||||
}
|
||||
|
||||
async getZZZAllLog() {
|
||||
const localLog = await this.getZZZLog();
|
||||
const remoteLog = await this.getZZZRemoteLog();
|
||||
const logs = _.unionBy(localLog, remoteLog, 'commit');
|
||||
logs.sort((a, b) => {
|
||||
return new Date(b.date) - new Date(a.date);
|
||||
});
|
||||
return logs;
|
||||
}
|
||||
|
||||
async hasUpdate() {
|
||||
const logs = await this.getZZZAllLog();
|
||||
const newLogs = logs.filter(log => !log.local);
|
||||
/** @type UpdateInfo */
|
||||
let result = {
|
||||
hasUpdate: false,
|
||||
logs: [],
|
||||
};
|
||||
if (newLogs.length) {
|
||||
result.hasUpdate = true;
|
||||
result.logs = newLogs;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export { ZZZUpdate };
|
||||
|
|
@ -2,6 +2,7 @@ import fs from 'fs';
|
|||
import lodash from 'lodash';
|
||||
import path from 'path';
|
||||
import { pluginPath } from './path.js';
|
||||
import { mdLogLineToHTML } from '../utils/data.js';
|
||||
|
||||
// 更新日志文件位置
|
||||
const _logPath = path.join(pluginPath, 'CHANGELOG.md');
|
||||
|
|
@ -21,26 +22,6 @@ let versionCount = 4;
|
|||
// 读取 package.json(此处为读取Yunzai-Bot的package.json)
|
||||
let packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
||||
|
||||
/**
|
||||
* 将 Markdown 行转换为 HTML
|
||||
* @param {*} line
|
||||
* @returns
|
||||
*/
|
||||
const getLine = function (line) {
|
||||
// 去除行首空格和换行符
|
||||
line = line.replace(/(^\s*\*|\r)/g, '');
|
||||
// 替换行内代码块
|
||||
line = line.replace(/\s*`([^`]+`)/g, '<span class="cmd">$1');
|
||||
line = line.replace(/`\s*/g, '</span>');
|
||||
// 替换行内加粗
|
||||
line = line.replace(/\s*\*\*([^\*]+\*\*)/g, '<span class="strong">$1');
|
||||
line = line.replace(/\*\*\s*/g, '</span>');
|
||||
// 替换行内表示更新内容
|
||||
line = line.replace(/ⁿᵉʷ/g, '<span class="new"></span>');
|
||||
// 返回转换后的行内容(HTML)
|
||||
return line;
|
||||
};
|
||||
|
||||
// 尝试读取更新日志文件
|
||||
try {
|
||||
if (fs.existsSync(_logPath)) {
|
||||
|
|
@ -54,9 +35,9 @@ try {
|
|||
let lastLine = {};
|
||||
lodash.forEach(logs, line => {
|
||||
// 如果版本数量小于0,返回false
|
||||
if (versionCount <= -1) {
|
||||
return false;
|
||||
}
|
||||
// if (versionCount <= -1) {
|
||||
// return false;
|
||||
// }
|
||||
// 匹配版本号
|
||||
const versionRet = /^#\s*([0-9a-zA-Z\\.~\s]+?)\s*$/.exec(line);
|
||||
if (versionRet && versionRet[1]) {
|
||||
|
|
@ -86,12 +67,12 @@ try {
|
|||
// 如果行以 * 开头,表示更新内容
|
||||
if (/^\*/.test(line)) {
|
||||
lastLine = {
|
||||
title: getLine(line),
|
||||
title: mdLogLineToHTML(line),
|
||||
logs: [],
|
||||
};
|
||||
temp.logs.push(lastLine);
|
||||
} else if (/^\s{2,}\*/.test(line)) {
|
||||
lastLine.logs.push(getLine(line));
|
||||
lastLine.logs.push(mdLogLineToHTML(line));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
141
resources/help/commit.css
Normal file
141
resources/help/commit.css
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
@charset "UTF-8";
|
||||
.special-title {
|
||||
padding: 0;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin: 0 1em;
|
||||
padding: 1em 0;
|
||||
}
|
||||
.card .list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
.card .list .item {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 0.5em;
|
||||
border: 0.1em solid rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(0.5em);
|
||||
position: relative;
|
||||
}
|
||||
.card .list .item .version {
|
||||
filter: drop-shadow(0 0 0.05em #f0d480);
|
||||
position: relative;
|
||||
margin-bottom: 0.5em;
|
||||
font-size: 0.8em;
|
||||
display: flex;
|
||||
}
|
||||
.card .list .item .version .id {
|
||||
background: linear-gradient(90deg, #ffe6b4, #f2c94c);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
position: relative;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
.card .list .item .version .id::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 0.2em;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: linear-gradient(0deg, #f2c94c, #ffe6b4);
|
||||
z-index: -1;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
.card .list .item .version .time {
|
||||
background: linear-gradient(90deg, #ffe6b4, #f2c94c);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
.card .list .item.current {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
backdrop-filter: blur(1.5em);
|
||||
}
|
||||
.card .list .item.current::after {
|
||||
content: "当前版本";
|
||||
font-size: 0.8em;
|
||||
position: absolute;
|
||||
right: 0.5em;
|
||||
top: 0.5em;
|
||||
color: #f2c94c;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.card .list .item.current .version {
|
||||
filter: drop-shadow(0 0 0.1em rgba(231, 241, 35, 0.3));
|
||||
font-size: 1em;
|
||||
}
|
||||
.card .list .item.current .version .id {
|
||||
color: #f2784c;
|
||||
background: none;
|
||||
background-clip: unset;
|
||||
-webkit-text-fill-color: unset;
|
||||
font-size: 0.8em;
|
||||
padding-top: 0.3em;
|
||||
}
|
||||
.card .list .item.current .version .id::before {
|
||||
background: #f2784c;
|
||||
}
|
||||
.card .list .item.current .version .time {
|
||||
background: linear-gradient(90deg, #f2784c, #ffbca4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
.card .list .item.newc::after {
|
||||
content: "NEW";
|
||||
font-size: 0.4em;
|
||||
background: linear-gradient(90deg, #f2c94c, #ffe6b4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 0.05em #f0d480);
|
||||
top: 1em;
|
||||
right: 1em;
|
||||
position: absolute;
|
||||
border: 0.1em solid #f2c94c;
|
||||
padding: 0.1em 0.3em 0.2em 0.3em;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
.card .list .item .content {
|
||||
font-size: 0.8em;
|
||||
margin: 0 1em;
|
||||
}
|
||||
.card .list .item .cmd {
|
||||
font-size: 0.8em;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 0.5em;
|
||||
margin: 0em 0.3em;
|
||||
border: 0.1em solid rgba(255, 255, 255, 0.1);
|
||||
color: #cadc9e;
|
||||
}
|
||||
.card .list .item .strong {
|
||||
color: #f2c94c;
|
||||
}
|
||||
.card .list .item .new {
|
||||
position: relative;
|
||||
}
|
||||
.card .list .item .new::before {
|
||||
content: "new";
|
||||
font-size: 0.4em;
|
||||
background: linear-gradient(90deg, #f2c94c, #ffe6b4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 0.05em #f0d480);
|
||||
bottom: 1.8em;
|
||||
left: 0em;
|
||||
position: relative;
|
||||
border: 0.1em solid #f2c94c;
|
||||
padding: 0em 0.3em 0.2em 0.3em;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=commit.css.map */
|
||||
27
resources/help/commit.html
Normal file
27
resources/help/commit.html
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{{extend defaultLayout}}
|
||||
|
||||
{{block 'css'}}
|
||||
<link rel="stylesheet" href="{{@sys.currentPath}}/commit.css">
|
||||
{{/block}}
|
||||
|
||||
{{block 'main'}}
|
||||
<div class="card">
|
||||
<% include(sys.specialTitle, {en: 'COMMIT' , cn: '更新日志' }) %>
|
||||
|
||||
<div class="list">
|
||||
{{each commitData commit i}}
|
||||
<div class="item {{commit.current ? 'current' : ''}} {{!commit.local ? 'newc' : ''}}">
|
||||
<div class="version">
|
||||
<div class="id no-zzz-font">{{commit.commit}}</div>
|
||||
<div class="time">{{commit.date}}</div>
|
||||
</div>
|
||||
<div class="content no-zzz-font">
|
||||
{{@commit.msg}}
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
{{/block}}
|
||||
139
resources/help/commit.scss
Normal file
139
resources/help/commit.scss
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
.special-title {
|
||||
padding: 0;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.card {
|
||||
margin: 0 1em;
|
||||
padding: 1em 0;
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
font-size: 0.9em;
|
||||
.item {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 0.5em;
|
||||
border: 0.1em solid rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(0.5em);
|
||||
position: relative;
|
||||
.version {
|
||||
filter: drop-shadow(0 0 0.05em #f0d480);
|
||||
position: relative;
|
||||
margin-bottom: 0.5em;
|
||||
font-size: 0.8em;
|
||||
display: flex;
|
||||
.id {
|
||||
background: linear-gradient(90deg, #ffe6b4, #f2c94c);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
position: relative;
|
||||
margin-right: 0.5em;
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 0.2em;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: linear-gradient(0deg, #f2c94c, #ffe6b4);
|
||||
z-index: -1;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
}
|
||||
.time {
|
||||
background: linear-gradient(90deg, #ffe6b4, #f2c94c);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
}
|
||||
&.current {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
backdrop-filter: blur(1.5em);
|
||||
&::after {
|
||||
content: '当前版本';
|
||||
font-size: 0.8em;
|
||||
position: absolute;
|
||||
right: 0.5em;
|
||||
top: 0.5em;
|
||||
color: #f2c94c;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.version {
|
||||
filter: drop-shadow(0 0 0.1em rgba(231, 241, 35, 0.3));
|
||||
font-size: 1em;
|
||||
.id {
|
||||
color: #f2784c;
|
||||
background: none;
|
||||
background-clip: unset;
|
||||
-webkit-text-fill-color: unset;
|
||||
font-size: 0.8em;
|
||||
padding-top: 0.3em;
|
||||
&::before {
|
||||
background: #f2784c;
|
||||
}
|
||||
}
|
||||
.time {
|
||||
background: linear-gradient(90deg, #f2784c, #ffbca4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.newc {
|
||||
&::after {
|
||||
content: 'NEW';
|
||||
font-size: 0.4em;
|
||||
background: linear-gradient(90deg, #f2c94c, #ffe6b4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 0.05em #f0d480);
|
||||
top: 1em;
|
||||
right: 1em;
|
||||
position: absolute;
|
||||
border: 0.1em solid #f2c94c;
|
||||
padding: 0.1em 0.3em 0.2em 0.3em;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
}
|
||||
.content {
|
||||
font-size: 0.8em;
|
||||
margin: 0 1em;
|
||||
}
|
||||
.cmd {
|
||||
font-size: 0.8em;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 0.5em;
|
||||
margin: 0em 0.3em;
|
||||
border: 0.1em solid rgba(255, 255, 255, 0.1);
|
||||
color: #cadc9e;
|
||||
}
|
||||
.strong {
|
||||
color: #f2c94c;
|
||||
}
|
||||
.new {
|
||||
position: relative;
|
||||
&::before {
|
||||
content: 'new';
|
||||
font-size: 0.4em;
|
||||
background: linear-gradient(90deg, #f2c94c, #ffe6b4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 0.05em #f0d480);
|
||||
bottom: 1.8em;
|
||||
left: 0em;
|
||||
position: relative;
|
||||
border: 0.1em solid #f2c94c;
|
||||
padding: 0em 0.3em 0.2em 0.3em;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
122
resources/help/version.css
Normal file
122
resources/help/version.css
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
@charset "UTF-8";
|
||||
.special-title {
|
||||
padding: 0;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
.card {
|
||||
margin: 0 1em;
|
||||
padding: 1em 0;
|
||||
}
|
||||
.card .list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
}
|
||||
.card .list .item {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 0.5em;
|
||||
border: 0.1em solid rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(0.5em);
|
||||
position: relative;
|
||||
}
|
||||
.card .list .item .version {
|
||||
width: fit-content;
|
||||
background: linear-gradient(90deg, #ffe6b4, #f2c94c);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 0.05em #f0d480);
|
||||
position: relative;
|
||||
margin-bottom: 0.5em;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
.card .list .item .version::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 2em;
|
||||
height: 0.2em;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: linear-gradient(0deg, #f2c94c, #ffe6b4);
|
||||
z-index: -1;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
.card .list .item:nth-child(1) {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
backdrop-filter: blur(1.5em);
|
||||
}
|
||||
.card .list .item:nth-child(1)::after {
|
||||
content: "当前版本";
|
||||
font-size: 0.8em;
|
||||
position: absolute;
|
||||
right: 0.5em;
|
||||
top: 0.5em;
|
||||
color: #f2c94c;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.card .list .item:nth-child(1) .version {
|
||||
background: linear-gradient(90deg, #f2784c, #ffbca4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 0.1em rgba(231, 241, 35, 0.3));
|
||||
font-size: 1em;
|
||||
}
|
||||
.card .list .item:nth-child(1) .version::before {
|
||||
background: #f2784c;
|
||||
}
|
||||
.card .list .item:nth-child(1) .version::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 0.3em 0.3em 0 0.3em;
|
||||
border-color: #f2784c transparent transparent transparent;
|
||||
bottom: -0.3em;
|
||||
left: 0.7em;
|
||||
}
|
||||
.card .list .item .content {
|
||||
font-size: 0.8em;
|
||||
margin: 0 1em;
|
||||
}
|
||||
.card .list .item .content ul {
|
||||
padding-left: 1em;
|
||||
}
|
||||
.card .list .item .content ul li {
|
||||
margin: 0.1em 0;
|
||||
}
|
||||
.card .list .item .cmd {
|
||||
font-size: 0.8em;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 0.5em;
|
||||
margin: 0em 0.3em;
|
||||
border: 0.1em solid rgba(255, 255, 255, 0.1);
|
||||
color: #cadc9e;
|
||||
}
|
||||
.card .list .item .strong {
|
||||
color: #f2c94c;
|
||||
}
|
||||
.card .list .item .new {
|
||||
position: relative;
|
||||
}
|
||||
.card .list .item .new::before {
|
||||
content: "new";
|
||||
font-size: 0.4em;
|
||||
background: linear-gradient(90deg, #f2c94c, #ffe6b4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 0.05em #f0d480);
|
||||
bottom: 1.8em;
|
||||
left: 0em;
|
||||
position: relative;
|
||||
border: 0.1em solid #f2c94c;
|
||||
padding: 0em 0.3em 0.2em 0.3em;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=version.css.map */
|
||||
28
resources/help/version.html
Normal file
28
resources/help/version.html
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
{{extend defaultLayout}}
|
||||
|
||||
{{block 'css'}}
|
||||
<link rel="stylesheet" href="{{@sys.currentPath}}/version.css">
|
||||
{{/block}}
|
||||
|
||||
{{block 'main'}}
|
||||
<div class="card">
|
||||
<% include(sys.specialTitle, {en: 'VERSION' , cn: '版本日志' }) %>
|
||||
<div class="list">
|
||||
{{each versionData version i}}
|
||||
<div class="item">
|
||||
<div class="version">ver {{version.version}}</div>
|
||||
<div class="content no-zzz-font">
|
||||
<ul>
|
||||
{{each version.logs log1 j}}
|
||||
<li>{{@log1.title}}</li>
|
||||
{{each log1.logs log2 k}}
|
||||
<li>{{@log2.title}}</li>
|
||||
{{/each}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
{{/block}}
|
||||
118
resources/help/version.scss
Normal file
118
resources/help/version.scss
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
.special-title {
|
||||
padding: 0;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
.card {
|
||||
margin: 0 1em;
|
||||
padding: 1em 0;
|
||||
.list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.5em;
|
||||
.item {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
padding: 0.5em 1em;
|
||||
border-radius: 0.5em;
|
||||
border: 0.1em solid rgba(255, 255, 255, 0.1);
|
||||
backdrop-filter: blur(0.5em);
|
||||
position: relative;
|
||||
.version {
|
||||
width: fit-content;
|
||||
background: linear-gradient(90deg, #ffe6b4, #f2c94c);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 0.05em #f0d480);
|
||||
position: relative;
|
||||
margin-bottom: 0.5em;
|
||||
font-size: 0.8em;
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 2em;
|
||||
height: 0.2em;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: linear-gradient(0deg, #f2c94c, #ffe6b4);
|
||||
z-index: -1;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
}
|
||||
&:nth-child(1) {
|
||||
background-color: rgba(255, 255, 255, 0.15);
|
||||
backdrop-filter: blur(1.5em);
|
||||
&::after {
|
||||
content: '当前版本';
|
||||
font-size: 0.8em;
|
||||
position: absolute;
|
||||
right: 0.5em;
|
||||
top: 0.5em;
|
||||
color: #f2c94c;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.version {
|
||||
background: linear-gradient(90deg, #f2784c, #ffbca4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 0.1em rgba(231, 241, 35, 0.3));
|
||||
font-size: 1em;
|
||||
&::before {
|
||||
background: #f2784c;
|
||||
}
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
border-width: 0.3em 0.3em 0 0.3em;
|
||||
border-color: #f2784c transparent transparent transparent;
|
||||
bottom: -0.3em;
|
||||
left: 0.7em;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content {
|
||||
font-size: 0.8em;
|
||||
margin: 0 1em;
|
||||
ul {
|
||||
padding-left: 1em;
|
||||
li {
|
||||
margin: 0.1em 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.cmd {
|
||||
font-size: 0.8em;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 0.5em;
|
||||
margin: 0em 0.3em;
|
||||
border: 0.1em solid rgba(255, 255, 255, 0.1);
|
||||
color: #cadc9e;
|
||||
}
|
||||
.strong {
|
||||
color: #f2c94c;
|
||||
}
|
||||
.new {
|
||||
position: relative;
|
||||
&::before {
|
||||
content: 'new';
|
||||
font-size: 0.4em;
|
||||
background: linear-gradient(90deg, #f2c94c, #ffe6b4);
|
||||
-webkit-background-clip: text;
|
||||
background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
filter: drop-shadow(0 0 0.05em #f0d480);
|
||||
bottom: 1.8em;
|
||||
left: 0em;
|
||||
position: relative;
|
||||
border: 0.1em solid #f2c94c;
|
||||
padding: 0em 0.3em 0.2em 0.3em;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,3 +25,23 @@ export const generateSeed = (length = 16) => {
|
|||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* 将 Markdown 日志行转换为 HTML
|
||||
* @param {*} line
|
||||
* @returns
|
||||
*/
|
||||
export const mdLogLineToHTML = function (line) {
|
||||
// 去除行首空格和换行符
|
||||
line = line.replace(/(^\s*\*|\r)/g, '');
|
||||
// 替换行内代码块
|
||||
line = line.replace(/\s*`([^`]+`)/g, '<span class="cmd">$1');
|
||||
line = line.replace(/`\s*/g, '</span>');
|
||||
// 替换行内加粗
|
||||
line = line.replace(/\s*\*\*([^\*]+\*\*)/g, '<span class="strong">$1');
|
||||
line = line.replace(/\*\*\s*/g, '</span>');
|
||||
// 替换行内表示更新内容
|
||||
line = line.replace(/ⁿᵉʷ/g, '<span class="new"></span>');
|
||||
// 返回转换后的行内容(HTML)
|
||||
return line.trim();
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue