| <template> | 
|   <el-form | 
|     style="display: inline-block; width: 100%" | 
|     :inline="true" | 
|     ref="volform" | 
|     @submit.prevent | 
|     :model="formFields" | 
|     :label-width="labelWidth" | 
|     :rules="rules" | 
|   > | 
|     <template v-for="(row, findex) in formRules" :key="findex"> | 
|       <div class="vol-form-item"> | 
|         <el-form-item | 
|           :label="item.title ? item.title + ':' : ''" | 
|           v-show="!item.hidden" | 
|           v-for="(item, index) in row" | 
|           :prop="item.field" | 
|           :key="item.field + index" | 
|           :style="{ width: getColWidth(item) + '%' }" | 
|         > | 
|           <!-- render --> | 
|           <form-expand | 
|             v-if="item.render && typeof item.render == 'function'" | 
|             :render="item.render" | 
|             :par="12" | 
|           ></form-expand> | 
|           <!-- 2021.10.17增加表单实时方法计算 --> | 
|           <span | 
|             v-else-if=" | 
|               item.readonly && typeof formFields[item.field] == 'function' | 
|             " | 
|             >{{ formFields[item.field]() }}</span | 
|           > | 
|           <!-- 只读图片或文件  --> | 
|           <div v-else-if="isReadonlyImgFile(item, formFields)"> | 
|             <div v-if="item.type == 'img'" class="form-imgs"> | 
|               <div | 
|                 class="img-item" | 
|                 v-for="(img, imgIndex) in formFields[item.field]" | 
|                 :key="imgIndex" | 
|               > | 
|                 <img | 
|                   :src="getSrc(img.path)" | 
|                   :onerror="errorImg" | 
|                   @click="previewImg(img.path)" | 
|                 /> | 
|               </div> | 
|             </div> | 
|             <div | 
|               v-else | 
|               class="form-file-list" | 
|               v-for="(file, fileIndex) in formFields[item.field]" | 
|               :key="fileIndex" | 
|             > | 
|               <a @click="dowloadFile(formFields[item.field][fileIndex])">{{ | 
|                 file.name | 
|               }}</a> | 
|             </div> | 
|           </div> | 
|   | 
|           <div v-else :class="{ 'form-item-extra': item.extra }"> | 
|             <!-- 只读属性 --> | 
|             <label | 
|               :style="item.inputStyle" | 
|               v-if="item.type == 'label'" | 
|               class="readonly-input" | 
|               >{{ getText(formFields, item) }}</label | 
|             > | 
|             <!-- 20223.05.13集成el-tree-select --> | 
|             <!-- :filter-method="(value)=>{filterMethod(value,item.data)}" --> | 
|             <!-- :filterable="true" --> | 
|             <el-tree-select | 
|               style="width: 100%" | 
|               v-else-if="item.type == 'treeSelect'" | 
|               v-model="formFields[item.field]" | 
|               :data="item.data" | 
|               :multiple="item.multiple" | 
|               :render-after-expand="false" | 
|               :show-checkbox="false" | 
|               :check-strictly="true" | 
|               check-on-click-node | 
|               node-key="key" | 
|               :props="{ label: 'label' }" | 
|             > | 
|               <template #default="{data,node }"> | 
|                 <!-- <el-checkbox v-model="node.checked"></el-checkbox> --> | 
|                <!-- {{getNode(node, data)}} --> | 
|                <!-- {{node.checked}} --> | 
|                <!-- 这里还有点问题,后面处理 --> | 
|                 {{  data.label}}</template | 
|               > | 
|             </el-tree-select> | 
|             <template | 
|               v-else-if="['select', 'selectList'].indexOf(item.type) != -1" | 
|             > | 
|               <el-select-v2 | 
|                 :disabled="item.readonly || item.disabled" | 
|                 v-show="!item.hidden" | 
|                 style="width: 100%" | 
|                 :size="size" | 
|                 v-if="item.data.length > select2Count" | 
|                 v-model="formFields[item.field]" | 
|                 filterable | 
|                 :multiple="item.type == 'select' ? false : true" | 
|                 :placeholder="item.placeholder ? item.placeholder : item.title" | 
|                 :allow-create="item.autocomplete" | 
|                 :options="item.data" | 
|                 @change=" | 
|                   (val) => { | 
|                     item.onChange(val, item.data); | 
|                   } | 
|                 " | 
|                 clearable | 
|               > | 
|                 <template #default="{ item }"> | 
|                   {{ item.label }} | 
|                 </template> | 
|               </el-select-v2> | 
|               <el-select | 
|                 :disabled="item.readonly || item.disabled" | 
|                 v-show="!item.hidden" | 
|                 style="width: 100%" | 
|                 :size="size" | 
|                 v-else-if="item.remote || item.url" | 
|                 v-model="formFields[item.field]" | 
|                 filterable | 
|                 :multiple="item.type == 'select' ? false : true" | 
|                 :placeholder="item.placeholder ? item.placeholder : item.title" | 
|                 clearable | 
|                 :remote-method=" | 
|                   (val) => { | 
|                     remoteSearch(item, formFields, val); | 
|                   } | 
|                 " | 
|               > | 
|                 <el-option | 
|                   v-for="item in item.data" | 
|                   :key="item.key" | 
|                   :label="item.value" | 
|                   :value="item.key" | 
|                 > | 
|                 </el-option> | 
|               </el-select> | 
|               <el-select | 
|                 :disabled="item.readonly || item.disabled" | 
|                 v-show="!item.hidden" | 
|                 style="width: 100%" | 
|                 :size="size" | 
|                 v-else | 
|                 v-model="formFields[item.field]" | 
|                 filterable | 
|                 :multiple="item.type == 'select' ? false : true" | 
|                 :placeholder="item.placeholder ? item.placeholder : item.title" | 
|                 :allow-create="item.autocomplete" | 
|                 @change=" | 
|                   (val) => { | 
|                     item.onChange(val, item.data); | 
|                   } | 
|                 " | 
|                 clearable | 
|               > | 
|                 <el-option | 
|                   v-show="!item.hidden" | 
|                   :disabled="item.disabled" | 
|                   v-for="item in item.data" | 
|                   :key="item.key" | 
|                   :label="item.value" | 
|                   :value="item.key" | 
|                 > | 
|                 </el-option> | 
|               </el-select> | 
|             </template> | 
|   | 
|             <el-switch | 
|               v-show="!item.hidden" | 
|               v-else-if="item.type == 'switch'" | 
|               v-model="formFields[item.field]" | 
|               :disabled="item.readonly || item.disabled" | 
|               active-color="#0f84ff" | 
|               @change="item.onChange" | 
|               inactive-color="rgb(194 194 194)" | 
|               :active-value=" | 
|                 typeof formFields[item.field] == 'boolean' | 
|                   ? true | 
|                   : typeof formFields[item.field] == 'string' | 
|                   ? '1' | 
|                   : 1 | 
|               " | 
|               :inactive-value=" | 
|                 typeof formFields[item.field] == 'boolean' | 
|                   ? false | 
|                   : typeof formFields[item.field] == 'string' | 
|                   ? '0' | 
|                   : 0 | 
|               " | 
|             > | 
|             </el-switch> | 
|   | 
|             <el-radio-group | 
|               :disabled="item.readonly || item.disabled" | 
|               v-show="!item.hidden" | 
|               v-model="formFields[item.field]" | 
|               v-else-if="item.type == 'radio'" | 
|               @change="item.onChange" | 
|             > | 
|               <el-radio | 
|                 v-for="kv in item.data" | 
|                 :disabled="item.readonly || item.disabled" | 
|                 :key="kv.key" | 
|                 :label="kv.key" | 
|                 >{{ kv.value }}</el-radio | 
|               > | 
|             </el-radio-group> | 
|   | 
|             <el-checkbox-group | 
|               :disabled="item.readonly || item.disabled" | 
|               v-show="!item.hidden" | 
|               v-model="formFields[item.field]" | 
|               v-else-if="item.type == 'checkbox'" | 
|               @change="item.onChange" | 
|             > | 
|               <el-checkbox | 
|                 v-for="kv in item.data" | 
|                 :key="kv.key" | 
|                 :disabled="item.readonly || item.disabled" | 
|                 :label="kv.key" | 
|                 >{{ kv.value }}</el-checkbox | 
|               > | 
|             </el-checkbox-group> | 
|             <div | 
|               class="v-date-range" | 
|               style="display: flex" | 
|               v-else-if=" | 
|                 ['date', 'datetime'].indexOf(item.type) != -1 && item.range | 
|               " | 
|             > | 
|               <el-date-picker | 
|                 :size="size" | 
|                 :disabled="item.readonly || item.disabled" | 
|                 style="flex: 1; width: auto" | 
|                 v-model="formFields[item.field][0]" | 
|                 :type="item.type == 'date' ? 'date' : 'datetime'" | 
|                 :disabledDate="(val) => getDateOptions(val, item)" | 
|                 placeholder="开始时间" | 
|                 @change=" | 
|                   (val) => { | 
|                     dateRangeChange(val, item); | 
|                   } | 
|                 " | 
|                 :value-format="getDateFormat(item)" | 
|               > | 
|               </el-date-picker> | 
|               <span style="margin: 0px 5px; font-size: 13px; color: #6f6b6b" | 
|                 >至</span | 
|               > | 
|               <el-date-picker | 
|                 :size="size" | 
|                 :disabled="item.readonly || item.disabled" | 
|                 style="flex: 1; width: auto" | 
|                 v-model="formFields[item.field][1]" | 
|                 placeholder="结束时间" | 
|                 :type="item.type == 'date' ? 'date' : 'datetime'" | 
|                 :disabledDate="(val) => getDateOptions(val, item)" | 
|                 @change=" | 
|                   (val) => { | 
|                     dateRangeChange(val, item); | 
|                   } | 
|                 " | 
|                 :value-format="getDateFormat(item)" | 
|               > | 
|               </el-date-picker> | 
|             </div> | 
|             <!-- v-show不添加根节点就会报错没有根点节 --> | 
|             <div | 
|               v-show="!item.hidden" | 
|               style="width: 100%" | 
|               v-else-if="['date', 'datetime', 'month'].indexOf(item.type) != -1" | 
|             > | 
|               <el-date-picker | 
|                 :size="size" | 
|                 clearable | 
|                 :disabled="item.readonly || item.disabled" | 
|                 style="width: 100%" | 
|                 v-model="formFields[item.field]" | 
|                 @change="item.onChange" | 
|                 :type="item.type" | 
|                 :placeholder=" | 
|                   item.placeholder ? item.placeholder : '请选择' + item.title | 
|                 " | 
|                 :disabledDate="(val) => getDateOptions(val, item)" | 
|                 :value-format="getDateFormat(item)" | 
|               > | 
|               </el-date-picker> | 
|             </div> | 
|   | 
|             <el-time-picker | 
|               :size="size" | 
|               v-else-if="item.type == 'time'" | 
|               v-model="formFields[item.field]" | 
|               :disabled="item.readonly || item.disabled" | 
|               placeholder="请选择时间" | 
|               :value-format="item.format || 'HH:mm:ss'" | 
|               :format="item.format" | 
|               style="width: 100%" | 
|             > | 
|             </el-time-picker> | 
|   | 
|             <el-scrollbar | 
|               style="border: 1px solid #c7d8db; border-radius: 5px" | 
|               :height="item.height || 150" | 
|               v-else-if=" | 
|                 item.type == 'editor' && (item.readonly || item.disabled) | 
|               " | 
|             > | 
|               <div ref="editor" v-html="formFields[item.field]"></div> | 
|             </el-scrollbar> | 
|   | 
|             <vol-wang-editor | 
|               ref="editor" | 
|               v-else-if="item.type == 'editor'" | 
|               :url="item.url || editor.uploadImgUrl" | 
|               :upload="item.upload || editor.upload" | 
|               v-model="formFields[item.field]" | 
|               :height="item.height || 350" | 
|             ></vol-wang-editor> | 
|   | 
|             <vol-upload | 
|               v-show="!item.hidden" | 
|               v-else-if="isFile(item, formFields)" | 
|               :desc="item.desc" | 
|               :multiple="item.multiple" | 
|               :max-file="item.maxFile" | 
|               :max-size="item.maxSize" | 
|               :autoUpload="item.autoUpload" | 
|               :fileInfo="formFields[item.field]" | 
|               :url="item.url" | 
|               :img="item.type == 'img' || item.columnType == 'img'" | 
|               :excel="item.type == 'excel'" | 
|               :fileTypes="item.fileTypes ? item.fileTypes : []" | 
|               :upload-before="item.uploadBefore" | 
|               :upload-after="item.uploadAfter" | 
|               :append="item.multiple" | 
|               :on-change=" | 
|                 (files) => { | 
|                   return fileOnChange(files, item); | 
|                 } | 
|               " | 
|               :file-click="item.fileClick" | 
|               :remove-before="item.removeBefore" | 
|               :downLoad="item.downLoad ? true : false" | 
|             ></vol-upload> | 
|             <el-cascader | 
|               :size="size" | 
|               clearable | 
|               style="width: 100%; margin-top: -3px" | 
|               v-model="formFields[item.field]" | 
|               :disabled="item.readonly || item.disabled" | 
|               v-else-if="item.type == 'cascader'" | 
|               :options="item.data" | 
|               :props="{ | 
|                 checkStrictly: item.changeOnSelect || item.checkStrictly | 
|               }" | 
|               @change="item.onChange" | 
|             > | 
|             </el-cascader> | 
|             <el-rate | 
|               v-else-if="item.type == 'rate'" | 
|               @change=" | 
|                 (val) => { | 
|                   item.onChange && item.onChange(val); | 
|                 } | 
|               " | 
|               :max="item.max" | 
|               v-model="formFields[item.field]" | 
|             /> | 
|             <div | 
|               style="display: flex" | 
|               v-else-if="item.type == 'range' || item.range" | 
|             > | 
|               <el-input | 
|                 :size="size" | 
|                 :disabled="item.readonly || item.disabled" | 
|                 style="flex: 1" | 
|                 v-model="formFields[item.field][0]" | 
|                 clearable | 
|               /> | 
|               <span style="margin: 0 5px">-</span> | 
|               <el-input | 
|                 :size="size" | 
|                 :disabled="item.readonly || item.disabled" | 
|                 style="flex: 1" | 
|                 v-model="formFields[item.field][1]" | 
|                 clearable | 
|               /> | 
|             </div> | 
|             <el-input | 
|               :size="size" | 
|               clearable | 
|               :ref="item.field" | 
|               :input-style="item.inputStyle" | 
|               :disabled="item.readonly || item.disabled" | 
|               v-else-if="item.type == 'textarea'" | 
|               v-model="formFields[item.field]" | 
|               type="textarea" | 
|               :autosize="{ | 
|                 minRows: item.minRows || 2, | 
|                 maxRows: item.maxRows || 10 | 
|               }" | 
|               :placeholder="item.placeholder ? item.placeholder : item.title" | 
|             /> | 
|             <el-input-number | 
|               :size="size" | 
|               style="width: 100%" | 
|               :ref="item.field" | 
|               :input-style="item.inputStyle" | 
|               v-else-if="item.type == 'number'" | 
|               v-model="formFields[item.field]" | 
|               :min="item.min" | 
|               :disabled="item.readonly || item.disabled" | 
|               :max="item.max" | 
|               controls-position="right" | 
|             /> | 
|             <el-input | 
|               :size="size" | 
|               clearable | 
|               :input-style="item.inputStyle" | 
|               v-else-if="item.type == 'password'" | 
|               type="password" | 
|               v-model="formFields[item.field]" | 
|               :disabled="item.readonly || item.disabled" | 
|               v-show="!item.hidden" | 
|               :placeholder="item.placeholder ? item.placeholder : item.title" | 
|             /> | 
|             <!-- 2021.11.18修复el-input没有默认enter事件时回车异常 --> | 
|             <el-input | 
|               :size="size" | 
|               clearable | 
|               :ref="item.field" | 
|               :input-style="item.inputStyle" | 
|               v-else-if="item.onKeyPress" | 
|               :placeholder="item.placeholder ? item.placeholder : item.title" | 
|               :disabled="item.readonly || item.disabled" | 
|               v-show="!item.hidden" | 
|               v-model="formFields[item.field]" | 
|               @keypress=" | 
|                 ($event) => { | 
|                   onKeyPress($event, item); | 
|                 } | 
|               " | 
|               @change="item.onKeyPress" | 
|               @keyup.enter="item.onKeyPress" | 
|             ></el-input> | 
|             <el-input | 
|               :size="size" | 
|               clearable | 
|               v-else | 
|               :ref="item.field" | 
|               :input-style="item.inputStyle" | 
|               :placeholder="item.placeholder ? item.placeholder : item.title" | 
|               :disabled="item.readonly || item.disabled" | 
|               v-show="!item.hidden" | 
|               v-model="formFields[item.field]" | 
|             ></el-input> | 
|   | 
|             <div class="form-extra" v-if="item.extra"> | 
|               <form-expand | 
|                 v-if="item.extra.render" | 
|                 :render="item.extra.render" | 
|               ></form-expand> | 
|               <a | 
|                 v-else-if="item.extra.click" | 
|                 :style="item.extra.style" | 
|                 @click="item.extra.click(item, formFields[item.field])" | 
|               > | 
|                 <i v-if="item.extra.icon" :class="item.extra.icon" /> | 
|                 {{ item.extra.text }} | 
|               </a> | 
|               <a v-else :style="item.extra.style"> | 
|                 <i v-if="item.extra.icon" :class="item.extra.icon" /> | 
|                 {{ item.extra.text }} | 
|               </a> | 
|             </div> | 
|           </div> | 
|         </el-form-item> | 
|       </div> | 
|     </template> | 
|     <slot></slot> | 
|     <div style="width: 100%"> | 
|       <slot name="footer"></slot> | 
|     </div> | 
|   </el-form> | 
| </template> | 
| <script> | 
| const rule = { | 
|   change: [ | 
|     'checkbox', | 
|     'select', | 
|     'date', | 
|     'datetime', | 
|     'drop', | 
|     'radio', | 
|     'cascader' | 
|   ], // 2020.05.31增加级联类型 | 
|   phone: /^[1][3,4,5,6,7,8,9][0-9]{9}$/, | 
|   decimal: /(^[\-0-9][0-9]*(.[0-9]+)?)$/, | 
|   number: /(^[\-0-9][0-9]*([0-9]+)?)$/ | 
| }; | 
| const inputTypeArr = ['text', 'string', 'mail', 'textarea', 'password']; | 
| const types = { | 
|   int: 'number', | 
|   byte: 'number', | 
|   decimal: 'number', // "float", | 
|   string: 'string', | 
|   bool: 'boolean', | 
|   date: 'datetime', | 
|   date: 'date', | 
|   mail: 'email' | 
| }; | 
| //表单验证注意:每次验证都必须执行callback,否则验证不执行回调方法 | 
| const colPow = Math.pow(10, 3); | 
| import FormExpand from './VolForm/VolFormRender'; | 
| import { | 
|   defineAsyncComponent, | 
|   defineComponent, | 
|   ref, | 
|   reactive, | 
|   toRefs, | 
|   getCurrentInstance, | 
|   onMounted, | 
|   watch | 
| } from 'vue'; | 
| export default defineComponent({ | 
|   components: { | 
|     FormExpand, | 
|     'vol-upload': defineAsyncComponent(() => | 
|       import('@/components/basic/VolUpload.vue') | 
|     ), | 
|     'vol-wang-editor': defineAsyncComponent(() => | 
|       import('@/components/editor/VolWangEditor.vue') | 
|     ) | 
|   }, | 
|   props: { | 
|     loadKey: { | 
|       // 是否加载formRules字段配置的数据源 | 
|       type: Boolean, | 
|       default: true | 
|     }, | 
|     width: { | 
|       // 表单宽度 | 
|       type: Number, | 
|       default: 0 | 
|     }, | 
|     labelWidth: { | 
|       // 表单左边label文字标签的宽度 | 
|       type: Number, | 
|       default: 100 | 
|     }, | 
|     formRules: { | 
|       // 表单配置规则,如字段类型,是否必填 | 
|       type: Array, | 
|       default: [] | 
|     }, | 
|     formFields: { | 
|       type: Object, | 
|       default: () => { | 
|         return {}; | 
|       } | 
|     }, | 
|     editor: { | 
|       // 2021.01.16编辑器信息 {uploadImgUrl:"",upload:null//上传方法} | 
|       type: Object, | 
|       default: () => { | 
|         return {}; | 
|       } | 
|     }, | 
|     size: { | 
|       type: String, //large / default / small | 
|       default: 'large' | 
|     }, | 
|     select2Count: { | 
|       //超出数量显示select2组件 | 
|       type: Number, | 
|       default: 500 | 
|     } | 
|   }, | 
|   computed: { | 
|     rules() { | 
|       let ruleResult = {}; | 
|       this.formRules.forEach((option, xIndex) => { | 
|         option.forEach((item) => { | 
|           ruleResult[item.field] = [this.getRule(item, this.formFields)]; | 
|         }); | 
|       }); | 
|       if (this.$refs.volform) { | 
|         setTimeout(() => { | 
|           this.$refs.volform.clearValidate(); | 
|         }, 100); | 
|       } | 
|       return ruleResult; | 
|     } | 
|   }, | 
|   setup(props, context) { | 
|     const { appContext, proxy } = getCurrentInstance(); | 
|     const remoteCall = ref(true); | 
|     const span = ref(1); | 
|     const rangeFields = toRefs([]); | 
|     const volform = ref(null); | 
|     const numberFields = toRefs([]); | 
|     onMounted(() => {}); | 
|     const initFormRules = (init) => { | 
|       if (props.loadKey) { | 
|         initSource(); | 
|       } | 
|       props.formRules.forEach((row, xIndex) => { | 
|         if (row.length > span.value) span.value = row.length; | 
|         let _count = 0, | 
|           _size = 0; | 
|         row.forEach((x) => { | 
|           if (x.colSize > 0) { | 
|             _size = _size + x.colSize; | 
|             _count++; | 
|           } | 
|         }); | 
|         if (_count > 0 && row.length - _count > 0) { | 
|           let _cellSize = (12 - _size) / (row.length - _count); | 
|           row.forEach((x) => { | 
|             if (!x.colSize) { | 
|               x.colSize = _cellSize; | 
|             } | 
|           }); | 
|         } | 
|         row.forEach((item, yIndex) => { | 
|           if (item.type == 'number') { | 
|             numberFields.push(item.field); | 
|           } | 
|           // 目前只支持select单选远程搜索,remote远程从后台字典数据源进行搜索,url从指定的url搜索 | 
|           if (item.remote || item.url) { | 
|             // item.remoteData = []; | 
|             item.loading = false; | 
|             item.point = { x: xIndex, y: yIndex }; | 
|           } | 
|           // 初始化上传文件信息 | 
|           initUpload(item, init); | 
|           // 初始化数据源空对象 | 
|           if (item.dataKey) { | 
|             // 下拉框都强制设置为字符串类型 | 
|             item.columnType = 'string'; | 
|             if (!item.data) { | 
|               item.data = []; | 
|             } | 
|           } | 
|   | 
|           if (item.range || item.type == 'range') { | 
|             if ( | 
|               !(props.formFields[item.field] instanceof Array) || | 
|               props.formFields[item.field].length != 2 | 
|             ) { | 
|               props.formFields[item.field] = ['', '']; | 
|             } | 
|             rangeFields.push(item.field); | 
|           } | 
|         }); | 
|       }); | 
|     }; | 
|   | 
|     const initSource = () => { | 
|       let keys = [], | 
|         binds = []; | 
|       // 初始化字典数据源 | 
|       props.formRules.forEach((item) => { | 
|         item.forEach((x) => { | 
|           if (x.dataKey && (!x.data || x.data.length == 0) && !x.remote) { | 
|             x.data = []; | 
|             binds.push({ key: x.dataKey, data: x.data, type: x.type }); | 
|             if (keys.indexOf(x.dataKey) == -1) { | 
|               keys.push(x.dataKey); | 
|             } | 
|           } | 
|         }); | 
|       }); | 
|   | 
|       if (keys.length == 0) return; | 
|       appContext.config.globalProperties.http | 
|         .post('/api/Sys_Dictionary/GetVueDictionary', keys) | 
|         .then((dic) => { | 
|           bindOptions(dic, binds); | 
|           proxy.$emit('dicInited', dic); | 
|         }); | 
|     }; | 
|     const bindOptions = (dic, binds) => { | 
|       dic.forEach((d) => { | 
|         if (d.data.length > props.select2Count) { | 
|           if ( | 
|             !binds.some((x) => { | 
|               return x.key == d.dicNo && x.type == 'cascader'; | 
|             }) | 
|           ) { | 
|             d.data.forEach((item) => { | 
|               item.label = item.value; | 
|               item.value = item.key; | 
|             }); | 
|           } | 
|         } | 
|         binds.forEach((x) => { | 
|           if (x.key != d.dicNo) return true; | 
|           // 如果有数据的则不查询 | 
|           if (x.data.length > 0) return true; | 
|           //2022.03.13增加级联数据源自动转换 | 
|           if (x.type == 'cascader' || x.type == 'treeSelect') { | 
|             let _data = JSON.parse(JSON.stringify(d.data)); | 
|             let cascaderArr = appContext.config.globalProperties.base.convertTree( | 
|               _data, | 
|               (node, data, isRoot) => { | 
|                 if (!node.inited) { | 
|                   node.inited = true; | 
|                   node.label = node.value; | 
|                   node.value = node.key; | 
|                 } | 
|               } | 
|             ); | 
|             props.formRules.forEach((option) => { | 
|               option.forEach((item) => { | 
|                 if (item.dataKey == x.key) { | 
|                   item.orginData = x.data; | 
|                   item.data = cascaderArr; | 
|                 } | 
|               }); | 
|             }); | 
|           } else if (d.data.length > 0 && !d.data[0].hasOwnProperty('key')) { | 
|             let source = d.data, | 
|               newSource = new Array(source.length); | 
|             for (let index = 0; index < source.length; index++) { | 
|               newSource[index] = { | 
|                 key: source['key'] + '', | 
|                 value: source['value'] | 
|               }; | 
|             } | 
|             x.data.push(...newSource); | 
|           } else { | 
|             x.data.push(...d.data); | 
|           } | 
|         }); | 
|       }); | 
|     }; | 
|   | 
|     const initUpload = (item, init) => { | 
|       if (!init) return; | 
|       if ( | 
|         ['img', 'excel', 'file'].indexOf(item.type != -1) || | 
|         item.columnType == 'img' | 
|       ) { | 
|         // 只是没设置是否自动上传的,默认都是选择文件后自动上传 | 
|         if (!item.hasOwnProperty('autoUpload')) { | 
|           item.autoUpload = true; | 
|         } | 
|         if (!item.hasOwnProperty('fileList')) { | 
|           item.fileList = true; | 
|         } | 
|         if (!item.hasOwnProperty('downLoad')) { | 
|           item.downLoad = true; | 
|         } | 
|         if (!item.removeBefore) { | 
|           item.removeBefore = (index, file, files) => { | 
|             return true; | 
|           }; | 
|         } | 
|         if (!item.fileClick) { | 
|           item.fileClick = (index, file, files) => { | 
|             return true; | 
|           }; | 
|         } | 
|         if (!item.onChange) { | 
|           item.onChange = (files) => { | 
|             return true; | 
|           }; | 
|         } | 
|         if (!item.uploadAfter) { | 
|           item.uploadAfter = (result, files) => { | 
|             return true; | 
|           }; | 
|         } | 
|         if (!item.uploadBefore) { | 
|           item.uploadBefore = (files) => { | 
|             return true; | 
|           }; | 
|         } | 
|       } | 
|     }; | 
|     const validate = (callback) => { | 
|       let result = true; | 
|       volform.value.validate((valid) => { | 
|         if (!valid) { | 
|           appContext.config.globalProperties.$message.error('数据验证未通过!'); | 
|           result = false; | 
|         } else if (typeof callback === 'function') { | 
|           try { | 
|             callback(valid); | 
|           } catch (error) { | 
|             let msg = `表单验证回调方法异常:${error.message}`; | 
|             appContext.config.globalProperties.$message.error(msg); | 
|             console.log(msg); | 
|           } | 
|         } | 
|       }); | 
|       return result; | 
|     }; | 
|   | 
|     initFormRules(true); | 
|     return { | 
|       remoteCall, | 
|       span, | 
|       rangeFields, | 
|       numberFields, | 
|       validate, | 
|       volform | 
|       //  initFormRules, | 
|       // initSource | 
|     }; | 
|   }, | 
|   created() { | 
|     this.formRules.forEach((rules) => { | 
|       rules.forEach((option) => { | 
|         if (option.type == 'treeSelect' && option.multiple === undefined) { | 
|           option.multiple = true; | 
|         } | 
|       }); | 
|     }); | 
|   }, | 
|   | 
|   data() { | 
|     return { | 
|       // remoteCall: true, | 
|       errorImg: 'this.src="' + require('@/assets/imgs/error-img.png') + '"' | 
|       // span: 1, | 
|       // rangeFields: [], | 
|     }; | 
|   }, | 
|   methods: { | 
|     getColWidth(item) { | 
|       //2021.08.30 增加动态计算表单宽度 | 
|       let _span = 0; | 
|       this.formRules.forEach((row, xIndex) => { | 
|         //2022.05.06 追加表单中隐藏的元素不参与动态计算表单宽度 | 
|         let rowLength = row.filter((item) => { | 
|           return !item.hidden; | 
|         }).length; | 
|         if (rowLength > _span) _span = rowLength; | 
|       }); | 
|       let rete = | 
|         Math.round(((item.colSize || 12 / _span) / 0.12) * colPow, 10.0) / | 
|         colPow; | 
|       if (item.colSize) return rete.toFixed(3); | 
|       return rete.toFixed(3); | 
|       // return (100 - rete).toFixed(3); | 
|     }, | 
|     previewImg(url) { | 
|       this.base.previewImg(url, this.http.ipAddress); | 
|     }, | 
|     getSrc(path) { | 
|       if (!path) return; | 
|       if (!this.base.isUrl(path) && path.indexOf('.') != -1) { | 
|         return this.http.ipAddress + path; | 
|       } | 
|       return path; | 
|     }, | 
|     // 是否为图片文件等格式并对字段的转换成数组:[{name:'1.jpg',path:'127.0.0.1/ff/1.jpg'}] | 
|     isFile(item, formFields) { | 
|       if ( | 
|         item.type == 'img' || | 
|         item.columnType == 'img' || | 
|         item.type == 'excel' || | 
|         item.type == 'file' | 
|       ) { | 
|         this.convertFileToArray(item, formFields); | 
|         return true; | 
|       } | 
|       return false; | 
|     }, | 
|     isReadonlyImgFile(item, formFields) { | 
|       if ((item.disabled || item.readonly) && this.isFile(item, formFields)) { | 
|         return true; | 
|       } | 
|       return false; | 
|     }, | 
|     convertFileToArray(item, formFields) { | 
|       if (!item.maxFile) { | 
|         item.maxFile = 1; // 默认只能上传一个文件,可以在onInit中设置 | 
|       } | 
|   | 
|       let fileInfo = formFields[item.field]; | 
|       if (fileInfo instanceof Array) { | 
|         return; | 
|       } | 
|       if (fileInfo === null || fileInfo === undefined) { | 
|         formFields[item.field] = []; | 
|         return; | 
|       } | 
|       // 将以逗号隔开的文件分割成数组127.0.0.1/aa/1.jpg,将127.0.0.1/aa/2.jpg | 
|       if (typeof fileInfo === 'string') { | 
|         if (fileInfo.trim() === '') { | 
|           formFields[item.field] = []; | 
|           return; | 
|         } | 
|         // 如果文件路径是字符串,则使用,拆分 | 
|         fileInfo = fileInfo.replace(/\\/g, '/'); | 
|         let files = fileInfo.split(','); | 
|         formFields[item.field] = []; | 
|         for (let index = 0; index < files.length; index++) { | 
|           let file = files[index]; | 
|           let splitFile = file.split('/'); | 
|           formFields[item.field].push({ | 
|             name: splitFile.length > 0 ? splitFile[splitFile.length - 1] : file, | 
|             path: file // this.base.isUrl(file) ? file : this.http.ipAddress + file, | 
|           }); | 
|         } | 
|       } | 
|     }, | 
|     dowloadFile(file) { | 
|       this.base.dowloadFile( | 
|         file.path, | 
|         file.name, | 
|         { | 
|           Authorization: this.$store.getters.getToken() | 
|         }, | 
|         this.http.ipAddress | 
|       ); | 
|     }, | 
|     validatorPhone(ruleOption, value, callback) { | 
|       if (!ruleOption.required && !value && value != '0') { | 
|         return callback(); | 
|       } | 
|       if (!rule.phone.test((value || '').trim())) { | 
|         return callback(new Error('请输入正确的手机号')); | 
|       } | 
|       callback(); | 
|     }, | 
|     validatorPwd(ruleOption, value, callback) { | 
|       if (!ruleOption.required && !value && value != '0') { | 
|         return callback(); | 
|       } | 
|       if ((value + '').trim().length < 6) { | 
|         return callback(new Error('密码长度不能小于6位')); | 
|       } | 
|       callback(); | 
|     }, | 
|     convertArrayValue(data, val) { | 
|       // 2020.12.13增加表单多选只转换字典 | 
|       // 编辑多选table显示 | 
|       //2023.04.20修复只读为label时原数据被字典替换了的问题 | 
|       let valArr = Array.isArray(val) | 
|         ? val.map((x) => { | 
|             return x; | 
|           }) | 
|         : val.split(','); | 
|       for (let index = 0; index < valArr.length; index++) { | 
|         var _item = data.find((x) => { | 
|           return x.key && x.key != '0' && x.key + '' == valArr[index] + ''; | 
|         }); | 
|         if (_item) { | 
|           valArr[index] = _item.value; | 
|         } | 
|       } | 
|       return valArr.join(','); | 
|     }, | 
|     getText(formFields, item) { | 
|       // 2019.10.24修复表单select组件为只读的属性时没有绑定数据源 | 
|       let text = formFields[item.field]; | 
|       if (typeof text === 'function') return text(formFields); | 
|       if (text === 'null' || text === '' || text === null || text === undefined) | 
|         return '--'; | 
|       //2021.03.02增加只读时日期处理 | 
|       if (item.type == 'date') { | 
|         return text.replace('T', ' ').split(' ')[0]; | 
|       } | 
|       //2021.03.31修复表单switch只读时没有转换值的问题 | 
|       if (item.type == 'switch') { | 
|         return text ? '是' : '否'; | 
|       } | 
|       if (!item.data) return text; | 
|       if (item.type == 'selectList' || item.type == 'checkbox') { | 
|         return this.convertArrayValue(item.data, text); | 
|       } | 
|       var _item = item.data.find((x) => { | 
|         return x.key == text; | 
|       }); | 
|       return _item ? _item.value : text; | 
|     }, | 
|     onClear(item, formFields) { | 
|       // 远程select标签清空选项 | 
|       item.data.splice(0); | 
|       // console.log(2); | 
|     }, | 
|     onChange(item, value) { | 
|       if (item.onChange && typeof item.onChange === 'function') { | 
|         item.onChange(value, item); | 
|       } | 
|     }, | 
|     onRemoteChange(item, value) { | 
|       // 第二次打开时,默认值成了undefined,待查viewgrid中重置代码 | 
|       if (value == undefined && item.data.length > 0) { | 
|         this.formFields[item.field] = item.data[0].key; | 
|         //  console.log('undefined'); | 
|       } | 
|       this.remoteCall = false; | 
|       if (item.onChange && typeof item.onChange === 'function') { | 
|         item.onChange(value, item); | 
|       } | 
|     }, | 
|     getData(item) { | 
|       return item.data; | 
|     }, | 
|   | 
|     // 远程搜索(打开弹出框时应该禁止搜索) | 
|     remoteSearch(item, formFields, val) { | 
|       if (!item.remote && !item.url) { | 
|         return; | 
|       } | 
|       if ( | 
|         val == '' || | 
|         (item.data.length == 1 && | 
|           (val == item.data[0].key || val == item.data[0].value)) | 
|       ) { | 
|         return; | 
|       } | 
|       // 弹出框或初始化表单时给data设置数组默认值2 | 
|       // 2020.09.26修复远程搜索自定义url不起作用的问题 | 
|       let url; | 
|       if (typeof item.url === 'function') { | 
|         url = item.url(val, item.dataKey, item); | 
|       } else { | 
|         url = | 
|           (item.url || '/api/Sys_Dictionary/GetSearchDictionary') + | 
|           '?dicNo=' + | 
|           item.dataKey + | 
|           '&value=' + | 
|           val; | 
|       } | 
|       this.http.post(url).then((dicData) => { | 
|         //this.$set(item, "loading", false); | 
|         item.loading = false; | 
|         item.data = dicData; | 
|         this.formRules[item.point.x].splice(item.point.y, 1, item); | 
|       }); | 
|     }, | 
|     getObject(date) { | 
|       if (typeof date === 'object') { | 
|         return date; | 
|       } | 
|       return new Date(date); | 
|     }, | 
|     reset(sourceObj) { | 
|       // 重置表单时,禁用远程查询 | 
|       this.$refs['volform'].resetFields(); | 
|       if (this.rangeFields.length) { | 
|         this.rangeFields.forEach((key) => { | 
|           this.formFields[key].splice(0); | 
|           this.formFields[key] = [null, null]; | 
|         }); | 
|       } | 
|       if (!sourceObj) return; | 
|       for (const key in this.formFields) { | 
|         if (sourceObj.hasOwnProperty(key)) { | 
|           this.formFields[key] = sourceObj[key]; | 
|           if (this.numberFields.indexOf(key) != -1) { | 
|             this.formFields[key] = sourceObj[key] * 1 || 0; | 
|           } | 
|         } | 
|       } | 
|       //  this.remoteCall = true; | 
|     }, | 
|   | 
|     fileOnChange(files, item) { | 
|       this.$refs.volform.clearValidate(item.field); | 
|       if (item.onChange) { | 
|         return item.onChange(files); | 
|       } | 
|       return true; | 
|     }, | 
|     isReadonly(item) { | 
|       return item.readonly || item.disabled; | 
|     }, | 
|     getRule(item, formFields) { | 
|       //2021.07.17增加只读表单不验证 | 
|       //range与swtich暂时不做校验 | 
|       if ( | 
|         // item.readonly || | 
|         // item.disabled || | 
|         item.type == 'switch' || | 
|         item.type == 'range' | 
|       ) | 
|         return { required: false }; | 
|       // 用户设置的自定义方法 | 
|       if (item.validator && typeof item.validator === 'function') { | 
|         return { | 
|           validator: (rule, val, callback) => { | 
|             // 用户自定义的方法,如果返回了值,直接显示返回的值,验证不通过 | 
|             let message = item.validator(rule, val); | 
|             if (message) return callback(new Error(message + '')); | 
|             return callback(); | 
|           }, | 
|           required: item.required, | 
|           trigger: rule.change.indexOf(item.type) != -1 ? 'change' : 'blur' | 
|         }; | 
|       } | 
|       if (['img', 'excel', 'file'].indexOf(item.type) != -1) { | 
|         return { | 
|           validator: (rule, val, callback) => { | 
|             //2021.09.05移除文件上传默认必填 | 
|             if ( | 
|               item.required && | 
|               !this.isReadonly(item) && | 
|               (!val || !val.length) | 
|             ) { | 
|               return callback( | 
|                 new Error(item.type == 'img' ? '请上传照片' : '请上传文件') | 
|               ); | 
|             } | 
|             return callback(); | 
|           }, | 
|           required: item.required, | 
|           trigger: 'change' | 
|         }; | 
|       } | 
|       // 设置数字的最大值民最小值 | 
|       if ( | 
|         item.type == 'number' || | 
|         item.columnType == 'number' || | 
|         item.columnType == 'int' || | 
|         item.type == 'decimal' | 
|       ) { | 
|         // 如果是必填项的数字,设置一个默认最大与最值小 | 
|         if (item.required && typeof item.min !== 'number') { | 
|           item.min = 0; //item.type == "decimal" ? 0.1 : 1; | 
|         } | 
|   | 
|         return { | 
|           required: item.required, | 
|           message: item.title + '只能是数字', | 
|           title: item.title, | 
|           trigger: 'blur', | 
|           min: item.min, | 
|           max: item.max, | 
|           type: item.columnType || item.type, | 
|           validator: (ruleObj, value, callback) => { | 
|             if (!ruleObj.min && !ruleObj.max) { | 
|               if (ruleObj.required) { | 
|                 if ((!value && value != '0') || !rule.decimal.test(value)) { | 
|                   return callback(new Error('只能是数字')); | 
|                 } | 
|               } | 
|               return callback(); | 
|             } | 
|             if (this.isReadonly(item)) return callback(); | 
|             if (ruleObj.type == 'number') { | 
|               if (!rule.number.test(value)) { | 
|                 ruleObj.message = ruleObj.title + '只能是整数'; | 
|                 return callback(new Error(ruleObj.message)); | 
|               } | 
|             } else { | 
|               if (!rule.decimal.test(value)) { | 
|                 ruleObj.message = ruleObj.title + '只能是数字'; | 
|                 return callback(new Error(ruleObj.message)); | 
|               } | 
|             } | 
|             if ( | 
|               ruleObj.min !== undefined && | 
|               typeof ruleObj.min === 'number' && | 
|               value < ruleObj.min | 
|             ) { | 
|               ruleObj.message = ruleObj.title + '不能小于' + ruleObj.min; | 
|               return callback(new Error(ruleObj.message)); | 
|             } | 
|             if ( | 
|               ruleObj.max !== undefined && | 
|               typeof ruleObj.max === 'number' && | 
|               value > ruleObj.max | 
|             ) { | 
|               ruleObj.message = ruleObj.title + '不能大于' + ruleObj.max; | 
|               return callback(new Error(ruleObj.message)); | 
|             } | 
|             return callback(); | 
|           } | 
|         }; | 
|       } | 
|   | 
|       // 手机、密码验证 | 
|       if (item.type == 'password' || item.type == 'phone') { | 
|         return { | 
|           validator: | 
|             item.type == 'phone' ? this.validatorPhone : this.validatorPwd, | 
|           required: item.required, | 
|           trigger: 'blur' | 
|         }; | 
|       } | 
|   | 
|       if (!item.required && item.type != 'mail') return { required: false }; | 
|   | 
|       if (!item.hasOwnProperty('type')) item.type = 'text'; | 
|   | 
|       if (inputTypeArr.indexOf(item.type) != -1) { | 
|         let message = | 
|           item.title + | 
|           (item.type == 'mail' ? '必须是一个邮箱地址' : '不能为空'); | 
|         let type = item.type == 'mail' ? 'email' : types[item.columnType]; | 
|         let _rule = { | 
|           required: true, | 
|           message: message, | 
|           trigger: 'blur', | 
|           type: type, | 
|           validator: (ruleObj, value, callback) => { | 
|             if ( | 
|               !this.isReadonly(item) && | 
|               (value === '' || value === undefined || value === null) | 
|             ) { | 
|               return callback(new Error(ruleObj.message)); | 
|             } | 
|             return callback(); | 
|           } | 
|         }; | 
|         if (item.type == 'mail') { | 
|           _rule.validator = undefined; | 
|           return _rule; | 
|         } | 
|         if (item.min) { | 
|           _rule.min = item.min; | 
|           _rule.message = item.title + '至少' + item.min + '个字符!'; | 
|         } | 
|         if (item.max) { | 
|           return [ | 
|             _rule, | 
|             { | 
|               max: item.max, | 
|               required: true, | 
|               message: item.title + '最多' + item.max + '个字符!', | 
|               trigger: 'blur' | 
|             } | 
|           ]; | 
|         } | 
|         return _rule; | 
|       } | 
|   | 
|       if (item.type == 'radio') { | 
|         return { | 
|           required: item.required, | 
|           message: '请选择' + item.title, | 
|           trigger: 'change', | 
|           type: 'string' | 
|         }; | 
|       } | 
|       if ( | 
|         item.type == 'date' || | 
|         item.type == 'datetime' || | 
|         item.type == 'month' || | 
|         item.type == 'time' | 
|       ) { | 
|         return { | 
|           required: true, | 
|           message: '请选择' + item.title, | 
|           trigger: 'change', | 
|           type: item.range ? 'array' : 'string', | 
|           validator: (rule, val, callback) => { | 
|             if (this.isReadonly(item)) return callback(); | 
|             // 用户自定义的方法,如果返回了值,直接显示返回的值,验证不通过 | 
|             if (!val || (item.range && !val.length)) { | 
|               return callback(new Error('请选择日期')); | 
|             } | 
|             return callback(); | 
|           } | 
|         }; | 
|       } | 
|   | 
|       if (item.type == 'cascader') { | 
|         return { | 
|           type: 'array', | 
|           required: true, | 
|           min: item.min || 1, | 
|           // message: "请选择" + item.title, | 
|           trigger: 'change', | 
|           validator: (rule, val, callback) => { | 
|             if (this.isReadonly(item)) return callback(); | 
|             // 用户自定义的方法,如果返回了值,直接显示返回的值,验证不通过 | 
|             let _arr = this.formFields[item.field]; | 
|             if (!_arr || !_arr.length) { | 
|               return callback(new Error('请选择' + item.title)); | 
|             } | 
|             return callback(); | 
|           } | 
|         }; | 
|       } | 
|   | 
|       if ( | 
|         ['select', 'selectList', 'checkbox', 'cascader', 'treeSelect'].indexOf( | 
|           item.type | 
|         ) != -1 | 
|       ) { | 
|         let _rule = { | 
|           type: item.type == 'select' ? 'string' : 'array', | 
|           required: true, | 
|           min: item.min || 1, | 
|           message: '请选择' + item.title, | 
|           trigger: 'change', | 
|           validator: (rule, value, callback) => { | 
|             if (this.isReadonly(item)) return callback(); | 
|             //2021.11.27修复多选没有提示的问题 | 
|             if (value == undefined || value === '') { | 
|               return callback(new Error(rule.message)); | 
|             } else if ( | 
|               (item.type == 'checkbox' || | 
|                 item.type == 'selectList' || | 
|                 item.type == 'treeSelect') && | 
|               (!(value instanceof Array) || !value.length) | 
|             ) { | 
|               return callback(new Error(rule.message)); | 
|             } | 
|             return callback(); | 
|           } | 
|         }; | 
|   | 
|         if (_rule.max) { | 
|           _rule.nax = item.max; | 
|           _rule.message = '最多只能选择' + item.max + '项'; | 
|         } | 
|         return _rule; | 
|       } | 
|       return {}; | 
|     }, | 
|     compareDate(date1, date2) { | 
|       if (!date2) { | 
|         return true; | 
|       } | 
|       return ( | 
|         date1.valueOf() < | 
|         (typeof date2 == 'number' ? date2 : new Date(date2).valueOf()) | 
|       ); | 
|     }, | 
|     getDateOptions(date, item) { | 
|       //2021.07.17设置时间可选范围 | 
|       if ((!item.min && !item.max) || !date) { | 
|         return false; | 
|       } | 
|       if (item.min && item.min.indexOf(' ') == -1) { | 
|         //不设置时分秒,后面会自动加上 08:00 | 
|         item.min = item.min + ' 00:00:000'; | 
|       } | 
|       return ( | 
|         this.compareDate(date, item.min) || !this.compareDate(date, item.max) | 
|       ); | 
|     }, | 
|     getDateFormat(item) { | 
|       if (item.type == 'month') { | 
|         return 'YYYY-MM'; | 
|       } | 
|       // if (item.type=='time') { | 
|       //     return 'HH:mm:ss' | 
|       // } | 
|       //见https://day.js.org/docs/zh-CN/display/format | 
|       return item.type == 'date' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'; | 
|     }, | 
|     dateRangeChange(val, item) { | 
|       if (!val) { | 
|         this.$emit('update:formFields'); | 
|         return; | 
|       } | 
|       item.onChange && item.onChange(val); | 
|     }, | 
|     onKeyPress($event, item) { | 
|       if ($event.keyCode == 13) { | 
|         return; | 
|       } | 
|       item.onKeyPress($event); | 
|     }, | 
|     filterMethod(value, data) { | 
|       return data.label.includes(value); | 
|     }, | 
|     getNode( label,node, data){ | 
|       console.log(label) | 
|     } | 
|   } | 
| }); | 
| </script> | 
| <style lang="less" scoped> | 
| .el-form-item { | 
|   margin-right: 0; | 
| } | 
| .el-form-item { | 
|   .form-imgs { | 
|     img { | 
|       float: left; | 
|       cursor: pointer; | 
|       object-fit: cover; | 
|       margin: 0 10px 10px 0; | 
|       width: 65px; | 
|       height: 65px; | 
|       border: 1px solid #c7c7c7; | 
|       overflow: hidden; | 
|       border-radius: 5px; | 
|       box-sizing: content-box; | 
|     } | 
|   } | 
| } | 
| .el-form-item ::v-deep(.el-form-item__label) { | 
|   padding: 0 0px 0 4px; | 
|   overflow: hidden; | 
|   text-overflow: ellipsis; | 
|   white-space: nowrap; | 
| } | 
| .el-form-item ::v-deep(.el-range-separator) { | 
|   text-align: center; | 
|   width: 13px; | 
|   padding: 0px 1px; | 
|   font-size: 12px; | 
| } | 
| .el-form-item ::v-deep(.el-range__close-icon) { | 
|   margin-right: -10px; | 
| } | 
| .form-item-extra { | 
|   > *:first-child { | 
|     flex: 1; | 
|   } | 
|   display: flex; | 
|   .form-extra { | 
|     padding-left: 7px; | 
|     line-height: 36px; | 
|   } | 
| } | 
| .vol-form-item { | 
|   width: 100%; | 
| } | 
| .vol-form-item ::v-deep(.el-form-item__content) { | 
|   display: unset !important; | 
| } | 
| .vol-form-item ::v-deep(.el-input--large .el-input__inner) { | 
|   height: 34px !important; | 
| } | 
| .vol-form-item ::v-deep(.el-input-number--large .el-input-number__increase) { | 
|   border-top: 1px solid #d4d4d4; | 
| } | 
| .vol-form-item ::v-deep(.el-input-number--large .el-input-number__decrease) { | 
|   border-bottom: 1px solid #d4d4d4; | 
| } | 
| .vol-form-item ::v-deep(.el-input--large.el-date-editor) { | 
|   height: 36px; | 
| } | 
| .v-date-range ::v-deep(.el-input__prefix) { | 
|   display: none; | 
| } | 
| .v-date-range ::v-deep(.el-input__inner) { | 
|   padding: 0; | 
| } | 
|   | 
| .el-form-item ::v-deep(.el-checkbox) { | 
|   margin-right: 8px; | 
| } | 
| .el-form-item ::v-deep(.el-checkbox .el-checkbox__label) { | 
|   padding-left: 5px; | 
| } | 
| .el-form-item ::v-deep(textarea) { | 
|   font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB', | 
|     'Microsoft YaHei', '微软雅黑', Arial, sans-serif !important; | 
| } | 
| .el-form-item ::v-deep(.el-select .el-select__tags > span) { | 
|   display: flex; | 
| } | 
| .el-form-item ::v-deep(.el-select-v2__combobox-input) { | 
|   height: 30px; | 
| } | 
| .el-form-item ::v-deep(.el-select__tags) { | 
|   overflow: hidden; | 
|   height: 30px; | 
| } | 
| .el-form-item ::v-deep(.el-select-tags-wrapper) { | 
|   position: absolute; | 
| } | 
|   | 
| .el-form-item { | 
|   vertical-align: top !important; | 
| } | 
| .form-file-list { | 
|   a { | 
|     color: #3ea9ff; | 
|   } | 
|   a:hover { | 
|     cursor: pointer; | 
|     color: #0281e7; | 
|   } | 
| } | 
| </style> |