checkBuilder.vue 6.75 KB
<template>
  <el-form ref="queryForm" :model="form" class="formClass">
    <div class="btn-group">
      <el-button
        type="primary"
        @click="handleDownload"
        style="margin-right: 20px"
        >下载所有模板</el-button
      >
      <el-radio-group v-model="merge">
        <el-radio-button :label="true">强关联选择对象 </el-radio-button>
        <el-radio-button :label="false">自主选择对象</el-radio-button>
      </el-radio-group>
    </div>
    <el-row :gutter="30">
      <el-col v-for="(item, index) in schemas" :key="index" :span="12">
        <div class="check-card">
          <div class="check-item">
            <div class="check-item-name">
              {{ item.describe }}
            </div>
            <div class="check-item-check">
              <el-checkbox
                @change="handleCilck(item.key)"
                v-model="item.status"
              >
                不适用
              </el-checkbox>
              <span v-if="item.notApplicable">
                <el-tooltip
                  class="box-item circle"
                  effect="dark"
                  content=""
                  placement="top"
                  style="border-radius: 100px; margin-left: 20px"
                >
                  <i class="el-icon-question smartTip"></i>
                  <div style="width: 250px" slot="content" class="tip">
                    {{ item.notApplicable }}
                  </div>
                </el-tooltip>
              </span>
            </div>
          </div>
          <div class="check-body">
            <el-form-item
              :prop="item.key"
              style="width: 100%"
              :rules="[
                {
                  validator: (rule, value, callback) => {
                    checkItem(item, value, callback)
                  },
                  // message: `${item.describe}不能为空`,
                  trigger: ['blur']
                }
              ]"
            >
              <component
                :is="item.type"
                :status="item.status"
                :prop="item.key"
                :mergeSource="mergeSource"
                :items="item.componentProps"
                :defaultValue="item.record ? item.record.defaultValue : ''"
                :result="item.result"
                :merge="merge"
                @changeVal="changeVal"
                @mergeVal="mergeVal"
                @makeRecord="makeRecord"
                ref="formItem"
              >
              </component>
            </el-form-item>
            <div class="desc" v-if="item.remark">
              {{ item.remark }}
            </div>
            <!-- <div class="desc">12334</div> -->
          </div>
        </div>
      </el-col>
    </el-row>
  </el-form>
</template>
<script>
import '@/components/CheckCoiumns'
import { isFunction } from 'lodash'
export default {
  name: 'FormBuilder',
  props: {
    schemas: {
      type: Array,
      default: () => []
    },
    value: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      form: {},
      record: [],
      merge: true,
      mergeArr: [],
      mergeSource: []
    }
  },
  computed: {
    formSchemas() {
      const schemas = this.schemas.map(item => {
        const { componentProps } = item
        if (typeof componentProps === 'object') {
          return item
        } else {
          if (isFunction(componentProps)) {
            const res = componentProps({
              fromSchemas: this.schemas,
              fromValue: this.value
            })
            console.log('componentProps', res)
            item.componentProps = res
            return item
          }
        }

        return {
          ...item
        }
      })
      return schemas
    }
  },
  mǒunted() {
    this.$nextTick(() => {
      this.from = this.value
      this.$refs.queryForm.clearValidate()
    })
  },
  methods: {
    handleDownload() {
      location.href =
        'http://10.12.48.78:443/vehicle-quality-review-oss/2024/10/17/SchemeTemplate.zip'
    },
    handleCilck(key) {
      this.$refs.queryForm.clearValidate(key)
    },
    changeVal(data) {
      const { name, val } = data
      this.form[name] = val
      console.log(this.form)

      this.$emit('input', this.form)
      this.$nextTick(() => {
        this.$refs.queryForm.clearValidate(name)
      })
    },
    mergeVal(e) {
      this.$refs.formItem.map(i => {
        if (typeof i.mergeSource == 'function') {
          i.mergeSource(e)
        }
      })
    },
    makeRecord(data) {
      const { name, record } = data
      if (!this.record[name]) {
        this.record[name] = {
          defaultValue: ''
        }
      }

      this.record[name].defaultValue = record
      console.log(this.record)

      this.$nextTick(() => {
        this.$refs.queryForm.clearValidate(name)
      })
    },
    checkItem(prop, value, cb) {
      if (!prop.status) {
        if (this.form[prop.key]) {
          cb()
        } else {
          cb(new Error(`${prop.describe}不能为空`))
        }
      }
      cb()
    },
    async getValidateVaule() {
      const res = await this.$refs.queryForm.validate
      if (res) {
        let arr = []
        let codes = []
        this.schemas.map((i, k) => {
          if (i.status == false) {
            i.result = this.form[i.key]
            i.record = this.record[i.key]
            codes.push(this.form[i.key])
          }
          console.log(i)

          arr.push(i)
        })
        codes = codes.filter(item => item && item !== '')
        console.log({
          record: arr,
          codes: codes.join(',')
        })

        return {
          record: arr,
          codes: codes.join(',')
        }
      } else {
        return false
      }
    }
  }
}
</script>
<style lang="scss" scoped>
.circle {
  fill: #456bd9;
  stroke: #0f1c3f;
  stroke-width: 0.1875em;
  padding: 6px 10px;
  color: gray;
}
.check-card {
  min-height: 11rem;
}
.check-item {
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: rgba(240, 247, 255, 1);
  position: relative;
  padding: 5px 25px;
  &-name {
    color: rgb(64, 158, 255);
    font-size: 14px;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;

    &::before {
      content: '';
      display: inline-block;
      width: 4px;
      height: 14px;
      background-color: rgb(64, 158, 255);
      margin-right: 10px;
    }
  }
  &-check {
    // flex: 1;
  }
}
.check-body {
  padding: 10px 20px;
}
::v-deep {
  .el-form-item {
    margin-bottom: 0;
  }
}
.btn-group {
  margin-bottom: 20px;
  display: flex;
  justify-content: flex-end;
}
.tip {
  letter-spacing: 2px;
  text-align: justify;
}
.desc {
  color: red;
  margin-top: 10px;
  font-size: 14px;
  font-weight: 800;
}
</style>