<!--
  动态表单
  props
  1   config    array   例子如下

 config: {
        uiConfig: {
          onSureText    String   确定文案  默认为确定 
          onResetText   String   取消文案  默认为取消
        },
        list: [
          {
            type    String  表单类型  如:'input'
            label   String  标题  
            name   String  绑定字段
            model  String or Array  默认值绑定值
            col    Number  宽度 默认为 24 
            EnableTemplate  Boolean 是否开启插槽
            radioType   String  默认为空  button可转换为按钮样式 仅在radio组件使用
            radioOptions  Array  选项集合 例如  { label: "Apple", value: "Apple" } 仅在radio组件使用
            selectOptions Array  选项集合 例如  { label: "Apple", value: "Apple", children: [] } 仅在select中使用
            slotName  String  插槽名 示例
                 <template v-slot:inputSlot="{Item,model,itemName}"> Item为该项 model为列表数据 itemName为字段名
            rules   Array   校验规则，与antd相同  如下 
            [         
              { required: true, message: 'Please input Activity name', trigger: 'blur' }
            ]
            event   Array 如下：
            [
               { eventName: "change", func: this.changeRadioFunc }
            ],
                事件列表
                    input 
                          change  与回成事件共用
                          search  带确认按钮的输入框
                    select
                          change  与回成事件共用
                          blur  失去焦点回调
                          focus  获取焦点
                          select 被选中时调用
            ... 通过$attrs 绑定antd 默认api参数   如：prefix disabled
          },
           onSure  function 确定按钮的回调函数
           onReset   funciton 取消按钮的回调函数
        ]
      },
-->
<template>
  <div>
    <a-config-provider :locale="locale">
      <a-form-model
        :ref="propsConfig.ref"
        :model="modelLits"
        :rules="propsConfig.rules"
        :label-col="propsConfig.uiConfig.labelCol"
        :wrapper-col="propsConfig.uiConfig.wrapperCol"
      >
        <a-row
          type="flex"
          justify="space-between"
        >
          <a-col
            :span="item.col ? item.col : 24"
            v-for="item in propsConfig.list"
            :key="item.name"
          >
            <a-form-model-item
              :label="item.label"
              :prop="item.name"
            >
              <component
                :is="module(item.type)"
                :item="item"
                :modelList="modelLits"
                :name="item.name"
                :funcList="funcList"
                v-if="!item.EnableTemplate"
              >
              </component>
              <slot
                :name="item.slotName"
                :Item="item"
                :model="modelLits"
                :itemName="item.name"
              >
              </slot>
            </a-form-model-item>
          </a-col>
        </a-row>
        <slot name="buttons">
          <a-button
            type="primary"
            @click="onSure"
          >
            {{ propsConfig.uiConfig.onSureText }}
          </a-button>
          <a-button
            style="margin-left: 10px"
            @click="onReset"
          >
            {{ propsConfig.uiConfig.onResetText }}
          </a-button>
        </slot>
      </a-form-model>
    </a-config-provider>
  </div>
</template>
<script>
import zhCN from "ant-design-vue/lib/locale-provider/zh_CN";
import {
  Col,
  ConfigProvider,
  FormModel,
  Button,
  Row,
  Form,
} from "ant-design-vue";
import FormItem from "ant-design-vue/lib/form-model/FormItem";
export default {
  name: "cy-form-create",
  components: {
    [Col.name]: Col,
    [ConfigProvider.name]: ConfigProvider,
    [FormModel.name]: FormModel,
    [Button.name]: Button,
    [Row.name]: Row,
    [Form.name]: Form,
    [FormItem.name]: FormItem,
  },
  props: {
    config: {
      type: Object,
      require: true,
    },
  },
  data () {
    return {
      modelLits: {},
      funcList: [],
      locale: zhCN,
    };
  },
  methods: {
    // json的深度替换
    mergeJSON (minor, main) {
      for (var key in minor) {
        if (main[key] === undefined) {
          main[key] = minor[key];
          continue;
        }
        if (typeof minor[key] == "object" && minor[key].constructor == Object) {
          arguments.callee(minor[key], main[key]);
        }
      }
      return main;
    },
    onSure () {
      this.$refs[this.propsConfig.ref].validate((valid) => {
        if (valid) {
          this.propsConfig.onSure(this.modelLits);
        } else {
          return false;
        }
      });
    },
    onReset () {
      this.$refs[this.propsConfig.ref].resetFields();
      this.propsConfig.onReset();
    },
  },
  computed: {
    module () {
      return function (type) {
        if (type) {
          return require(`./form_common/${type}.vue`).default;
        }
        // return = () => import('./form_common/input.vue')
      };
    },
    propsConfig () {
      let defaultConfig = {
        uiConfig: {
          onSureText: "确定",
          onResetText: "取消",
        },
        rules: {},
        list: [],
        modelLits: {},
        ref: "ruleForm",
        onSure: () => { },
      };
      let config = this.config;
      let newConifg = this.mergeJSON(defaultConfig, config);
      // 重组rules form数据
      newConifg.list.forEach((_) => {
        this.$set(newConifg.rules, _.name, _.rules);
        this.$set(this.modelLits, _.name, _.model);
        if (_.event) {
          _.event.forEach((r) => {
            this.funcList.push({
              eventName: r.eventName + "-" + _.name,
              func: r.func,
            });
          });
        }
      });
      return newConifg;
    },
  },
};
</script>
