Skip to content

Commit

Permalink
支持自定义文件压缩
Browse files Browse the repository at this point in the history
  • Loading branch information
MarSeventh committed Sep 28, 2024
1 parent f72a670 commit d90183b
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 44 deletions.
120 changes: 82 additions & 38 deletions src/components/UploadForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</el-icon>
<div class="el-upload__text"><em>拖拽</em> <em>点击</em> 或 <em>Ctrl + V</em> 粘贴上传</div>
<template #tip>
<div class="el-upload__tip">支持多文件上传,支持图片和视频,不超过20MB</div>
<div class="el-upload__tip">支持多文件上传,支持图片和视频,不超过50MB</div>
</template>
</el-upload>
<el-card class="upload-list-card" :class="{'upload-list-busy': fileList.length}">
Expand Down Expand Up @@ -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() {
Expand All @@ -142,7 +162,8 @@ data() {
waitingList: [],
exceptionList: [],
listScrolled: false,
fileListLength: 0
fileListLength: 0,
uploadCount: 0
}
},
watch: {
Expand Down Expand Up @@ -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) => {
Expand Down Expand Up @@ -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,
Expand All @@ -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('文件过大')
Expand Down Expand Up @@ -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;
Expand Down
14 changes: 12 additions & 2 deletions src/store/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -26,6 +33,9 @@ export default createStore({
},
setUploadCopyUrlForm(state, uploadCopyUrlForm) {
state.uploadCopyUrlForm = uploadCopyUrlForm;
},
setCompressConfig(state, { key, value }) {
state.compressConfig[key] = value;
}
},
actions: {
Expand Down
120 changes: 116 additions & 4 deletions src/views/UploadHome.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
<img id="bg1" class="background-image1" alt="Background Image"/>
<img id="bg2" class="background-image2" alt="Background Image"/>
<div class="toolbar">
<el-tooltip content="压缩设置" placement="left">
<el-button class="toolbar-button" size="large" @click="openCompressDialog" circle>
<font-awesome-icon icon="file-archive" class="compress-icon" size="lg"/>
</el-button>
</el-tooltip>
<el-tooltip content="链接格式" placement="left">
<el-button class="toolbar-button" size="large" @click="openUrlDialog" circle>
<font-awesome-icon icon="link" class="link-icon" size="lg"/>
Expand All @@ -25,9 +30,16 @@
</a>
<h1 class="title"><a class="main-title" href="https://github.com/MarSeventh/CloudFlare-ImgBed" target="_blank">{{ ownerName }}</a> ImgHub</h1>
</div>
<UploadForm :selectedUrlForm="selectedUrlForm" class="upload"/>
<UploadForm
:selectedUrlForm="selectedUrlForm"
:customerCompress="customerCompress"
:compressQuality="compressQuality"
:compressBar="compressBar"
:serverCompress="serverCompress"
class="upload"
/>
<Footer/>
<el-dialog title="选择复制链接格式" v-model="showUrlDialog" width="40%" :show-close="false">
<el-dialog title="选择复制链接格式" v-model="showUrlDialog" :width="dialogWidth" :show-close="false">
<el-radio-group v-model="selectedUrlForm" @change="changeUrlForm">
<el-radio value="url">原始链接</el-radio>
<el-radio value="md">MarkDown</el-radio>
Expand All @@ -38,6 +50,46 @@
<el-button type="primary" @click="showUrlDialog = false">确定</el-button>
</div>
</el-dialog>
<el-dialog title="压缩设置" v-model="showCompressDialog" :width="dialogWidth" :show-close="false">
<el-form label-width="25%">
<p style="font-size: medium; font-weight: bold">客户端压缩</p>
<el-form-item label="开启压缩">
<el-switch
v-model="customerCompress"
active-text="开启"
inactive-text="关闭"
active-color="#13ce66"
inactive-color="#ff4949"
/>
</el-form-item>
<el-form-item label="压缩阈值" v-if="customerCompress">
<el-slider v-model="compressBar" :min="1" :max="50" show-input/>
</el-form-item>
<el-form-item label="压缩后大小" v-if="customerCompress">
<el-slider v-model="compressQuality" :min="1" :max="compressBar" show-input/>
</el-form-item>
<p style="font-size: medium; font-weight: bold">服务端压缩</p>
<el-form-item label="开启压缩">
<el-switch
v-model="serverCompress"
active-text="开启"
inactive-text="关闭"
active-color="#13ce66"
inactive-color="#ff4949"
/>
</el-form-item>
<p style="text-align: left;font-size: small;">
<br/>*Tips:
<br/>1.本设置仅针对图片文件,单位为MB
<br/>2.客户端压缩指上传前压缩,服务端压缩指Telegram端压缩
<br/>3.若图片大小>10MB,或压缩后图片大小>10MB,服务端压缩将自动失效!
<br/>4.若图片大小>50MB,将自动进行客户端压缩!
</p>
<div class="dialog-action">
<el-button type="primary" @click="showCompressDialog = false">确定</el-button>
</div>
</el-form>
</el-dialog>
</div>
</template>

Expand All @@ -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'
},
Expand All @@ -71,6 +142,9 @@ export default {
},
bkOpacity() {
return this.userConfig?.bkOpacity || 1
},
dialogWidth() {
return window.innerWidth > 768 ? '40%' : '80%'
}
},
mounted() {
Expand Down Expand Up @@ -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,
Expand All @@ -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 })
}
}
}
Expand All @@ -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% {
Expand Down Expand Up @@ -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;
}
Expand Down

0 comments on commit d90183b

Please sign in to comment.