|
@@ -1,5 +1,8 @@
|
|
|
<template>
|
|
|
- <div class="cus-form-column-upload-com" :class="{'cus-form-column-upload-com_view': view}" v-loading="loading" :element-loading-background="elementLoadingBackground" style="width: 100%;">
|
|
|
+ <div class="cus-form-column-upload-com"
|
|
|
+ :class="{'cus-form-column-upload-com_view': view, 'cus-form-column-upload-com_list': layout === 'list', 'cus-form-column-upload-com_card': layout === 'card'}"
|
|
|
+ v-loading="loading"
|
|
|
+ :element-loading-background="elementLoadingBackground">
|
|
|
<el-upload
|
|
|
class="el-upload-com"
|
|
|
ref="ref_upload"
|
|
@@ -16,8 +19,8 @@
|
|
|
>
|
|
|
<el-tooltip :content="acceptTooltipCpt" placement="top" popper-class="upload-tooltip-popper">
|
|
|
<template v-if="layout === 'card'">
|
|
|
- <div class="upload-layout-card __hover" >
|
|
|
- <SvgIcon name="add" color="#0062E9"/>
|
|
|
+ <div class="upload-layout-card __hover" :class="{'limit-disabled': isLimitCpt}">
|
|
|
+ <SvgIcon name="add" color="#0062E9" size="24"/>
|
|
|
<div>选择{{acceptTypeFormatCpt}}</div>
|
|
|
<div v-if="limit > 0">(最多{{ limit }}个)</div>
|
|
|
</div>
|
|
@@ -25,31 +28,47 @@
|
|
|
<template v-else>
|
|
|
<div class="upload-layout-list_button" :class="{'limit-disabled': isLimitCpt}">
|
|
|
<SvgIcon name="add" color="#ffffff" size="14"/>
|
|
|
- 选择{{acceptTypeFormatCpt}}<template v-if="limit > 0">(最多{{ limit }}个)</template>
|
|
|
+ 选择{{acceptTypeFormatCpt}}
|
|
|
+ <template v-if="limit > 0">(最多{{ limit }}个)</template>
|
|
|
</div>
|
|
|
</template>
|
|
|
</el-tooltip>
|
|
|
<template #file="{file}">
|
|
|
<template v-if="layout === 'card'">
|
|
|
- <div class="upload-layout-card_item" :class="{'item-view': view || !delRule(file)}" @mouseenter="file.hover = true" @mouseleave="file.hover = false">
|
|
|
- <template v-if="validImgByUrl(file.fUrl)">
|
|
|
- <img class="img __hover" :src="$util.proxyNginxUrl(file.fUrl)"/>
|
|
|
- </template>
|
|
|
- <template v-else>
|
|
|
- <img class="file" :src="getFileImgByUrl(file.fUrl)"/>
|
|
|
- </template>
|
|
|
- <img class="del __hover" src="@/assets/images/cus/file-del.png" v-if="file.hover && !view && delRule(file)" @click.stop="ref_upload.handleRemove(file)"/>
|
|
|
- </div>
|
|
|
+ <el-tooltip placement="top" :content="file[nameKey] ?? file[urlKey]">
|
|
|
+ <div class="upload-layout-card_item" :class="{'item-view': view || !delRule(file)}" @mouseenter="file.hover = true" @mouseleave="file.hover = false">
|
|
|
+ <template v-if="validImgByUrl(file[urlKey])">
|
|
|
+ <img class="img __hover" :src="$util.proxyNginxUrl(file[urlKey])" @click="viewImg(file[urlKey])"/>
|
|
|
+ </template>
|
|
|
+ <template v-else-if="validVideoByUrl(file[urlKey])">
|
|
|
+ <video class="video __hover" controls :src="$util.proxyNginxUrl(file[urlKey])"/>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <img class="file __hover" :src="getFileImgByUrl(file[urlKey])" @click="downloadFileByUrl(file[urlKey], file[nameKey])"/>
|
|
|
+ </template>
|
|
|
+ <img class="del __hover" src="@/assets/images/cus/file-del.png" v-if="file.hover && !view && delRule(file)" @click.stop="ref_upload.handleRemove(file)"/>
|
|
|
+ </div>
|
|
|
+ </el-tooltip>
|
|
|
</template>
|
|
|
<template v-else>
|
|
|
- <div class="upload-layout-list_item __hover" :class="{'item-view': view || !delRule(file)}" @click="downloadFileByUrl(file.fUrl, file.fName)">
|
|
|
- <img class="file-type-img" :src="getFileImgByUrl(file.fUrl)"/>
|
|
|
- <CusEllipsis class="label" :value="file.fUrl"/>
|
|
|
+ <div class="upload-layout-list_item __hover" :class="{'item-view': view || !delRule(file)}" @click="validImgByUrl(file[urlKey]) ? viewImg(file[urlKey]) : downloadFileByUrl(file[urlKey], file[nameKey])">
|
|
|
+ <img class="file-type-img" :src="getFileImgByUrl(file[urlKey])"/>
|
|
|
+ <CusEllipsis v-if="file[nameKey] ?? file[urlKey]" class="label" :value="file[nameKey] ?? file[urlKey]"/>
|
|
|
<SvgIcon v-if="!view && delRule(file)" class="close" name="close_2" size="12" @click.stop="ref_upload.handleRemove(file)"/>
|
|
|
</div>
|
|
|
</template>
|
|
|
</template>
|
|
|
</el-upload>
|
|
|
+ <el-image-viewer
|
|
|
+ v-if="currentImg.show"
|
|
|
+ :zoom-rate="2"
|
|
|
+ :max-scale="10"
|
|
|
+ :min-scale="0.2"
|
|
|
+ :hide-on-click-modal="true"
|
|
|
+ :url-list="[currentImg.url]"
|
|
|
+ :initial-index="0"
|
|
|
+ @close="imageClose"
|
|
|
+ />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
@@ -92,10 +111,15 @@ export default defineComponent({
|
|
|
layout: {default: 'list', validator(val: string) {
|
|
|
return ['list', 'card'].includes(val)
|
|
|
}},
|
|
|
- acceptType: {default: ''},
|
|
|
- acceptMax: {default: 0},
|
|
|
+ acceptType: {default: '', type: String},
|
|
|
+ acceptMax: {default: 0, type: Number},
|
|
|
+ acceptFunc: {default: () => (options) => {}},
|
|
|
view: {default: false},
|
|
|
- delRule: {default: () => () => false}
|
|
|
+ delRule: {default: () => () => false},
|
|
|
+ cardWidth: {default: '147px'},
|
|
|
+ cardHeight: {default: '128px'},
|
|
|
+ urlKey: {default: 'url'},
|
|
|
+ nameKey: {default: 'name'}
|
|
|
},
|
|
|
setup(props, { emit }) {
|
|
|
const store = useStore();
|
|
@@ -106,6 +130,10 @@ export default defineComponent({
|
|
|
paramVal: <any>props.param,
|
|
|
loading: true,
|
|
|
elementLoadingBackground: inject('element-loading-background', null),
|
|
|
+ currentImg: {
|
|
|
+ show: false,
|
|
|
+ url: ''
|
|
|
+ }
|
|
|
})
|
|
|
watch(() => state.paramVal, (n) => {
|
|
|
emit('emitParam', n)
|
|
@@ -123,6 +151,15 @@ export default defineComponent({
|
|
|
}
|
|
|
return false
|
|
|
}
|
|
|
+ const validVideoByUrl = (url) => {
|
|
|
+ if (url) {
|
|
|
+ const videoList = ['avi', 'mp4', 'mov', 'wmv', 'flv', 'mkv', 'mpeg', '3gp'];
|
|
|
+ //进行图片匹配
|
|
|
+ let result = [...videoList.map(v => v.toLowerCase()), ...videoList.map(v => v.toUpperCase())].some((t) => url.includes('.' + t));
|
|
|
+ return result
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ }
|
|
|
const acceptTypeCpt = computed(() => {
|
|
|
let str = ''
|
|
|
if (that.$util.isValue(props.acceptType)) {
|
|
@@ -223,9 +260,16 @@ export default defineComponent({
|
|
|
}
|
|
|
return file
|
|
|
}
|
|
|
- const handleRequest = (options) => {
|
|
|
+ const handleRequest = async (options) => {
|
|
|
+ state.loading = true
|
|
|
if (that.$util.isValue(props.acceptType)) {
|
|
|
-
|
|
|
+ const result: any = await props.acceptFunc(options)
|
|
|
+ if (result?.[props.urlKey] && result?.[props.nameKey]) {
|
|
|
+ state.paramVal = [...state.paramVal, result]
|
|
|
+ } else {
|
|
|
+ state.paramVal = [...state.paramVal]
|
|
|
+ }
|
|
|
+ state.loading = false
|
|
|
} else {
|
|
|
if (store.state.app.uploadConfig.imgType.split(',').some(v => options.file.name.includes(v))) {
|
|
|
const formData = new FormData();
|
|
@@ -233,10 +277,13 @@ export default defineComponent({
|
|
|
that.$api.uploadPicOnly(formData).then(res => {
|
|
|
if (res?.code === 200) {
|
|
|
state.paramVal = [...state.paramVal, {
|
|
|
- fUrl: res.imgPath,
|
|
|
- fName: res.fileName
|
|
|
+ [props.urlKey]: res.imgPath,
|
|
|
+ [props.nameKey]: res.fileName
|
|
|
}]
|
|
|
}
|
|
|
+ state.loading = false
|
|
|
+ }).catch(() => {
|
|
|
+ state.loading = false
|
|
|
})
|
|
|
} else if (store.state.app.uploadConfig.fileType.split(',').some(v => options.file.name.includes(v))) {
|
|
|
const formData = new FormData();
|
|
@@ -244,10 +291,13 @@ export default defineComponent({
|
|
|
that.$api.uploadFile(formData).then(res => {
|
|
|
if (res?.code === 200) {
|
|
|
state.paramVal = [...state.paramVal, {
|
|
|
- fUrl: res.url,
|
|
|
- fName: res.fileName
|
|
|
+ [props.urlKey]: res.url,
|
|
|
+ [props.nameKey]: res.fileName
|
|
|
}]
|
|
|
}
|
|
|
+ state.loading = false
|
|
|
+ }).catch(() => {
|
|
|
+ state.loading = false
|
|
|
})
|
|
|
}
|
|
|
}
|
|
@@ -297,6 +347,14 @@ export default defineComponent({
|
|
|
};
|
|
|
xhr.send();
|
|
|
}
|
|
|
+ const viewImg = (url) => {
|
|
|
+ state.currentImg.url = url
|
|
|
+ state.currentImg.show = true
|
|
|
+ }
|
|
|
+ const imageClose = () => {
|
|
|
+ state.currentImg.show = false
|
|
|
+ state.currentImg.url = ''
|
|
|
+ }
|
|
|
onMounted(() => {
|
|
|
state.loading = true
|
|
|
store.dispatch('app/LOAD_UPLOAD_CONFIG').then(() => {
|
|
@@ -310,12 +368,15 @@ export default defineComponent({
|
|
|
handleRequest,
|
|
|
handleRemove,
|
|
|
validImgByUrl,
|
|
|
+ validVideoByUrl,
|
|
|
acceptTooltipCpt,
|
|
|
acceptTypeFormatCpt,
|
|
|
getFileImgByUrl,
|
|
|
ref_upload,
|
|
|
downloadFileByUrl,
|
|
|
- isLimitCpt
|
|
|
+ isLimitCpt,
|
|
|
+ viewImg,
|
|
|
+ imageClose
|
|
|
}
|
|
|
},
|
|
|
})
|
|
@@ -323,8 +384,9 @@ export default defineComponent({
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
.cus-form-column-upload-com {
|
|
|
- $uploadWidth: 95px;
|
|
|
- $uploadHeight: 71px;
|
|
|
+ $uploadWidth: v-bind(cardWidth);
|
|
|
+ $uploadHeight: v-bind(cardHeight);
|
|
|
+ width: 100%;
|
|
|
position: relative;
|
|
|
.el-upload-com {
|
|
|
:deep(.el-upload) {
|
|
@@ -357,20 +419,20 @@ export default defineComponent({
|
|
|
line-height: 1;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
- > img {
|
|
|
- margin-bottom: 4px;
|
|
|
+ background-color: rgba(46, 129, 255, 0.04);
|
|
|
+ .svg-icon {
|
|
|
+ margin-bottom: 10px;
|
|
|
+ opacity: 0.5;
|
|
|
}
|
|
|
> div {
|
|
|
- font-size: 20px;
|
|
|
+ font-size: 14px;
|
|
|
font-family: PingFang SC-Regular, PingFang SC;
|
|
|
font-weight: 400;
|
|
|
- color: #FFFFFF;
|
|
|
- transform: scale(0.5);
|
|
|
- line-height: 12px;
|
|
|
-
|
|
|
- &:last-child {
|
|
|
- color: rgba(255, 255, 255, 0.6);
|
|
|
- }
|
|
|
+ color: rgba(0,98,233,0.5);
|
|
|
+ }
|
|
|
+ &.limit-disabled {
|
|
|
+ cursor: no-drop;
|
|
|
+ opacity: 0.5;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -406,6 +468,11 @@ export default defineComponent({
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
}
|
|
|
+ .video {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ object-fit: fill;
|
|
|
+ }
|
|
|
.file {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
@@ -429,5 +496,19 @@ export default defineComponent({
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+ &.cus-form-column-upload-com_card {
|
|
|
+ .el-upload-com {
|
|
|
+ :deep(.el-upload) {
|
|
|
+ width: $uploadWidth;
|
|
|
+ height: $uploadHeight;
|
|
|
+ }
|
|
|
+ :deep(.el-upload-list) {
|
|
|
+ .el-upload-list__item {
|
|
|
+ width: $uploadWidth;
|
|
|
+ height: $uploadHeight;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|