添加工具:比例计算、生成批量下载链接、Unix 时间戳转换
This commit is contained in:
@@ -11,7 +11,7 @@ let navTools = {
|
||||
// 工具标题
|
||||
title: '计算下载用时',
|
||||
// 工具简介
|
||||
desc: '根据设定的文件大小和下载速度简单计算大约下载完成所需的时间',
|
||||
desc: '根据设定的文件大小和下载速度简单计算大约下载完成所需的时间。',
|
||||
// 组件名称
|
||||
component: 'CalcDownloadTime',
|
||||
// 更新时间
|
||||
@@ -20,8 +20,12 @@ let navTools = {
|
||||
enabled: false
|
||||
},
|
||||
'ratio': {
|
||||
title: '计算比例',
|
||||
component: 'CalcRatio'
|
||||
title: '比例计算',
|
||||
desc: '按设定的比例计算给出的数值所对应的数值。',
|
||||
component: 'CalcRatio',
|
||||
update: '2021-11-14',
|
||||
version: '1',
|
||||
enabled: true
|
||||
},
|
||||
'simple': {
|
||||
title: '简易计算器',
|
||||
@@ -35,13 +39,15 @@ let navTools = {
|
||||
list: {
|
||||
'links': {
|
||||
title: '生成批量下载链接',
|
||||
desc: '根据设置,生成有一定规律的用于批量下载的链接',
|
||||
desc: '根据设置,生成有一定规律的用于批量下载的链接。',
|
||||
component: 'GenLinks',
|
||||
enabled: false
|
||||
update: '2021-11-14',
|
||||
version: '1',
|
||||
enabled: true
|
||||
},
|
||||
'random-str': {
|
||||
title: '生成随机字符串',
|
||||
desc: '生成随机组合的字符串,可用于密码',
|
||||
desc: '生成随机组合的字符串,可用于密码。',
|
||||
component: 'GenRandomStr',
|
||||
update: '2021-05-04',
|
||||
version: '1',
|
||||
@@ -68,9 +74,11 @@ let navTools = {
|
||||
},
|
||||
'timestamp': {
|
||||
title: 'Unix 时间戳转换',
|
||||
desc: 'Unix 时间戳转时间 / 时间转 Unix 时间戳',
|
||||
desc: '时间戳转时间 / 时间转时间戳',
|
||||
component: 'ConvertTimestamp',
|
||||
enabled: false
|
||||
update: '2021-11-14',
|
||||
version: '1',
|
||||
enabled: true
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -84,13 +92,13 @@ let navTools = {
|
||||
},
|
||||
'dynmap-renderdata-gen': {
|
||||
title: 'Dynmap renderdata 生成',
|
||||
desc: '生成用于 Minecraft Dynmap 插件 / 模组的 renderdata 数据',
|
||||
desc: '生成用于 Minecraft Dynmap 插件 / 模组的 renderdata 数据。',
|
||||
component: 'MinecraftDynmapRenderdataGen',
|
||||
enabled: false
|
||||
},
|
||||
'uuidConverter': {
|
||||
title: 'UUID 转换',
|
||||
desc: 'UUID 与 UUID Least、UUID Most 相互转换',
|
||||
desc: 'UUID 与 UUID Least、UUID Most 相互转换。',
|
||||
component: 'MinecraftUUIDConverter',
|
||||
enabled: false
|
||||
},
|
||||
|
135
src/components/tools/CalcRatio.vue
Normal file
135
src/components/tools/CalcRatio.vue
Normal file
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<div class="tool-page">
|
||||
|
||||
<div class="calc-mode">
|
||||
<div class="title">计算模式</div>
|
||||
<div class="content">
|
||||
<el-select v-model="mode" size="small">
|
||||
<el-option label="1 -> 2" value="1-to-2"></el-option>
|
||||
<el-option label="2 -> 1" value="2-to-1"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="digits">
|
||||
<div class="title">小数位数</div>
|
||||
<div class="content">
|
||||
<el-input-number
|
||||
v-model="digits"
|
||||
controls-position="right"
|
||||
size="small"
|
||||
:min="0"
|
||||
:max="10"
|
||||
:step="1"
|
||||
step-strictly
|
||||
@change="update()"
|
||||
></el-input-number>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ratio-base">
|
||||
<div class="title">基础比例</div>
|
||||
<div class="content">
|
||||
<el-input-number
|
||||
v-model="base.a"
|
||||
controls-position="right"
|
||||
size="small"
|
||||
:step="1"
|
||||
@change="update()"
|
||||
></el-input-number>
|
||||
<span class="split">:</span>
|
||||
<el-input-number
|
||||
v-model="base.b"
|
||||
controls-position="right"
|
||||
size="small"
|
||||
:step="1"
|
||||
@change="update()"
|
||||
></el-input-number>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ratio-calc">
|
||||
<div class="title">计算比例</div>
|
||||
<div class="content">
|
||||
<el-input-number
|
||||
v-model="calc.a"
|
||||
controls-position="right"
|
||||
size="small"
|
||||
:step="1"
|
||||
:disabled="mode === '2-to-1'"
|
||||
@change="update()"
|
||||
></el-input-number>
|
||||
<span class="split">:</span>
|
||||
<el-input-number
|
||||
v-model="calc.b"
|
||||
controls-position="right"
|
||||
size="small"
|
||||
:step="1"
|
||||
:disabled="mode === '1-to-2'"
|
||||
@change="update()"
|
||||
></el-input-number>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { divide, multiply, round } from 'mathjs';
|
||||
|
||||
export default {
|
||||
name: 'CalcRatio',
|
||||
data() {
|
||||
return {
|
||||
// 基础比例
|
||||
base: {
|
||||
a: 1,
|
||||
b: 1,
|
||||
},
|
||||
// 计算比例
|
||||
calc: {
|
||||
a: 1,
|
||||
b: 1,
|
||||
},
|
||||
// 小数位数
|
||||
digits: 5,
|
||||
// 模式
|
||||
mode: '1-to-2',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 计算
|
||||
*/
|
||||
update() {
|
||||
const base = this.base;
|
||||
const calc = this.calc;
|
||||
const digits = this.digits;
|
||||
const mode = this.mode;
|
||||
const ratio = base.a / base.b;
|
||||
|
||||
if (mode === '1-to-2') {
|
||||
calc.b = round(divide(calc.a, ratio), digits);
|
||||
} else if (mode === '2-to-1') {
|
||||
calc.a = round(multiply(calc.b, ratio), digits);
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.el-input-number,
|
||||
.el-select {
|
||||
width: 10rem;
|
||||
}
|
||||
|
||||
.split {
|
||||
display: inline-block;
|
||||
width: 2em;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
323
src/components/tools/ConvertTimestamp.vue
Normal file
323
src/components/tools/ConvertTimestamp.vue
Normal file
@@ -0,0 +1,323 @@
|
||||
<template>
|
||||
<div class="tool-page">
|
||||
|
||||
<div class="ctrl">
|
||||
<div class="title">控制</div>
|
||||
<div class="content">
|
||||
<!-- 转换模式 -->
|
||||
<div class="item">
|
||||
<span class="label">转换模式</span>
|
||||
<el-select v-model="mode" size="medium">
|
||||
<el-option
|
||||
v-for="item in modes"
|
||||
:key="item.name"
|
||||
:label="item.label"
|
||||
:value="item.name"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<!-- 时间戳类型 -->
|
||||
<div class="item">
|
||||
<span class="label">时间戳类型</span>
|
||||
<el-select v-model="tsType" size="medium">
|
||||
<el-option
|
||||
v-for="item in tsTypes"
|
||||
:key="item.name"
|
||||
:label="item.label"
|
||||
:value="item.name"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<!-- 操作 -->
|
||||
<div class="item">
|
||||
<span class="label">操作</span>
|
||||
<el-button
|
||||
:type="update ? 'success' : 'warning'"
|
||||
size="small"
|
||||
plain
|
||||
@click="toggleUpdate()"
|
||||
>状态:{{ update ? '自动更新' : '暂停更新' }}</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
plain
|
||||
@click="convert()"
|
||||
>转换</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
plain
|
||||
@click="clear()"
|
||||
>清空</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="current">
|
||||
<div class="title">当前</div>
|
||||
<div class="content">
|
||||
<div class="item">
|
||||
<span class="label">时间</span>
|
||||
<el-input
|
||||
v-model="current.t"
|
||||
size="medium"
|
||||
readonly
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="label">时间戳</span>
|
||||
<el-input
|
||||
v-model="current.ts"
|
||||
size="medium"
|
||||
readonly
|
||||
></el-input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="inputs">
|
||||
<div class="title">输入</div>
|
||||
<div class="content">
|
||||
<div class="notice">
|
||||
<p>注意:</p>
|
||||
<p>在“本地时间 -> 时间戳”的模式中,若省略“时间”,将会加上本地时区与零时区的时差后计算;</p>
|
||||
<p>例如北京时间(UTC+8)按 08:00 计算,东京时间(UTC+9)按 09:00 计算。</p>
|
||||
</div>
|
||||
<el-input
|
||||
v-model="textInputs"
|
||||
:placeholder="placeholder"
|
||||
size="medium"
|
||||
></el-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="outputs">
|
||||
<div class="title">结果</div>
|
||||
<div class="content">
|
||||
<el-input
|
||||
v-model="textOutputs"
|
||||
size="medium"
|
||||
></el-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ConvertTimestamp',
|
||||
data() {
|
||||
return {
|
||||
// 转换模式
|
||||
mode: 't-to-ts',
|
||||
modes: [
|
||||
{ name: 't-to-ts', label: '本地时间 -> 时间戳' },
|
||||
{ name: 'ts-to-t', label: '时间戳 -> 本地时间' },
|
||||
],
|
||||
// 定时器
|
||||
timer: null,
|
||||
// 是否更新当前时间
|
||||
update: true,
|
||||
// 时间戳类型
|
||||
tsType: 'ms',
|
||||
tsTypes: [
|
||||
{ name: 'ms', label: '毫秒' },
|
||||
{ name: 's', label: '秒' },
|
||||
],
|
||||
// 当前时间
|
||||
current: {
|
||||
t: '',
|
||||
ts: '',
|
||||
},
|
||||
// 输入
|
||||
textInputs: '',
|
||||
// 输出
|
||||
textOutputs: '',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
// 输入占位文本
|
||||
placeholder() {
|
||||
const mode = this.mode;
|
||||
const type = this.tsType;
|
||||
|
||||
if (mode === 't-to-ts') {
|
||||
return '参考格式:年-月-日 时:分:秒';
|
||||
} else if (mode === 'ts-to-t') {
|
||||
if (type === 's') {
|
||||
return '参考范例:1577808000';
|
||||
} else if (type === 'ms') {
|
||||
return '参考范例:1577808000000';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
},
|
||||
|
||||
},
|
||||
created () {
|
||||
this.init();
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearInterval(this.timer);
|
||||
},
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
init() {
|
||||
this.timer = setInterval(() => {
|
||||
if (this.update) {
|
||||
this.current.t = this.tsToTime();
|
||||
this.current.ts = this.timeToTs();
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
/**
|
||||
* 清空
|
||||
*/
|
||||
clear() {
|
||||
this.textInputs = '';
|
||||
this.textOutputs = '';
|
||||
},
|
||||
|
||||
/**
|
||||
* 转换
|
||||
*/
|
||||
convert() {
|
||||
const mode = this.mode;
|
||||
|
||||
if (mode === 't-to-ts') {
|
||||
this.textOutputs = this.timeToTs(this.textInputs);
|
||||
} else if (mode === 'ts-to-t') {
|
||||
this.textOutputs = this.tsToTime(this.textInputs);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 时间 -> 时间戳
|
||||
*
|
||||
* @param {string} [timeStr] 时间字符串(年-月-日 时:分:秒)
|
||||
* @returns {string} 转换结果
|
||||
*/
|
||||
timeToTs(timeStr) {
|
||||
const date = (timeStr ? new Date(timeStr) : new Date());
|
||||
|
||||
if (date.toString() === 'Invalid Date') {
|
||||
return '格式错误';
|
||||
}
|
||||
|
||||
const result = date.getTime();
|
||||
|
||||
if (this.tsType === 'ms') {
|
||||
// 毫秒
|
||||
return result;
|
||||
} else {
|
||||
// 秒
|
||||
return (result / 1000).toFixed(0);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 时间戳 -> 时间
|
||||
*
|
||||
* @param {(number|string)} [ts] 时间戳
|
||||
* @returns {string} 转换结果(年-月-日 时:分:秒)
|
||||
*/
|
||||
tsToTime(ts = null) {
|
||||
if (ts === '') {
|
||||
ts = null;
|
||||
}
|
||||
|
||||
// 是否有参数
|
||||
const tsParam = (ts !== null);
|
||||
|
||||
// 时间戳是秒
|
||||
if (tsParam && this.tsType === 's') {
|
||||
ts += '000';
|
||||
}
|
||||
|
||||
// 转为数值
|
||||
const timestamp = parseInt(ts);
|
||||
|
||||
if (tsParam && isNaN(timestamp)) {
|
||||
return '格式错误';
|
||||
}
|
||||
|
||||
const date = (tsParam ? new Date(timestamp) : new Date());
|
||||
const t = {
|
||||
y: date.getFullYear(),
|
||||
m: date.getMonth() + 1,
|
||||
d: date.getDate(),
|
||||
h: date.getHours(),
|
||||
i: date.getMinutes(),
|
||||
s: date.getSeconds(),
|
||||
};
|
||||
|
||||
// 补零
|
||||
for (let key in t) {
|
||||
(t[key] < 10) && (t[key] = ('0' + t[key]));
|
||||
}
|
||||
|
||||
return `${t.y}-${t.m}-${t.d} ${t.h}:${t.i}:${t.s}`;
|
||||
},
|
||||
|
||||
/**
|
||||
* 切换自动更新
|
||||
*/
|
||||
toggleUpdate() {
|
||||
this.update = !this.update;
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ctrl, .current {
|
||||
.content {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.item {
|
||||
margin: 0.5rem 0.5rem;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.ctrl {
|
||||
.el-select {
|
||||
width: 12em;
|
||||
}
|
||||
}
|
||||
|
||||
.current {
|
||||
.el-input {
|
||||
width: 20em;
|
||||
}
|
||||
|
||||
.label {
|
||||
width: 3.5em;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.inputs, .outputs {
|
||||
.el-input {
|
||||
max-width: 25em;
|
||||
}
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
</style>
|
449
src/components/tools/GenLinks.vue
Normal file
449
src/components/tools/GenLinks.vue
Normal file
@@ -0,0 +1,449 @@
|
||||
<template>
|
||||
<div class="tool-page">
|
||||
|
||||
<div class="link-base">
|
||||
<div class="title">链接模板</div>
|
||||
<div class="content">
|
||||
<el-input
|
||||
v-model="linkBase"
|
||||
size="medium"
|
||||
placeholder="使用 {n} 表示变量"
|
||||
clearable
|
||||
></el-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config">
|
||||
<div class="title">参数配置</div>
|
||||
<div class="content">
|
||||
<el-radio-group v-model="mode">
|
||||
|
||||
<!-- 等差数列 -->
|
||||
<div class="mode-item mode-as">
|
||||
|
||||
<div class="config-row">
|
||||
<el-radio label="as">等差数列</el-radio>
|
||||
</div>
|
||||
|
||||
<div class="config-row">
|
||||
<div class="config-item">
|
||||
<span class="label">首项</span>
|
||||
<el-input-number
|
||||
v-model="modes.as.first"
|
||||
controls-position="right"
|
||||
size="medium"
|
||||
:step="1"
|
||||
step-strictly
|
||||
></el-input-number>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<span class="label">公差</span>
|
||||
<el-input-number
|
||||
v-model="modes.as.diff"
|
||||
controls-position="right"
|
||||
size="medium"
|
||||
:step="1"
|
||||
step-strictly
|
||||
></el-input-number>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<span class="label">项数</span>
|
||||
<el-input-number
|
||||
v-model="modes.as.count"
|
||||
controls-position="right"
|
||||
size="medium"
|
||||
:step="1"
|
||||
step-strictly
|
||||
></el-input-number>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-row">
|
||||
<div class="config-item">
|
||||
<span class="label">格式</span>
|
||||
<el-checkbox
|
||||
v-model="modes.as.zero"
|
||||
>补零</el-checkbox>
|
||||
<el-checkbox
|
||||
v-model="modes.as.reverse"
|
||||
>倒序</el-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 等差数列 -->
|
||||
|
||||
<!-- 等比数列 -->
|
||||
<div class="mode-item mode-ps">
|
||||
|
||||
<div class="config-row">
|
||||
<el-radio label="ps">等比数列</el-radio>
|
||||
</div>
|
||||
|
||||
<div class="config-row">
|
||||
<div class="config-item">
|
||||
<span class="label">首项</span>
|
||||
<el-input-number
|
||||
v-model="modes.ps.first"
|
||||
controls-position="right"
|
||||
size="medium"
|
||||
:step="1"
|
||||
step-strictly
|
||||
></el-input-number>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<span class="label">公比</span>
|
||||
<el-input-number
|
||||
v-model="modes.ps.diff"
|
||||
controls-position="right"
|
||||
size="medium"
|
||||
:step="1"
|
||||
step-strictly
|
||||
></el-input-number>
|
||||
</div>
|
||||
<div class="config-item">
|
||||
<span class="label">项数</span>
|
||||
<el-input-number
|
||||
v-model="modes.ps.count"
|
||||
controls-position="right"
|
||||
size="medium"
|
||||
:step="1"
|
||||
step-strictly
|
||||
></el-input-number>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="config-row">
|
||||
<div class="config-item">
|
||||
<span class="label">格式</span>
|
||||
<el-checkbox
|
||||
v-model="modes.ps.zero"
|
||||
>补零</el-checkbox>
|
||||
<el-checkbox
|
||||
v-model="modes.ps.reverse"
|
||||
>倒序</el-checkbox>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 等比数列 -->
|
||||
|
||||
<!-- 字母变化 -->
|
||||
<div class="mode-item mode-lc">
|
||||
|
||||
<div class="config-row">
|
||||
<el-radio label="lc">字母变化</el-radio>
|
||||
</div>
|
||||
|
||||
<div class="config-row">
|
||||
<span class="label">从</span>
|
||||
<el-input
|
||||
v-model="modes.lc.start"
|
||||
size="medium"
|
||||
:maxlength="1"
|
||||
></el-input>
|
||||
<span class="label">到</span>
|
||||
<el-input
|
||||
v-model="modes.lc.end"
|
||||
size="medium"
|
||||
:maxlength="1"
|
||||
></el-input>
|
||||
<el-checkbox
|
||||
v-model="modes.lc.reverse"
|
||||
>倒序</el-checkbox>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 字母变化 -->
|
||||
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action">
|
||||
<div class="title">操作</div>
|
||||
<div class="content">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
plain
|
||||
@click="generate()"
|
||||
>生成链接</el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="small"
|
||||
plain
|
||||
@click="clear()"
|
||||
>清空结果</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="link-result">
|
||||
<div class="title">生成结果</div>
|
||||
<div class="content">
|
||||
<el-input
|
||||
v-model="linkResult"
|
||||
type="textarea"
|
||||
:rows="10"
|
||||
></el-input>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GenLinks',
|
||||
data() {
|
||||
return {
|
||||
// 链接模板
|
||||
linkBase: '',
|
||||
// 生成结果
|
||||
linkResult: '',
|
||||
// 正则,匹配链接变量
|
||||
linkReg: /\{n\}/g,
|
||||
// 当前模式
|
||||
mode: 'as',
|
||||
modes: {
|
||||
// 等差数列(Arithmetic Sequence)
|
||||
as: {
|
||||
first: 0,
|
||||
diff: 1,
|
||||
count: 10,
|
||||
zero: false,
|
||||
reverse: false,
|
||||
},
|
||||
// 等比数列(Proportional Sequence)
|
||||
ps: {
|
||||
first: 1,
|
||||
diff: 2,
|
||||
count: 10,
|
||||
zero: false,
|
||||
reverse: false,
|
||||
},
|
||||
// 字母变化(Letter Change)
|
||||
lc: {
|
||||
start: 'a',
|
||||
end: 'z',
|
||||
reverse: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
/**
|
||||
* 清空
|
||||
*/
|
||||
clear() {
|
||||
this.linkResult = '';
|
||||
},
|
||||
|
||||
/**
|
||||
* 生成
|
||||
*/
|
||||
generate() {
|
||||
const mode = this.mode;
|
||||
|
||||
switch (mode) {
|
||||
case 'as':
|
||||
this.linkResult = this.generateSeq('as');
|
||||
break;
|
||||
case 'ps':
|
||||
this.linkResult = this.generateSeq('ps');
|
||||
break;
|
||||
case 'lc':
|
||||
this.linkResult = this.generateLetter();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 生成数列
|
||||
*
|
||||
* @param {string} typs 类型(as - 等差数列,ps - 等比数列)
|
||||
* @returns {string} 生成结果
|
||||
*/
|
||||
generateSeq(type) {
|
||||
const linkBase = this.linkBase;
|
||||
const linkReg = this.linkReg;
|
||||
|
||||
if (!linkBase) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const data = this.modes[type];
|
||||
|
||||
if (!data) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const nFirst = data.first
|
||||
const nCount = data.count;
|
||||
const nDiff = data.diff;
|
||||
|
||||
const nResult = {
|
||||
digits: 0, // 最大位数
|
||||
numbers: [], // 生成的数值
|
||||
};
|
||||
|
||||
const links = [];
|
||||
|
||||
// 等差数列公式
|
||||
const expAS = (i) => {
|
||||
return (nFirst + (i - 1) * nDiff);
|
||||
};
|
||||
// 等比数列公式
|
||||
const expPS = (i) => {
|
||||
return (nFirst * Math.pow(nDiff, (i - 1)));
|
||||
};
|
||||
// 实际使用的公式
|
||||
const exp = (type === 'as' ? expAS : expPS);
|
||||
|
||||
// 生成数值
|
||||
for (let i = 1; i <= nCount; i++) {
|
||||
// 等差数列 / 等比数列
|
||||
const n = exp(i);
|
||||
const digits = Math.abs(n).toString().length;
|
||||
|
||||
(digits > nResult.digits) && (nResult.digits = digits);
|
||||
nResult.numbers.push(n);
|
||||
}
|
||||
|
||||
// 补零
|
||||
if (data.zero) {
|
||||
const digits = nResult.digits;
|
||||
const base = Math.pow(10, digits);
|
||||
const numbers = nResult.numbers;
|
||||
|
||||
for (let i = 0; i < numbers.length; i++) {
|
||||
const n = numbers[i];
|
||||
|
||||
if (n >= 0) {
|
||||
numbers[i] = (n / base).toFixed(digits).substr(2);
|
||||
} else {
|
||||
numbers[i] = '-' + (n / base).toFixed(digits).substr(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 倒序
|
||||
if (data.reverse) {
|
||||
nResult.numbers.reverse();
|
||||
}
|
||||
|
||||
// 生成链接
|
||||
nResult.numbers.forEach((n) => {
|
||||
links.push(linkBase.replace(linkReg, n));
|
||||
});
|
||||
|
||||
return links.join('\n');
|
||||
},
|
||||
|
||||
/**
|
||||
* 生成字母
|
||||
*/
|
||||
generateLetter() {
|
||||
const linkBase = this.linkBase;
|
||||
const linkReg = this.linkReg;
|
||||
|
||||
if (!linkBase) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const data = this.modes.lc;
|
||||
|
||||
// 编码数值
|
||||
const cStart = data.start.charCodeAt(0);
|
||||
const cEnd = data.end.charCodeAt(0);
|
||||
|
||||
const chars = [];
|
||||
const links = [];
|
||||
|
||||
// 生成字母
|
||||
if (cStart >= 65 && cStart <= 122 && cEnd >= 65 && cEnd <= 122) {
|
||||
if (cStart < cEnd) {
|
||||
for (let i = cStart; i <= cEnd; i++) {
|
||||
// 跳过符号 [ \ ] ^ _ `
|
||||
if (i >= 91 && i <= 96) {
|
||||
continue;
|
||||
}
|
||||
chars.push(String.fromCharCode(i));
|
||||
}
|
||||
} else if (cStart > cEnd) {
|
||||
return '字母先后顺序有误。注意:大写字母需要在前。';
|
||||
} else if (cStart === cEnd) {
|
||||
return '仅有 1 条链接,无需生成。';
|
||||
} else {
|
||||
return '未知错误。';
|
||||
}
|
||||
} else {
|
||||
return '输入有误,请检查。';
|
||||
}
|
||||
|
||||
// 倒序
|
||||
if (data.reverse) {
|
||||
chars.reverse();
|
||||
}
|
||||
|
||||
// 生成链接
|
||||
chars.forEach((c) => {
|
||||
links.push(linkBase.replace(linkReg, c));
|
||||
});
|
||||
|
||||
return links.join('\n');
|
||||
},
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.config {
|
||||
.el-input-number {
|
||||
width: 8rem;
|
||||
}
|
||||
|
||||
.mode-item {
|
||||
padding: 0.5rem 0;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: 0.0625rem solid #EEE;
|
||||
}
|
||||
}
|
||||
|
||||
.config-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
padding: 0.25rem 0;
|
||||
}
|
||||
|
||||
.config-item {
|
||||
margin: 0.25rem 0;
|
||||
}
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
margin: 0 1em;
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
}
|
||||
|
||||
.mode-lc {
|
||||
/deep/ .el-checkbox {
|
||||
margin: 0 1em;
|
||||
}
|
||||
|
||||
/deep/ .el-input {
|
||||
width: 3.5em;
|
||||
}
|
||||
|
||||
/deep/ .el-input__inner {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user