diff --git a/package-lock.json b/package-lock.json
index fdc1ac7..15b5e05 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "sanyue_imghub",
- "version": "2.3.4",
+ "version": "2.4.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sanyue_imghub",
- "version": "2.3.4",
+ "version": "2.4.1",
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@fortawesome/fontawesome-svg-core": "^6.6.0",
diff --git a/src/components/SysCogOthers.vue b/src/components/SysCogOthers.vue
index 19c270a..45e608a 100644
--- a/src/components/SysCogOthers.vue
+++ b/src/components/SysCogOthers.vue
@@ -63,6 +63,33 @@
+
公开浏览
+
+
+
+
+
+
+
+
+
+
+ 开放目录
+
+
+
+
允许公开浏览的目录,多个目录用逗号分隔
+
示例:wallpaper,photos,album
+
支持子目录:2026/lucky,2026/rich
+
访问链接:https://你的域名/browse/2026/lucky
+
+
+
+
+
+
+
+
@@ -83,7 +110,8 @@ data() {
telemetry: {},
randomImageAPI: {},
cloudflareApiToken: {},
- webDAV: {}
+ webDAV: {},
+ publicBrowse: {}
},
// 加载状态
loading: false
diff --git a/src/components/TransformMedia.vue b/src/components/TransformMedia.vue
new file mode 100644
index 0000000..7716c66
--- /dev/null
+++ b/src/components/TransformMedia.vue
@@ -0,0 +1,407 @@
+
+
+
![]()
+
+
+
+
+
+
+
diff --git a/src/components/UploadForm.vue b/src/components/UploadForm.vue
index 5b765e9..6eb5f0a 100644
--- a/src/components/UploadForm.vue
+++ b/src/components/UploadForm.vue
@@ -406,15 +406,18 @@ methods: {
// 并发控制:如果当前上传数已达上限,加入队列等待
if (this.activeUploads >= this.maxConcurrentUploads) {
this.uploadQueue.push(file)
- this.fileList.find(item => item.uid === file.file.uid).status = 'waiting'
+ const waitingItem = this.fileList.find(item => item.uid === file.file.uid)
+ if (waitingItem) waitingItem.status = 'waiting'
return
}
// 开始上传,增加计数
this.activeUploads++
- this.fileList.find(item => item.uid === file.file.uid).status = 'uploading'
+ const uploadingItem = this.fileList.find(item => item.uid === file.file.uid)
+ if (uploadingItem) uploadingItem.status = 'uploading'
- const uploadChannel = this.fileList.find(item => item.uid === file.file.uid).uploadChannel || this.uploadChannel
+ const fileItem = this.fileList.find(item => item.uid === file.file.uid)
+ const uploadChannel = fileItem?.uploadChannel || this.uploadChannel
// 如果上传渠道为外链,直接使用外链上传
if (uploadChannel === 'external') {
@@ -827,35 +830,39 @@ methods: {
}
},
handleSuccess(response, file) {
+ const fileItem = this.fileList.find(item => item.uid === file.uid)
+ if (!fileItem) return // 文件已被删除
+
try {
// 对上传渠道为外链的,不修改链接
- const uploadChannel = this.fileList.find(item => item.uid === file.uid).uploadChannel || this.uploadChannel
+ const uploadChannel = fileItem.uploadChannel || this.uploadChannel
if (uploadChannel !== 'external') {
// 从response.data[0].src中去除/file/前缀
const srcID = response.data[0].src.replace('/file/', '')
- this.fileList.find(item => item.uid === file.uid).url = `${window.location.protocol}//${window.location.host}/file/` + srcID
- this.fileList.find(item => item.uid === file.uid).finalURL = this.rootUrl + srcID
- this.fileList.find(item => item.uid === file.uid).mdURL = ``
- this.fileList.find(item => item.uid === file.uid).htmlURL = `
`
- this.fileList.find(item => item.uid === file.uid).ubbURL = `[img]${this.rootUrl + srcID}[/img]`
- this.fileList.find(item => item.uid === file.uid).srcID = srcID
+ fileItem.url = `${window.location.protocol}//${window.location.host}/file/` + srcID
+ fileItem.finalURL = this.rootUrl + srcID
+ fileItem.mdURL = ``
+ fileItem.htmlURL = `
`
+ fileItem.ubbURL = `[img]${this.rootUrl + srcID}[/img]`
+ fileItem.srcID = srcID
}
- this.fileList.find(item => item.uid === file.uid).progreess = 100
- this.fileList.find(item => item.uid === file.uid).status = 'success'
+ fileItem.progreess = 100
+ fileItem.status = 'success'
// Save to history
- this.saveToHistory(this.fileList.find(item => item.uid === file.uid))
+ this.saveToHistory(fileItem)
this.$message({
type: 'success',
message: this.truncateFilename(file.name) + '上传成功'
})
setTimeout(() => {
- this.fileList.find(item => item.uid === file.uid).status = 'done'
+ const item = this.fileList.find(item => item.uid === file.uid)
+ if (item) item.status = 'done'
}, 1000)
} catch (error) {
this.$message.error(this.truncateFilename(file.name) + '上传失败')
- this.fileList.find(item => item.uid === file.uid).status = 'exception'
+ fileItem.status = 'exception'
}
// 注意:并发控制的 onUploadComplete 已在各上传方法的 finally 中调用
},
@@ -875,8 +882,11 @@ methods: {
}
},
handleError(err, file) {
+ const fileItem = this.fileList.find(item => item.uid === file.uid)
+ if (!fileItem) return // 文件已被删除
+
this.$message.error(this.truncateFilename(file.name) + '上传失败')
- this.fileList.find(item => item.uid === file.uid).status = 'exception'
+ fileItem.status = 'exception'
// 如果开启了自动重试,安排自动重试
if (this.autoReUpload) {
@@ -987,7 +997,10 @@ methods: {
})
},
handleProgress(event) {
- this.fileList.find(item => item.uid === event.file.uid).progreess = event.percent
+ const fileItem = this.fileList.find(item => item.uid === event.file.uid)
+ if (fileItem) {
+ fileItem.progreess = event.percent
+ }
},
copyAll() {
if (this.selectedUrlForm === 'url') {
diff --git a/src/router/index.js b/src/router/index.js
index 425e699..3cccc9d 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -99,6 +99,11 @@ const routes = [
name: 'whiteliston',
component: () => import('../views/WhiteListOn.vue'),
},
+ {
+ path: '/browse/:dir*',
+ name: 'publicBrowse',
+ component: () => import('../views/PublicBrowse.vue'),
+ },
{
path: '/:pathMatch(.*)*',
name: 'notFound',
diff --git a/src/views/PublicBrowse.vue b/src/views/PublicBrowse.vue
new file mode 100644
index 0000000..37d8186
--- /dev/null
+++ b/src/views/PublicBrowse.vue
@@ -0,0 +1,1338 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ getFolderName(folder.name) }}
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ previewIndex + 1 }} / {{ mediaFiles.length }}
+
+
+
+
+
+
+
+
+