<!--
 * @Author: fengyang9326@163.com
 * @Date: 2024-05-13 10:36:07
 * @LastEditors: fengyang9326@163.com
 * @LastEditTime: 2024-05-20 09:18:31
 * @FilePath: /web/framework/src/views/system/temporary/form-dialog.vue
 * @Description: 表单
-->
<template>
  <div v-loading="loadingForm" class="inline_false">
    <el-form ref="form" :model="formInline" :label-width="labelWidth" class="form_inline_false">
      <!-- 表单循环 -->
      <el-form-item
        v-for="(item, index) in formItemConfigArr"
        :key="item.id + index"
        :label="item.label"
        :prop="item.prop"
        :rules="item.deliveryLevel === 'ESS' ? rulesForm[item.prop] : {}"
      >
        <template id="formItemTemp">
          <!-- 表单左侧 label 与 校验 * 号图标 -->
          <span slot="label" class="label_title" :title="item.label">
            <!-- <i v-if="item.deliveryLevel === 'ESS'" class="red_must">*</i> -->
            <!-- <span class="item_label" :title="item.label">{{ item.label }}</span> -->
            {{ item.label }}
          </span>

          <!-- 1. 选择器_单选 SelectorSingleSelection -->
          <el-select
            v-if="item.itemType === 'SelectorSingleSelection' || item.itemType === '选择器_单选'"
            v-model="valueSelectorSingle"
            class="form_select"
            :placeholder="`请选择${item.label}`"
            @focus="setMinWidth"
            @change="handleSelectorSingle($event, item.prop, index)"
          >
            <el-option
              v-for="(optionItem, optionIndex) in item.optionArr"
              :key="optionItem.optionValue + optionIndex"
              :label="optionItem.optionLabel"
              :value="optionItem.optionValue"
              :style="{ width: minWidth + 2 + 'px' }"
            />
          </el-select>

          <!-- 2. 选择器_多选 SelectorMultipleSelection -->
          <el-cascader
            v-if="item.itemType === 'SelectorMultipleSelection' || item.itemType === '选择器_多选'"
            ref="formCascader"
            class="form_cascader"
            :options="item.optionArr"
            :placeholder="`请选择${item.label}`"
            :props="{
              checkStrictly: false,
              multiple: true,
              emitPath: false,
              label: 'optionLabel',
              value: 'optionValue',
            }"
            clearable
            @input="handleSelectorMultiple($event, item.prop)"
          />

          <!-- 3. 选择器_树结构 SelectorTreeStructure -->
          <SelectTree
            v-if="item.itemType === 'SelectorTreeStructure' || item.itemType === '选择器_树结构'"
            ref="SelectTree"
            :filterable="true"
            :value-key="`deptId`"
            :select-key="`deptId`"
            :value-name="`deptName`"
            :tree-data="item.optionArr"
            :tree-props="{
              id: 'deptId',
              label: 'deptName',
              children: 'children',
            }"
            :tree-node-key="`deptId`"
            :placeholder-title="`请选择${item.label}`"
            @nodeClickTree="nodeClickTree"
          />

          <!-- 4. 选择器_单时间 SelectorSingleTime -->
          <el-date-picker
            v-if="item.itemType === 'SelectorSingleTime' || item.itemType === '选择器_单时间'"
            v-model="formInline[item.prop]"
            type="datetime"
            class="form_dataTime"
            format="yyyy-MM-dd HH:mm:ss"
            value-format="yyyy-MM-dd HH:mm:ss"
            :placeholder="`请选择${item.label}日期时间`"
            @input="handleInputValue($event, item.prop)"
          />

          <!-- 5. 选择器_单日期 SelectorSingleDate -->
          <el-date-picker
            v-if="item.itemType === 'SelectorSingleDate' || item.itemType === '选择器_单日期'"
            v-model="formInline[item.prop]"
            type="date"
            class="form_picker"
            :placeholder="`请选择${item.label}日期`"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
            @input="handleInputValue($event, item.prop)"
          />

          <!-- 6. 选择器_日期范围 SelectorDateRange -->
          <el-date-picker
            v-if="item.itemType === 'SelectorDateRange' || item.itemType === '选择器_日期范围'"
            v-model="formInline[item.prop]"
            type="daterange"
            class="form_daterange"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            @input="handleSelectorDateRange($event, item.prop)"
          />

          <!-- 7. 多行文本 MultilineText -->
          <el-input
            v-if="item.itemType === 'MultilineText' || item.itemType === '多行文本'"
            v-model="formInline[item.prop]"
            type="textarea"
            class="form_multiline"
            :autosize="{ minRows: 2, maxRows: 4 }"
            placeholder="请输入内容"
            @input="handleInputValue($event, item.prop)"
          />

          <!-- 8. 单选框 RadioBox -->
          <el-radio-group
            v-if="item.itemType === 'RadioBox' || item.itemType === '单选框'"
            v-model="formInline[item.prop]"
            class="form_radio"
            @input="handleInputValue($event, item.prop)"
          >
            <el-radio
              v-for="(optionItem, optionIndex) in item.optionArr"
              :key="optionItem.optionValue + optionIndex"
              :label="optionItem"
            >
              {{ optionItem.optionLabel }}
            </el-radio>
          </el-radio-group>

          <!-- 9. 多选框 MultipleCheckbox -->
          <el-checkbox-group
            v-if="item.itemType === 'MultipleCheckbox' || item.itemType === '多选框'"
            v-model="formInline[item.prop]"
            class="form_checkbox"
            @input="handleInputValue($event, item.prop)"
          >
            <el-checkbox
              v-for="(optionItem, optionIndex) in item.optionArr"
              :key="optionItem.optionValue + optionIndex"
              :label="optionItem"
            >
              {{ optionItem.optionLabel }}
            </el-checkbox>
          </el-checkbox-group>

          <!-- 10. 输入框 InputString InputInteger InputDecimals -->
          <el-input
            v-if="item.itemType === 'InputString' || item.itemType === '字符型'"
            v-model="formInline[item.prop]"
            class="form_input"
            :placeholder="`请选择${item.label}`"
            @input="handleInputValue($event, item.prop)"
          />
          <el-input
            v-if="item.itemType === 'InputDecimals' || item.itemType === '小数型'"
            v-model="formInline[item.prop]"
            class="form_input"
            :placeholder="`请选择${item.label}`"
            oninput="value=value.replace(/[^\d^\.]+/g, '').replace(/^0+(\d)/, '$1').replace(/^\./, '0.').match(/^\d*(\.?\d{0,3})/g)[0]"
            @input="handleInputValue($event, item.prop)"
          />
          <el-input
            v-if="item.itemType === 'InputInteger' || item.itemType === '整数型'"
            v-model="formInline[item.prop]"
            class="form_input"
            :placeholder="`请选择${item.label}`"
            oninput="value=value.replace(/[^\d]/g,'')"
            @input="handleInputValue($event, item.prop)"
          />

          <!-- 11. 计数器 CounterFrame -->
          <el-input-number
            v-if="item.itemType === 'CounterFrame' || item.itemType === '计数器'"
            v-model="formInline[item.prop]"
            :min="0"
            :max="10000"
            class="form_number"
            label="描述文字"
            @input="handleInputValue($event, item.prop)"
          />

          <!-- 12. 文件上传 FileUpload -->

          <!-- 13. 富文本 RichText -->

          <!-- 备用校验方法 -->
          <!-- <div class="input_error" v-if="item.isRulesType"> <span class="input_error_label" :title="item.label">{{item.label}}</span>不能为空 </div> -->
        </template>
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
export default {
  name: 'FormDialog',
  components: {
    SelectTree: () =>
      import('./components/SelectTree') /* 3. 选择器_树结构 SelectorTreeStructure */,
  },
  props: {
    /* el-form-item表单循环项 */
    formItemConfigArr: {
      type: Array,
      default: () => [],
    },
    /* 表单label宽度 */
    labelWidth: {
      type: String,
      default: '120px',
    },
  },
  data() {
    return {
      /* 表单加载状态 */
      loadingForm: false,
      /* 表单model绑定对象 */
      formInline: {},
      /* 下拉框最小宽度样式 */
      minWidth: undefined,
      /* 1. 选择器_单选 SelectorSingleSelection 绑定的值 */
      valueSelectorSingle: '',
      /* 表单校验 */
      rulesForm: {},
    };
  },
  computed: {},
  watch: {},
  created() {
    this.initialization();
  },
  mounted() {},
  methods: {
    /* 初始化数据 */
    initialization() {
      for (let i = 1; i < this.formItemConfigArr.length; i++) {
        const item = this.formItemConfigArr[i];
        this.rulesForm[item.prop] = {
          required: true,
          validator: this.validateRules(),
          trigger: 'blur',
        };
        switch (item.itemType) {
          /* 1. 选择器_单选 SelectorSingleSelection */
          case 'SelectorSingleSelection':
            this.formInline[item.prop] = {};
            break;

          /* 2. 选择器_多选 SelectorMultipleSelection */
          case 'SelectorMultipleSelection':
            this.formInline[item.prop] = [];
            break;

          /* 3. 选择器_树结构 SelectorTreeStructure */
          case 'SelectorTreeStructure':
            this.formInline[item.prop] = {};
            break;

          /* 8. 单选框 RadioBox */
          case 'RadioBox':
            this.formInline[item.prop] = {};
            break;

          /* 9. 多选框 MultipleCheckbox */
          case 'MultipleCheckbox':
            this.formInline[item.prop] = [];
            break;

          /* 11. 计数器 CounterFrame */
          case 'CounterFrame':
            this.formInline[item.prop] = 0;
            break;

          /**
           * 4. 选择器_单时间 SelectorSingleTime
           * 5. 选择器_单日期 SelectorSingleDate
           * 6. 选择器_日期范围 SelectorDateRange
           * 7. 多行文本 MultilineText
           * 10. 输入框 InputString InputInteger InputDecimals
           * 12. 文件上传 FileUpload
           * 13. 富文本 RichText
           **/
          default:
            this.formInline[item.prop] = '';
        }
      }
    },
    /* 下拉框样式 无数据的情况下，给请选择提示设置最小宽度*/
    setMinWidth(val) {
      this.minWidth = val.srcElement.clientWidth;
    },
    validateRules(value, prop) {
      console.log('validateRules', value, prop);
      if (!value) {
        return `${prop}不能为空`;
      } else if (this.isNameType(value)) {
        return `${prop}只包含中文、英文、空格、数字、中划线、下划线`;
      }
    },
    /**
     *  只包含英文、数字、空格、中划线、下划线
     *  true 符合 false 不符合
     **/
    isCodeType(str, prop) {
      if (str.length === 0) {
        return `${prop}不能为空`;
      }
      const reg =
        /[`~!@#$%^&*()+=<>?:"{}|,.;'·~！@#￥%……&*（）——+={}|《》？：“”【】、；‘'，。、]/im;
      const regOne = /^[^\u4e00-\u9fa5]+$/;
      const regTwo = /\\/;
      if (!reg.test(str) && regOne.test(str) && !regTwo.test(str)) {
        return `${prop}只包含中文、英文、空格、数字、中划线、下划线`;
      }
      return true;
    },
    /**
     *  可输入英文、中文、空格、数字、中划线、下划线，特殊字符可以排除
     *  true 符合 false 不符合
     **/
    isNameType(str, prop) {
      if (str.length === 0) {
        return `${prop}不能为空`;
      }
      const reg =
        /[`~!@#$%^&*()+=<>?:"{}|,.;'·~！@#￥%……&*（）——+={}|《》？：“”【】、；‘'，。、]/im;
      const regTwo = /\\/;
      if (!reg.test(str) && !regTwo.test(str)) {
        return `${prop}只包含英文、数字、空格、中划线、下划线`;
      }
      return true;
    },

    /* 1. 选择器_单选 SelectorSingleSelection */
    handleSelectorSingle(e, prop, index) {
      this.formInline[prop] = {};
      const arr = this.formItemConfigArr[index].optionArr;
      const objIndex = arr.find(item => {
        if (item.optionValue === e) return item;
      });
      this.handleInputValue(objIndex, prop);
    },
    /* 2. 选择器_多选 SelectorMultipleSelection */
    handleSelectorMultiple(e, prop) {
      this.formInline[prop] = [];
      const nodesObj = this.$refs['formCascader'][0].getCheckedNodes();
      const selectorMultipleSelectionArr = [];
      nodesObj.forEach(item => {
        selectorMultipleSelectionArr.push(item.data);
      });
      this.handleInputValue(selectorMultipleSelectionArr, prop);
    },

    /* 3. 选择器_树结构 SelectorTreeStructure */
    nodeClickTree(data) {
      this.handleInputValue(data, 'SelectorTreeStructure');
    },

    /* 6. 选择器_日期范围 SelectorDateRange */
    handleSelectorDateRange(e, prop) {
      this.formInline[prop] = [];
      this.handleInputValue(e, prop);
    },

    /* 12. 文件上传 FileUpload */
    /* 13. 富文本 RichText */

    /**
     * 4. 选择器_单时间 SelectorSingleTime
     * 5. 选择器_单日期 SelectorSingleDate
     * 7. 多行文本 MultilineText
     * 8. 单选框 RadioBox
     * 9. 多选框 MultipleCheckbox
     * 10. 输入框 InputString InputInteger InputDecimals
     * 11. 计数器 CounterFrame
     **/
    handleInputValue(e, prop) {
      this.formInline[prop] = e;
      this.$forceUpdate();
      const data = { data: e, prop: prop };
      this.$emit('handleInputValue', data);
    },
  },
};
</script>
<style lang="scss" scoped>
// 1. 选择器_单选 form_select
.form_select {
  width: 100%;
}

// 2. 选择器_多选 form_cascader
.form_cascader {
  width: 100%;
}

// 3. 选择器_树结构 SelectorTreeStructure

// 4. 选择器_单时间 form_dataTime
.form_dataTime {
  width: 100%;
}

// 5. 选择器_单日期 form_picker
.form_picker {
  width: 100%;
}

// 6. 选择器_日期范围 form_daterange
.form_daterange {
  width: 100%;
}

// 7. 多行文本 form_multiline
.form_multiline {
  width: 100%;
}

// 8. 单选框 form_radio
.form_radio {
  width: 100%;
}

// 9. 多选框 form_checkbox
.form_checkbox {
  width: 100%;
}

// 10. 输入框 form_input
.form_input {
  width: 100%;
}

// 11. 计数器 form_number
.form_number {
  width: 100%;
}

// 12. 文件上传 FileUpload
// 13. 富文本 RichText

/* 表单 label 宽度样式 */
.label_title {
  display: inline-block;
  max-width: calc(100% - 10px);
  box-sizing: border-box;
  // padding-right: 10px;
  /*让长段文本不换行*/
  white-space: nowrap;
  /*设置文本超出元素宽度部分隐藏*/
  overflow-x: hidden;
  /*设置文本超出部分用省略号显示*/
  text-overflow: ellipsis;
  vertical-align: middle;
}
</style>
