feat: 添加头文件信息,添加图床工具。
This commit is contained in:
1 parent
f8fba79d55
commit
fda826a272
12 files changed
+515
-13
No files matched your search
@@ -18,7 +18,7 @@ import "/style/default.scss";
|
||||
useHead({
|
||||
title: '杪 Blog',
|
||||
meta: [
|
||||
{ name: 'description', content: '杪儿的博客' }
|
||||
{ name: 'description', content: '杪儿的博客', lang: 'zh-CN' }
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<template><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512"><rect x="128" y="128" width="336" height="336" rx="57" ry="57" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32"></rect><path d="M383.5 128l.5-24a56.16 56.16 0 0 0-56-56H112a64.19 64.19 0 0 0-64 64v216a56.16 56.16 0 0 0 56 56h24" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"></path></svg></template>
|
||||
@@ -0,0 +1 @@
|
||||
<template><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 512 512"><path d="M320 367.79h76c55 0 100-29.21 100-83.6s-53-81.47-96-83.6c-8.89-85.06-71-136.8-144-136.8c-69 0-113.44 45.79-128 91.2c-60 5.7-112 43.88-112 106.4s54 106.4 120 106.4h56" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"></path><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M320 255.79l-64-64l-64 64"></path><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M256 448.21V207.79"></path></svg></template>
|
||||
@@ -24,6 +24,7 @@
|
||||
"node-fetch": "^3.3.2",
|
||||
"nuxt": "^3.15.1",
|
||||
"pinia": "^2.3.0",
|
||||
"qrcode": "^1.5.4",
|
||||
"unplugin-auto-import": "^19.0.0",
|
||||
"unplugin-vue-components": "^28.0.0",
|
||||
"vue": "^3.4.21",
|
||||
@@ -44,6 +45,7 @@
|
||||
"@types/better-sqlite3": "^7.6.12",
|
||||
"@types/jsonwebtoken": "^9.0.7",
|
||||
"@types/markdown-it": "^14.1.2",
|
||||
"@types/qrcode": "^1.5.5",
|
||||
"element-plus": "^2.9.3",
|
||||
"sass": "^1.83.1",
|
||||
"vite-plugin-mkcert": "^1.17.6"
|
||||
|
||||
+15
-1
@@ -91,8 +91,12 @@ const PageContent = reactive<PageContent[]>([
|
||||
},
|
||||
{
|
||||
name: 'MiaoBlog',
|
||||
description: '施工中,不过不要抱有太大期待',
|
||||
description: '施工中,不过最好不要抱有太大期待,毕竟还是以实现功能为目标去做的',
|
||||
links: [
|
||||
{
|
||||
name: "gitea",
|
||||
url: "https://nj.miaospring.top:3001/539943419/miaoBlog.git"
|
||||
},
|
||||
{
|
||||
name: "github",
|
||||
url: "https://github.com/Zioywishing/miaoBlog"
|
||||
@@ -134,6 +138,16 @@ const PageContent = reactive<PageContent[]>([
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '喵喵图床',
|
||||
description: '其实就是一个很简陋的图床,上传,下载,没了',
|
||||
nuxtLinks: [
|
||||
{
|
||||
name: 'link',
|
||||
to: `/tools/imgBed`
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
}, {
|
||||
subTitle: '学习资料',
|
||||
|
||||
@@ -0,0 +1,196 @@
|
||||
<template>
|
||||
<div class="imgBed-wrapper">
|
||||
<div class="imgBed-wrapper-upload">
|
||||
<el-upload class="imgBed-wrapper-upload-el" :auto-upload="false" v-model="fileList"
|
||||
action="/api/tools/imgBed/upload" ref="uploadRef" :headers="headers" drag :data="data"
|
||||
@success="handleSuccess">
|
||||
<template #trigger>
|
||||
<div class="imgBed-upload">
|
||||
<upload class="imgBed-upload-icon"></upload>
|
||||
<el-text style="margin: 0;">拖拽 图片 至此<br />或单击此处选择文件</el-text>
|
||||
</div>
|
||||
</template>
|
||||
</el-upload>
|
||||
<el-row>
|
||||
<el-col :span="17">
|
||||
<el-input v-model="expire" placeholder="有效期(小时)" style="width: 100%;">
|
||||
<template #prepend>过期时间(小时)</template>
|
||||
</el-input>
|
||||
</el-col>
|
||||
<el-col :span="7" class="flex-end">
|
||||
<el-button type="primary" @click="handleUpload">
|
||||
点击上传图片
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-table :data="tableData" style="width: 100%">
|
||||
<el-table-column show-overflow-tooltip prop="name" label="文件名" />
|
||||
<el-table-column prop="expire" label="过期时间" width="180" />
|
||||
<el-table-column fixed="right" prop="share" label="操作" width="180">
|
||||
<template #default="scoped">
|
||||
<el-button link type="primary" size="small" @click="handleDownload(scoped.row)">
|
||||
下载
|
||||
</el-button>
|
||||
<el-button link type="primary" size="small" @click="handleShare(scoped.row)">分享</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-dialog v-model="showShareDialog" title="分享链接">
|
||||
<div style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
|
||||
<img :src="shareDialogData.img" alt="shareQRCodeBase64" />
|
||||
<div style="max-width: 80%;">
|
||||
<span>{{ shareDialogData.url }}</span>
|
||||
<span>
|
||||
<copy style="width: 15px; margin-left: 4px; transform: translateY(3px); cursor: pointer;" @click="handleCopyUrl(shareDialogData.url)"></copy>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { UploadInstance } from 'element-plus';
|
||||
import upload from '~/components/icons/upload.vue';
|
||||
import copy from '~/components/icons/copy.vue';
|
||||
// @ts-ignore
|
||||
import QRCode from 'qrcode'
|
||||
|
||||
const fileList = ref([])
|
||||
const headers = reactive({
|
||||
Authorization: ``
|
||||
})
|
||||
const uploadRef = ref<UploadInstance>()
|
||||
|
||||
const tableData = reactive<{
|
||||
name: string;
|
||||
expire: string;
|
||||
hash: string;
|
||||
}[]>([])
|
||||
|
||||
const showShareDialog = ref(false)
|
||||
|
||||
const shareDialogData = ref({
|
||||
img: '',
|
||||
url: '',
|
||||
})
|
||||
|
||||
const expire = ref(1)
|
||||
|
||||
const data = computed(() => {
|
||||
return {
|
||||
expire: expire.value * 3600 * 1000
|
||||
}
|
||||
})
|
||||
|
||||
const handleUpload = () => {
|
||||
uploadRef.value!.submit()
|
||||
}
|
||||
|
||||
const handleSuccess = (res: {
|
||||
code: number;
|
||||
fileName: string;
|
||||
expire: number;
|
||||
hash: string;
|
||||
fileSize: number;
|
||||
}) => {
|
||||
if (res.code === 200) {
|
||||
const data = {
|
||||
name: res.fileName,
|
||||
expire: formatDate(new Date(Number(res.expire)), 'yyyy-MM-dd HH:mm:ss'),
|
||||
expireDate: Number(res.expire),
|
||||
hash: res.hash,
|
||||
}
|
||||
tableData.push(data)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDownload = (row: {
|
||||
name: string;
|
||||
hash: string;
|
||||
}) => {
|
||||
const url = `/api/tools/imgBed/download/${row.hash}`
|
||||
const a = document.createElement('a')
|
||||
a.download = row.name
|
||||
a.href = url
|
||||
a.click()
|
||||
}
|
||||
|
||||
const handleShare = async (row: {
|
||||
name: string;
|
||||
hash: string;
|
||||
}) => {
|
||||
const url = `${location.origin}/api/tools/imgBed/download/${row.hash}`
|
||||
const data = await QRCode.toDataURL(url)
|
||||
shareDialogData.value = {
|
||||
img: data,
|
||||
url: url,
|
||||
}
|
||||
showShareDialog.value = true
|
||||
}
|
||||
|
||||
const handleCopyUrl = async (url: string) => {
|
||||
await navigator.clipboard.writeText(url)
|
||||
ElMessage.success('复制成功')
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const record = localStorage.getItem('miaoTool-imgBed-uploadRecord')
|
||||
if (record) {
|
||||
let _record = JSON.parse(record)
|
||||
// console.log({ _record, record })
|
||||
_record = _record.filter((item: { expireDate: number }) => {
|
||||
return item.expireDate && item.expireDate > Date.now()
|
||||
})
|
||||
tableData.push(..._record)
|
||||
}
|
||||
|
||||
watchEffect(() => {
|
||||
localStorage.setItem('miaoTool-imgBed-uploadRecord', JSON.stringify(tableData))
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.imgBed-wrapper {
|
||||
// box-sizing: border-box;
|
||||
position: relative;
|
||||
margin: 0 20px;
|
||||
padding: 20px 0 0 0;
|
||||
width: 100%;
|
||||
// height: calc(100vh - 60px);
|
||||
// max-height: calc(100vh - 60px);
|
||||
max-width: 800px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
&-upload {
|
||||
width: 95%;
|
||||
|
||||
&-el {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.imgBed-upload {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 5px;
|
||||
|
||||
&-icon {
|
||||
display: block;
|
||||
width: 45px;
|
||||
color: #595959;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flex-end {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
Generated
+158
@@ -50,6 +50,9 @@ importers:
|
||||
pinia:
|
||||
specifier: ^2.3.0
|
||||
version: 2.3.0(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
|
||||
qrcode:
|
||||
specifier: ^1.5.4
|
||||
version: 1.5.4
|
||||
unplugin-auto-import:
|
||||
specifier: ^19.0.0
|
||||
version: 19.0.0(@nuxt/kit@3.15.1(magicast@0.3.5)(rollup@4.30.1))(@vueuse/core@9.13.0(vue@3.5.13(typescript@5.7.3)))(rollup@4.30.1)
|
||||
@@ -105,6 +108,9 @@ importers:
|
||||
'@types/markdown-it':
|
||||
specifier: ^14.1.2
|
||||
version: 14.1.2
|
||||
'@types/qrcode':
|
||||
specifier: ^1.5.5
|
||||
version: 1.5.5
|
||||
element-plus:
|
||||
specifier: ^2.9.3
|
||||
version: 2.9.3(vue@3.5.13(typescript@5.7.3))
|
||||
@@ -1172,6 +1178,9 @@ packages:
|
||||
'@types/parse-path@7.0.3':
|
||||
resolution: {integrity: sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg==}
|
||||
|
||||
'@types/qrcode@1.5.5':
|
||||
resolution: {integrity: sha512-CdfBi/e3Qk+3Z/fXYShipBT13OJ2fDO2Q2w5CIP5anLTLIndQG9z6P1cnm+8zCWSpm5dnxMFd/uREtb0EXuQzg==}
|
||||
|
||||
'@types/resolve@1.20.2':
|
||||
resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==}
|
||||
|
||||
@@ -1466,6 +1475,10 @@ packages:
|
||||
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
camelcase@5.3.1:
|
||||
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
caniuse-api@3.0.0:
|
||||
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
|
||||
|
||||
@@ -1505,6 +1518,9 @@ packages:
|
||||
resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
cliui@6.0.0:
|
||||
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
|
||||
|
||||
cliui@8.0.1:
|
||||
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1699,6 +1715,10 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
decamelize@1.2.0:
|
||||
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
decompress-response@6.0.0:
|
||||
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -1768,6 +1788,9 @@ packages:
|
||||
resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==}
|
||||
engines: {node: '>=0.3.1'}
|
||||
|
||||
dijkstrajs@1.0.3:
|
||||
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
|
||||
|
||||
@@ -1932,6 +1955,10 @@ packages:
|
||||
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
find-up@4.1.0:
|
||||
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
flatted@3.3.2:
|
||||
resolution: {integrity: sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==}
|
||||
|
||||
@@ -2310,6 +2337,10 @@ packages:
|
||||
resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
locate-path@5.0.0:
|
||||
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
lodash-es@4.17.21:
|
||||
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
|
||||
|
||||
@@ -2647,6 +2678,18 @@ packages:
|
||||
peerDependencies:
|
||||
typescript: ^5.x
|
||||
|
||||
p-limit@2.3.0:
|
||||
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
p-locate@4.1.0:
|
||||
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
p-try@2.2.0:
|
||||
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
package-json-from-dist@1.0.1:
|
||||
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
|
||||
|
||||
@@ -2675,6 +2718,10 @@ packages:
|
||||
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
path-exists@4.0.0:
|
||||
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
path-is-absolute@1.0.1:
|
||||
resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -2734,6 +2781,10 @@ packages:
|
||||
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
pngjs@5.0.0:
|
||||
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
|
||||
postcss-calc@10.1.0:
|
||||
resolution: {integrity: sha512-uQ/LDGsf3mgsSUEXmAt3VsCSHR3aKqtEIkmB+4PhzYwRYOW5MZs/GhCCFpsOtJJkP6EC6uGipbrnaTjqaJZcJw==}
|
||||
engines: {node: ^18.12 || ^20.9 || >=22.0}
|
||||
@@ -2944,6 +2995,11 @@ packages:
|
||||
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
qrcode@1.5.4:
|
||||
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
hasBin: true
|
||||
|
||||
queue-microtask@1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
@@ -3005,6 +3061,9 @@ packages:
|
||||
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
require-main-filename@2.0.0:
|
||||
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
|
||||
|
||||
resolve-from@5.0.0:
|
||||
resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -3087,6 +3146,9 @@ packages:
|
||||
resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==}
|
||||
engines: {node: '>= 0.8.0'}
|
||||
|
||||
set-blocking@2.0.0:
|
||||
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
|
||||
|
||||
setprototypeof@1.2.0:
|
||||
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
|
||||
|
||||
@@ -3682,6 +3744,9 @@ packages:
|
||||
whatwg-url@5.0.0:
|
||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||
|
||||
which-module@2.0.1:
|
||||
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
|
||||
|
||||
which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
engines: {node: '>= 8'}
|
||||
@@ -3692,6 +3757,10 @@ packages:
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
hasBin: true
|
||||
|
||||
wrap-ansi@6.2.0:
|
||||
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -3715,6 +3784,9 @@ packages:
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
y18n@4.0.3:
|
||||
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
|
||||
|
||||
y18n@5.0.8:
|
||||
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -3737,10 +3809,18 @@ packages:
|
||||
engines: {node: '>= 14'}
|
||||
hasBin: true
|
||||
|
||||
yargs-parser@18.1.3:
|
||||
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
yargs-parser@21.1.1:
|
||||
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
yargs@15.4.1:
|
||||
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
yargs@17.7.2:
|
||||
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -4939,6 +5019,10 @@ snapshots:
|
||||
|
||||
'@types/parse-path@7.0.3': {}
|
||||
|
||||
'@types/qrcode@1.5.5':
|
||||
dependencies:
|
||||
'@types/node': 22.10.5
|
||||
|
||||
'@types/resolve@1.20.2': {}
|
||||
|
||||
'@types/web-bluetooth@0.0.16': {}
|
||||
@@ -5335,6 +5419,8 @@ snapshots:
|
||||
|
||||
cac@6.7.14: {}
|
||||
|
||||
camelcase@5.3.1: {}
|
||||
|
||||
caniuse-api@3.0.0:
|
||||
dependencies:
|
||||
browserslist: 4.24.4
|
||||
@@ -5383,6 +5469,12 @@ snapshots:
|
||||
is-wsl: 3.1.0
|
||||
is64bit: 2.0.0
|
||||
|
||||
cliui@6.0.0:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
wrap-ansi: 6.2.0
|
||||
|
||||
cliui@8.0.1:
|
||||
dependencies:
|
||||
string-width: 4.2.3
|
||||
@@ -5566,6 +5658,8 @@ snapshots:
|
||||
optionalDependencies:
|
||||
supports-color: 9.4.0
|
||||
|
||||
decamelize@1.2.0: {}
|
||||
|
||||
decompress-response@6.0.0:
|
||||
dependencies:
|
||||
mimic-response: 3.1.0
|
||||
@@ -5607,6 +5701,8 @@ snapshots:
|
||||
|
||||
diff@7.0.0: {}
|
||||
|
||||
dijkstrajs@1.0.3: {}
|
||||
|
||||
dom-serializer@2.0.0:
|
||||
dependencies:
|
||||
domelementtype: 2.3.0
|
||||
@@ -5827,6 +5923,11 @@ snapshots:
|
||||
dependencies:
|
||||
to-regex-range: 5.0.1
|
||||
|
||||
find-up@4.1.0:
|
||||
dependencies:
|
||||
locate-path: 5.0.0
|
||||
path-exists: 4.0.0
|
||||
|
||||
flatted@3.3.2: {}
|
||||
|
||||
follow-redirects@1.15.9(debug@4.4.0):
|
||||
@@ -6213,6 +6314,10 @@ snapshots:
|
||||
mlly: 1.7.4
|
||||
pkg-types: 1.3.0
|
||||
|
||||
locate-path@5.0.0:
|
||||
dependencies:
|
||||
p-locate: 4.1.0
|
||||
|
||||
lodash-es@4.17.21: {}
|
||||
|
||||
lodash-unified@1.0.3(@types/lodash-es@4.17.12)(lodash-es@4.17.21)(lodash@4.17.21):
|
||||
@@ -6703,6 +6808,16 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
||||
p-limit@2.3.0:
|
||||
dependencies:
|
||||
p-try: 2.2.0
|
||||
|
||||
p-locate@4.1.0:
|
||||
dependencies:
|
||||
p-limit: 2.3.0
|
||||
|
||||
p-try@2.2.0: {}
|
||||
|
||||
package-json-from-dist@1.0.1: {}
|
||||
|
||||
package-manager-detector@0.2.8: {}
|
||||
@@ -6731,6 +6846,8 @@ snapshots:
|
||||
|
||||
parseurl@1.3.3: {}
|
||||
|
||||
path-exists@4.0.0: {}
|
||||
|
||||
path-is-absolute@1.0.1: {}
|
||||
|
||||
path-key@3.1.1: {}
|
||||
@@ -6776,6 +6893,8 @@ snapshots:
|
||||
|
||||
pluralize@8.0.0: {}
|
||||
|
||||
pngjs@5.0.0: {}
|
||||
|
||||
postcss-calc@10.1.0(postcss@8.4.49):
|
||||
dependencies:
|
||||
postcss: 8.4.49
|
||||
@@ -6980,6 +7099,12 @@ snapshots:
|
||||
|
||||
punycode.js@2.3.1: {}
|
||||
|
||||
qrcode@1.5.4:
|
||||
dependencies:
|
||||
dijkstrajs: 1.0.3
|
||||
pngjs: 5.0.0
|
||||
yargs: 15.4.1
|
||||
|
||||
queue-microtask@1.2.3: {}
|
||||
|
||||
queue-tick@1.0.1: {}
|
||||
@@ -7048,6 +7173,8 @@ snapshots:
|
||||
|
||||
require-from-string@2.0.2: {}
|
||||
|
||||
require-main-filename@2.0.0: {}
|
||||
|
||||
resolve-from@5.0.0: {}
|
||||
|
||||
resolve@1.22.10:
|
||||
@@ -7157,6 +7284,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
set-blocking@2.0.0: {}
|
||||
|
||||
setprototypeof@1.2.0: {}
|
||||
|
||||
shebang-command@2.0.0:
|
||||
@@ -7732,6 +7861,8 @@ snapshots:
|
||||
tr46: 0.0.3
|
||||
webidl-conversions: 3.0.1
|
||||
|
||||
which-module@2.0.1: {}
|
||||
|
||||
which@2.0.2:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
@@ -7740,6 +7871,12 @@ snapshots:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
|
||||
wrap-ansi@6.2.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
string-width: 4.2.3
|
||||
strip-ansi: 6.0.1
|
||||
|
||||
wrap-ansi@7.0.0:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
@@ -7756,6 +7893,8 @@ snapshots:
|
||||
|
||||
ws@8.18.0: {}
|
||||
|
||||
y18n@4.0.3: {}
|
||||
|
||||
y18n@5.0.8: {}
|
||||
|
||||
yallist@3.1.1: {}
|
||||
@@ -7768,8 +7907,27 @@ snapshots:
|
||||
|
||||
yaml@2.7.0: {}
|
||||
|
||||
yargs-parser@18.1.3:
|
||||
dependencies:
|
||||
camelcase: 5.3.1
|
||||
decamelize: 1.2.0
|
||||
|
||||
yargs-parser@21.1.1: {}
|
||||
|
||||
yargs@15.4.1:
|
||||
dependencies:
|
||||
cliui: 6.0.0
|
||||
decamelize: 1.2.0
|
||||
find-up: 4.1.0
|
||||
get-caller-file: 2.0.5
|
||||
require-directory: 2.1.1
|
||||
require-main-filename: 2.0.0
|
||||
set-blocking: 2.0.0
|
||||
string-width: 4.2.3
|
||||
which-module: 2.0.1
|
||||
y18n: 4.0.3
|
||||
yargs-parser: 18.1.3
|
||||
|
||||
yargs@17.7.2:
|
||||
dependencies:
|
||||
cliui: 8.0.1
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// @ts-ignore
|
||||
import testData from "~/public/testData/test.md"
|
||||
import DB from 'better-sqlite3';
|
||||
import { postItem } from "~/types/post";
|
||||
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
// @ts-ignore
|
||||
import DB from 'better-sqlite3';
|
||||
import { defineEventHandler, getRouterParam } from 'h3';
|
||||
import fs from 'fs';
|
||||
import { sendStream } from 'h3';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const hash = getRouterParam(event, 'hash');
|
||||
if (!hash) {
|
||||
return { code: 400, msg: 'Invalid hash parameter' };
|
||||
}
|
||||
const db = new DB('./userData/db/imgBed.db');
|
||||
// 从数据库中查询文件信息
|
||||
const fileInfo = db.prepare(`
|
||||
SELECT name, expire FROM imgBed WHERE hash =?
|
||||
`).get(hash) as { name: string, expire: number };
|
||||
db.close();
|
||||
|
||||
if (!fileInfo) {
|
||||
return { code: 404, msg: 'File not found' };
|
||||
}
|
||||
|
||||
const fileName = fileInfo.name;
|
||||
const filePath = `./userData/imgBed/${hash}`;
|
||||
// 检查文件是否存在
|
||||
if (!fs.existsSync(filePath)) {
|
||||
return { code: 404, msg: 'File not found on disk' };
|
||||
}
|
||||
const fileStream = fs.createReadStream(filePath);
|
||||
|
||||
setResponseHeader(event, 'Content-Disposition', `attachment; filename="${fileName}"`);
|
||||
// 发送文件流
|
||||
return sendStream(event, fileStream);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return { code: 500, msg: 'Internal Server Error' };
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
// @ts-ignore
|
||||
import DB from 'better-sqlite3';
|
||||
import { defineEventHandler, readBody } from 'h3';
|
||||
import crypto from 'crypto';
|
||||
import fs from 'fs';
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const data = await readFormData(event)
|
||||
const file = data.get('file') as File
|
||||
const expire = data.get('expire') as string
|
||||
console.log({
|
||||
file: file.name,
|
||||
expire,
|
||||
})
|
||||
const fileBuffer = Buffer.from(await file.arrayBuffer());
|
||||
// 计算文件的 MD5 哈希值
|
||||
const hash = crypto.createHash('md5').update(fileBuffer).digest('hex');
|
||||
const fileName = file.name;
|
||||
const filePath = `./userData/imgBed/${hash}`;
|
||||
// 将文件写入磁盘
|
||||
await fs.promises.writeFile(filePath, fileBuffer);
|
||||
// 获取文件大小
|
||||
const fileSize = fileBuffer.length;
|
||||
|
||||
const db = new DB('./userData/db/imgBed.db');
|
||||
// 插入数据到数据库
|
||||
db.prepare(`
|
||||
INSERT INTO imgBed (name, hash, size, expire)
|
||||
VALUES (?,?,?,?)
|
||||
`).run([fileName, hash, fileSize, expire]);
|
||||
db.close();
|
||||
|
||||
return { code: 200, hash, fileName, fileSize, expire: Number(expire) + Date.now() };
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return { code: 500, msg: 'Internal Server Error' };
|
||||
}
|
||||
});
|
||||
@@ -7,12 +7,10 @@ const pathNeedAuth = serverConfig.auth.api
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
const path = getRequestURL(event).pathname
|
||||
// console.log(path)
|
||||
if (pathNeedAuth.has(path)) {
|
||||
const key = getKey()
|
||||
// @ts-ignore
|
||||
const authHeader = event.headers.get('authorization');
|
||||
// console.log(authHeader)
|
||||
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
||||
throw createError({ statusCode: 401, statusMessage: 'Unauthorized' })
|
||||
}
|
||||
@@ -20,7 +18,6 @@ export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const decoded = jwt.verify(token, key) as { userId: number, password: string, username: string, exp: number }
|
||||
if (decoded.exp > Date.now()) {
|
||||
// console.log('token expired')
|
||||
throw createError({ statusCode: 401, statusMessage: 'Token invalid or expired', data: { err: 'token expired', token } })
|
||||
}
|
||||
// console.log(decoded)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import mkfileIfNotExist from "./mkfileIfNotExist"
|
||||
import db from 'better-sqlite3'
|
||||
import DB from 'better-sqlite3'
|
||||
import fs from 'fs'
|
||||
|
||||
let checked = false
|
||||
|
||||
@@ -14,6 +15,7 @@ function checkUserData() {
|
||||
const dirList = [
|
||||
'./userData/',
|
||||
'./userData/db/',
|
||||
'./userData/imgBed/',
|
||||
]
|
||||
dirList.forEach(mkdirIfNotExist)
|
||||
|
||||
@@ -24,9 +26,14 @@ function checkUserData() {
|
||||
}
|
||||
|
||||
function createDB() {
|
||||
const userDB = new db('./userData/db/user.db');
|
||||
const postsDB = new db('./userData/db/posts.db');
|
||||
createUserDB();
|
||||
createPostsDB();
|
||||
createImgBedDB();
|
||||
}
|
||||
|
||||
|
||||
const createUserDB = () => {
|
||||
const userDB = new DB('./userData/db/user.db');
|
||||
userDB.exec(`
|
||||
CREATE TABLE IF NOT EXISTS user (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -36,7 +43,11 @@ function createDB() {
|
||||
lastLoginTime INTEGER NOT NULL
|
||||
);
|
||||
`);
|
||||
userDB.close();
|
||||
}
|
||||
|
||||
const createPostsDB = () => {
|
||||
const postsDB = new DB('./userData/db/posts.db');
|
||||
postsDB.exec(`
|
||||
CREATE TABLE IF NOT EXISTS posts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -49,14 +60,12 @@ function createDB() {
|
||||
FOREIGN KEY(tag_id) REFERENCES tags(id)
|
||||
);
|
||||
`);
|
||||
|
||||
postsDB.exec(`
|
||||
CREATE TABLE IF NOT EXISTS postContent (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
content TEXT NOT NULL
|
||||
);
|
||||
`);
|
||||
|
||||
postsDB.exec(`
|
||||
CREATE TABLE IF NOT EXISTS tags (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
@@ -77,9 +86,56 @@ function createDB() {
|
||||
tag15 TEXT
|
||||
);
|
||||
`);
|
||||
|
||||
postsDB.close();
|
||||
userDB.close();
|
||||
}
|
||||
|
||||
const createImgBedDB = () => {
|
||||
const imgBedDB = new DB('./userData/db/imgBed.db');
|
||||
imgBedDB.exec(`
|
||||
CREATE TABLE IF NOT EXISTS imgBed (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
hash TEXT NOT NULL,
|
||||
size INTEGER NOT NULL,
|
||||
expire INTEGER NOT NULL
|
||||
);
|
||||
`);
|
||||
imgBedDB.close();
|
||||
setInterval(cleanExpiredFiles_imgBed, 1000 * 30 * 60 );
|
||||
// cleanExpiredFiles_imgBed()
|
||||
}
|
||||
|
||||
const cleanExpiredFiles_imgBed = async () => {
|
||||
try {
|
||||
const db = new DB('./userData/db/imgBed.db');
|
||||
const currentTime = Date.now();
|
||||
// 从数据库中查询过期文件的哈希
|
||||
const expiredFiles = db.prepare(`
|
||||
SELECT hash FROM imgBed WHERE expire <?
|
||||
`).all(currentTime) as {
|
||||
hash: string;
|
||||
}[];
|
||||
db.close();
|
||||
|
||||
for (const file of expiredFiles) {
|
||||
const hash = file.hash;
|
||||
const filePath = useRuntimeConfig().public.userDataPath + `/imgBed/${hash}`;
|
||||
// 检查文件是否存在
|
||||
if (fs.existsSync(filePath)) {
|
||||
// 删除文件
|
||||
fs.unlinkSync(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
// 从数据库中删除过期文件的记录
|
||||
const db2 = new DB('./userData/db/imgBed.db');
|
||||
db2.prepare(`
|
||||
DELETE FROM imgBed WHERE expire <?
|
||||
`).run(currentTime);
|
||||
db2.close();
|
||||
} catch (error) {
|
||||
console.error('Error cleaning expired files:', error);
|
||||
}
|
||||
};
|
||||
|
||||
export default checkUserData
|
||||
Reference in new issue
Block a user