Compare commits
6 Commits
855695bc13
...
383280031c
Author | SHA1 | Date | |
---|---|---|---|
383280031c | |||
bca8602a3a | |||
04c76dc347 | |||
d75232e5e0 | |||
ca27b2bbcc | |||
6486a90812 |
10
README.md
10
README.md
@@ -2,7 +2,15 @@
|
|||||||
|
|
||||||
## 简介
|
## 简介
|
||||||
|
|
||||||
一个多功能的网址导航,绿色无广告。
|
一个使用 Vue 3 开发的网站导航和工具箱,绿色无广告。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## 使用方法
|
## 使用方法
|
||||||
|
|
||||||
|
35
package.json
35
package.json
@@ -9,33 +9,34 @@
|
|||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
|
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
|
||||||
},
|
},
|
||||||
|
"packageManager": "pnpm@10.11.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@frost-utils/javascript": "^2.1.3",
|
"@frost-utils/javascript": "^2.1.3",
|
||||||
"@mdi/font": "^7.4.47",
|
"@mdi/font": "^7.4.47",
|
||||||
"@vueuse/core": "^12.5.0",
|
"@vueuse/core": "^13.3.0",
|
||||||
"axios": "^1.7.9",
|
"axios": "^1.9.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"highlight.js": "^11.11.1",
|
"highlight.js": "^11.11.1",
|
||||||
"lunisolar": "^2.5.1",
|
"lunisolar": "^2.5.2",
|
||||||
"mathjs": "^14.2.0",
|
"mathjs": "^14.5.2",
|
||||||
"naive-ui": "^2.41.0",
|
"naive-ui": "^2.41.0",
|
||||||
"radash": "^12.1.0",
|
"radash": "^12.1.0",
|
||||||
"uuid": "^11.0.5",
|
"uuid": "^11.1.0",
|
||||||
"vue": "^3.5.13",
|
"vue": "^3.5.16",
|
||||||
"vue-router": "^4.5.0",
|
"vue-router": "^4.5.1",
|
||||||
"zxing-wasm": "^2.0.1"
|
"zxing-wasm": "^2.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tsconfig/node20": "^20.1.4",
|
"@tsconfig/node20": "^20.1.5",
|
||||||
"@types/node": "^20.17.16",
|
"@types/node": "^20.17.57",
|
||||||
"@types/uuid": "^10.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"@vitejs/plugin-legacy": "^6.0.0",
|
"@vitejs/plugin-legacy": "^6.1.1",
|
||||||
"@vitejs/plugin-vue": "^5.2.1",
|
"@vitejs/plugin-vue": "^5.2.4",
|
||||||
"@vitejs/plugin-vue-jsx": "^4.1.1",
|
"@vitejs/plugin-vue-jsx": "~4.1.2",
|
||||||
"@vue/tsconfig": "^0.7.0",
|
"@vue/tsconfig": "^0.7.0",
|
||||||
"eslint": "^9.19.0",
|
"eslint": "^9.28.0",
|
||||||
"eslint-plugin-vue": "^9.32.0",
|
"eslint-plugin-vue": "^9.33.0",
|
||||||
"less": "^4.2.2",
|
"less": "^4.3.0",
|
||||||
"vite": "^6.0.11"
|
"vite": "^6.3.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2514
pnpm-lock.yaml
generated
2514
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
3
pnpm-workspace.yaml
Normal file
3
pnpm-workspace.yaml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
onlyBuiltDependencies:
|
||||||
|
- core-js
|
||||||
|
- esbuild
|
@@ -1,2 +1,2 @@
|
|||||||
zxing_full.wasm
|
zxing_full.wasm
|
||||||
zxing-wasm v2.0.1
|
zxing-wasm v2.1.2
|
||||||
|
Binary file not shown.
BIN
screenshots/image_01.png
Normal file
BIN
screenshots/image_01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 26 KiB |
BIN
screenshots/image_02.png
Normal file
BIN
screenshots/image_02.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 87 KiB |
BIN
screenshots/image_03.png
Normal file
BIN
screenshots/image_03.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 78 KiB |
BIN
screenshots/image_04.png
Normal file
BIN
screenshots/image_04.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 77 KiB |
@@ -122,7 +122,8 @@ function initCssVars() {
|
|||||||
'--color-green': 'var(--color-success)',
|
'--color-green': 'var(--color-success)',
|
||||||
'--color-blue': 'var(--color-info)',
|
'--color-blue': 'var(--color-info)',
|
||||||
'--color-orange': 'var(--color-warning)',
|
'--color-orange': 'var(--color-warning)',
|
||||||
// 滚动条大小
|
// 元素大小
|
||||||
|
'--dialog-content-max-height': 'calc(100vh - 160px)',
|
||||||
'--scrollbar-size': '8px',
|
'--scrollbar-size': '8px',
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -265,6 +266,11 @@ html {
|
|||||||
|
|
||||||
// -- Naive UI --
|
// -- Naive UI --
|
||||||
|
|
||||||
|
.n-dialog-content--with-max-height {
|
||||||
|
max-height: var(--dialog-content-max-height);
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.n-drawer--right-placement {
|
.n-drawer--right-placement {
|
||||||
.n-drawer-body {
|
.n-drawer-body {
|
||||||
height: 0;
|
height: 0;
|
||||||
|
@@ -3,19 +3,19 @@
|
|||||||
import { useLocalStorage } from '@vueuse/core';
|
import { useLocalStorage } from '@vueuse/core';
|
||||||
|
|
||||||
/** 本地储存 key 前缀 */
|
/** 本地储存 key 前缀 */
|
||||||
const PREFIX = 'frost-navigation/';
|
export const KEY_PREFIX = 'frost-navigation/';
|
||||||
|
|
||||||
/** NavView 模块 */
|
/** NavView 模块 */
|
||||||
export const storeNavView = {
|
export const storeNavView = {
|
||||||
|
|
||||||
/** 导航链接侧边栏折叠状态 */
|
/** 导航链接侧边栏折叠状态 */
|
||||||
isAsideCollapsed: useLocalStorage(PREFIX + 'nav-view/is-aside-collapsed', false),
|
isAsideCollapsed: useLocalStorage(KEY_PREFIX + 'nav-view/isAsideCollapsed', false),
|
||||||
|
|
||||||
/** 导航链接当前选中分类 */
|
/** 导航链接当前选中分类 */
|
||||||
currentCategory: useLocalStorage(PREFIX + 'nav-view/current-category', ''),
|
currentCategory: useLocalStorage(KEY_PREFIX + 'nav-view/currentCategory', ''),
|
||||||
|
|
||||||
/** 导航链接搜索类型 */
|
/** 导航链接搜索类型 */
|
||||||
searchType: useLocalStorage(PREFIX + 'nav-view/search-type', 'all'),
|
searchType: useLocalStorage(KEY_PREFIX + 'nav-view/searchType', 'all'),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -23,6 +23,6 @@ export const storeNavView = {
|
|||||||
export const storeSearchView = {
|
export const storeSearchView = {
|
||||||
|
|
||||||
/** 当前使用的搜索引擎名称 */
|
/** 当前使用的搜索引擎名称 */
|
||||||
searchEngineName: useLocalStorage(PREFIX + 'search-view/search-engine-name', '必应'),
|
searchEngineName: useLocalStorage(KEY_PREFIX + 'search-view/searchEngineName', '必应'),
|
||||||
|
|
||||||
};
|
};
|
||||||
|
15
src/assets/js/toolbox-changelogs.js
Normal file
15
src/assets/js/toolbox-changelogs.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/** 工具更新日志 */
|
||||||
|
export const CHANGE_LOGS = {
|
||||||
|
'json-formatter': [
|
||||||
|
'[2] - 2025-02-07\n优化“输出内容”显示样式,解决内容较多时行号显示不全的问题。',
|
||||||
|
'[1] - 2025-02-04\n初始版本。',
|
||||||
|
],
|
||||||
|
'keep-screen-on': [
|
||||||
|
'[2] - 2024-10-13\n优化界面样式,背景添加圆角。',
|
||||||
|
'[1] - 2024-10-11\n初始版本。',
|
||||||
|
],
|
||||||
|
'qrcode-reader-and-generator': [
|
||||||
|
'[2] - 2025-02-23\n支持生成二维码。\n支持解析剪贴板中的二维码图片。\n优化解析功能,在二维码所在位置添加矩形标记。',
|
||||||
|
'[1] - 2025-02-21\n初始版本。',
|
||||||
|
],
|
||||||
|
};
|
@@ -1,5 +1,7 @@
|
|||||||
// 工具箱
|
// 工具箱
|
||||||
|
|
||||||
|
import { CHANGE_LOGS } from './toolbox-changelogs';
|
||||||
|
|
||||||
const MODULES = import.meta.glob('../../views/ToolboxView/**/*.vue');
|
const MODULES = import.meta.glob('../../views/ToolboxView/**/*.vue');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,6 +86,7 @@ export const toolList = [
|
|||||||
updatedAt: '2025-02-23',
|
updatedAt: '2025-02-23',
|
||||||
version: '2',
|
version: '2',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
changelogs: CHANGE_LOGS['qrcode-reader-and-generator'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'convert-text-structure',
|
id: 'convert-text-structure',
|
||||||
@@ -135,6 +138,7 @@ export const toolList = [
|
|||||||
updatedAt: '2025-02-07',
|
updatedAt: '2025-02-07',
|
||||||
version: '2',
|
version: '2',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
changelogs: CHANGE_LOGS['json-formatter'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -273,6 +277,7 @@ export const toolList = [
|
|||||||
updatedAt: '2024-10-13',
|
updatedAt: '2024-10-13',
|
||||||
version: '2',
|
version: '2',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
changelogs: CHANGE_LOGS['keep-screen-on'],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'open-new-window',
|
id: 'open-new-window',
|
||||||
@@ -307,6 +312,17 @@ export const toolList = [
|
|||||||
version: '1',
|
version: '1',
|
||||||
enabled: true,
|
enabled: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'visualized-working-hours',
|
||||||
|
component: 'Other/VisualizedWorkingHours/VisualizedWorkingHours',
|
||||||
|
title: '工作时间可视化',
|
||||||
|
iconClass: 'mdi mdi-clock-digital',
|
||||||
|
desc: '用趣味化的方式呈现工作收益与时间进度,让薪资进度和下班期待看得见。',
|
||||||
|
createdAt: '',
|
||||||
|
updatedAt: '',
|
||||||
|
version: '0',
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@@ -0,0 +1,243 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tool-detail-page">
|
||||||
|
|
||||||
|
<!-- 配置选项 -->
|
||||||
|
<n-card size="small" style="--color: #2196F3;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-title">
|
||||||
|
<span class="card-title__icon mdi mdi-cog-outline"></span>
|
||||||
|
<span class="card-title__label">配置选项</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<n-form
|
||||||
|
class="form-no-feedback config-inputs"
|
||||||
|
label-align="right"
|
||||||
|
label-placement="left"
|
||||||
|
label-width="auto"
|
||||||
|
>
|
||||||
|
|
||||||
|
<n-form-item label="日薪">
|
||||||
|
<n-input-number
|
||||||
|
v-model:value="configData.dailyWage.value"
|
||||||
|
:min="0"
|
||||||
|
:max="99999999"
|
||||||
|
:precision="2"
|
||||||
|
:step="1"
|
||||||
|
></n-input-number>
|
||||||
|
</n-form-item>
|
||||||
|
|
||||||
|
<n-form-item label="收入币种">
|
||||||
|
<n-input
|
||||||
|
v-model:value="configData.currencyOfIncome.value"
|
||||||
|
placeholder="用于显示,例如:¥"
|
||||||
|
type="text"
|
||||||
|
:maxlength="8"
|
||||||
|
></n-input>
|
||||||
|
</n-form-item>
|
||||||
|
|
||||||
|
<n-form-item label="工作时间">
|
||||||
|
<n-input-group>
|
||||||
|
<n-time-picker
|
||||||
|
v-model:formatted-value="configData.workTimeStart.value"
|
||||||
|
format="HH:mm"
|
||||||
|
/>
|
||||||
|
<n-time-picker
|
||||||
|
v-model:formatted-value="configData.workTimeStop.value"
|
||||||
|
format="HH:mm"
|
||||||
|
/>
|
||||||
|
</n-input-group>
|
||||||
|
</n-form-item>
|
||||||
|
|
||||||
|
</n-form>
|
||||||
|
</n-card>
|
||||||
|
|
||||||
|
<!-- 实时进度 -->
|
||||||
|
<n-card size="small" style="--color: #F44336;">
|
||||||
|
|
||||||
|
<template #header>
|
||||||
|
<div class="card-title">
|
||||||
|
<span class="card-title__icon mdi mdi-chart-line"></span>
|
||||||
|
<span class="card-title__label">实时进度</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="progress-item">
|
||||||
|
<div class="progress-item__row">
|
||||||
|
<span>本月已赚</span>
|
||||||
|
<span>1000 ¥</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress-item__row">
|
||||||
|
<n-progress
|
||||||
|
color="var(--color)"
|
||||||
|
type="line"
|
||||||
|
:height="16"
|
||||||
|
:percentage="35"
|
||||||
|
:processing="true"
|
||||||
|
:show-indicator="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="progress-item__row">
|
||||||
|
<span>35%</span>
|
||||||
|
<span>剩余 20.5 天</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="progress-item">
|
||||||
|
<div class="progress-item__row">
|
||||||
|
<span>今日已赚</span>
|
||||||
|
<span>100 ¥</span>
|
||||||
|
</div>
|
||||||
|
<div class="progress-item__row">
|
||||||
|
<n-progress
|
||||||
|
color="var(--color)"
|
||||||
|
type="line"
|
||||||
|
:height="16"
|
||||||
|
:percentage="60"
|
||||||
|
:processing="true"
|
||||||
|
:show-indicator="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="progress-item__row">
|
||||||
|
<span>60%</span>
|
||||||
|
<span>剩余 5.6 小时</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</n-card>
|
||||||
|
|
||||||
|
<!-- 下班冲刺 -->
|
||||||
|
<n-card size="small" style="--color: #4CAF50;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-title">
|
||||||
|
<span class="card-title__icon mdi mdi-clock-outline"></span>
|
||||||
|
<span class="card-title__label">下班冲刺</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div class="time-info">
|
||||||
|
<div class="time-info__row">
|
||||||
|
<span>距离下班还剩</span>
|
||||||
|
</div>
|
||||||
|
<div class="time-info__row">
|
||||||
|
<span>05:30:20</span>
|
||||||
|
</div>
|
||||||
|
<div class="time-info__row">
|
||||||
|
<span>漫长的一天才过一半,加油吧!</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</n-card>
|
||||||
|
|
||||||
|
<!-- 获得成就 -->
|
||||||
|
<!-- <n-card size="small" style="--color: #FF9800;">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-title">
|
||||||
|
<span class="card-title__icon mdi mdi-trophy-outline"></span>
|
||||||
|
<span class="card-title__label">获得成就</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</n-card> -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
NButton, NCard, NForm, NFormItem,
|
||||||
|
NInput, NInputGroup, NInputNumber,
|
||||||
|
NProgress, NTimePicker,
|
||||||
|
} from 'naive-ui';
|
||||||
|
|
||||||
|
import {
|
||||||
|
onBeforeMount,
|
||||||
|
} from 'vue';
|
||||||
|
|
||||||
|
import {
|
||||||
|
configData, initData,
|
||||||
|
} from './data';
|
||||||
|
|
||||||
|
onBeforeMount(() => {
|
||||||
|
initData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.card-title > span {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title__icon {
|
||||||
|
color: var(--color, #252525);
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-title__label {
|
||||||
|
margin-left: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.config-inputs {
|
||||||
|
.n-form-item {
|
||||||
|
max-width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.n-form-item-blank) > * {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.n-input-group) > * {
|
||||||
|
flex-grow: 1;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-item :not(:first-child) {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-item__row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
&:not(:first-child) {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child, &:last-child {
|
||||||
|
color: #505050;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child span:last-child {
|
||||||
|
color: var(--color);
|
||||||
|
font-size: 1.2em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-info {
|
||||||
|
padding: 16px 0;
|
||||||
|
background-color: var(--color-action);
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-info__row {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:first-child, &:last-child {
|
||||||
|
color: #505050;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
font-size: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(3) {
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
50
src/views/ToolboxView/Other/VisualizedWorkingHours/data.js
Normal file
50
src/views/ToolboxView/Other/VisualizedWorkingHours/data.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { useLocalStorage } from '@vueuse/core';
|
||||||
|
import { KEY_PREFIX } from '@/assets/js/local-storage';
|
||||||
|
|
||||||
|
/** 模块名称 */
|
||||||
|
const STORAGE_PREFIX = KEY_PREFIX + 'visualized-working-hours/';
|
||||||
|
|
||||||
|
/** 配置选项 */
|
||||||
|
export const configData = {
|
||||||
|
|
||||||
|
/** 收入币种 */
|
||||||
|
currencyOfIncome: useLocalStorage(STORAGE_PREFIX + 'currencyOfIncome', ''),
|
||||||
|
|
||||||
|
/** 日薪 */
|
||||||
|
dailyWage: useLocalStorage(STORAGE_PREFIX + 'dailyWage', 100),
|
||||||
|
|
||||||
|
/** 午休时长 */
|
||||||
|
lunchBreakDuration: useLocalStorage(STORAGE_PREFIX + 'lunchBreakDuration', 1),
|
||||||
|
|
||||||
|
/** 工作开始时间 */
|
||||||
|
workTimeStart: useLocalStorage(STORAGE_PREFIX + 'workTimeStart', ''),
|
||||||
|
|
||||||
|
/** 工作结束时间 */
|
||||||
|
workTimeStop: useLocalStorage(STORAGE_PREFIX + 'workTimeStop', ''),
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 初始化数据 */
|
||||||
|
export function initData() {
|
||||||
|
|
||||||
|
let {
|
||||||
|
currencyOfIncome,
|
||||||
|
workTimeStart,
|
||||||
|
workTimeStop,
|
||||||
|
} = configData;
|
||||||
|
|
||||||
|
let timeRegExp = new RegExp(/^\d{2}:\d{2}$/);
|
||||||
|
|
||||||
|
if (!currencyOfIncome.value) {
|
||||||
|
currencyOfIncome.value = '¥';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!workTimeStart.value.match(timeRegExp)) {
|
||||||
|
workTimeStart.value = '09:00';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!workTimeStop.value.match(timeRegExp)) {
|
||||||
|
workTimeStop.value = '18:00';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -5,7 +5,7 @@
|
|||||||
<!-- 返回上一级 -->
|
<!-- 返回上一级 -->
|
||||||
<n-button
|
<n-button
|
||||||
v-show="isToolDetail"
|
v-show="isToolDetail"
|
||||||
class="back-button"
|
class="header-button"
|
||||||
:text="true"
|
:text="true"
|
||||||
@click="handleCloseTool"
|
@click="handleCloseTool"
|
||||||
>
|
>
|
||||||
@@ -18,10 +18,20 @@
|
|||||||
<!-- 占位 -->
|
<!-- 占位 -->
|
||||||
<div class="placeholder"></div>
|
<div class="placeholder"></div>
|
||||||
|
|
||||||
|
<!-- 查看信息 -->
|
||||||
|
<n-button
|
||||||
|
v-show="isToolDetail"
|
||||||
|
class="header-button"
|
||||||
|
:text="true"
|
||||||
|
@click="showToolItemInfo"
|
||||||
|
>
|
||||||
|
<span class="mdi mdi-information-slab-circle-outline"></span>
|
||||||
|
</n-button>
|
||||||
|
|
||||||
<!-- 新窗口打开 -->
|
<!-- 新窗口打开 -->
|
||||||
<n-button
|
<n-button
|
||||||
v-show="isToolDetail"
|
v-show="isToolDetail"
|
||||||
class="back-button"
|
class="header-button"
|
||||||
:text="true"
|
:text="true"
|
||||||
@click="handleOpenNewWindow"
|
@click="handleOpenNewWindow"
|
||||||
>
|
>
|
||||||
@@ -89,17 +99,47 @@
|
|||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 工具信息 -->
|
||||||
|
<n-modal
|
||||||
|
v-model:show="toolInfo.show"
|
||||||
|
content-class="n-dialog-content--with-max-height"
|
||||||
|
preset="dialog"
|
||||||
|
title="工具信息"
|
||||||
|
:show-icon="false"
|
||||||
|
>
|
||||||
|
<template v-if="true">
|
||||||
|
<n-h4>版本信息</n-h4>
|
||||||
|
<n-ul>
|
||||||
|
<n-li>创建日期:{{ toolInfo.dateCreated }}</n-li>
|
||||||
|
<n-li>更新日期:{{ toolInfo.dateUpdated }}</n-li>
|
||||||
|
<n-li>当前版本:{{ toolInfo.currVersion }}</n-li>
|
||||||
|
</n-ul>
|
||||||
|
</template>
|
||||||
|
<template v-if="toolInfo.changelogs.length > 0">
|
||||||
|
<n-h4>更新日志</n-h4>
|
||||||
|
<n-ul>
|
||||||
|
<n-li
|
||||||
|
v-for="(text, index) in toolInfo.changelogs"
|
||||||
|
:key="index"
|
||||||
|
class="changelogs-row"
|
||||||
|
>{{ text }}</n-li>
|
||||||
|
</n-ul>
|
||||||
|
</template>
|
||||||
|
</n-modal>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import {
|
||||||
NButton, NCollapse, NCollapseItem, NEllipsis, NTooltip,
|
NButton, NCollapse, NCollapseItem,
|
||||||
|
NEllipsis, NModal, NTooltip,
|
||||||
|
NH4, NUl, NLi,
|
||||||
} from 'naive-ui';
|
} from 'naive-ui';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
computed,
|
computed, reactive,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -112,7 +152,7 @@ import {
|
|||||||
|
|
||||||
/** 是否为工具页面 */
|
/** 是否为工具页面 */
|
||||||
const isToolDetail = computed(() => {
|
const isToolDetail = computed(() => {
|
||||||
return route.meta.isToolDetail;
|
return Boolean(route.meta.isToolDetail);
|
||||||
});
|
});
|
||||||
|
|
||||||
/** 路由 */
|
/** 路由 */
|
||||||
@@ -126,6 +166,15 @@ const routeTitle = computed(() => {
|
|||||||
return route.meta.title;
|
return route.meta.title;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** 工具信息 */
|
||||||
|
const toolInfo = reactive({
|
||||||
|
changelogs: [],
|
||||||
|
currVersion: '',
|
||||||
|
dateCreated: '',
|
||||||
|
dateUpdated: '',
|
||||||
|
show: false,
|
||||||
|
});
|
||||||
|
|
||||||
/** 关闭工具 */
|
/** 关闭工具 */
|
||||||
function handleCloseTool() {
|
function handleCloseTool() {
|
||||||
return router.push({
|
return router.push({
|
||||||
@@ -154,10 +203,53 @@ function handleOpenTool(data) {
|
|||||||
name: `Toolbox/${data.component}`,
|
name: `Toolbox/${data.component}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 查看当前工具信息 */
|
||||||
|
function showToolItemInfo() {
|
||||||
|
|
||||||
|
let routePath = route.path;
|
||||||
|
let toolIdMatch = routePath.match(/\/([^/]*)$/);
|
||||||
|
let toolIdStr = toolIdMatch ? toolIdMatch[1] : null;
|
||||||
|
let toolItem = null;
|
||||||
|
|
||||||
|
if (toolIdStr) {
|
||||||
|
for (let i = 0; i < toolList.length; i++) {
|
||||||
|
|
||||||
|
let category = toolList[i];
|
||||||
|
let list = category.items;
|
||||||
|
|
||||||
|
if (!category.enabled || !list) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let j = 0; j < list.length; j++) {
|
||||||
|
let item = list[j];
|
||||||
|
if (item.id === toolIdStr) {
|
||||||
|
toolItem = item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toolItem) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (toolItem) {
|
||||||
|
toolInfo.changelogs = toolItem.changelogs || [];
|
||||||
|
toolInfo.currVersion = toolItem.version || '';
|
||||||
|
toolInfo.dateCreated = toolItem.createdAt || '';
|
||||||
|
toolInfo.dateUpdated = toolItem.updatedAt || '';
|
||||||
|
toolInfo.show = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.back-button {
|
.header-button {
|
||||||
margin-right: 0.5em;
|
margin-right: 0.5em;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
@@ -243,4 +335,8 @@ function handleOpenTool(data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.changelogs-row {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
2
types/web.d.ts
vendored
2
types/web.d.ts
vendored
@@ -65,6 +65,8 @@ declare global {
|
|||||||
version: string;
|
version: string;
|
||||||
/** 是否启用 */
|
/** 是否启用 */
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
/** 更新日志 */
|
||||||
|
changelogs: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
// window
|
// window
|
||||||
|
Reference in New Issue
Block a user