优化upload模块

This commit is contained in:
icssoa 2022-06-30 11:29:55 +08:00
parent bbe4b1cfd8
commit 06ebfe7e60
6 changed files with 207 additions and 128 deletions

View File

@ -1,6 +1,6 @@
{
"name": "front-next",
"version": "5.5.0",
"version": "5.5.1",
"scripts": {
"dev": "vite --host",
"build": "vite build",
@ -9,7 +9,7 @@
"lint:eslint": "eslint \"{src,mock}/**/*.{vue,ts,tsx}\" --fix"
},
"dependencies": {
"@cool-vue/crud": "^5.2.3",
"@cool-vue/crud": "^5.2.7",
"@element-plus/icons-vue": "^1.1.3",
"@vueuse/core": "^8.2.5",
"axios": "^0.27.2",

View File

@ -46,15 +46,10 @@
<!-- 文件 -->
<template v-else>
<div class="cl-upload__icon">
<!-- 图标 -->
<el-icon :size="20"><document /></el-icon>
<!-- 扩展名 -->
<span>{{ extname(item.preload) }}</span>
</div>
<!-- 文件名 -->
<span class="cl-upload__name">{{ fileName(item.preload) }}</span>
<span class="cl-upload__name"
>{{ fileName(item.preload) }}.{{ extname(item.preload) }}</span
>
<!-- 大小 -->
<span class="cl-upload__size">
@ -259,7 +254,7 @@ function beforeUpload(file: any, item?: Item) {
}
const d = {
type: file.type.includes("image") ? "image" : "file",
type: file.type?.includes("image") ? "image" : "file",
preload: "",
progress: 0,
url: "",
@ -289,6 +284,11 @@ function remove(index: number) {
update();
}
//
function clear() {
list.value = [];
}
//
function preview(item: Item) {
if (item.type == "image") {
@ -312,38 +312,39 @@ async function httpRequest(req: any, item?: any) {
//
return new Promise((resolve, reject) => {
async function next(params: any) {
const data = new FormData();
//
async function next({ host, preview, data }: any) {
const fd = new FormData();
for (const i in params) {
if (!["host", "publicDomain", "fileKey", "uploadUrl", "preview"].includes(i)) {
data.append(i, params[i]);
}
//
for (const i in data) {
fd.append(i, data[i]);
}
if (mode == "local") {
data.append("key", fileName);
} else {
//
if (mode == "cloud") {
fileName = [props.prefixPath, dayjs().format("YYYY-MM-DD"), fileName]
.filter(Boolean)
.join("/");
data.append("key", fileName);
}
data.append("file", req.file);
//
fd.append("key", fileName);
//
fd.append("file", req.file);
//
await service
.request({
url: params.host,
url: host,
method: "POST",
headers: {
"Content-Type": "multipart/form-data"
},
timeout: 600000,
data,
onUploadProgress(e: any) {
item.progress = parseInt((e.loaded / e.total) * 100);
data: fd,
onUploadProgress(e: { loaded: number; total: number }) {
item.progress = parseInt(String((e.loaded / e.total) * 100));
emit("progress", item);
},
proxy: mode == "local" ? true : false
@ -352,7 +353,7 @@ async function httpRequest(req: any, item?: any) {
if (mode === "local") {
item.url = res;
} else {
item.url = `${params.preview}/${fileName}`;
item.url = `${preview || host}/${fileName}`;
}
emit("success", item);
@ -375,11 +376,36 @@ async function httpRequest(req: any, item?: any) {
service.base.comm
.upload()
.then((res) => {
switch (type) {
//
case "cos":
next({
host: res.url,
data: res.credentials
});
break;
//
case "oss":
next({
host: res.host,
data: {
OSSAccessKeyId: res.OSSAccessKeyId,
policy: res.policy,
signature: res.signature
}
});
break;
//
case "qiniu":
next({
host: res.uploadUrl,
preview: res.host || res.publicDomain,
...res
preview: res.publicDomain,
data: {
token: res.token
}
});
break;
}
})
.catch(reject);
}
@ -452,8 +478,11 @@ defineExpose({
isAdd,
list,
check,
clear,
remove,
upload(file: File) {
clear();
Upload.value.clearFiles();
Upload.value.handleStart(file);
Upload.value.submit();
}
@ -581,14 +610,11 @@ defineExpose({
}
&__name {
height: 15px;
display: inline-block;
width: 100%;
margin-top: 5px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 13px;
text-align: center;
word-break: break-all;
}
&__size {

View File

@ -8,15 +8,22 @@
<cl-dialog
v-model="visible"
title="文件空间"
height="630px"
width="1000px"
height="650px"
width="1080px"
keep-alive
custom-class="cl-upload-space__dialog"
:close-on-click-modal="false"
append-to-body
:controls="['slot-expand', 'cl-flex1', 'fullscreen', 'close']"
>
<div class="cl-upload-space">
<div
class="cl-upload-space"
:class="{
'is-mini': app.browser.isMini
}"
@dragover="onDragover"
@drop="onDrop"
>
<!-- 类目 -->
<category />
@ -42,7 +49,7 @@
</div>
<el-button type="success" :disabled="!isSelected" @click="confirm()"
>使用选中文件 {{ selection.length }} / {{ limit }}</el-button
>使用选中文件 {{ selection.length }}/{{ limit }}</el-button
>
<el-button type="danger" :disabled="!isSelected" @click="remove()"
@ -55,22 +62,17 @@
class="cl-upload-space__file scroller1"
v-infinite-scroll="loadmore"
v-loading="loading"
@dragover="onDragover"
@drop="onDrop"
>
<!-- 文件列表 -->
<template v-if="list.length > 0">
<div class="cl-upload-space__file-list">
<el-row :gutter="10">
<el-col
:xs="12"
:sm="6"
<div
class="cl-upload-space__file-item"
v-for="item in list"
:key="item.preload || item.url"
>
<file-item :data="item" @select="select" @remove="remove" />
</el-col>
</el-row>
</div>
</div>
</template>
@ -211,7 +213,10 @@ function close() {
//
function onSuccess(data: any) {
service.space.info
.add(data)
.add({
classifyId: category.id,
...data
})
.then((res) => {
data.id = res.id;
})
@ -222,7 +227,6 @@ function onSuccess(data: any) {
//
function onUpload(data: any) {
data.classifyId = category.id;
list.value.unshift(data);
}
@ -316,8 +320,10 @@ function onDragover(e: any) {
function onDrop(e: any) {
e.preventDefault();
e.dataTransfer.files.forEach((f: File) => {
e.dataTransfer.files.forEach((f: File, i: number) => {
setTimeout(() => {
Upload.value.upload(f);
}, i * 10);
});
}
@ -359,7 +365,6 @@ defineExpose({
&__content {
flex: 1;
max-width: 100%;
padding: 0 10px;
box-sizing: border-box;
background-color: #fff;
border-radius: 5px;
@ -370,16 +375,24 @@ defineExpose({
align-items: center;
height: 50px;
overflow: auto hidden;
padding: 0 10px;
}
&__file {
height: calc(100% - 50px);
padding: 0 10px;
box-sizing: border-box;
position: relative;
&-list {
.el-row {
width: 100%;
display: flex;
flex-wrap: wrap;
}
&-item {
height: 150px;
width: 150px;
margin: 0 10px 10px 0;
}
&-empty {
@ -415,5 +428,11 @@ defineExpose({
&__footer {
padding: 9px 0;
}
&.is-mini {
.cl-upload-space__file-list {
justify-content: center;
}
}
}
</style>

View File

@ -7,9 +7,8 @@
}"
>
<div class="cl-upload-space-category__search">
<el-button type="primary" @click="edit()">添加分类</el-button>
<el-input v-model="keyword" placeholder="关键字过滤" clearable />
<el-button type="primary" @click="edit()">添加</el-button>
<el-input v-model="keyword" placeholder="搜索" clearable />
</div>
<div class="cl-upload-space-category__list">
@ -209,7 +208,7 @@ onMounted(() => {
border-radius: 5px;
&.is-show {
width: 250px;
width: 220px;
margin-right: 5px;
}
@ -244,18 +243,20 @@ onMounted(() => {
.item {
list-style: none;
font-size: 14px;
height: 40px;
line-height: 40px;
border-bottom: 1px dashed #eee;
font-size: 13px;
height: 35px;
line-height: 35px;
padding: 0 10px;
cursor: pointer;
background-color: #f7f7f7;
margin-bottom: 10px;
border-radius: 3px;
&.is-active {
color: var(--color-primary);
background-color: #eee;
}
&:not(.cl-context-menu__target):hover {
&:not(.is-active):hover {
background-color: #f7f7f7;
}
}

View File

@ -1,4 +1,5 @@
<template>
<div class="cl-upload-space-file__wrap">
<div
class="cl-upload-space-file"
:class="[`is-${info.type}`]"
@ -25,13 +26,10 @@
<!-- 其他 -->
<template v-else>
<div class="cl-upload-space-file__icon">
<el-icon :size="20"><document /></el-icon>
<span>{{ extname(url) }}</span>
</div>
<!-- 文件名 -->
<span class="cl-upload-space-file__name">{{ fileName(url) }}</span>
<span class="cl-upload-space-file__name"
>{{ fileName(url) }}.{{ extname(url) }}</span
>
<!-- 大小 -->
<span class="cl-upload-space-file__size">{{ fileSize(info.size) }}</span>
@ -51,6 +49,7 @@
<span>{{ index + 1 }}</span>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
@ -98,6 +97,9 @@ function remove() {
//
function onContextMenu(e: any) {
ContextMenu.open(e, {
hover: {
target: "cl-upload-space-file__wrap"
},
list: [
{
label: "预览",
@ -139,7 +141,7 @@ function onContextMenu(e: any) {
flex-direction: column;
align-items: center;
justify-content: center;
height: 160px;
height: 100%;
width: 100%;
cursor: pointer;
position: relative;
@ -149,12 +151,17 @@ function onContextMenu(e: any) {
background-color: #f7f7f7;
margin-bottom: 10px;
&__wrap {
height: 100%;
width: 100%;
}
&.is-image {
overflow: hidden;
:deep(.el-image) {
height: 100%;
width: 100%;
max-height: 100%;
max-width: 100%;
}
.image-error {
@ -164,7 +171,8 @@ function onContextMenu(e: any) {
justify-content: center;
font-size: 14px;
color: #f56c6c;
height: 100%;
height: 150px;
width: 150px;
background-color: #fef0f0;
padding: 10px;
box-sizing: border-box;
@ -188,14 +196,11 @@ function onContextMenu(e: any) {
}
&__name {
height: 15px;
display: inline-block;
width: 100%;
margin-top: 10px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 13px;
text-align: center;
word-break: break-all;
}
&__size {

View File

@ -984,14 +984,14 @@
"@babel/helper-validator-identifier" "^7.16.7"
to-fast-properties "^2.0.0"
"@cool-vue/crud@^5.2.3":
version "5.2.3"
resolved "https://registry.npmjs.org/@cool-vue/crud/-/crud-5.2.3.tgz#05e24d484e7748b71f4dcdf5649fd297113a6ee5"
integrity sha512-LWrfEnFVkIZyVUdCI/hsF3Kl4v0BrsweHMXYW7WBpfDEG/IR9n2mYTZPqFXjlqgX/vWux4YXmD0pg1cIAN2bMQ==
"@cool-vue/crud@^5.2.7":
version "5.2.7"
resolved "https://registry.npmjs.org/@cool-vue/crud/-/crud-5.2.7.tgz#4b3b693887dc077e839b531b7c7b8b2b94ee8c89"
integrity sha512-1HkYUs45vTxtZ3pYmlshnQF0YH6xYAL0txaPGN0QclIZ1DHtoyQBLfouZ+mJSOMfUnj8+RuOKlieDJRDhOK7Yg==
dependencies:
array.prototype.flat "^1.2.4"
core-js "^3.21.1"
element-plus "^2.2.5"
element-plus "^2.2.6"
merge "^2.1.1"
mitt "^3.0.0"
vue "^3.2.31"
@ -1038,6 +1038,13 @@
dependencies:
"@floating-ui/core" "^0.7.3"
"@floating-ui/dom@^0.5.3":
version "0.5.4"
resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-0.5.4.tgz#4eae73f78bcd4bd553ae2ade30e6f1f9c73fe3f1"
integrity sha512-419BMceRLq0RrmTSDxn8hf9R3VCJv2K9PUfugh5JyEFmdjzDo+e8U5EdR8nzKq8Yj1htzLm3b6eQEEam3/rrtg==
dependencies:
"@floating-ui/core" "^0.7.3"
"@hapi/hoek@^9.0.0":
version "9.2.1"
resolved "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.2.1.tgz#9551142a1980503752536b5050fd99f4a7f13b17"
@ -2994,6 +3001,27 @@ element-plus@^2.2.5:
memoize-one "^6.0.0"
normalize-wheel-es "^1.1.2"
element-plus@^2.2.6:
version "2.2.6"
resolved "https://registry.npmjs.org/element-plus/-/element-plus-2.2.6.tgz#60b9e91a2159526123d1b950263de37947153433"
integrity sha512-N9G4yWSxDt1YtreCJgt7UaSsXKuR4Fzb3ThzlBjbGDYDhcHijsrLL3qkdLZgeoSB13LRyr9pgP1ljNXdaYGa+g==
dependencies:
"@ctrl/tinycolor" "^3.4.1"
"@element-plus/icons-vue" "^2.0.5"
"@floating-ui/dom" "^0.5.3"
"@popperjs/core" "npm:@sxzz/popperjs-es@^2.11.7"
"@types/lodash" "^4.14.182"
"@types/lodash-es" "^4.17.6"
"@vueuse/core" "^8.6.0"
async-validator "^4.1.1"
dayjs "^1.11.3"
escape-html "^1.0.3"
lodash "^4.17.21"
lodash-es "^4.17.21"
lodash-unified "^1.0.2"
memoize-one "^6.0.0"
normalize-wheel-es "^1.1.2"
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"