<template>
|
|
<div>
|
|
<div v-for="(item, index) in formConfig" :key="index">
|
|
<template v-if="item.type === 'cardItem'">
|
|
<div class="grid-container">
|
|
<div v-for="(sItem, key) in item.config" class="form-item" :class="sItem.span == 1 ? 'full-row' : ''"
|
|
:key="key">
|
|
<template v-if="sItem.type === 'input'">
|
|
<div class="form-title">{{ sItem.label }}</div>
|
|
<HandleFormItem :item="sItem" :value="formFields[key]" @input="onInput(key, $event)"
|
|
@copy="onCopy(sItem, key)" />
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else-if="item.type === 'conditionItem'">
|
|
<div class="form-item ">
|
|
<div class="form-title fs-16" v-if="item.label">{{ item.label }}</div>
|
|
<div v-for="(sItem, key) in item.config" class="c-Item grid-container">
|
|
<div class="p-r-20">
|
|
<div class="form-title">{{ sItem.label }}</div>
|
|
<div class="flex ">
|
|
<HandleFormItem type="select" :item="sItem" :value="formFields[key]"
|
|
@copy="onCopy(sItem, key)" @change="onSelectChange(key, $event)" />
|
|
|
|
</div>
|
|
</div>
|
|
<div class="p-r-20">
|
|
<div v-show="isShowOther(formFields[key])">
|
|
<div class="form-title">其他</div>
|
|
<div class="flex">
|
|
<el-input v-model="formFields[sItem.otherCode]"
|
|
:class="sItem.borderType | getBorderType"></el-input>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template v-else-if="item.type === 'cellItem'">
|
|
<div class="form-item ">
|
|
<div class="form-title fs-16" v-if="item.label">{{ item.label }}</div>
|
|
<div class="grid-container">
|
|
<div v-for="(sItem, key) in item.config" class="c-Item " :class="sItem.span == 1 ? 'full-row' : ''"
|
|
:key="key">
|
|
<div class="form-title" v-if="sItem.label">{{ sItem.label }}</div>
|
|
<div v-if="sItem.type === 'dateTime'">
|
|
<el-date-picker v-model="formFields[key]" type="datetime" class="w-100"
|
|
format="yyyy/MM/DD HH:mm:ss" value-format="yyyy/MM/DD HH:mm:ss"
|
|
:placeholder="sItem.placeholder ? sItem.placeholder : ('请选择' + sItem.label)">
|
|
</el-date-picker>
|
|
</div>
|
|
<div v-else-if="sItem.type === 'select'">
|
|
<el-select class="w-100" :class="sItem.borderType | getBorderType" v-model="formFields[key]"
|
|
multiple :placeholder="sItem.placeholder ? sItem.placeholder : ('请选择' + sItem.label)">
|
|
<el-option v-for="op in sItem.options" :key="op.value" :label="op.label"
|
|
:value="op.value">
|
|
</el-option>
|
|
</el-select>
|
|
</div>
|
|
<div v-else-if="sItem.type === 'input'">
|
|
<el-input class="w-100" :class="sItem.borderType | getBorderType" v-model="formFields[key]"
|
|
:placeholder="sItem.placeholder ? sItem.placeholder : ('请输入' + sItem.label)"></el-input>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import HandleFormItem from "./HandleFormItem.vue"
|
|
export default {
|
|
components: {
|
|
HandleFormItem
|
|
},
|
|
props: {
|
|
formConfig: {
|
|
type: Array,
|
|
value: () => [],
|
|
},
|
|
formData: {
|
|
type: Object,
|
|
value: () => ({})
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
formFields: {},//表单双休绑定字段
|
|
allFieldsConfig: {},//包含config的所有字段,主要用于校验表单是否填写
|
|
};
|
|
},
|
|
watch: {
|
|
immediate: true,
|
|
formData: {
|
|
handler(v) {
|
|
this.handleFormField();
|
|
}
|
|
}
|
|
},
|
|
mounted() {
|
|
this.handleFormField();
|
|
},
|
|
filters: {
|
|
getBorderType(type) {
|
|
const typeObj = {
|
|
orange: "orange-border",
|
|
green: "green-border",
|
|
blue: "blue-border",
|
|
}
|
|
return typeObj[type] || ""
|
|
},
|
|
|
|
},
|
|
methods: {
|
|
isShowOther(v = []) {
|
|
console.log(v, "vvv")
|
|
return v.includes("-1");
|
|
},
|
|
//根据formConifg回填form表单数据
|
|
handleFormField() {
|
|
const result = {};
|
|
let config = {};
|
|
const { formConfig, formData } = this;
|
|
formConfig.forEach((item) => {
|
|
if (item.config) {
|
|
config = { ...config, ...item.config }
|
|
Object.keys(item.config).forEach(key => {
|
|
const currentConfig = item.config[key];
|
|
result[key] = formData[key];
|
|
if (currentConfig.otherCode) {//如果有其它的字段需要赋值给formData
|
|
const { otherCode } = currentConfig;
|
|
result[otherCode] = formData[otherCode]
|
|
config[otherCode] = { label: "其他", type: "input" }
|
|
}
|
|
});
|
|
console.log(item.config, "config")
|
|
if (item.config?.otherCode) {
|
|
config[item.config?.otherCode] = item.config?.otherCode;
|
|
}
|
|
}
|
|
|
|
})
|
|
this.formFields = result;
|
|
this.allFieldsConfig = config;
|
|
console.log(config, "allFieldsConfig")
|
|
},
|
|
getFormData() {
|
|
const { formFields, allFieldsConfig } = this;
|
|
return new Promise((resolve,reject)=>{
|
|
for (const key in formFields) {
|
|
if (!formFields[key]) {
|
|
const o = allFieldsConfig[key];
|
|
let prefix = "";
|
|
if (o.type === "input") {
|
|
prefix = "填写"
|
|
} else {
|
|
prefix = "选择"
|
|
}
|
|
this.$message.error(`${o.label}还未${prefix}请${prefix}后再提交`);
|
|
reject("还未填写完");
|
|
return;
|
|
}
|
|
}
|
|
resolve(formFields)
|
|
})
|
|
|
|
},
|
|
onInput(key, val) {
|
|
this.formFields[key] = val;
|
|
this.$emit("input", { key, value: val });
|
|
},
|
|
onSelectChange(key, val) {
|
|
this.formFields[key] = val;
|
|
this.$emit("select", { key, value: val });
|
|
},
|
|
//复制
|
|
onCopy(config, key) {
|
|
const { formFields } = this;
|
|
if (config.copyFrom) {
|
|
formFields[key] = formFields[config.copyFrom]
|
|
}
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.grid-container {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
/* 默认2列 */
|
|
gap: 0 24px;
|
|
}
|
|
|
|
.w-100 {
|
|
width: 100% !important;
|
|
}
|
|
|
|
.form-item {
|
|
background: #fff;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
|
|
margin-top: 24px;
|
|
padding: 24px;
|
|
border-radius: 5px 5px;
|
|
|
|
}
|
|
|
|
/* 或者使用 span 语法 */
|
|
.full-row {
|
|
grid-column: span 2;
|
|
}
|
|
|
|
.c-Item {
|
|
&:not(:last-child) {
|
|
margin-bottom: 16px;
|
|
}
|
|
}
|
|
|
|
.form-title {
|
|
margin-bottom: 12px;
|
|
font-size: 14px;
|
|
font-weight: normal;
|
|
color: #606266;
|
|
}
|
|
.p-r-20{
|
|
padding-right: 20px;
|
|
}
|
|
.orange-border {
|
|
input {
|
|
border-color: #f9c588;
|
|
|
|
&:focus {
|
|
border-color: #f9c588;
|
|
}
|
|
|
|
&:hover {
|
|
border-color: #f9c588;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
.green-border {
|
|
input {
|
|
border-color: green;
|
|
|
|
&:focus {
|
|
border-color: green;
|
|
}
|
|
|
|
&:hover {
|
|
border-color: green;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
.blue-border {
|
|
input {
|
|
border-color: #4ea2ff;
|
|
|
|
&:focus {
|
|
border-color: #4ea2ff;
|
|
}
|
|
|
|
&:hover {
|
|
border-color: #4ea2ff;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
.fs-16 {
|
|
font-size: 0.96rem;
|
|
font-weight: bold;
|
|
color: #464647
|
|
}
|
|
|
|
.flex1 {
|
|
flex: 1;
|
|
}
|
|
|
|
.flex {
|
|
display: flex;
|
|
}
|
|
|
|
.mr-24 {
|
|
margin-right: 24px;
|
|
}
|
|
</style>
|