模板代码:
定义变量:
文件限制的函数:
上传的函数:
样式函数:
完整代码:
<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-uploadaction="#":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-uploadaction="#":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 : 1if (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 anyparams = 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].authUrlif (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 anyparams = G.buildInputs(params)G.baseAjax({type: 'POST',data: G.param(params) + '&_at=' + G.buildAt(params)}).then((res:any) => {const { success, model } = resif (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 anyparams = G.buildInputs(params)G.baseAjax({type: 'POST',data: G.param(params) + '&_at=' + G.buildAt(params)}).then((res:any) => {const { success } = resif (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>
最终效果: