|
|
@@ -9,6 +9,9 @@
|
|
|
:close-on-click-modal="false"
|
|
|
class="el_button"
|
|
|
>
|
|
|
+
|
|
|
+ <slot name="form_pre"></slot>
|
|
|
+
|
|
|
<el-form
|
|
|
v-loading="formLoading"
|
|
|
:inline="true"
|
|
|
@@ -24,7 +27,9 @@
|
|
|
:prop="item.key"
|
|
|
:rules="item.rules"
|
|
|
:style="item.style"
|
|
|
- :class="[item.className,{'top_label':(item.type=='textarea'||item.type=='checkbox'||item.type=='file' || item.custom === true || item.type=='noDragFile')}]"
|
|
|
+ :class="[item.className,{'top_label':(item.type=='textarea'||item.type=='checkbox'||item.type=='file' ||
|
|
|
+ item.custom === true || item.type=='noDragFile' || item.type=='imgFile' ||
|
|
|
+ item.type == 'fileShowList' || item.type=='radio')}]"
|
|
|
>
|
|
|
<template v-if="item.custom">
|
|
|
<slot :name="item.key" :formItem="item"></slot>
|
|
|
@@ -77,6 +82,40 @@
|
|
|
/>
|
|
|
</el-select>
|
|
|
|
|
|
+ <el-select
|
|
|
+ class="multipleSelect"
|
|
|
+ v-else-if="item.type=='multipleSelectSearch'"
|
|
|
+ v-model="formData[item.key]"
|
|
|
+ filterable
|
|
|
+ multiple
|
|
|
+ @change="(val)=>handleSelectChange(item.key,val)"
|
|
|
+ :disabled="item.disabled" :placeholder="item.placeholder"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="selectItem in item.selectList"
|
|
|
+ :key="selectItem.value"
|
|
|
+ :label="selectItem.label"
|
|
|
+ :value="selectItem.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+
|
|
|
+ <el-select
|
|
|
+ class="multipleSelect"
|
|
|
+ v-else-if="item.type=='singleSelectSearch'"
|
|
|
+ v-model="formData[item.key]"
|
|
|
+ filterable
|
|
|
+ @change="(val)=>handleSelectChange(item.key,val)"
|
|
|
+ :disabled="item.disabled" :placeholder="item.placeholder"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="selectItem in item.selectList"
|
|
|
+ :key="selectItem.value"
|
|
|
+ :label="selectItem.label"
|
|
|
+ :value="selectItem.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+
|
|
|
+
|
|
|
<template v-else-if="item.type == 'unionSelect'">
|
|
|
<span style="display: flex;width: 100%;gap:20px">
|
|
|
<el-select v-for="unionSubItem in item.unionSelectList"
|
|
|
@@ -142,6 +181,20 @@
|
|
|
size="default"
|
|
|
:disabled="item.disabled"
|
|
|
/>
|
|
|
+
|
|
|
+ <el-date-picker
|
|
|
+ v-else-if="item.type=='datePickerNoRange'"
|
|
|
+ v-model="formData[item.key] "
|
|
|
+ type="date"
|
|
|
+ :range-separator="item.placeholder.rangeSeparator"
|
|
|
+ :start-placeholder="item.placeholder.startPlaceholder"
|
|
|
+ :end-placeholder="item.placeholder.endPlaceholder"
|
|
|
+ size="default"
|
|
|
+ :disabled="item.disabled"
|
|
|
+ :disabled-date="item.disabledDate"
|
|
|
+
|
|
|
+ />
|
|
|
+
|
|
|
|
|
|
<el-date-picker
|
|
|
v-else-if="item.type=='dateTimePicker'"
|
|
|
@@ -159,6 +212,16 @@
|
|
|
:disabled-date="item.disabledDate"
|
|
|
/>
|
|
|
|
|
|
+ <el-date-picker
|
|
|
+ v-else-if="item.type=='dateTimePickerNoRange'"
|
|
|
+ v-model="formData[item.key]"
|
|
|
+ type="datetime"
|
|
|
+ :placeholder="item.placeholder"
|
|
|
+ :disabled="item.disabled"
|
|
|
+ style="width: 100%;"
|
|
|
+ @change="(val)=>handleSelectChange(item.key,val,item.type)"
|
|
|
+ />
|
|
|
+
|
|
|
<el-upload
|
|
|
v-else-if="item.type=='file'"
|
|
|
class="upload-demo"
|
|
|
@@ -237,9 +300,22 @@
|
|
|
</template>
|
|
|
</el-upload>
|
|
|
|
|
|
- <template v-else-if="item.type=='imgFile'" >
|
|
|
+ <!-- imgFile 原先的组件 -->
|
|
|
+ <template v-else-if="0" >
|
|
|
<div class="img_file_area">
|
|
|
- <span v-if="props.fileLoading" class="cover" style="gap: 3px;line-height: 1.5;color:#2e64fa">
|
|
|
+ <el-upload
|
|
|
+ v-model:file-list="fileList"
|
|
|
+ action="#"
|
|
|
+ :auto-upload="false"
|
|
|
+ @change="(file)=>handleFileChange(file,item)"
|
|
|
+ :on-preview="handlePictureCardPreview"
|
|
|
+ :on-remove="handleRemove"
|
|
|
+ >
|
|
|
+ <div class="operation_area">
|
|
|
+ <i class="iconfont hjx-a-Folder-uploadwenjianjia-shangchuan"></i>
|
|
|
+ </div>
|
|
|
+ </el-upload>
|
|
|
+ <span v-if="props.fileLoading" class="cover" style="gap: 3px;line-height: 1.5;color:#2e64fa">
|
|
|
上传中
|
|
|
<el-icon class="is-loading">
|
|
|
<Loading />
|
|
|
@@ -249,6 +325,11 @@
|
|
|
<img class="cover" :src="formData[item.key]?.url" alt="">
|
|
|
<img class="close" @click="HandleRemove(item.key)" :src="closeFillImg">
|
|
|
</span>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-else-if="item.type=='imgFile'" >
|
|
|
+ <div class="img_file_area1">
|
|
|
<el-upload
|
|
|
v-model:file-list="fileList"
|
|
|
action="#"
|
|
|
@@ -258,15 +339,111 @@
|
|
|
:on-remove="handleRemove"
|
|
|
>
|
|
|
<div class="operation_area">
|
|
|
- <i class="iconfont hjx-a-Folder-uploadwenjianjia-shangchuan"></i>
|
|
|
+ <el-icon class="icon"><Plus /></el-icon>
|
|
|
+ <span>{{item.uploadTips ? item.uploadTips : '上传文件'}}</span>
|
|
|
</div>
|
|
|
</el-upload>
|
|
|
- </div>
|
|
|
|
|
|
+ <span v-if="props.fileLoading" class="cover" style="gap: 3px;line-height: 1.5;color:#2e64fa">
|
|
|
+ 上传中
|
|
|
+ <el-icon class="is-loading">
|
|
|
+ <Loading />
|
|
|
+ </el-icon>
|
|
|
+ </span>
|
|
|
+
|
|
|
+ <!-- 单张 -->
|
|
|
+ <template v-if="item.limit == 1 && !props.fileLoading">
|
|
|
+ <span class="img_file" v-if="formData[item.key]?.url">
|
|
|
+ <img class="cover" :src="formData[item.key]?.url" alt="">
|
|
|
+ <img class="close" @click="HandleRemove(item.key)" :src="closeFillImg">
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
|
|
|
+ <!-- 多张 -->
|
|
|
+ <template v-else-if="item.limit > 1">
|
|
|
+ <span class="img_file" v-for="fileItm in formData[item.key]" :key="fileItm">
|
|
|
+ <img class="cover" :src="fileItm?.url" alt="">
|
|
|
+ <div class="operation_btn">
|
|
|
+ <span class="delete" @click="HandleRemoveSingleImg(item.key,fileItm)">删除</span>
|
|
|
+ <span class="preview" @click="HandleImgPreview(fileItm?.url)">查看</span>
|
|
|
+ </div>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+ <el-image-viewer
|
|
|
+ v-if="imgVisible"
|
|
|
+ :url-list="[dialogImageUrl]"
|
|
|
+ show-progress
|
|
|
+ @close="imgVisible = false"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</template>
|
|
|
|
|
|
-
|
|
|
+
|
|
|
+ <template v-else-if="item.type=='fileShowList'" >
|
|
|
+ <div class="file_show_list">
|
|
|
+ <el-upload
|
|
|
+ v-model:file-list="fileList"
|
|
|
+ action="#"
|
|
|
+ :auto-upload="false"
|
|
|
+ @change="(file)=>handleFileChange(file,item)"
|
|
|
+ :on-preview="handlePictureCardPreview"
|
|
|
+ :on-remove="handleRemove"
|
|
|
+ >
|
|
|
+ <div class="operation_area">
|
|
|
+ <el-icon class="icon"><Plus /></el-icon>
|
|
|
+ <span>{{item.uploadTips ? item.uploadTips : '上传文件'}}</span>
|
|
|
+ </div>
|
|
|
+ </el-upload>
|
|
|
+
|
|
|
+ <span v-if="props.fileLoading" class="cover" style="gap: 3px;line-height: 1.5;color:#2e64fa">
|
|
|
+ 上传中
|
|
|
+ <el-icon class="is-loading">
|
|
|
+ <Loading />
|
|
|
+ </el-icon>
|
|
|
+ </span>
|
|
|
+
|
|
|
+ <div class="file_list">
|
|
|
+ <!-- 单张 -->
|
|
|
+ <template v-if="item.limit == 1 && !props.fileLoading">
|
|
|
+ <div class="file_desc" v-if="formData[item.key]?.url">
|
|
|
+ <img class="icon" :src="fileIcon" alt="">
|
|
|
+ <div class="file_msg">
|
|
|
+ <span class="name" :title="formData[item.key]?.name">{{ formData[item.key]?.name }}</span>
|
|
|
+
|
|
|
+ <span class="size">
|
|
|
+ <span>{{ formData[item.key]?.fileSize }}</span>
|
|
|
+ <span>{{ formData[item.key]?.time }}</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="table_row_option">
|
|
|
+ <span class="el_button_delete" @click="HandleRemove(item.key)">删除</span>
|
|
|
+ <span class="el_button_editor" @click="HandleFilePreview(formData[item.key])">预览</span>
|
|
|
+ <span class="el_button_editor" @click="HandleFileDownload(formData[item.key]?.url)">下载</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 多张 -->
|
|
|
+ <template v-else-if="item.limit > 1">
|
|
|
+ <div class="file_desc" v-for="fileItm in formData[item.key]" :key="fileItm">
|
|
|
+ <img class="icon" :src="fileIcon" alt="">
|
|
|
+ <div class="file_msg">
|
|
|
+ <span class="name" :title="fileItm?.name">{{ fileItm?.name }}</span>
|
|
|
+ <span class="size">
|
|
|
+ <span>{{ fileItm?.fileSize }}</span>
|
|
|
+ <span>{{ fileItm?.time }}</span>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ <div class="table_row_option">
|
|
|
+ <span class="el_button_delete" @click="HandleRemoveSingleImg(item.key,fileItm)">删除</span>
|
|
|
+ <span class="el_button_editor" @click="HandleFilePreview(fileItm)"> 预览</span>
|
|
|
+ <span class="el_button_editor" @click="HandleFileDownload(fileItm?.url)">下载</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
|
|
|
<a v-else-if="item.type=='url'" @click="HandlePreviewFile(formData[item.key])" >{{ formData[item.key]?.name }}</a>
|
|
|
</template>
|
|
|
@@ -340,6 +517,8 @@ import closeFillImg from '@/assets/icon/close_fill.svg'
|
|
|
|
|
|
import { ElMessage } from 'element-plus'
|
|
|
|
|
|
+// import fileIcon from '@/assets/icon/file.png'
|
|
|
+
|
|
|
|
|
|
const previewVisible = ref(false)
|
|
|
const fileList = ref([
|
|
|
@@ -359,14 +538,16 @@ const handleRemove = ()=>{
|
|
|
}
|
|
|
type ItemType =
|
|
|
|'input'|'password'|'textarea'|'number'|'radio'
|
|
|
- |'select'|'multipleSelect'| 'unionSelect' |'checkbox'|'datePicker'
|
|
|
- |'dateTimePicker'|'url'|'file' | 'switch' | 'imgFile' | 'noDragFile'
|
|
|
+ |'select'|'multipleSelect' | 'singleSelectSearch' | 'multipleSelectSearch' | 'unionSelect' |'checkbox'|'datePicker'
|
|
|
+ |'dateTimePicker'| 'dateTimePickerNoRange' |'datePickerNoRange' |'url'|'file' | 'switch' | 'imgFile' | 'noDragFile' | 'fileShowList'
|
|
|
|
|
|
|
|
|
interface formItemProperty {
|
|
|
key: String,
|
|
|
label: String,
|
|
|
type?:ItemType,
|
|
|
+ limit:Number, // 文件上传限制的数量
|
|
|
+ uploadTips:String,
|
|
|
acceptType?:[],
|
|
|
checkAll?:Boolean,
|
|
|
placeholder?:|String
|
|
|
@@ -423,7 +604,8 @@ const props = defineProps({
|
|
|
},
|
|
|
defaultFormData:{
|
|
|
type:Object,
|
|
|
- default:()=>{}
|
|
|
+ required:true,
|
|
|
+ // default:()=>{}
|
|
|
},
|
|
|
formDisabled:{
|
|
|
type:Boolean,
|
|
|
@@ -529,6 +711,33 @@ const HandleRemove = (formKey)=>{
|
|
|
formData.value[formKey] = null
|
|
|
}
|
|
|
|
|
|
+const HandleRemoveSingleImg = (formKey,aimFile) =>{
|
|
|
+ formData.value[formKey] = formData.value[formKey].filter(item=>{
|
|
|
+ return item !== aimFile
|
|
|
+ })
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+const imgVisible = ref(false)
|
|
|
+const dialogImageUrl = ref('')
|
|
|
+const HandleImgPreview = (url)=>{
|
|
|
+ imgVisible.value = true
|
|
|
+ dialogImageUrl.value = url
|
|
|
+}
|
|
|
+const HandleFileDownload = (url)=>{
|
|
|
+ let link = document.createElement('a')
|
|
|
+ link.href = url
|
|
|
+ link.download = url
|
|
|
+ link.style.display = 'none';
|
|
|
+ document.body.appendChild(link)
|
|
|
+ link.click();
|
|
|
+ document.body.removeChild(link)
|
|
|
+}
|
|
|
+
|
|
|
+const HandleFilePreview = (params)=>{
|
|
|
+ previewVisible.value = true
|
|
|
+ fileMessage.value = params
|
|
|
+}
|
|
|
</script>
|
|
|
<style lang="scss" scoped>
|
|
|
.img_file_area{
|
|
|
@@ -560,12 +769,210 @@ const HandleRemove = (formKey)=>{
|
|
|
justify-content: center;
|
|
|
}
|
|
|
|
|
|
+ .operation_area1{
|
|
|
+ width: 200px;
|
|
|
+ height: 117px;
|
|
|
+ color:#CCCED4;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ border-radius: 6px;
|
|
|
+ background-color: #f0f4f8;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
.operation_area{
|
|
|
background-color: #F0F4F8;
|
|
|
font-size: 24px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+.img_file_area1{
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ gap:10px;
|
|
|
+ align-items: center;
|
|
|
+ flex-wrap: wrap;
|
|
|
+
|
|
|
+ >span{
|
|
|
+ position: relative;
|
|
|
+ .close{
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ color: #F56C6C;
|
|
|
+ position:absolute;
|
|
|
+ top:-5px;
|
|
|
+ right: -2px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .cover,
|
|
|
+ .operation_area{
|
|
|
+ width: 200px;
|
|
|
+ height: 117px;
|
|
|
+ color:#CCCED4;
|
|
|
+ font-size: 14px;
|
|
|
+ border-radius: 6px;
|
|
|
+ background-color: #f0f4f8;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .cover{
|
|
|
+ border:solid #CED1D8 1px
|
|
|
+ }
|
|
|
+
|
|
|
+ .operation_area{
|
|
|
+ background-color: #FAFBFF;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ border:dashed #CCCED4 1px;
|
|
|
+ gap:8px;
|
|
|
+ .icon{
|
|
|
+ font-size: 40px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .img_file{
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .operation_btn{
|
|
|
+ display: none;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ gap:10px;
|
|
|
+
|
|
|
+ background-color:rgba(0, 0, 0,0.1);
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ top:0px;
|
|
|
+ left:0px;
|
|
|
+
|
|
|
+ .delete,
|
|
|
+ .preview{
|
|
|
+ line-height: 1;
|
|
|
+ padding:8px 20px;
|
|
|
+ background-color: white;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .delete{
|
|
|
+ color:#F56C6C;
|
|
|
+ }
|
|
|
+ .preview{
|
|
|
+ color:#2E64FA;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover{
|
|
|
+ .operation_btn{
|
|
|
+ display:flex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.file_show_list{
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ gap:10px;
|
|
|
+ align-items: flex-start;
|
|
|
+ flex-wrap: now-wrap;
|
|
|
+ >span{
|
|
|
+ position: relative;
|
|
|
+ .close{
|
|
|
+ width: 14px;
|
|
|
+ height: 14px;
|
|
|
+ color: #F56C6C;
|
|
|
+ position:absolute;
|
|
|
+ top:-5px;
|
|
|
+ right: -2px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .operation_area{
|
|
|
+ width: 200px;
|
|
|
+ height: 80px;
|
|
|
+ color:#CCCED4;
|
|
|
+ font-size: 14px;
|
|
|
+ border-radius: 6px;
|
|
|
+ background-color: #f0f4f8;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background-color: #FAFBFF;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ border:dashed #CCCED4 1px;
|
|
|
+ gap:8px;
|
|
|
+ .icon{
|
|
|
+ font-size: 24px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .img_file{
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ }
|
|
|
+ .file_list{
|
|
|
+ max-width: calc(100% - 200px - 10px);
|
|
|
+ flex:1 1;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap:20px;
|
|
|
+
|
|
|
+ .file_desc{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap:10px;
|
|
|
+ height: 80px;
|
|
|
+ width: 100%;
|
|
|
+
|
|
|
+ border:solid #EBEEF5 1px;
|
|
|
+ border-radius: 10px;
|
|
|
+ padding:20px;
|
|
|
+ line-height: 1.5;
|
|
|
+ .icon{
|
|
|
+ width: 40px;
|
|
|
+ height: 40px;
|
|
|
+ vertical-align: middle;
|
|
|
+ }
|
|
|
+
|
|
|
+ .file_msg{
|
|
|
+ max-width: calc(100% - 40px - 20px - 117px);
|
|
|
+ flex-grow: auto;
|
|
|
+ flex-shrink: 0;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ gap:4px;
|
|
|
+ .name{
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #333333;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .size{
|
|
|
+ font-size: 12px;
|
|
|
+ color: #999999;
|
|
|
+ display: flex;
|
|
|
+ gap:10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .table_row_option{
|
|
|
+ justify-content: flex-end;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
.multipleSelect{
|
|
|
:deep(.el-select__wrapper){
|
|
|
height: auto;
|
|
|
@@ -687,6 +1094,10 @@ const HandleRemove = (formKey)=>{
|
|
|
flex-direction: column;
|
|
|
justify-content: flex-start;
|
|
|
overflow: auto;
|
|
|
+ .el-date-editor--date.el-input{
|
|
|
+ width: 100%;
|
|
|
+ border:none;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
a{
|