升级 Vite 并补齐管理子路径鉴权参数
This commit is contained in:
+2
-2
@@ -11,8 +11,8 @@ LionWebsite 是一个基于 Vue 3 + Vite 构建的漫画/Gallery 下载与管理
|
|||||||
| 技术 | 用途 |
|
| 技术 | 用途 |
|
||||||
|------|------|
|
|------|------|
|
||||||
| **Vue 3** (Composition API, `<script setup>`) | 前端框架 |
|
| **Vue 3** (Composition API, `<script setup>`) | 前端框架 |
|
||||||
| **Vite 5** | 构建工具 |
|
| **Vite 8** | 构建工具 |
|
||||||
| **Element Plus 2.2** | UI 组件库 |
|
| **Element Plus 2** | UI 组件库 |
|
||||||
| **Vuex 4** | 状态管理 |
|
| **Vuex 4** | 状态管理 |
|
||||||
| **Axios** | HTTP 请求 |
|
| **Axios** | HTTP 请求 |
|
||||||
| **qs** | URL 序列化 |
|
| **qs** | URL 序列化 |
|
||||||
|
|||||||
Generated
+598
-519
File diff suppressed because it is too large
Load Diff
+4
-3
@@ -5,7 +5,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"test": "node --test tests/*.test.mjs"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.0.0",
|
"axios": "^1.0.0",
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
"vuex": "^4.0.2"
|
"vuex": "^4.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^5.0.0",
|
"@vitejs/plugin-vue": "6.0.9",
|
||||||
"vite": "^5.0.10"
|
"vite": "8.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
<el-dialog title="查询" v-model="chosenGallery" style="height: 350px">
|
<el-dialog title="查询" v-model="chosenGallery" style="height: 350px">
|
||||||
<el-image v-show='chosenGallery.thumb_link !== undefined'
|
<el-image v-show='chosenGallery.thumb_link !== undefined'
|
||||||
style="float: right; width: 250px; height: 250px;" fit="contain"
|
style="float: right; width: 250px; height: 250px;" fit="contain"
|
||||||
:src="chosenGallery.thumb_link !== undefined ? 'https://downloader.lionwebsite.xyz/GalleryManage/ehThumbnail?path=' + chosenGallery.thumb_link: ''"/>
|
:src="chosenGallery.thumb_link !== undefined ? thumbnailUrl(chosenGallery.thumb_link) : ''"/>
|
||||||
<table>
|
<table>
|
||||||
<tr>名字:{{chosenGallery.name}}</tr>
|
<tr>名字:{{chosenGallery.name}}</tr>
|
||||||
<tr>页数:{{chosenGallery.pages}}</tr>
|
<tr>页数:{{chosenGallery.pages}}</tr>
|
||||||
@@ -293,6 +293,13 @@ function readOnlineGallery(gallery){
|
|||||||
store.dispatch("readOnlineGallery", gallery)
|
store.dispatch("readOnlineGallery", gallery)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function thumbnailUrl(path) {
|
||||||
|
return "https://downloader.lionwebsite.xyz/GalleryManage/ehThumbnail?" + new URLSearchParams({
|
||||||
|
path,
|
||||||
|
AuthCode: store.state.AuthCode
|
||||||
|
}).toString()
|
||||||
|
}
|
||||||
|
|
||||||
function resetUndone(){
|
function resetUndone(){
|
||||||
store.dispatch("resetUndone").then()
|
store.dispatch("resetUndone").then()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,6 +65,13 @@ function queryRemoteTask(){
|
|||||||
function close(){
|
function close(){
|
||||||
emit("close")
|
emit("close")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function thumbnailUrl(path) {
|
||||||
|
return "https://downloader.lionwebsite.xyz/GalleryManage/ehThumbnail?" + new URLSearchParams({
|
||||||
|
path,
|
||||||
|
AuthCode: store.state.AuthCode
|
||||||
|
}).toString()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -74,8 +81,8 @@ function close(){
|
|||||||
</div>
|
</div>
|
||||||
<el-scrollbar height="75vh" ref="scrollBar">
|
<el-scrollbar height="75vh" ref="scrollBar">
|
||||||
<div style="height: 251px; width: 100%; " v-for="gallery in galleries">
|
<div style="height: 251px; width: 100%; " v-for="gallery in galleries">
|
||||||
<el-image alt="picture" :preview-src-list="['https://downloader.lionwebsite.xyz/GalleryManage/ehThumbnail?path=' + gallery.thumbnailUrl,]"
|
<el-image alt="picture" :preview-src-list="[thumbnailUrl(gallery.thumbnailUrl)]"
|
||||||
:src="'https://downloader.lionwebsite.xyz/GalleryManage/ehThumbnail?path=' + gallery.thumbnailUrl"
|
:src="thumbnailUrl(gallery.thumbnailUrl)"
|
||||||
style="height:250px;width:250px;float: left;"
|
style="height:250px;width:250px;float: left;"
|
||||||
fit="contain"
|
fit="contain"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
@@ -121,4 +128,4 @@ function close(){
|
|||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
to { transform: rotate(360deg); }
|
to { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+16
-4
@@ -19,7 +19,7 @@ axios.interceptors.response.use(
|
|||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
reconnect(context) {
|
reconnect(context) {
|
||||||
axios.post(GalleryManageUrl + "/reconnect", {
|
axios.post(GalleryManageUrl + "/reconnect", null, {
|
||||||
params: {
|
params: {
|
||||||
AuthCode: context.state.AuthCode
|
AuthCode: context.state.AuthCode
|
||||||
}
|
}
|
||||||
@@ -181,7 +181,9 @@ const actions = {
|
|||||||
if(gallery.images !== undefined && gallery.images.length !== 0)
|
if(gallery.images !== undefined && gallery.images.length !== 0)
|
||||||
context.commit("_setReadingGallery", gallery)
|
context.commit("_setReadingGallery", gallery)
|
||||||
else
|
else
|
||||||
axios.post(GalleryManageUrl + "/cache?url=" + gallery.link).then((res) => {
|
return axios.post(GalleryManageUrl + "/cache", null, {
|
||||||
|
params: {url: gallery.link, AuthCode: context.state.AuthCode}
|
||||||
|
}).then((res) => {
|
||||||
if (res.data.result === 'success') {
|
if (res.data.result === 'success') {
|
||||||
gallery.pages = res.data.data.pages
|
gallery.pages = res.data.data.pages
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@@ -243,7 +245,10 @@ const mutations = {
|
|||||||
//处理名字
|
//处理名字
|
||||||
task.shortName = getShortname(task.name)
|
task.shortName = getShortname(task.name)
|
||||||
if(task.thumb_link.trim() !== '')
|
if(task.thumb_link.trim() !== '')
|
||||||
task.thumb_link = GalleryManageUrl + "/ehThumbnail?path=" + task.thumb_link
|
task.thumb_link = buildGalleryManageUrl("/ehThumbnail", {
|
||||||
|
path: task.thumb_link,
|
||||||
|
AuthCode: state.AuthCode
|
||||||
|
})
|
||||||
else
|
else
|
||||||
delete task.thumb_link
|
delete task.thumb_link
|
||||||
|
|
||||||
@@ -396,7 +401,10 @@ const mutations = {
|
|||||||
if(gallery.images === undefined) {
|
if(gallery.images === undefined) {
|
||||||
gallery.images = []
|
gallery.images = []
|
||||||
for(let i=1; i<=gallery.pages; i++)
|
for(let i=1; i<=gallery.pages; i++)
|
||||||
gallery.images.push(GalleryManageUrl + "/onlineImage/" + i + "?gid=" + gallery.gid);
|
gallery.images.push(buildGalleryManageUrl("/onlineImage/" + i, {
|
||||||
|
gid: gallery.gid,
|
||||||
|
AuthCode: state.AuthCode
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
state.readingGallery = gallery
|
state.readingGallery = gallery
|
||||||
state.isReading = true;
|
state.isReading = true;
|
||||||
@@ -499,6 +507,10 @@ function buildGalleryDownloadUrl(gid, AuthCode){
|
|||||||
return GalleryManageUrl + "/file/" + gid + ".zip?" + params.toString()
|
return GalleryManageUrl + "/file/" + gid + ".zip?" + params.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildGalleryManageUrl(path, params){
|
||||||
|
return GalleryManageUrl + path + "?" + new URLSearchParams(params).toString()
|
||||||
|
}
|
||||||
|
|
||||||
function confirmCurrentTask(state){
|
function confirmCurrentTask(state){
|
||||||
switch (state.category){
|
switch (state.category){
|
||||||
case 'myDownload':
|
case 'myDownload':
|
||||||
|
|||||||
+46
-1
@@ -8,9 +8,11 @@ function fixture() {
|
|||||||
.replace(/^import .*$/gm, '')
|
.replace(/^import .*$/gm, '')
|
||||||
.replace('export default new vuex.Store(', 'globalThis.store = new vuex.Store(')
|
.replace('export default new vuex.Store(', 'globalThis.store = new vuex.Store(')
|
||||||
const messages = []
|
const messages = []
|
||||||
|
const showMessage = message => messages.push(message)
|
||||||
|
showMessage.error = message => messages.push(message)
|
||||||
const axios = {interceptors: {response: {use() {}}}}
|
const axios = {interceptors: {response: {use() {}}}}
|
||||||
const context = vm.createContext({axios, vuex: {Store: function (config) {Object.assign(this, config)}},
|
const context = vm.createContext({axios, vuex: {Store: function (config) {Object.assign(this, config)}},
|
||||||
ElMessage: message => messages.push(message), URLSearchParams, console,
|
ElMessage: showMessage, URLSearchParams, console,
|
||||||
qs: {stringify: () => ''}})
|
qs: {stringify: () => ''}})
|
||||||
vm.runInContext(code, context)
|
vm.runInContext(code, context)
|
||||||
const store = context.store
|
const store = context.store
|
||||||
@@ -48,3 +50,46 @@ test('submission reloads persisted status without duplicating a completed task',
|
|||||||
assert.equal(store.state.totalGalleryTask[0].status, '下载完成')
|
assert.equal(store.state.totalGalleryTask[0].status, '下载完成')
|
||||||
assert.equal(store.state.chosenGallery, false)
|
assert.equal(store.state.chosenGallery, false)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('gallery management subrequests carry the active auth code', async () => {
|
||||||
|
const {store, axios, api} = fixture()
|
||||||
|
store.state.AuthCode = 'test-auth'
|
||||||
|
let call
|
||||||
|
axios.post = async (...args) => {
|
||||||
|
call = args
|
||||||
|
return {data: {result: args[0].endsWith('/cache') ? 'failure' : 'success', data: 'expected test response'}}
|
||||||
|
}
|
||||||
|
await store.actions.reconnect(api)
|
||||||
|
assert.equal(call[0], 'https://downloader.lionwebsite.xyz/GalleryManage/reconnect')
|
||||||
|
assert.equal(call[1], null)
|
||||||
|
assert.equal(call[2].params.AuthCode, 'test-auth')
|
||||||
|
|
||||||
|
await store.actions.readOnlineGallery(api, {link: 'https://example.org/g/1/key/', images: []})
|
||||||
|
assert.equal(call[0], 'https://downloader.lionwebsite.xyz/GalleryManage/cache')
|
||||||
|
assert.equal(call[1], null)
|
||||||
|
assert.deepEqual({...call[2].params}, {
|
||||||
|
url: 'https://example.org/g/1/key/',
|
||||||
|
AuthCode: 'test-auth'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('thumbnail and online image URLs carry the active auth code', () => {
|
||||||
|
const {store} = fixture()
|
||||||
|
store.state.AuthCode = 'code with spaces'
|
||||||
|
store.mutations._updateGalleryTasks(store.state, [{
|
||||||
|
gid: 123,
|
||||||
|
name: 'sample',
|
||||||
|
status: '已提交',
|
||||||
|
thumb_link: 'https://example.org/thumb?a=1&b=2',
|
||||||
|
createTime: 1,
|
||||||
|
downloader: 7
|
||||||
|
}])
|
||||||
|
const thumbnail = new URL(store.state.totalGalleryTask[0].thumb_link)
|
||||||
|
assert.equal(thumbnail.searchParams.get('AuthCode'), 'code with spaces')
|
||||||
|
assert.equal(thumbnail.searchParams.get('path'), 'https://example.org/thumb?a=1&b=2')
|
||||||
|
|
||||||
|
store.mutations._setReadingGallery(store.state, {gid: 123, pages: 1})
|
||||||
|
const image = new URL(store.state.readingGallery.images[0])
|
||||||
|
assert.equal(image.searchParams.get('gid'), '123')
|
||||||
|
assert.equal(image.searchParams.get('AuthCode'), 'code with spaces')
|
||||||
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user