mirror of
https://github.com/cool-team-official/cool-admin-vue.git
synced 2024-11-01 06:02:38 +08:00
优化 upload 模块
This commit is contained in:
parent
e2470a31bf
commit
07ca7ddadd
@ -24,10 +24,12 @@
|
|||||||
|
|
||||||
<div class="item">
|
<div class="item">
|
||||||
<p>自定义内容</p>
|
<p>自定义内容</p>
|
||||||
<cl-upload text="选择图片" multiple>
|
<cl-upload text="选择图片" multiple drag>
|
||||||
<el-button>上传</el-button>
|
<div style="width: 100%">
|
||||||
<template #item="{ item, index }">
|
<el-button>上传</el-button>
|
||||||
<p>{{ item.url }}</p>
|
</div>
|
||||||
|
<template #item="{ item }">
|
||||||
|
<div class="cs-item">{{ item.url }}</div>
|
||||||
</template>
|
</template>
|
||||||
</cl-upload>
|
</cl-upload>
|
||||||
</div>
|
</div>
|
||||||
@ -63,5 +65,10 @@ const list = computed(() => urls.value.split(",").filter(Boolean));
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cs-item {
|
||||||
|
border: 1px solid var(--el-border-color);
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -6,10 +6,40 @@
|
|||||||
`cl-upload--${type}`,
|
`cl-upload--${type}`,
|
||||||
{
|
{
|
||||||
'is-slot': $slots.default,
|
'is-slot': $slots.default,
|
||||||
|
'is-custom': $slots.item,
|
||||||
'is-disabled': disabled
|
'is-disabled': disabled
|
||||||
}
|
}
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
|
<div class="cl-upload__header">
|
||||||
|
<el-upload
|
||||||
|
ref="Upload"
|
||||||
|
action=""
|
||||||
|
:accept="accept"
|
||||||
|
:show-file-list="false"
|
||||||
|
:before-upload="beforeUpload"
|
||||||
|
:http-request="httpRequest"
|
||||||
|
:headers="headers"
|
||||||
|
:multiple="multiple"
|
||||||
|
:disabled="disabled"
|
||||||
|
>
|
||||||
|
<slot>
|
||||||
|
<template v-if="type == 'image' && isAdd">
|
||||||
|
<div class="cl-upload__item">
|
||||||
|
<el-icon :size="24"><picture-filled /></el-icon>
|
||||||
|
<span class="cl-upload__text">{{ text }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-if="type == 'file'">
|
||||||
|
<div class="cl-upload__btn">
|
||||||
|
<el-button type="success">{{ text }}</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</slot>
|
||||||
|
</el-upload>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<draggable
|
<draggable
|
||||||
v-model="list"
|
v-model="list"
|
||||||
@ -93,36 +123,6 @@
|
|||||||
</slot>
|
</slot>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #header>
|
|
||||||
<el-upload
|
|
||||||
ref="Upload"
|
|
||||||
action=""
|
|
||||||
class="un-drag"
|
|
||||||
:accept="accept"
|
|
||||||
:show-file-list="false"
|
|
||||||
:before-upload="beforeUpload"
|
|
||||||
:http-request="httpRequest"
|
|
||||||
:headers="headers"
|
|
||||||
:multiple="multiple"
|
|
||||||
:disabled="disabled"
|
|
||||||
>
|
|
||||||
<slot>
|
|
||||||
<template v-if="type == 'image' && isAdd">
|
|
||||||
<div class="cl-upload__item">
|
|
||||||
<el-icon :size="24"><picture-filled /></el-icon>
|
|
||||||
<span class="cl-upload__text">{{ text }}</span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-else-if="type == 'file'">
|
|
||||||
<div class="cl-upload__btn">
|
|
||||||
<el-button type="success">{{ text }}</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</slot>
|
|
||||||
</el-upload>
|
|
||||||
</template>
|
|
||||||
</draggable>
|
</draggable>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -142,7 +142,7 @@ import { PictureFilled, ZoomIn, Delete } from "@element-plus/icons-vue";
|
|||||||
import { useCool, module } from "/@/cool";
|
import { useCool, module } from "/@/cool";
|
||||||
import { extname, uuid } from "/@/cool/utils";
|
import { extname, uuid } from "/@/cool/utils";
|
||||||
import { useBase } from "/$/base";
|
import { useBase } from "/$/base";
|
||||||
import { fileSize, fileName } from "../utils";
|
import { fileSize, fileName, fileType } from "../utils";
|
||||||
|
|
||||||
interface Item {
|
interface Item {
|
||||||
url: string;
|
url: string;
|
||||||
@ -257,7 +257,7 @@ function beforeUpload(file: any, item?: Item) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const d = {
|
const d = {
|
||||||
type: file.type?.includes("image") ? "image" : "file",
|
type: fileType(file.name).value,
|
||||||
preload: "",
|
preload: "",
|
||||||
progress: 0,
|
progress: 0,
|
||||||
url: "",
|
url: "",
|
||||||
@ -423,23 +423,6 @@ function check() {
|
|||||||
return list.value.find((e) => e.progress != 100);
|
return list.value.find((e) => e.progress != 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 文件类型
|
|
||||||
function fileType(path: string) {
|
|
||||||
if (props.type == "image") {
|
|
||||||
return "image";
|
|
||||||
} else {
|
|
||||||
if (
|
|
||||||
["bmp", "jpg", "jpeg", "png", "tif", "gif", "svg", "webp"].includes(
|
|
||||||
extname(path).toLocaleLowerCase()
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
return "image";
|
|
||||||
} else {
|
|
||||||
return "file";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新
|
// 更新
|
||||||
function update() {
|
function update() {
|
||||||
const check = list.value.find((e) => !e.url);
|
const check = list.value.find((e) => !e.url);
|
||||||
@ -463,7 +446,7 @@ watch(
|
|||||||
return item;
|
return item;
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
type: fileType(url),
|
type: fileType(url).value,
|
||||||
progress: 0,
|
progress: 0,
|
||||||
uid: uuid(),
|
uid: uuid(),
|
||||||
url,
|
url,
|
||||||
@ -519,34 +502,26 @@ defineExpose({
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-drag {
|
|
||||||
margin: 0 5px 5px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.un-drag {
|
|
||||||
.cl-upload__item {
|
|
||||||
margin-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cl-upload__btn {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--file {
|
&--file {
|
||||||
.cl-upload__list {
|
.cl-upload__list {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.un-drag {
|
&__header {
|
||||||
width: 100%;
|
.cl-upload__item {
|
||||||
}
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__list {
|
&__list {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
margin: 0 5px 0 0;
|
|
||||||
|
.cl-upload__item {
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__text {
|
&__text {
|
||||||
@ -606,7 +581,7 @@ defineExpose({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-file {
|
&:not(.is-image) {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
.cl-upload {
|
.cl-upload {
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
@drop="onDrop"
|
@drop="onDrop"
|
||||||
>
|
>
|
||||||
<!-- 类目 -->
|
<!-- 类目 -->
|
||||||
<Category />
|
<category />
|
||||||
|
|
||||||
<!-- 内容 -->
|
<!-- 内容 -->
|
||||||
<div class="cl-upload-space__content">
|
<div class="cl-upload-space__content">
|
||||||
@ -40,6 +40,7 @@
|
|||||||
:show-file-list="false"
|
:show-file-list="false"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:limit="9999"
|
:limit="9999"
|
||||||
|
:accept="accept"
|
||||||
multiple
|
multiple
|
||||||
@success="onSuccess"
|
@success="onSuccess"
|
||||||
@upload="onUpload"
|
@upload="onUpload"
|
||||||
@ -119,6 +120,8 @@ const props = defineProps({
|
|||||||
limit: Number,
|
limit: Number,
|
||||||
// 是否禁用
|
// 是否禁用
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
|
// 类型
|
||||||
|
accept: String,
|
||||||
// 显示按钮
|
// 显示按钮
|
||||||
showBtn: {
|
showBtn: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -137,7 +140,7 @@ const { app } = useBase();
|
|||||||
const { options } = module.get("upload");
|
const { options } = module.get("upload");
|
||||||
|
|
||||||
// cl-upload
|
// cl-upload
|
||||||
const Upload = ref<any>();
|
const Upload = ref();
|
||||||
|
|
||||||
// 选择图片的数量
|
// 选择图片的数量
|
||||||
const limit = props.limit || options.limit?.select;
|
const limit = props.limit || options.limit?.select;
|
||||||
@ -181,14 +184,6 @@ watch(
|
|||||||
// 是否选中
|
// 是否选中
|
||||||
const isSelected = computed(() => !isEmpty(selection.value));
|
const isSelected = computed(() => !isEmpty(selection.value));
|
||||||
|
|
||||||
// 共享
|
|
||||||
provide("space", {
|
|
||||||
category,
|
|
||||||
selection,
|
|
||||||
refresh,
|
|
||||||
loading
|
|
||||||
});
|
|
||||||
|
|
||||||
// 打开
|
// 打开
|
||||||
function open() {
|
function open() {
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
@ -225,27 +220,33 @@ function onUpload(data: any) {
|
|||||||
list.value.unshift(data);
|
list.value.unshift(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const reqParams = {
|
||||||
|
page: 1
|
||||||
|
};
|
||||||
|
|
||||||
// 刷新资源文件
|
// 刷新资源文件
|
||||||
async function refresh(params: any = {}) {
|
async function refresh(params: any = {}) {
|
||||||
// 清空选择
|
// 清空选择
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
const d = {
|
// 合并参数
|
||||||
|
Object.assign(reqParams, {
|
||||||
|
type: props.accept?.split("/")[0],
|
||||||
...pagination,
|
...pagination,
|
||||||
...params,
|
...params,
|
||||||
classifyId: category.id
|
classifyId: category.id
|
||||||
};
|
});
|
||||||
|
|
||||||
// 加载中
|
// 加载中
|
||||||
if (d.page == 1) {
|
if (reqParams.page == 1) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
await service.space.info.page(d).then((res) => {
|
await service.space.info.page(reqParams).then((res) => {
|
||||||
// 合并
|
// 合并
|
||||||
Object.assign(pagination, res.pagination);
|
Object.assign(pagination, res.pagination);
|
||||||
|
|
||||||
if (d.page == 1) {
|
if (reqParams.page == 1) {
|
||||||
list.value = [];
|
list.value = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,6 +332,14 @@ function loadmore() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 共享
|
||||||
|
provide("space", {
|
||||||
|
category,
|
||||||
|
selection,
|
||||||
|
refresh,
|
||||||
|
loading
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
refresh();
|
refresh();
|
||||||
});
|
});
|
||||||
|
@ -30,11 +30,17 @@
|
|||||||
<span class="cl-upload-space-file__name"
|
<span class="cl-upload-space-file__name"
|
||||||
>{{ fileName(url) }}.{{ extname(url) }}</span
|
>{{ fileName(url) }}.{{ extname(url) }}</span
|
||||||
>
|
>
|
||||||
|
|
||||||
<!-- 大小 -->
|
|
||||||
<span class="cl-upload-space-file__size">{{ fileSize(info.size) }}</span>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 文件类型 -->
|
||||||
|
<span
|
||||||
|
class="cl-upload-space-file__type"
|
||||||
|
:style="{
|
||||||
|
backgroundColor: type.color
|
||||||
|
}"
|
||||||
|
>{{ type.label }}</span
|
||||||
|
>
|
||||||
|
|
||||||
<!-- 进度条 -->
|
<!-- 进度条 -->
|
||||||
<div
|
<div
|
||||||
class="cl-upload-space-file__progress"
|
class="cl-upload-space-file__progress"
|
||||||
@ -56,7 +62,7 @@
|
|||||||
import { computed, inject } from "vue";
|
import { computed, inject } from "vue";
|
||||||
import { ContextMenu } from "@cool-vue/crud";
|
import { ContextMenu } from "@cool-vue/crud";
|
||||||
import { extname } from "/@/cool/utils";
|
import { extname } from "/@/cool/utils";
|
||||||
import { fileSize, fileName } from "../../utils";
|
import { fileName, fileType } from "../../utils";
|
||||||
import { useClipboard } from "@vueuse/core";
|
import { useClipboard } from "@vueuse/core";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
@ -83,6 +89,9 @@ const isSelected = computed(() => index.value >= 0);
|
|||||||
// 地址
|
// 地址
|
||||||
const url = computed(() => info.value.preload || info.value.url);
|
const url = computed(() => info.value.preload || info.value.url);
|
||||||
|
|
||||||
|
// 类型
|
||||||
|
const type = computed(() => fileType(info.value.url));
|
||||||
|
|
||||||
// 选择
|
// 选择
|
||||||
function select() {
|
function select() {
|
||||||
emit("select", info.value);
|
emit("select", info.value);
|
||||||
@ -178,7 +187,7 @@ function onContextMenu(e: any) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.is-file {
|
&:not(.is-image) {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
|
||||||
.cl-upload-space-file {
|
.cl-upload-space-file {
|
||||||
@ -220,6 +229,17 @@ function onContextMenu(e: any) {
|
|||||||
width: calc(100% - 20px);
|
width: calc(100% - 20px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__type {
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
left: 5px;
|
||||||
|
color: #fff;
|
||||||
|
background-color: var(--color-primary);
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
&__error {
|
&__error {
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
color: red;
|
color: red;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { filename } from "/@/cool/utils";
|
import { filename, extname } from "/@/cool/utils";
|
||||||
|
|
||||||
// 文件大小
|
// 文件大小
|
||||||
export function fileSize(size: number): string {
|
export function fileSize(size: number): string {
|
||||||
@ -17,3 +17,37 @@ export function fileSize(size: number): string {
|
|||||||
export function fileName(url: string) {
|
export function fileName(url: string) {
|
||||||
return filename(url.substring(url.indexOf("_") + 1));
|
return filename(url.substring(url.indexOf("_") + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 文件类型
|
||||||
|
export function fileType(path: string) {
|
||||||
|
const fs = [
|
||||||
|
{
|
||||||
|
label: "图片",
|
||||||
|
value: "image",
|
||||||
|
format: ["bmp", "jpg", "jpeg", "png", "tif", "gif", "svg", "webp"],
|
||||||
|
color: "#67C23A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "视频",
|
||||||
|
value: "video",
|
||||||
|
format: ["avi", "wmv", "mpg", "mpeg", "mov", "rm", "ram", "swf", "flv", "mp4"],
|
||||||
|
color: "#409EFF"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "音频",
|
||||||
|
value: "audio",
|
||||||
|
format: ["mp3", "wav", "wma", "mp2", "flac", "midi", "ra", "ape", "aac", "cda"],
|
||||||
|
color: "#E6A23C"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
fs.find((e) => {
|
||||||
|
return e.format.find((a) => a == extname(path).toLocaleLowerCase());
|
||||||
|
}) || {
|
||||||
|
label: "文件",
|
||||||
|
value: "file",
|
||||||
|
color: "#909399"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user