From d90183bcfa7bfca7239f5af0e087b7008fd49fb1 Mon Sep 17 00:00:00 2001
From: MarSeventh <1193267292@qq.com>
Date: Sat, 28 Sep 2024 17:05:13 +0800
Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89?=
=?UTF-8?q?=E6=96=87=E4=BB=B6=E5=8E=8B=E7=BC=A9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/UploadForm.vue | 120 +++++++++++++++++++++++-----------
src/store/index.js | 14 +++-
src/views/UploadHome.vue | 120 ++++++++++++++++++++++++++++++++--
3 files changed, 210 insertions(+), 44 deletions(-)
diff --git a/src/components/UploadForm.vue b/src/components/UploadForm.vue
index 670f6d6..a7990d0 100644
--- a/src/components/UploadForm.vue
+++ b/src/components/UploadForm.vue
@@ -19,7 +19,7 @@
拖拽 点击 或 Ctrl + V 粘贴上传
- 支持多文件上传,支持图片和视频,不超过20MB
+ 支持多文件上传,支持图片和视频,不超过50MB
@@ -132,6 +132,26 @@ props: {
type: String,
default: 'url',
required: false
+ },
+ customerCompress: {
+ type: Boolean,
+ default: true,
+ required: false
+ },
+ compressQuality: {
+ type: Number,
+ default: 4,
+ required: false
+ },
+ compressBar: {
+ type: Number,
+ default: 5,
+ required: false
+ },
+ serverCompress: {
+ type: Boolean,
+ default: true,
+ required: false
}
},
data() {
@@ -142,7 +162,8 @@ data() {
waitingList: [],
exceptionList: [],
listScrolled: false,
- fileListLength: 0
+ fileListLength: 0,
+ uploadCount: 0
}
},
watch: {
@@ -199,8 +220,10 @@ methods: {
}
const formData = new FormData()
formData.append('file', file.file)
+ // 判断是否需要服务端压缩
+ const needServerCompress = this.fileList.find(item => item.uid === file.file.uid).serverCompress
axios({
- url: '/upload' + '?authCode=' + cookies.get('authCode'),
+ url: '/upload' + '?authCode=' + cookies.get('authCode') + '&serverCompress=' + needServerCompress,
method: 'post',
data: formData,
onUploadProgress: (progressEvent) => {
@@ -300,39 +323,11 @@ methods: {
},
beforeUpload(file) {
return new Promise((resolve, reject) => {
- const isLt5M = file.size / 1024 / 1024 < 5
- const isLt20M = file.size / 1024 / 1024 < 20
- if (!isLt5M && file.type.includes('image')) {
- //尝试压缩图片
- imageConversion.compressAccurately(file, 4096).then((res) => {
- //如果压缩后仍大于20MB,则不上传
- if (res.size / 1024 / 1024 > 20) {
- this.$message.error(file.name + '压缩后文件过大,无法上传!')
- reject('文件过大')
- }
- this.uploading = true
- //将res包装成新的file
- const newFile = new File([res], file.name, { type: res.type })
- newFile.uid = file.uid
- const fileUrl = URL.createObjectURL(newFile)
- this.fileList.push({
- uid: file.uid,
- name: file.name,
- url: fileUrl,
- finalURL: '',
- mdURL: '',
- htmlURL: '',
- ubbURL: '',
- status: 'uploading',
- progreess: 0
- })
- resolve(newFile)
- }).catch((err) => {
- this.$message.error(file.name + '文件过大且压缩失败,无法上传!')
- reject(err)
- })
- } else if (isLt20M) {
- this.uploading = true
+ // 客户端压缩条件:1.文件类型为图片 2.开启客户端压缩,且文件大小大于压缩阈值;或文件大小大于50MB
+ const needCustomCompress = file.type.includes('image') && (this.customerCompress && file.size / 1024 / 1024 > this.compressBar || file.size / 1024 / 1024 > 50)
+ const isLt50M = file.size / 1024 / 1024 < 50
+
+ const pushFileToQueue = (file, serverCompress) => {
const fileUrl = URL.createObjectURL(file)
this.fileList.push({
uid: file.uid,
@@ -343,9 +338,58 @@ methods: {
htmlURL: '',
ubbURL: '',
status: 'uploading',
- progreess: 0
+ progreess: 0,
+ serverCompress: serverCompress
})
resolve(file)
+ }
+
+ if (needCustomCompress) {
+ //尝试压缩图片
+ imageConversion.compressAccurately(file, 1024 * this.compressQuality).then((res) => {
+ //如果压缩后大于50MB,则不上传
+ if (res.size / 1024 / 1024 > 50) {
+ this.$message.error(file.name + '压缩后文件过大,无法上传!')
+ reject('文件过大')
+ }
+ this.uploading = true
+ //将res包装成新的file
+ const newFile = new File([res], file.name, { type: res.type })
+ newFile.uid = file.uid
+
+ const myUploadCount = this.uploadCount++
+
+ //开启服务端压缩条件:1.开启服务端压缩 2.文件大小小于10MB
+ const needServerCompress = this.serverCompress && newFile.size / 1024 / 1024 < 10
+
+ if (myUploadCount === 0) {
+ pushFileToQueue(newFile, needServerCompress)
+ } else {
+ setTimeout(() => {
+ pushFileToQueue(newFile, needServerCompress)
+ this.uploadCount--
+ }, 300 * myUploadCount)
+ }
+ }).catch((err) => {
+ this.$message.error(file.name + '压缩失败,无法上传!')
+ reject(err)
+ })
+ } else if (isLt50M) {
+ this.uploading = true
+
+ const myUploadCount = this.uploadCount++
+
+ // 开启服务端压缩条件:1.开启服务端压缩 2.如果为图片,则文件大小小于10MB,否则不限制大小
+ const needServerCompress = this.serverCompress && (file.type.includes('image') ? file.size / 1024 / 1024 < 10 : true)
+
+ if (myUploadCount === 0) {
+ pushFileToQueue(file, needServerCompress)
+ } else {
+ setTimeout(() => {
+ pushFileToQueue(file, needServerCompress)
+ this.uploadCount--
+ }, 300 * myUploadCount)
+ }
} else {
this.$message.error(file.name + '文件过大,无法上传!')
reject('文件过大')
@@ -742,7 +786,7 @@ methods: {
justify-content: space-between;
align-items: center;
height: 7vh;
- padding: 0 20px;
+ padding: 0 15px;
position: sticky;
top: 0;
z-index: 1;
diff --git a/src/store/index.js b/src/store/index.js
index af8980b..f8b4cf4 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -6,13 +6,20 @@ export default createStore({
userConfig: null,
bingWallPapers: [],
credentials: null,
- uploadCopyUrlForm: ''
+ uploadCopyUrlForm: '',
+ compressConfig: {
+ customerCompress: true,
+ compressQuality: 4,
+ compressBar: 5,
+ serverCompress: true,
+ },
},
getters: {
userConfig: state => state.userConfig,
bingWallPapers: state => state.bingWallPapers,
credentials: state => state.credentials,
- uploadCopyUrlForm: state => state.uploadCopyUrlForm
+ uploadCopyUrlForm: state => state.uploadCopyUrlForm,
+ compressConfig: state => state.compressConfig,
},
mutations: {
setUserConfig(state, userConfig) {
@@ -26,6 +33,9 @@ export default createStore({
},
setUploadCopyUrlForm(state, uploadCopyUrlForm) {
state.uploadCopyUrlForm = uploadCopyUrlForm;
+ },
+ setCompressConfig(state, { key, value }) {
+ state.compressConfig[key] = value;
}
},
actions: {
diff --git a/src/views/UploadHome.vue b/src/views/UploadHome.vue
index d603cf3..6d6b313 100644
--- a/src/views/UploadHome.vue
+++ b/src/views/UploadHome.vue
@@ -3,6 +3,11 @@
-
+
-
+
原始链接
MarkDown
@@ -38,6 +50,46 @@
确定
+
+
+ 客户端压缩
+
+
+
+
+
+
+
+
+
+ 服务端压缩
+
+
+
+
+
*Tips:
+
1.本设置仅针对图片文件,单位为MB
+
2.客户端压缩指上传前压缩,服务端压缩指Telegram端压缩
+
3.若图片大小>10MB,或压缩后图片大小>10MB,服务端压缩将自动失效!
+
4.若图片大小>50MB,将自动进行客户端压缩!
+
+
+ 确定
+
+
+
@@ -55,11 +107,30 @@ export default {
selectedUrlForm: ref(''),
showUrlDialog: false,
bingWallPaperIndex: 0,
- customWallPaperIndex: 0
+ customWallPaperIndex: 0,
+ showCompressDialog: false,
+ customerCompress: true, //上传前压缩
+ compressQuality: 4, //压缩后大小
+ compressBar: 5, //压缩阈值
+ serverCompress: true, //服务器端压缩
+ }
+ },
+ watch: {
+ customerCompress(val) {
+ this.updateCompressConfig('customerCompress', val)
+ },
+ compressQuality(val) {
+ this.updateCompressConfig('compressQuality', val)
+ },
+ compressBar(val) {
+ this.updateCompressConfig('compressBar', val)
+ },
+ serverCompress(val) {
+ this.updateCompressConfig('serverCompress', val)
}
},
computed: {
- ...mapGetters(['userConfig', 'bingWallPapers', 'uploadCopyUrlForm']),
+ ...mapGetters(['userConfig', 'bingWallPapers', 'uploadCopyUrlForm', 'compressConfig']),
ownerName() {
return this.userConfig?.ownerName || 'Sanyue'
},
@@ -71,6 +142,9 @@ export default {
},
bkOpacity() {
return this.userConfig?.bkOpacity || 1
+ },
+ dialogWidth() {
+ return window.innerWidth > 768 ? '40%' : '80%'
}
},
mounted() {
@@ -126,6 +200,11 @@ export default {
}
// 读取用户选择的链接格式
this.selectedUrlForm = this.uploadCopyUrlForm || 'url'
+ // 读取用户选择的压缩设置
+ this.customerCompress = this.compressConfig.customerCompress
+ this.compressQuality = this.compressConfig.compressQuality
+ this.compressBar = this.compressConfig.compressBar
+ this.serverCompress = this.compressConfig.serverCompress
},
components: {
UploadForm,
@@ -145,6 +224,12 @@ export default {
},
changeUrlForm() {
this.$store.commit('setUploadCopyUrlForm', this.selectedUrlForm)
+ },
+ openCompressDialog() {
+ this.showCompressDialog = true
+ },
+ updateCompressConfig(key, value) {
+ this.$store.commit('setCompressConfig', { key, value })
}
}
}
@@ -156,6 +241,11 @@ export default {
animation: spin 2s ease-in-out; /* 动画时长为2秒,执行一次 */
}
+/* 定义放大缩小动画 */
+.scale {
+ animation: scale 0.5s ease-in-out; /* 动画时长为0.5秒,执行一次 */
+}
+
/* 关键帧:先顺时针旋转,再逆时针旋转 */
@keyframes spin {
0% {
@@ -208,8 +298,30 @@ export default {
}
}
+/* 关键帧:放大缩小 */
+@keyframes scale {
+ 0% {
+ transform: scale(1); /* 初始大小 */
+ }
+ 25% {
+ transform: scale(1.2); /* 放大20% */
+ }
+ 50% {
+ transform: scale(1); /* 回到初始大小 */
+ }
+ 75% {
+ transform: scale(1.2); /* 放大20% */
+ }
+ 100% {
+ transform: scale(1); /* 回到初始大小 */
+ }
+}
+
/* 非移动端时的图标动画样式 */
@media (min-width: 768px) {
+ .compress-icon:hover {
+ animation: scale 1s ease-in-out;
+ }
.config-icon:hover {
animation: spin 2s ease-in-out;
}