模板代码:
定义变量:
文件限制的函数:
上传的函数:
样式函数:
完整代码:
<template>
<div class="dialog-upload" v-if="showUploadDialog">
<div class="dialog-upload__head">
<div class="title">上传图片</div>
<div class="close" @click="closeDialog"></div>
</div>
<div class="dialog-upload__body">
<div class="upload-box">
<span class="text">tab:</span>
<div class="pic-box">
<div v-for="(item,index) in cqImgUrl" :key="index" class="pic-box__single">
<a-image class="pic" :src="item" />
<div @click="deleteImg('tab',item)" class="pic-delete"></div>
</div>
<a-upload
action="#"
:multiple="true"
list-type="picture"
:before-upload="beforeUpload"
:customRequest="handleChange"
:show-upload-list="false"
>
<div v-if="!cqImgUrl.length || cqImgUrl.length <5" class="img" @click="uploadImg('tab')"></div>
</a-upload>
</div>
</div>
<div class="upload-box">
<span class="text">tab1:</span>
<div class="pic-box">
<div v-for="(item,index) in nyImgUrl" :key="index" class="pic-box__single">
<a-image class="pic" :src="item" />
<div @click="deleteImg('tab1',item)" class="pic-delete"></div>
</div>
<a-upload
action="#"
:multiple="true"
list-type="picture"
:before-upload="beforeUpload"
:customRequest="handleChange"
:show-upload-list="false"
>
<div v-if="!nyImgUrl.length || nyImgUrl.length <5" class="img" @click="uploadImg('tab1')"></div>
</a-upload>
</div>
</div>
</div>
<div class="dialog-upload__foot">
<span class="sure" @click="sure">确定</span>
<span class="cancle" @click="closeDialog">取消</span>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, toRefs, watch, nextTick } from 'vue'
import { message } from 'ant-design-vue'
import G from '@/request/G'
import axios from 'axios'
export default defineComponent({
name: 'SmartDialog',
props: {
showUploadDialog: {
type: Boolean,
default: false
},
activeTab: {
type: String,
default: 'tab'
},
imgUrl: {
type: Array,
default: () => {
return []
}
},
qyStoreId: {
type: String,
default: ''
}
},
setup (props, { emit }) {
interface FileItem {
uid: string;
name?: string;
status?: string;
response?: string;
url?: string;
percent?:number;
type?:string;
}
interface FileInfo {
file: FileItem;
fileList: FileItem[];
}
const data = reactive({
dialogVisible: false,
cqImgUrl: [] as Array<string> | any,
nyImgUrl: [] as Array<string> | any,
cqImgList: [] as any,
nyImgList: [] as any,
uploadType: '',
limitError: false
})
watch(
() => props.showUploadDialog,
(val: boolean) => {
data.dialogVisible = !!val
},
{
immediate: true,
deep: true
}
)
watch(
() => props.activeTab,
(val: string) => {
const type = val === 'tab' ? 2 : 1
if (props.qyStoreId) {
nextTick(() => {
getPicUrl(type)
})
}
},
{
immediate: true,
deep: true
}
)
const handleChange = (info: FileInfo) => {
console.log('data.limitError',data.limitError)
if (!data.limitError) {
const formData = new FormData()
formData.append('file', info.file as any)
let params = {
biz: 'energy',
_api: 'el.image.upload',
_v: '1.0'
} as any
params = G.buildInputs(params)
params._at = G.buildAt(params)
Object.keys(params).forEach(key => {
formData.append(key, params[key])
})
axios.post('/upload', formData).then((res: any) => {
if (res.data && res.data.success && res.data.model) {
if (res.data.model[0]) {
let url = res.data.model[0].authUrl
if (data.uploadType === 'tab') {
data.cqImgUrl.push(url)
data.cqImgList = []
}
if (data.uploadType === 'tab1') {
data.nyImgUrl.push(url)
data.nyImgList = []
}
}
} else {
message.error(res.data.msgInfo)
}
})
}
}
const getPicUrl = (val:number) => {
let params = {
_api: 'el.energy.storeDraw',
storeId: props.qyStoreId,
drawType: val,
_v: '1.0'
} as any
params = G.buildInputs(params)
G.baseAjax({
type: 'POST',
data: G.param(params) + '&_at=' + G.buildAt(params)
}).then((res:any) => {
const { success, model } = res
if (success) {
if (props.activeTab === 'tab') {
data.nyImgUrl = model.split(',')
}
if (props.activeTab === 'tab1') {
data.cqImgUrl = model.split(',')
}
}
}).finally(() => {
if (props.activeTab === 'tab') {
data.cqImgUrl = JSON.parse(JSON.stringify(props.imgUrl))
} else if (props.activeTab === 'tab1') {
data.nyImgUrl = JSON.parse(JSON.stringify(props.imgUrl))
}
})
}
const closeDialog = () => {
emit('closeDialog', false)
}
const uploadImg = (type:string) => {
data.uploadType = type
}
const deleteImg = (type:string, item:string) => {
if (type === 'tab') {
if (data.cqImgUrl && data.cqImgUrl.length) {
let index = data.cqImgUrl.indexOf(item)
data.cqImgUrl.splice(index,1)
}
}
if (type === 'tab1') {
if (data.nyImgUrl && data.nyImgUrl.length) {
let index = data.nyImgUrl.indexOf(item)
data.nyImgUrl.splice(index,1)
}
}
}
const beforeUpload = (file: FileItem) => {
if (data.uploadType === 'tab') {
data.cqImgList.push(file)
data.limitError = (data.cqImgList.concat(...data.cqImgUrl)).length > 5
}
if (data.uploadType === 'tab1') {
data.nyImgList.push(file)
data.limitError = (data.nyImgList.concat(...data.nyImgUrl)).length > 5
}
console.log('data.limitError',data.limitError)
if (data.limitError) {
if (data.uploadType === 'tab') {
data.cqImgList = []
}
if (data.uploadType === 'tab1') {
data.nyImgList = []
}
message.error('厂区图和能源图至多上传五张图片!')
}
return !data.limitError
}
const sure = () => {
let params = {
_api: 'el.energy.addImage',
storeId: props.qyStoreId,
factoryDraw: data.cqImgUrl.join(','),
energyDraw: data.nyImgUrl.join(','),
_v: '1.0'
} as any
params = G.buildInputs(params)
G.baseAjax({
type: 'POST',
data: G.param(params) + '&_at=' + G.buildAt(params)
}).then((res:any) => {
const { success } = res
if (success) {
message.success('上传成功!')
} else {
message.error(res.msgInfo)
}
}).finally(() => {
emit('submitDialog', {
cqImgUrl: data.cqImgUrl,
nyImgUrl: data.nyImgUrl
})
})
}
return {
...toRefs(data),
closeDialog,
uploadImg,
sure,
handleChange,
beforeUpload,
deleteImg
}
}
})
</script>
<style lang="scss" scoped>
.dialog-upload {
width: 1056px;
height: 947px;
z-index: 200;
position: absolute;
top: 20%;
left: 40%;
background: url("@/assets/images/uploadDialog.png") no-repeat;
background-size: 100% 100%;
overflow: auto;
&::-webkit-scrollbar {
display: none;
}
&__head {
position: relative;
.title {
padding: 32px 0 77px 48px;
font-size: 44px;
font-weight: 600;
color: #ffffff;
line-height: 62px;
}
.close {
position: absolute;
top: 24px;
right: 24px;
cursor: pointer;
width: 32px;
height: 32px;
background: url("@/assets/images/close.png") no-repeat;
background-size: 32px auto;
}
}
&__body {
display: flex;
flex-direction: column;
.upload-box {
display: flex;
margin-bottom: 32px;
.text {
display: inline-block;
white-space: nowrap;
width: 236px;
flex: 1;
font-size: 28px;
font-weight: 400;
color: #fff;
text-align: right;
}
.img {
cursor: pointer;
width: 200px;
height: 122px;
background: url("@/assets/images/upload.png") no-repeat;
background-size: 200px auto;
}
}
.pic-box {
display: flex;
flex-wrap: wrap;
flex: 3;
&__single {
position: relative;
width: 200px;
height: 122px;
border: 2px dashed #4E93F8;
border-radius: 8px;
margin: 0 20px 24px 0;
.pic {
width: 200px;
height: 122px;
object-fit: contain;
border-radius: 8px;
}
.pic-delete {
cursor: pointer;
z-index: 200;
position: absolute;
z-index: 50;
top: -16px;
right: -12px;
width: 30px;
height: 30px;
background: url("@/assets/images/deleteImg.png") no-repeat;
background-size: 30px auto;
}
}
}
}
&__foot {
position: absolute;
bottom: 40px;
left: 50%;
transform: translateX(-50%);
.sure {
cursor: pointer;
display: inline-block;
background: #3196FA;
border: 2px solid #3196FA;
border-radius: 8px;
padding: 12px 41px;
margin-right: 44px;
font-size: 28px;
color: #fff;
}
.cancle {
cursor: pointer;
display: inline-block;
border: 2px solid #FFFFFF;
border-radius: 8px;
padding: 12px 41px;
font-size: 28px;
color: #fff;
}
}
}
</style>
<style lang="scss">
.dialog-upload {
.ant-image {
width: 196px;
height: 118px;
border-radius: 8px;
}
.ant-image-img {
width: 196px;
height: 118px;
object-fit: contain;
border-radius: 8px;
}
.ant-image-mask-info {
visibility: hidden;
font-size: 0;
}
.ant-image-mask-info span{
visibility: visible;
font-size: 48px;
}
}
</style>
最终效果: