structuralForm.vue 6.59 KB
<template>
  <view>
    <u-form :model="seriesForm" ref="seriesRef" :label-style="{ width: '160rpx', overflow: 'hidden', 'text-overflow': 'ellipsis', 'white-space': 'nowrap', display: 'block' }" label-width="160rpx">
      <u-form-item v-for="(item, index) in seriesFunctionList" :key="item.identifier" :label="item.functionName" :prop="item.identifier">
        <u-input v-if="item.dataType.type == 'INT' || item.dataType.type == 'DOUBLE'" shape="circle" type="number" v-model="seriesForm[item.identifier]" :placeholder="`请输入${item.functionName}`" />
        <u-input v-if="item.dataType.type == 'TEXT'" shape="circle" type="text" v-model="seriesForm[item.identifier]" :placeholder="`请输入${item.functionName}`" />
        <view @click="handleBool(item.identifier, item.dataType, index)">
          <u-input
            v-if="item.dataType.type == 'BOOL'"
            shape="circle"
            v-model="seriesForm[item.identifier]"
            :placeholder="`请选择${item.functionName}`"
            disabled
            disabledColor="#fff"
            suffixIcon="arrow-down"
          />
          <u-picker
            :show="showPickerView"
            :columns="[boolList]"
            keyName="label"
            closeOnClickOverlay
            @cancel="handleCancel(index)"
            @close="handleCancel(index)"
            @confirm="(e) => handleSelectBool(e, item.identifier, index)"
          ></u-picker>
        </view>

        <view @click="handleEnum(item.identifier, item.dataType, index)">
          <u-input
            v-if="item.dataType.type == 'ENUM'"
            shape="circle"
            v-model="seriesForm[item.identifier]"
            :placeholder="`请选择${item.functionName}`"
            disabled
            disabledColor="#fff"
            suffixIcon="arrow-down"
          />
          <u-picker
            :show="showPickerView"
            :columns="[enumList.map((item) => ({ label: item.name, value: item.value }))]"
            keyName="label"
            closeOnClickOverlay
            @cancel="handleCancel(index)"
            @close="handleCancel(index)"
            @confirm="(e) => handleSelectEnum(e, item.identifier, index)"
          ></u-picker>
        </view>
      </u-form-item>
    </u-form>
  </view>
</template>

<script>
export default {
  name: 'StructForm',
  props: {
    seriesInputData: {
      type: Array,
      default: () => [],
    },
  },
  data() {
    return {
      showPickerView: false,
      boolInfo: {},
      enumInfo: {},
      seriesForm: {},
      seriesRules: {},
      seriesFunctionList: [],
      boolList: [],
      enumList: [],
    }
  },
  async mounted() {
    await this.$nextTick(() => {
      this.createInit()
    })
  },
  watch: {
    seriesInputData: {
      deep: true,
      handler(newVal, oldVal) {
        this.createInit()
      },
    },
  },

  methods: {
    createInit() {
      this.seriesFunctionList = this.seriesInputData
      this.seriesInputData.forEach((item) => {
        this.$set(item, 'isShowModel', false)
        this.showPickerView=false
        const {
          dataType: { specs, type },
          identifier,
          functionName,
        } = item || {}

        this.$set(this.seriesForm, identifier, '')
        const { valueRange, length = 10240 } = specs || {}

        const { max = 2147483647, min = -2147483647 } = valueRange || {}

        this.seriesRules[identifier] = [
          { required: true, message: type == 'BOOL' || type == 'ENUM' ? '请选择' : '请输入' + functionName },
          type == 'INT' || type == 'DOUBLE'
            ? {
                type: 'number',
                trigger: 'change',
                validator: (_rule, value) => {
                  const reg = /^[0-9]*$/
                  if (!reg.test(value)) return Promise.reject(new Error(`${functionName}不是一个有效的数字`))
                  if (value < min || value > max) return Promise.reject(new Error(`${functionName}取值范围在${min}~${max}之间`))

                  return Promise.resolve(value)
                },
              }
            : type == 'TEXT'
            ? {
                type: 'string',
                trigger: 'change',
                validator: (_rule, value) => {
                  if ((value?.length || 0) > length) return Promise.reject(new Error(`${functionName}数据长度应该小于${length}`))

                  return Promise.resolve(value)
                },
              }
            : {},
        ]
      })
      this.$nextTick(() => {
        this.$refs.seriesRef.setRules(this.seriesRules)
      })
    },

    handleBool(name, dataType, num) {
      this.seriesFunctionList.forEach((item, index) => {
        if (index == num) {
          item.isShowModel = true
          this.showPickerView=true
        }
      })
      const { specs } = dataType || {}
      const { boolClose, boolOpen } = specs || {}
      this.boolList = [
        { label: boolClose + '0', value: 0 },
        { label: boolOpen + '0', value: 1 },
      ]
      this.isShowBool = true
    },
    handleSelectBool(e, name, num) {
      this.isShowBool = false
      const { value } = e || {}
      this.boolInfo[name] = value[0].value
      this.$set(this.seriesForm, name, value[0].label)
      this.seriesFunctionList.forEach((item, index) => {
        if (index == num) {
          item.isShowModel = false
          this.showPickerView=false
        }
      })
    },

    getFormField() {
      return {
        ...this.seriesForm,
        ...this.boolInfo,
        ...this.enumInfo,
      }
    },

    handleEnum(name, dataType, num) {
      const { specsList } = dataType || {}
      this.isShowEnum = true
      this.enumList = specsList || []
      if(!this.enumList.length){
        return uni.$u.toast(`暂无可选的${name}`)
      }
      this.seriesFunctionList.forEach((item, index) => {
        if (index == num) {
          item.isShowModel = true
          this.showPickerView=true
        }
      })
    },
    handleSelectEnum(e, name, num) {
      const { value } = e || {}
      this.enumInfo[name] = value[0].value
      this.$set(this.seriesForm, name, value[0].label)
      this.seriesFunctionList.forEach((item, index) => {
        if (index == num) {
          item.isShowModel = false
          this.showPickerView=false
        }
      })
    },
    handleCancel(num){
      this.seriesFunctionList.forEach((item, index) => {
        if (index == num) {
          item.isShowModel = false
          this.showPickerView=false
        }
      })
    },

    handleValidate() {
      return this.$refs.seriesRef?.validate((valid) => {
        if (!valid) return
      })
    },
  },
}
</script>

<style lang="scss" scoped></style>