feat(工具箱): 实现“下载用时计算”工具

This commit is contained in:
2024-09-08 16:06:31 +08:00
parent 10ab2fb670
commit a31ad98a9e
3 changed files with 224 additions and 7 deletions

View File

@@ -11,7 +11,7 @@ export const toolList = [
{ {
id: 'calculation-tools', id: 'calculation-tools',
title: '计算', title: '计算',
enabled: false, enabled: true,
items: [ items: [
{ {
id: 'calc-download-time', id: 'calc-download-time',
@@ -19,10 +19,10 @@ export const toolList = [
title: '下载用时计算', title: '下载用时计算',
iconClass: 'mdi mdi-calculator-variant-outline', iconClass: 'mdi mdi-calculator-variant-outline',
desc: '根据设定的文件大小和下载速度简单计算大约下载完成所需的时间。', desc: '根据设定的文件大小和下载速度简单计算大约下载完成所需的时间。',
createdAt: '', createdAt: '2024-09-08',
updatedAt: '', updatedAt: '2024-09-08',
version: '0', version: '1',
enabled: false, enabled: true,
}, },
{ {
id: 'calc-ratio', id: 'calc-ratio',

View File

@@ -1,9 +1,209 @@
<template> <template>
<div class="tool-detail-page"></div> <div class="tool-detail-page">
<!-- 参数 -->
<n-card size="small" title="参数">
<n-form
label-align="right"
label-placement="left"
label-width="auto"
:model="inputs"
>
<n-form-item label="文件大小:">
<n-input-group>
<n-input-number
v-model:value="inputs.sizeValue"
:precision="2"
:min="0"
:max="10000"
:step="1"
/>
<n-select
v-model:value="inputs.sizeUnit"
label-field="name"
value-field="name"
:options="units"
/>
</n-input-group>
</n-form-item>
<n-form-item label="已下载大小:">
<n-input-group>
<n-input-number
v-model:value="inputs.downloadedValue"
:precision="2"
:min="0"
:max="10000"
:step="1"
/>
<n-select
v-model:value="inputs.downloadedUnit"
label-field="name"
value-field="name"
:options="units"
/>
</n-input-group>
</n-form-item>
<n-form-item label="下载速度:">
<n-input-group>
<n-input-number
v-model:value="inputs.speedValue"
:precision="2"
:min="0"
:max="10000"
:step="1"
/>
<n-select
v-model:value="inputs.speedUnit"
label-field="speed"
value-field="name"
:options="units"
/>
</n-input-group>
</n-form-item>
</n-form>
</n-card>
<!-- 计算结果 -->
<n-card size="small" title="计算结果">
<n-form
label-align="right"
label-placement="left"
label-width="auto"
:model="outputs"
>
<n-form-item label="大约需要时长:">
<span>{{ outputs.duration || '未计算' }}</span>
</n-form-item>
<n-form-item label="大约结束时间:">
<span>{{ outputs.time || '未计算' }}</span>
</n-form-item>
</n-form>
</n-card>
</div>
</template> </template>
<script setup> <script setup>
import {
NCard, NForm, NFormItem,
NInputGroup, NInputNumber, NSelect,
} from 'naive-ui';
import {
reactive, ref,
watch,
} from 'vue';
import {
$message,
} from '@/assets/js/naive-ui';
import dayjs from 'dayjs';
/** 单位和比率(基于 KB */
const units = [
{ name: 'KiB', speed: 'KiB/s', rate: 1 },
{ name: 'MiB', speed: 'MiB/s', rate: 1024 },
{ name: 'GiB', speed: 'GiB/s', rate: 1048576 },
];
/** 参数 */
const inputs = reactive({
downloadedUnit: 'KiB',
downloadedValue: 0,
sizeUnit: 'KiB',
sizeValue: 0,
speedUnit: 'KiB',
speedValue: 0,
});
/** 计算结果 */
const outputs = reactive({
duration: '',
time: '',
});
/** 防抖定时器 */
const timer = ref(null);
/** 计算结果 */
function calc() {
let {
downloadedUnit, downloadedValue,
sizeUnit, sizeValue,
speedUnit, speedValue,
} = inputs;
if (sizeValue === 0 || speedValue === 0) {
outputs.duration = '';
outputs.time = '';
return;
}
// 获取转换比例
let downloadedRate = units[units.findIndex((obj) => {
return (obj.name === downloadedUnit);
})].rate;
let sizeRate = units[units.findIndex((obj) => {
return (obj.name === sizeUnit);
})].rate;
let speedRate = units[units.findIndex((obj) => {
return (obj.name === speedUnit);
})].rate;
// 转为 KB 单位
let realDownloaded = downloadedValue * downloadedRate;
let realSize = sizeValue * sizeRate - realDownloaded;
let realSpeed = speedValue * speedRate;
if (realSize < 0) {
$message.warning('参数有误,请检查');
return;
}
// 时长(秒)
let dSeconds = (realSize / realSpeed).toFixed(0);
// 起始时间
let timeStart = dayjs();
// 结束时间
let timeEnd = timeStart.add(dSeconds, 'second');
// 时长(天,整数)
let dDays = timeEnd.diff(timeStart, 'day');
// 最后一天的起始时间
let timeLastDay = timeStart.add(dDays, 'day');
// 时长(格式化,最后一天剩余)
let dLastDay = dayjs.duration(timeEnd.diff(timeLastDay)).format('HH 时 mm 分 ss 秒');
outputs.duration = `${dDays}${dLastDay}`;
outputs.time = timeEnd.format('YYYY-MM-DD HH:mm:ss');
}
// 自动计算
watch(inputs, () => {
clearTimeout(timer.value);
timer.value = setTimeout(() => {
calc();
}, 1000);
}, { deep: true });
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.tool-detail-page {
:deep(.n-input-number) {
width: 12em;
}
:deep(.n-select) {
width: 8em;
}
}
</style> </style>

View File

@@ -91,7 +91,7 @@ const routeTitle = computed(() => {
return route.meta.title; return route.meta.title;
}); });
/** /**
* @description 打开工具 * @description 打开工具
* @param {ToolboxItem} data * @param {ToolboxItem} data
*/ */
@@ -149,8 +149,25 @@ function handleOpenTool(data) {
position: absolute; position: absolute;
left: 0; left: 0;
top: 0; top: 0;
padding: 20px;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: #FFF; background-color: #FFF;
:deep(.tool-detail-page) {
width: 100%;
height: 100%;
overflow-y: auto;
> .n-card {
&:not(:first-child) {
margin-top: 20px;
}
.n-card__content {
padding-top: var(--n-padding-top);
}
}
}
} }
</style> </style>