feat: 完成用户鉴权相关api

This commit is contained in:
539943419 committed 2025-01-13 17:22:52 +08:00
1 parent 79cc9c34d6
commit 4c69f57aaa
22 files changed
+902 -67

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
export const uploadPost = (body: {
title: string,
summary: string,
type: string,
tags: string[],
url: string,
date: number,
content: string
}) => $fetch('/api/posts/uploadPost', {
method: 'POST',
body
})
export const updatePost = (body: {
id: number,
title: string,
summary: string,
type: string,
tags: string[],
url: string,
date: number,
content: string
}) => $fetch('/api/posts/uploadPost', {
method: 'POST',
body
})
+6
View File
@@ -12,7 +12,10 @@
"dependencies": {
"@pinia/nuxt": "^0.9.0",
"@types/node": "^22.10.5",
"bcryptjs": "^2.4.3",
"better-sqlite3": "11.3.0",
"dayjs": "^1.11.13",
"jsonwebtoken": "^9.0.2",
"markdown-it": "^14.1.0",
"node-fetch": "^3.3.2",
"nuxt": "^3.15.1",
@@ -24,6 +27,9 @@
},
"devDependencies": {
"@element-plus/nuxt": "^1.1.1",
"@types/bcryptjs": "^2.4.6",
"@types/better-sqlite3": "^7.6.12",
"@types/jsonwebtoken": "^9.0.7",
"@types/markdown-it": "^14.1.2",
"element-plus": "^2.9.3",
"sass": "^1.83.1"
+2 -1
View File
@@ -42,7 +42,8 @@ const getData = async () => {
if (cache) {
return cache as postItem[]
}
const res = await $fetch('/api/posts/getPostList')
const response = await $fetch('/api/posts/getPostList')
const res = response.data
store.setCache('posts', res)
return res
}
+80 -3
View File
@@ -1,13 +1,90 @@
<template>
<div>
index
<div>
<el-button @click="uploadTest">
uploadPostTest
</el-button>
<el-button @click="editTest">
editPostTest
</el-button>
<el-button @click="testLogin">
testLogin
</el-button>
<el-button @click="testRegister">
testRegister
</el-button>
<el-button @click="testRefreshToken">
testRefreshToken
</el-button>
</div>
</div>
</template>
<script setup lang="ts">
import useUserStore from '~/hooks/pinia/useUserStore';
import { uploadPost, updatePost } from '~/hooks/useFetch';
const userStore = useUserStore()
const uploadTest = () => {
uploadPost({
title: `测试上传`,
summary: `测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要`,
type:'markdown',
tags: ['test', 'test1'],
url: '',
date: parseInt(new Date().getTime().toFixed()),
content: '测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传'
})
}
const editTest = () => {
updatePost({
id: 1,
title: `测试上传`,
summary: `测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要`,
type:'markdown',
tags: ['test', 'test1'],
url: '',
date: parseInt(new Date().getTime().toFixed()),
content: '测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传测试上传'
})
}
const testLogin = async () => {
const response = await $fetch('/api/user/login', {
method: 'POST',
body: {
username: 'admin',
password: 'admin'
}
})
const token = response.token
userStore.setToken(token)
}
const testRegister = () => {
$fetch('/api/user/register', {
method: 'POST',
body: {
username: 'admin',
password: 'admin'
}
})
}
const testRefreshToken = async () => {
const response = await $fetch('/api/user/refreshToken', {
method: 'POST',
body: {
token: userStore.token
}
})
const token = response.token
userStore.setToken(token)
}
</script>
<style lang="scss" scoped>
</style>
<style lang="scss" scoped></style>
+329 -10
View File
@@ -14,9 +14,18 @@ importers:
'@types/node':
specifier: ^22.10.5
version: 22.10.5
bcryptjs:
specifier: ^2.4.3
version: 2.4.3
better-sqlite3:
specifier: 11.3.0
version: 11.3.0
dayjs:
specifier: ^1.11.13
version: 1.11.13
jsonwebtoken:
specifier: ^9.0.2
version: 9.0.2
markdown-it:
specifier: ^14.1.0
version: 14.1.0
@@ -25,7 +34,7 @@ importers:
version: 3.3.2
nuxt:
specifier: ^3.15.1
version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(ioredis@5.4.2)(magicast@0.3.5)(rollup@4.30.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.7.0))(yaml@2.7.0)
version: 3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(better-sqlite3@11.3.0)(db0@0.2.1(better-sqlite3@11.3.0))(ioredis@5.4.2)(magicast@0.3.5)(rollup@4.30.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.7.0))(yaml@2.7.0)
pinia:
specifier: ^2.3.0
version: 2.3.0(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
@@ -45,6 +54,15 @@ importers:
'@element-plus/nuxt':
specifier: ^1.1.1
version: 1.1.1(@element-plus/icons-vue@2.3.1(vue@3.5.13(typescript@5.7.3)))(element-plus@2.9.3(vue@3.5.13(typescript@5.7.3)))(magicast@0.3.5)(rollup@4.30.1)
'@types/bcryptjs':
specifier: ^2.4.6
version: 2.4.6
'@types/better-sqlite3':
specifier: ^7.6.12
version: 7.6.12
'@types/jsonwebtoken':
specifier: ^9.0.7
version: 9.0.7
'@types/markdown-it':
specifier: ^14.1.2
version: 14.1.2
@@ -928,12 +946,21 @@ packages:
resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==}
engines: {node: '>=10.13.0'}
'@types/bcryptjs@2.4.6':
resolution: {integrity: sha512-9xlo6R2qDs5uixm0bcIqCeMCE6HiQsIyel9KQySStiyqNl2tnj2mP3DX1Nf56MD6KMenNNlBBsy3LJ7gUEQPXQ==}
'@types/better-sqlite3@7.6.12':
resolution: {integrity: sha512-fnQmj8lELIj7BSrZQAdBMHEHX8OZLYIHXqAKT1O7tDfLxaINzf00PMjw22r3N/xXh0w/sGHlO6SVaCQ2mj78lg==}
'@types/estree@1.0.6':
resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==}
'@types/http-proxy@1.17.15':
resolution: {integrity: sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==}
'@types/jsonwebtoken@9.0.7':
resolution: {integrity: sha512-ugo316mmTYBl2g81zDFnZ7cfxlut3o+/EQdaP7J8QN2kY6lJ22hmQYCK5EHcJHbrW+dkCGSCPgbG8JtYj6qSrg==}
'@types/linkify-it@5.0.0':
resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
@@ -1171,6 +1198,12 @@ packages:
base64-js@1.5.1:
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
bcryptjs@2.4.3:
resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==}
better-sqlite3@11.3.0:
resolution: {integrity: sha512-iHt9j8NPYF3oKCNOO5ZI4JwThjt3Z6J6XrcwG85VNMVzv1ByqrHWv5VILEbCMFWDsoHhXvQ7oC8vgRXFAKgl9w==}
binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
@@ -1181,6 +1214,9 @@ packages:
birpc@0.2.19:
resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==}
bl@4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
boolbase@1.0.0:
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
@@ -1203,9 +1239,15 @@ packages:
resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==}
engines: {node: '>=8.0.0'}
buffer-equal-constant-time@1.0.1:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
buffer@5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
buffer@6.0.3:
resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==}
@@ -1246,6 +1288,9 @@ packages:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'}
chownr@1.1.4:
resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
chownr@2.0.0:
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
engines: {node: '>=10'}
@@ -1445,6 +1490,14 @@ packages:
supports-color:
optional: true
decompress-response@6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'}
deep-extend@0.6.0:
resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
engines: {node: '>=4.0.0'}
deepmerge@4.3.1:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
@@ -1526,6 +1579,9 @@ packages:
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
ecdsa-sig-formatter@1.0.11:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
@@ -1551,6 +1607,9 @@ packages:
resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==}
engines: {node: '>= 0.8'}
end-of-stream@1.4.4:
resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
enhanced-resolve@5.18.0:
resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==}
engines: {node: '>=10.13.0'}
@@ -1615,6 +1674,10 @@ packages:
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
engines: {node: '>=16.17'}
expand-template@2.0.3:
resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
engines: {node: '>=6'}
externality@1.0.2:
resolution: {integrity: sha512-LyExtJWKxtgVzmgtEHyQtLFpw1KFhQphF9nTG8TpAIVkiI/xQ3FJh75tRFLYl4hkn7BNIIdLJInuDAavX35pMw==}
@@ -1671,6 +1734,9 @@ packages:
resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==}
engines: {node: '>= 0.6'}
fs-constants@1.0.0:
resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
fs-extra@11.2.0:
resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==}
engines: {node: '>=14.14'}
@@ -1723,6 +1789,9 @@ packages:
git-url-parse@16.0.0:
resolution: {integrity: sha512-Y8iAF0AmCaqXc6a5GYgPQW9ESbncNLOL+CeQAJRhmWUOmnPkKpBYeWYp4mFd3LA5j53CdGDdslzX12yEBVHQQg==}
github-from-package@0.0.0:
resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
@@ -1963,6 +2032,16 @@ packages:
jsonfile@6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
jsonwebtoken@9.0.2:
resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==}
engines: {node: '>=12', npm: '>=6'}
jwa@1.4.1:
resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==}
jws@3.2.2:
resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==}
kleur@3.0.3:
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
engines: {node: '>=6'}
@@ -2012,12 +2091,33 @@ packages:
lodash.defaults@4.2.0:
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
lodash.includes@4.3.0:
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
lodash.isarguments@3.1.0:
resolution: {integrity: sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg==}
lodash.isboolean@3.0.3:
resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==}
lodash.isinteger@4.0.4:
resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==}
lodash.isnumber@3.0.3:
resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==}
lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
lodash.isstring@4.0.1:
resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==}
lodash.memoize@4.1.2:
resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==}
lodash.once@4.1.1:
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
lodash.uniq@4.5.0:
resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==}
@@ -2090,6 +2190,10 @@ packages:
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
engines: {node: '>=12'}
mimic-response@3.1.0:
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
engines: {node: '>=10'}
minimatch@3.1.2:
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
@@ -2101,6 +2205,9 @@ packages:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
minimist@1.2.8:
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
minipass@3.3.6:
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
engines: {node: '>=8'}
@@ -2124,6 +2231,9 @@ packages:
mitt@3.0.1:
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
mkdirp-classic@0.5.3:
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
mkdirp@1.0.4:
resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
engines: {node: '>=10'}
@@ -2160,6 +2270,9 @@ packages:
nanotar@0.1.1:
resolution: {integrity: sha512-AiJsGsSF3O0havL1BydvI4+wR76sKT+okKRwWIaK96cZUnXqH0uNBOsHlbwZq3+m2BR1VKqHDVudl3gO4mYjpQ==}
napi-build-utils@1.0.2:
resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==}
nitropack@2.10.4:
resolution: {integrity: sha512-sJiG/MIQlZCVSw2cQrFG1H6mLeSqHlYfFerRjLKz69vUfdu0EL2l0WdOxlQbzJr3mMv/l4cOlCCLzVRzjzzF/g==}
engines: {node: ^16.11.0 || >=17.0.0}
@@ -2170,6 +2283,10 @@ packages:
xml2js:
optional: true
node-abi@3.71.0:
resolution: {integrity: sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==}
engines: {node: '>=10'}
node-addon-api@7.1.1:
resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==}
@@ -2554,6 +2671,11 @@ packages:
resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==}
engines: {node: ^10 || ^12 || >=14}
prebuild-install@7.1.2:
resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==}
engines: {node: '>=10'}
hasBin: true
pretty-bytes@6.1.1:
resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==}
engines: {node: ^14.13.1 || >=16.0.0}
@@ -2572,6 +2694,9 @@ packages:
protocols@2.0.1:
resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==}
pump@3.0.2:
resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==}
punycode.js@2.3.1:
resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
engines: {node: '>=6'}
@@ -2595,9 +2720,17 @@ packages:
rc9@2.1.2:
resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
rc@1.2.8:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
hasBin: true
readable-stream@2.3.8:
resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
readable-stream@3.6.2:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'}
readable-stream@4.7.0:
resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -2733,6 +2866,12 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
simple-concat@1.0.1:
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
simple-get@4.0.1:
resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
simple-git@3.27.0:
resolution: {integrity: sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==}
@@ -2808,6 +2947,10 @@ packages:
resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
engines: {node: '>=12'}
strip-json-comments@2.0.1:
resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
engines: {node: '>=0.10.0'}
strip-literal@2.1.1:
resolution: {integrity: sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==}
@@ -2849,6 +2992,13 @@ packages:
resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==}
engines: {node: '>=6'}
tar-fs@2.1.2:
resolution: {integrity: sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==}
tar-stream@2.2.0:
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
engines: {node: '>=6'}
tar-stream@3.1.7:
resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
@@ -2893,6 +3043,9 @@ packages:
tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
tunnel-agent@0.6.0:
resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
type-fest@0.21.3:
resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==}
engines: {node: '>=10'}
@@ -4215,12 +4368,22 @@ snapshots:
'@trysound/sax@0.2.0': {}
'@types/bcryptjs@2.4.6': {}
'@types/better-sqlite3@7.6.12':
dependencies:
'@types/node': 22.10.5
'@types/estree@1.0.6': {}
'@types/http-proxy@1.17.15':
dependencies:
'@types/node': 22.10.5
'@types/jsonwebtoken@9.0.7':
dependencies:
'@types/node': 22.10.5
'@types/linkify-it@5.0.0': {}
'@types/lodash-es@4.17.12':
@@ -4544,6 +4707,13 @@ snapshots:
base64-js@1.5.1: {}
bcryptjs@2.4.3: {}
better-sqlite3@11.3.0:
dependencies:
bindings: 1.5.0
prebuild-install: 7.1.2
binary-extensions@2.3.0: {}
bindings@1.5.0:
@@ -4552,6 +4722,12 @@ snapshots:
birpc@0.2.19: {}
bl@4.1.0:
dependencies:
buffer: 5.7.1
inherits: 2.0.4
readable-stream: 3.6.2
boolbase@1.0.0: {}
brace-expansion@1.1.11:
@@ -4576,8 +4752,15 @@ snapshots:
buffer-crc32@1.0.0: {}
buffer-equal-constant-time@1.0.1: {}
buffer-from@1.1.2: {}
buffer@5.7.1:
dependencies:
base64-js: 1.5.1
ieee754: 1.2.1
buffer@6.0.3:
dependencies:
base64-js: 1.5.1
@@ -4638,6 +4821,8 @@ snapshots:
dependencies:
readdirp: 4.1.1
chownr@1.1.4: {}
chownr@2.0.0: {}
chownr@3.0.0: {}
@@ -4805,7 +4990,9 @@ snapshots:
dayjs@1.11.13: {}
db0@0.2.1: {}
db0@0.2.1(better-sqlite3@11.3.0):
optionalDependencies:
better-sqlite3: 11.3.0
debug@2.6.9:
dependencies:
@@ -4817,6 +5004,12 @@ snapshots:
optionalDependencies:
supports-color: 9.4.0
decompress-response@6.0.0:
dependencies:
mimic-response: 3.1.0
deep-extend@0.6.0: {}
deepmerge@4.3.1: {}
default-browser-id@5.0.0: {}
@@ -4876,6 +5069,10 @@ snapshots:
eastasianwidth@0.2.0: {}
ecdsa-sig-formatter@1.0.11:
dependencies:
safe-buffer: 5.2.1
ee-first@1.1.1: {}
electron-to-chromium@1.5.80: {}
@@ -4909,6 +5106,10 @@ snapshots:
encodeurl@2.0.0: {}
end-of-stream@1.4.4:
dependencies:
once: 1.4.0
enhanced-resolve@5.18.0:
dependencies:
graceful-fs: 4.2.11
@@ -5018,6 +5219,8 @@ snapshots:
signal-exit: 4.1.0
strip-final-newline: 3.0.0
expand-template@2.0.3: {}
externality@1.0.2:
dependencies:
enhanced-resolve: 5.18.0
@@ -5073,6 +5276,8 @@ snapshots:
fresh@0.5.2: {}
fs-constants@1.0.0: {}
fs-extra@11.2.0:
dependencies:
graceful-fs: 4.2.11
@@ -5122,6 +5327,8 @@ snapshots:
dependencies:
git-up: 8.0.0
github-from-package@0.0.0: {}
glob-parent@5.1.2:
dependencies:
is-glob: 4.0.3
@@ -5355,6 +5562,30 @@ snapshots:
optionalDependencies:
graceful-fs: 4.2.11
jsonwebtoken@9.0.2:
dependencies:
jws: 3.2.2
lodash.includes: 4.3.0
lodash.isboolean: 3.0.3
lodash.isinteger: 4.0.4
lodash.isnumber: 3.0.3
lodash.isplainobject: 4.0.6
lodash.isstring: 4.0.1
lodash.once: 4.1.1
ms: 2.1.3
semver: 7.6.3
jwa@1.4.1:
dependencies:
buffer-equal-constant-time: 1.0.1
ecdsa-sig-formatter: 1.0.11
safe-buffer: 5.2.1
jws@3.2.2:
dependencies:
jwa: 1.4.1
safe-buffer: 5.2.1
kleur@3.0.3: {}
klona@2.0.6: {}
@@ -5414,10 +5645,24 @@ snapshots:
lodash.defaults@4.2.0: {}
lodash.includes@4.3.0: {}
lodash.isarguments@3.1.0: {}
lodash.isboolean@3.0.3: {}
lodash.isinteger@4.0.4: {}
lodash.isnumber@3.0.3: {}
lodash.isplainobject@4.0.6: {}
lodash.isstring@4.0.1: {}
lodash.memoize@4.1.2: {}
lodash.once@4.1.1: {}
lodash.uniq@4.5.0: {}
lodash@4.17.21: {}
@@ -5480,6 +5725,8 @@ snapshots:
mimic-fn@4.0.0: {}
mimic-response@3.1.0: {}
minimatch@3.1.2:
dependencies:
brace-expansion: 1.1.11
@@ -5492,6 +5739,8 @@ snapshots:
dependencies:
brace-expansion: 2.0.1
minimist@1.2.8: {}
minipass@3.3.6:
dependencies:
yallist: 4.0.0
@@ -5512,6 +5761,8 @@ snapshots:
mitt@3.0.1: {}
mkdirp-classic@0.5.3: {}
mkdirp@1.0.4: {}
mkdirp@3.0.1: {}
@@ -5535,7 +5786,9 @@ snapshots:
nanotar@0.1.1: {}
nitropack@2.10.4(typescript@5.7.3):
napi-build-utils@1.0.2: {}
nitropack@2.10.4(better-sqlite3@11.3.0)(typescript@5.7.3):
dependencies:
'@cloudflare/kv-asset-handler': 0.3.4
'@netlify/functions': 2.8.2
@@ -5559,7 +5812,7 @@ snapshots:
cookie-es: 1.2.2
croner: 9.0.0
crossws: 0.3.1
db0: 0.2.1
db0: 0.2.1(better-sqlite3@11.3.0)
defu: 6.1.4
destr: 2.0.3
dot-prop: 9.0.0
@@ -5602,7 +5855,7 @@ snapshots:
unctx: 2.4.1
unenv: 1.10.0
unimport: 3.14.5(rollup@4.30.1)
unstorage: 1.14.4(db0@0.2.1)(ioredis@5.4.2)
unstorage: 1.14.4(db0@0.2.1(better-sqlite3@11.3.0))(ioredis@5.4.2)
untyped: 1.5.2
unwasm: 0.3.9
transitivePeerDependencies:
@@ -5632,6 +5885,10 @@ snapshots:
- typescript
- uploadthing
node-abi@3.71.0:
dependencies:
semver: 7.6.3
node-addon-api@7.1.1: {}
node-domexception@1.0.0: {}
@@ -5678,7 +5935,7 @@ snapshots:
nuxi@3.20.0: {}
nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(db0@0.2.1)(ioredis@5.4.2)(magicast@0.3.5)(rollup@4.30.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.7.0))(yaml@2.7.0):
nuxt@3.15.1(@parcel/watcher@2.5.0)(@types/node@22.10.5)(better-sqlite3@11.3.0)(db0@0.2.1(better-sqlite3@11.3.0))(ioredis@5.4.2)(magicast@0.3.5)(rollup@4.30.1)(sass@1.83.1)(terser@5.37.0)(typescript@5.7.3)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.7.0))(yaml@2.7.0):
dependencies:
'@nuxt/devalue': 2.0.2
'@nuxt/devtools': 1.7.0(rollup@4.30.1)(vite@6.0.7(@types/node@22.10.5)(jiti@2.4.2)(sass@1.83.1)(terser@5.37.0)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))
@@ -5715,7 +5972,7 @@ snapshots:
magic-string: 0.30.17
mlly: 1.7.4
nanotar: 0.1.1
nitropack: 2.10.4(typescript@5.7.3)
nitropack: 2.10.4(better-sqlite3@11.3.0)(typescript@5.7.3)
nuxi: 3.20.0
nypm: 0.4.1
ofetch: 1.4.1
@@ -5738,7 +5995,7 @@ snapshots:
unimport: 3.14.5(rollup@4.30.1)
unplugin: 2.1.2
unplugin-vue-router: 0.10.9(rollup@4.30.1)(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
unstorage: 1.14.4(db0@0.2.1)(ioredis@5.4.2)
unstorage: 1.14.4(db0@0.2.1(better-sqlite3@11.3.0))(ioredis@5.4.2)
untyped: 1.5.2
vue: 3.5.13(typescript@5.7.3)
vue-bundle-renderer: 2.1.1
@@ -6102,6 +6359,21 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
prebuild-install@7.1.2:
dependencies:
detect-libc: 2.0.3
expand-template: 2.0.3
github-from-package: 0.0.0
minimist: 1.2.8
mkdirp-classic: 0.5.3
napi-build-utils: 1.0.2
node-abi: 3.71.0
pump: 3.0.2
rc: 1.2.8
simple-get: 4.0.1
tar-fs: 2.1.2
tunnel-agent: 0.6.0
pretty-bytes@6.1.1: {}
process-nextick-args@2.0.1: {}
@@ -6115,6 +6387,11 @@ snapshots:
protocols@2.0.1: {}
pump@3.0.2:
dependencies:
end-of-stream: 1.4.4
once: 1.4.0
punycode.js@2.3.1: {}
queue-microtask@1.2.3: {}
@@ -6134,6 +6411,13 @@ snapshots:
defu: 6.1.4
destr: 2.0.3
rc@1.2.8:
dependencies:
deep-extend: 0.6.0
ini: 1.3.8
minimist: 1.2.8
strip-json-comments: 2.0.1
readable-stream@2.3.8:
dependencies:
core-util-is: 1.0.3
@@ -6144,6 +6428,12 @@ snapshots:
string_decoder: 1.1.1
util-deprecate: 1.0.2
readable-stream@3.6.2:
dependencies:
inherits: 2.0.4
string_decoder: 1.3.0
util-deprecate: 1.0.2
readable-stream@4.7.0:
dependencies:
abort-controller: 3.0.0
@@ -6295,6 +6585,14 @@ snapshots:
signal-exit@4.1.0: {}
simple-concat@1.0.1: {}
simple-get@4.0.1:
dependencies:
decompress-response: 6.0.0
once: 1.4.0
simple-concat: 1.0.1
simple-git@3.27.0:
dependencies:
'@kwsites/file-exists': 1.1.1
@@ -6372,6 +6670,8 @@ snapshots:
strip-final-newline@3.0.0: {}
strip-json-comments@2.0.1: {}
strip-literal@2.1.1:
dependencies:
js-tokens: 9.0.1
@@ -6410,6 +6710,21 @@ snapshots:
tapable@2.2.1: {}
tar-fs@2.1.2:
dependencies:
chownr: 1.1.4
mkdirp-classic: 0.5.3
pump: 3.0.2
tar-stream: 2.2.0
tar-stream@2.2.0:
dependencies:
bl: 4.1.0
end-of-stream: 1.4.4
fs-constants: 1.0.0
inherits: 2.0.4
readable-stream: 3.6.2
tar-stream@3.1.7:
dependencies:
b4a: 1.6.7
@@ -6464,6 +6779,10 @@ snapshots:
tr46@0.0.3: {}
tunnel-agent@0.6.0:
dependencies:
safe-buffer: 5.2.1
type-fest@0.21.3: {}
type-fest@4.32.0: {}
@@ -6597,7 +6916,7 @@ snapshots:
acorn: 8.14.0
webpack-virtual-modules: 0.6.2
unstorage@1.14.4(db0@0.2.1)(ioredis@5.4.2):
unstorage@1.14.4(db0@0.2.1(better-sqlite3@11.3.0))(ioredis@5.4.2):
dependencies:
anymatch: 3.1.3
chokidar: 3.6.0
@@ -6608,7 +6927,7 @@ snapshots:
ofetch: 1.4.1
ufo: 1.5.4
optionalDependencies:
db0: 0.2.1
db0: 0.2.1(better-sqlite3@11.3.0)
ioredis: 5.4.2
untun@0.1.3:
-4
View File
@@ -1,4 +0,0 @@
export default defineEventHandler(async (event) => {
const body = await readBody(event)
return
})
+84
View File
@@ -0,0 +1,84 @@
// editPost.ts
import DB from 'better-sqlite3';
import cacheResult from '~/server/utils/cacheRes';
function prepareDB() {
const db = new DB('./userData/db/posts.db');
const updatePostStmt = db.prepare(`
UPDATE posts
SET title = ?, summary = ?, type = ?, url = ?, date = ?, tag_id = ?
WHERE id = ?
`);
const updateContentStmt = db.prepare(`
UPDATE postContent
SET content = ?
WHERE id = ?
`);
const updateTagsStmt = db.prepare(`
UPDATE tags
SET tag1 = ?, tag2 = ?, tag3 = ?, tag4 = ?, tag5 = ?,
tag6 = ?, tag7 = ?, tag8 = ?, tag9 = ?, tag10 = ?,
tag11 = ?, tag12 = ?, tag13 = ?, tag14 = ?, tag15 = ?
WHERE id = ?
`);
const insertTagsStmt = db.prepare(`
INSERT INTO tags (tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9, tag10, tag11, tag12, tag13, tag14, tag15)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
return { updatePostStmt, updateContentStmt, updateTagsStmt, insertTagsStmt, db };
}
export default defineEventHandler(async (event) => {
const { updatePostStmt, updateContentStmt, updateTagsStmt, insertTagsStmt, db } = cacheResult(prepareDB)();
const body = await readBody(event);
const { id, title, summary, tags: _tags, type, url, date, content } = body;
if ([id, title, summary, _tags, type, url, date, content].some(item => item === undefined)) {
return {
code: 400,
msg: '参数错误',
body
}
}
const tagsArray = Array.isArray(_tags) ? _tags : [_tags];
const tags = tagsArray.slice(0, 15).concat(new Array(15 - tagsArray.length).fill(null));
try {
db.transaction(() => {
// 检查是否存在tag_id,如果不存在则插入新标签
const tagRow: any = db.prepare(`SELECT tag_id FROM posts WHERE id = ?`).get(id);
if (tagRow.tag_id) {
// 更新现有标签
updateTagsStmt.run(...tags, tagRow.tag_id);
} else {
// 插入新标签并获取tag_id
const tagResult = insertTagsStmt.run(...tags);
const tagId = tagResult.lastInsertRowid;
// 更新posts表中的tag_id
updatePostStmt.run(title, summary, type, url, date, tagId, id);
}
// 更新posts表
updatePostStmt.run(title, summary, type, url, date, tagRow.tag_id, id);
// 更新postContent表
updateContentStmt.run(content, id);
})();
return {
code: 200,
msg: '更新成功'
};
} catch (error) {
console.error('更新数据时出错:', error);
return {
code: 500,
msg: '服务器内部错误'
};
}
});
+33 -2
View File
@@ -1,8 +1,39 @@
// @ts-ignore
import testData from "~/public/testData/test.md"
import DB from 'better-sqlite3';
export default defineEventHandler(async (event) => {
const body = await readBody(event)
const data = testData
return { data, title: `测试标题::{${body.id}}` }
const id = body.id;
if (!id || isNaN(Number(id))) {
return {
code: 400,
msg: '无效的id'
};
}
const db = new DB('./userData/db/posts.db');
const post: any = db.prepare('SELECT * FROM posts WHERE id = ?').get(Number(id));
const content: any = db.prepare('SELECT content FROM postContent WHERE id = ?').get(Number(id));
db.close();
if (!post) {
return {
code: 404,
msg: '文章不存在'
};
}
if (!content) {
return {
code: 404,
msg: '文章内容不存在'
};
}
return {
code: 200,
data: content.content,
title: post.title
};
})
+32 -19
View File
@@ -1,22 +1,35 @@
import type { postItem } from "~/types/post";
import { defineEventHandler } from 'h3';
import DB from 'better-sqlite3';
function generateFakeData(length: number) {
const data: postItem[] = [];
for (let i = 0; i < length; i++) {
data.push({
id: i,
title: `测试标题`,
summary: `测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要测试摘要`,
type: 'markdown',
tags: ['test', 'test1'],
url: '',
date: parseInt(new Date().getTime().toFixed()),
});
export default defineEventHandler(async (event) => {
const db = new DB('./userData/db/posts.db');
// 获取所有标签
const tagsMap = new Map<number, string[]>();
const tagsRows = db.prepare('SELECT id, tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9, tag10, tag11, tag12, tag13, tag14, tag15 FROM tags').all();
tagsRows.forEach((row: any) => {
const tags = [];
for (let i = 1; i <= 15; i++) {
const tag = row[`tag${i}`];
if (tag) {
tags.push(tag);
}
return data;
}
}
tagsMap.set(row.id, tags);
});
export default defineEventHandler((event) => {
const data = generateFakeData(50)
return data
})
// 获取所有文章
const posts = db.prepare('SELECT id, title, summary, type, tag_id, url, date FROM posts').all();
// 替换tag_id为标签数组
posts.forEach((post: any) => {
post.tags = tagsMap.get(post.tag_id) || [];
});
db.close();
return {
code: 200,
data: posts
};
});
+69
View File
@@ -0,0 +1,69 @@
import DB from 'better-sqlite3';
import cacheResult from '~/server/utils/cacheRes';
function prepareDB() {
const db = new DB('./userData/db/posts.db');
const insertPostStmt = db.prepare(`
INSERT INTO posts (title, summary, type, url, date, tag_id)
VALUES (?, ?, ?, ?, ?, ?)
`);
const insertContentStmt = db.prepare(`
INSERT INTO postContent (id, content)
VALUES (?, ?)
`);
const insertTagsStmt = db.prepare(`
INSERT INTO tags (tag1, tag2, tag3, tag4, tag5, tag6, tag7, tag8, tag9, tag10, tag11, tag12, tag13, tag14, tag15)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
`);
return { db, insertPostStmt, insertContentStmt, insertTagsStmt };
}
export default defineEventHandler(async (event) => {
const { db, insertPostStmt, insertContentStmt, insertTagsStmt } = cacheResult(prepareDB)();
const body = await readBody(event);
const { title, summary, tags: _tags, type, url, date, content } = body;
if([title, summary, _tags, type, url, date, content].some(item => item === undefined)){
return {
code: 400,
msg: '参数错误',
body
}
}
// 确保_tags是一个数组
const tagsArray = Array.isArray(_tags) ? _tags : [_tags];
// 填充或截取前15个标签
const tags = tagsArray.slice(0, 15).concat(new Array(15 - tagsArray.length).fill(null));
try {
db.transaction(() => {
// 插入tags表
const tagResult = insertTagsStmt.run(...tags);
const tagId = tagResult.lastInsertRowid;
// 插入posts表
const postResult = insertPostStmt.run(title, summary, type, url, date, tagId);
const postId = postResult.lastInsertRowid;
// 插入postContent表
insertContentStmt.run(postId, content);
})();
return {
code: 200,
msg: '插入成功'
};
} catch (error) {
console.error('插入数据时出错:', error);
return {
code: 500,
msg: '服务器内部错误'
};
}
});
+1 -1
View File
@@ -1,5 +1,5 @@
import fs from 'fs';
import checkUserData from '~/server/utils/checkUserData';
import checkUserData from '~/server/utils/initUserData';
export default defineEventHandler((event) => {
checkUserData()
+27
View File
@@ -0,0 +1,27 @@
// import { defineEventHandler, readBody, createError } from 'h3';
import bcrypt from 'bcryptjs';
import BetterSqlite3 from 'better-sqlite3';
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { username, password } = body;
// 查询用户
const userDB = BetterSqlite3('./userData/db/user.db');
const user: any = userDB.prepare('SELECT * FROM user WHERE username = ?').get(username);
if (!user || password !== user.password) {
userDB.close();
throw createError({ statusCode: 401, statusMessage: 'Invalid username or password' });
}
// 更新最后登录时间
userDB.prepare('UPDATE user SET lastLoginTime = ? WHERE id = ?').run(Date.now(), user.id);
// 生成 JWT
const token = createToken(user.id);
userDB.close();
return { token , expiresIn: Date.now() + 168 * 60 * 60 * 1000 };
});
+20
View File
@@ -0,0 +1,20 @@
import { defineEventHandler, readBody, createError } from 'h3';
import jwt from 'jsonwebtoken';
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { token } = body;
const jwtSecret = getKey();
try {
// 验证旧的 Token
const decoded = jwt.verify(token, jwtSecret) as { userId: number };
// 生成新的 Token
const newToken = jwt.sign({ userId: decoded.userId }, jwtSecret, { expiresIn: '168h' });
return { token: newToken, expiresIn: Date.now() + 168 * 60 * 60 * 1000 };
} catch (err) {
throw createError({ statusCode: 401, statusMessage: 'Token invalid or expired', data: { err, token } });
}
});
+34
View File
@@ -0,0 +1,34 @@
import bcrypt from 'bcryptjs';
import BetterSqlite3 from 'better-sqlite3';
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { username, password } = body;
// 检查用户名是否已存在
const userDB = BetterSqlite3('./userData/db/user.db');
const existingUser = userDB.prepare('SELECT * FROM user WHERE username = ?').get(username);
if (existingUser) {
userDB.close();
throw createError({ statusCode: 400, statusMessage: 'Username already exists' });
}
// 哈希密码
// const salt = getKey().substring(0, 10);
// const hashedPassword = bcrypt.hashSync(password, salt);
const hashedPassword = password
// 插入新用户
const createTime = Date.now();
const lastLoginTime = createTime;
const stmt = userDB.prepare('INSERT INTO user (username, password, createTime, lastLoginTime) VALUES (?, ?, ?, ?)');
const result = stmt.run(username, hashedPassword, createTime, lastLoginTime);
// 生成 JWT
const userId = result.lastInsertRowid as number;
const token = createToken(userId);
userDB.close();
return { token, expiresIn: Date.now() + 168 * 60 * 60 * 1000 };
});
+31
View File
@@ -0,0 +1,31 @@
// import { defineEventHandler, readBody, createError } from 'h3';
import bcrypt from 'bcryptjs';
import BetterSqlite3 from 'better-sqlite3';
export default defineEventHandler(async (event) => {
const body = await readBody(event);
const { oldPassword, newPassword } = body;
const userId = event.context.user.id;
// 查询用户
const userDB = new BetterSqlite3('./userData/db/user.db');
const user: any = userDB.prepare('SELECT * FROM user WHERE id = ?').get(userId);
if (!user || !bcrypt.compareSync(oldPassword, user.password)) {
userDB.close();
throw createError({ statusCode: 401, statusMessage: 'Invalid old password' });
}
// 哈希新密码
const salt = bcrypt.genSaltSync(10);
const hashedPassword = bcrypt.hashSync(newPassword, salt);
// 更新密码
userDB.prepare('UPDATE user SET password = ? WHERE id = ?').run(hashedPassword, userId);
// 生成新的 JWT
const token = createToken(userId);
userDB.close();
return { token , expiresIn: Date.now() + 168 * 60 * 60 * 1000 };
});
+17 -4
View File
@@ -1,12 +1,25 @@
import serverConfig from "../server.config"
// import { verify } from 'jsonwebtoken'
import jwt from 'jsonwebtoken'
import getKey from "../utils/getKey"
const pathNeedAuth = serverConfig.auth.api
export default defineEventHandler((event) => {
// console.log('New request: ' + getRequestURL(event))
const key = getKey()
const path = getRequestURL(event).pathname
if(pathNeedAuth.has(path)){
// console.log('Auth needed')
return true
if (pathNeedAuth.has(path)) {
const authHeader = event.node.req.headers.authorization
if (!authHeader || !authHeader.startsWith('Bearer ')) {
throw createError({ statusCode: 401, statusMessage: 'Unauthorized' })
}
const token = authHeader.split('Bearer ')[1].trim()
try {
const decoded = jwt.verify(token, key)
// 将用户ID挂载到事件对象,供后续使用
// event.context.userId = decoded.userId
} catch (err) {
throw createError({ statusCode: 401, statusMessage: 'Token invalid or expired' })
}
}
})
+1 -1
View File
@@ -1,4 +1,4 @@
export default defineEventHandler((event) => {
checkUserData()
initUserData()
// console.log('New request: ' + getRequestURL(event))
})
+9
View File
@@ -0,0 +1,9 @@
export default function cacheResult<T>(func: () => T): () => T {
let result: any;
return () => {
if (result === undefined) {
result = func();
}
return result;
};
}
-22
View File
@@ -1,22 +0,0 @@
import mkfileIfNotExist from "./mkfileIfNotExist"
let checked = false
/**
* 检查并完善userData的目录结构,若不存在密钥则生成随机的密钥
* @returns {void}
*/
const checkUserData = () => {
if (checked) return
checked = true
// console.log('check userData')
const dirList = [
'./userData/',
'./userData/db/',
'./userData/md/',
]
dirList.forEach(mkdirIfNotExist)
mkfileIfNotExist('./userData/key.txt', new Array(2048).fill(0).map(() => Math.floor(Math.random() * 16).toString(16)).join(''))
}
export default checkUserData
+8
View File
@@ -0,0 +1,8 @@
import jwt from "jsonwebtoken"
import getKey from "./getKey"
export default function createToken(userId: number): string {
const key = getKey()
return jwt.sign({ userId }, key, { expiresIn: '168h' })
}
+7
View File
@@ -0,0 +1,7 @@
import { sign } from 'jsonwebtoken'
import fs from 'fs'
import path from 'path'
const getKey = cacheRes(() => fs.readFileSync(path.join(process.cwd(), 'userData/key.txt'), 'utf-8') as string)
export default getKey
+85
View File
@@ -0,0 +1,85 @@
import mkfileIfNotExist from "./mkfileIfNotExist"
import db from 'better-sqlite3'
let checked = false
/**
* 检查并完善userData的目录结构,若不存在密钥则生成随机的密钥,初始化数据库
* @returns {void}
*/
function checkUserData() {
if (checked) return
checked = true
// console.log('check userData')
const dirList = [
'./userData/',
'./userData/db/',
]
dirList.forEach(mkdirIfNotExist)
mkfileIfNotExist('./userData/key.txt', new Array(2048).fill(0).map(() => Math.floor(Math.random() * 16).toString(16)).join(''))
createDB()
}
function createDB() {
const userDB = new db('./userData/db/user.db');
const postsDB = new db('./userData/db/posts.db');
userDB.exec(`
CREATE TABLE IF NOT EXISTS user (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password TEXT NOT NULL,
createTime INTEGER NOT NULL,
lastLoginTime INTEGER NOT NULL
);
`);
postsDB.exec(`
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
date INTEGER NOT NULL,
summary TEXT NOT NULL,
type TEXT NOT NULL,
url TEXT NOT NULL,
tag_id INTEGER NOT NULL,
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,
tag1 TEXT,
tag2 TEXT,
tag3 TEXT,
tag4 TEXT,
tag5 TEXT,
tag6 TEXT,
tag7 TEXT,
tag8 TEXT,
tag9 TEXT,
tag10 TEXT,
tag11 TEXT,
tag12 TEXT,
tag13 TEXT,
tag14 TEXT,
tag15 TEXT
);
`);
postsDB.close();
userDB.close();
}
export default checkUserData