<!--
 * @Descripttion: 增删改查列表查询页-新增编辑组件
 * @Author: Devli
 * @Date: 2021-7-17 10:42:24
 * @Last Modified by:   qianlishi
 * @Last Modified time: 2021-12-13 10:40:24
 !-->
<template>
  <div
    v-if="option['hide'] == null || option['hide'] == false"
    class="anji-card"
  >
    <div class="card-head">
      {{ option.title }}
      <div class="main-card-header-button">
        <el-button type="text" @click="handleSetRowColNum(4)">||||</el-button>
        <el-button type="text" @click="handleSetRowColNum(3)">|||</el-button>
        <el-button type="text" @click="handleSetRowColNum(2)">||</el-button>
      </div>
    </div>
    <div class="card-body">
      <el-form
        ref="editForm"
        :model="editForm"
        :label-width="option.labelWidth || '100px'"
      >
        <!--:disabled="modelType == 'view'"-->
        <template v-for="group in columnGroups">
          <el-divider v-if="groupModel" :key="group" content-position="left">{{
            group
          }}</el-divider>
          <el-row :key="group" class="form_table">
            <template v-for="item in groupFormFields[group]">
              <el-col
                v-if="fieldIsHide(item.editHide) == false"
                :key="item.editField"
                :span="
                  item.rowColSpan == null ? cardRowColSpan : item.rowColSpan
                "
              >
                <el-form-item
                  :label="item.label"
                  :rules="item.rules"
                  :prop="item.editField"
                  :disabled="item.disabled"
                >
                  <!-- 输入框 -->
                  <span
                    v-if="item.tips != '' && item.tips != null"
                    :style="{ 'margin-left': '-13px' }"
                    class="input_tips"
                  >
                    <el-tooltip
                      class="item"
                      effect="dark"
                      :content="item.tips"
                      placement="top-start"
                    >
                      <svg-icon icon-class="tishi-yiwen" />
                    </el-tooltip>
                  </span>
                  <el-input
                    v-if="item.inputType == 'input'"
                    v-model.trim="editForm[item.editField]"
                    :placeholder="item.placeholder || '请输入'"
                    :clearable="item.clearable !== false"
                    :disabled="fieldIsDisable(item.disabled)"
                    @change="value => formChange(item.editField, value, null)"
                  />
                  <!-- 开关 -->
                  <el-switch
                    v-else-if="item.inputType == 'switch'"
                    v-model.trim="editForm[item.editField]"
                    :disabled="fieldIsDisable(item.disabled)"
                    :active-value="1"
                    :inactive-value="0"
                    inactive-color="#ccc"
                    active-color="#5887fb"
                    @change="value => formChange(item.editField, value, null)"
                  />
                  <el-input-number
                    v-else-if="item.inputType == 'input-number'"
                    v-model.trim="editForm[item.editField]"
                    :min="item.inputNumberOption.min"
                    :max="item.inputNumberOption.max"
                    :placeholder="item.placeholder || '请输入'"
                    :clearable="item.clearable !== false"
                    :disabled="fieldIsDisable(item.disabled)"
                    @change="value => formChange(item.editField, value, null)"
                  />
                  <!-- 自定义input -->
                  <anji-input
                    v-else-if="item.inputType == 'anji-input'"
                    v-model.trim="editForm[item.editField]"
                    :unit="item.anjiInput.unit"
                    :default-unit="item.anjiInput.defaultUnit"
                    :placeholder="item.placeholder || '请输入'"
                    :clearable="item.clearable !== false"
                    :disabled="fieldIsDisable(item.disabled)"
                    @change="value => formChange(item.editField, value, null)"
                  />
                  <!-- 下拉框 -->
                  <anji-select
                    v-else-if="item.inputType == 'anji-select'"
                    v-model.trim="editForm[item.editField]"
                    :allow-create="item.anjiSelectOption.allowCreate"
                    :multiple="item.anjiSelectOption.multiple"
                    :disabled="fieldIsDisable(item.disabled)"
                    :dict-code="item.anjiSelectOption.dictCode"
                    :placeholder="item.placeholder"
                    :url="item.anjiSelectOption.url"
                    :method="item.anjiSelectOption.method"
                    :query-param="item.anjiSelectOption.queryParam"
                    :merge-label="item.anjiSelectOption.mergeLabel"
                    :option="item.anjiSelectOption.option"
                    :label="item.anjiSelectOption.label"
                    :remote-filter="item.anjiSelectOption.remoteFilter"
                    :disabled-options="item.anjiSelectOption.disabledOptions"
                    :select-keyword="item.anjiSelectOption.selectKeyword"
                    @change="
                      (value, option) =>
                        formChange(item.editField, value, option)
                    "
                  />
                  <!-- 日期时间框  -->
                  <el-date-picker
                    v-else-if="item.inputType.indexOf('date') >= 0"
                    v-model="editForm[item.editField]"
                    style="width: 100%"
                    :placeholder="item.placeholder || '请选择'"
                    :type="item.inputType"
                    :format="item.format"
                    :value-format="item.valueFormat"
                    :disabled="fieldIsDisable(item.disabled)"
                    :clearable="item.clearable !== false"
                    @change="value => formChange(item.editField, value, null)"
                  />
                  <!-- checkbox -->
                  <anji-checkbox
                    v-else-if="item.inputType == 'checkbox'"
                    v-model.trim="editForm[item.editField]"
                    :dict-code="item.anjiCheckbox.dictCode"
                    :url="item.anjiCheckbox.url"
                    :label="item.anjiCheckbox.label"
                    :disabled="fieldIsDisable(item.disabled)"
                    @change="
                      (value, options) =>
                        formChange(item.editField, value, options)
                    "
                  />
                  <!-- 城市三级联动 -->
                  <anji-cascader
                    v-else-if="item.inputType == 'anji-cascader'"
                    v-model.trim="editForm[item.editField]"
                    :disabled="fieldIsDisable(item.disabled)"
                    :single-display="item.anjiCascader.singleDisplay"
                    :url="item.anjiCascader.url"
                    @change="value => formChange(item.editField, value, null)"
                  />
                  <!-- 上传组件 -->
                  <anji-upload
                    v-else-if="item.inputType == 'anji-upload'"
                    v-model.trim="editForm[item.editField]"
                    :up-load-url="item.anjiUpload.upLoadUrl"
                    :view-url="item.anjiUpload.viewUrl"
                    :upload-type="item.anjiUpload.uploadType"
                    :limit="item.anjiUpload.limit"
                    @change="value => formChange(item.editField, value, null)"
                  />
                  <!-- input自带输入建议 -->
                  <anji-autocomplete
                    v-else-if="item.inputType == 'anji-autocomplete'"
                    v-model.trim="editForm[item.editField]"
                    :disabled="fieldIsDisable(item.disabled)"
                    :label="item.anjiAutocomplete.label"
                    :option="item.anjiAutocomplete.option"
                    :appoint-value="item.anjiAutocomplete.appointValue"
                    :url="item.anjiAutocomplete.url"
                    @change="
                      (value, option) =>
                        formChange(item.editField, value, option)
                    "
                  />
                  <!-- textarea -->
                  <el-input
                    v-else-if="item.inputType == 'textarea'"
                    v-model.trim="editForm[item.editField]"
                    :placeholder="item.placeholder || '请输入'"
                    :clearable="item.clearable !== false"
                    :disabled="fieldIsDisable(item.disabled)"
                    type="textarea"
                    :rows="2"
                    @change="value => formChange(item.editField, value, null)"
                  />
                  <!-- 城市四级联动 -->
                  <anji-fourlevel
                    v-else-if="item.inputType == 'anji-country'"
                    v-model.trim="editForm[item.editField]"
                    @change="value => formChange(item.editField, value, null)"
                  />
                  <el-input
                    v-else
                    placeholder="组件不支持此类型表单请至组件内部自行扩展"
                    disabled
                  />
                </el-form-item>
              </el-col>
            </template>
          </el-row>
        </template>
      </el-form>
    </div>
  </div>
</template>

<script>
export default {
  components: {},
  props: {
    modelType: String, // add view edit
    showDialog: Boolean,
    option: {
      // 界面渲染相关配置json
      type: [Object],
      default: () => {
        return {
          title: "", // 页面标题
          labelWidth: "", // 表单输入框label宽度
          queryFormFields: [], // 查询表单条件
          buttons: {
            // 按钮
            query: {},
            edit: {},
            delete: {},
            add: {}
          },
          columns: [], // 表格列
          formChange: (formData, fieldName, fieldVal, fieldExtend) => {} // 弹出框表单修改回调
        };
      }
    },
    // 当relateData不为空时，该组件是渲染与relateData一对一关联的子表信息
    relateData: {
      type: [Object],
      default: () => {
        return {};
      }
    },
    value: {
      type: [Object],
      default: () => {
        return {};
      }
    }
  },
  data() {
    return {
      cardRowColNum: this.option.rowColForm || 2, // 主信息一行显示几列
      editForm: {} // 提交表单的数据
    };
  },
  computed: {
    // 主键的列名
    primaryKeyFieldName() {
      let primaryKey = this.option.columns.find(
        item => item["primaryKey"] == true
      );
      if (primaryKey != null) {
        return primaryKey["field"];
      } else {
        return null;
        console.warn(
          "在columns中查找primaryKey=true失败，会导致查询详情和删除失败"
        );
      }
    },
    // 指定当前实体关联主表的
    joinColumn() {
      let columnName = this.option.joinColumn;
      if (this.isBlank(columnName)) {
        console.warn(
          "在joinEntity中查找joinColumn属性失败，会导致查询详情和删除失败"
        );
        columnName = "";
      }
      return columnName;
    },
    // 提交表单中所有的列，因部分翻译字段，表格中和表单中的key不一样，field editField不全，这里补全下，
    formFields() {
      if (this.option.columns == null) {
        return [];
      }
      let fields = this.deepClone(this.option.columns);
      fields = fields.map(item => {
        if (this.isBlank(item["editField"])) {
          item["editField"] = item["field"];
        }
        // 没有设定分组的，全部补全成 其它信息
        if (this.isBlank(item["group"])) {
          item["group"] = "其它";
        }
        return item;
      });
      return fields;
    },
    // 卡片设定中一行显示几列，每列的col数
    cardRowColSpan() {
      return 24 / this.cardRowColNum;
    },
    // 如果表单内容较多，启用了分组，这里先算出所有的分组
    columnGroups() {
      if (this.isBlank(this.formFields)) {
        return [];
      } else {
        // 找出所有hide != true的关联表
        let groups = this.formFields
          .map(item => {
            return item["group"];
          })
          .filter((currentValue, index, arr) => {
            return arr.indexOf(currentValue) == index;
          });
        return groups;
      }
    },
    /* {
      '分组1': [{column1.1}],
      '分组2': [{column2.1}],
    }*/
    groupFormFields() {
      if (this.showDialog) {
        // 将每个分组初始化
        let groupFormFields = {};
        this.columnGroups.forEach((value, index, array) => {
          groupFormFields[value] = [];
        });
        // 将所有编辑列，按分组存放
        this.formFields.forEach((item, index, array) => {
          groupFormFields[item["group"]].push(item);
        });
        return groupFormFields;
      }
      return [];
    },
    groupModel() {
      return this.columnGroups.length > 1;
    }
  },
  created() {
    // 如果表单，是做为主表的编辑页面，如果是通过v-model传递进来的值，通过监听value，更新this.editForm
    this.$watch(
      function() {
        return this.value;
      },
      function(newVal, oldVal) {
        this.editForm = newVal;
        // 通过v-model传递值进来时，说明当前form是主表信息
        this.formChange();
      }
    );
    // 如果表单，是做为子表的编辑页面，当relateData中的关联字段发生更新时，触发查询，比如在goods详情中，goodsCode
    this.$watch(
      function() {
        return this.relateData[this.joinColumn];
      },
      function(newVal, oldVal) {
        // 如果是父组件(弹出框)关闭时，设置this.relateData = {}时触发，清空本组件的数据
        if (this.isBlank(this.relateData)) {
          this.cardRowColNum = 2;
          this.editForm = {};
          return;
        }
        // 如果是关联字段发生更新，触发查询
        if (this.isNotBlank(newVal)) {
          this.queryDetail();
        }
      }
    );
  },
  mounted() {
    // 如果表单，是做为主表的编辑页面，如果是通过v-model传递进来的值
    if (this.isNotBlank(this.value)) {
      this.editForm = this.value;
      this.formChange();
    }
    // 如果表单，是做为子表的编辑页面，首次打开时，根据关联属性，加载详情数据
    if (
      this.isNotBlank(this.relateData) &&
      this.isNotBlank(this.relateData[this.joinColumn])
    ) {
      this.queryDetail();
    }
  },
  methods: {
    // 该行是否显示 true/false/ 'hideOnAdd hideOnView hideOnEdit'
    fieldIsHide(editHide) {
      if (typeof editHide == "boolean") {
        return editHide;
      }
      if (typeof editHide == "string") {
        if (this.modelType == "add") {
          return editHide.indexOf("hideOnAdd") >= 0;
        }
        if (this.modelType == "view") {
          return editHide.indexOf("hideOnView") >= 0;
        }
        if (this.modelType == "edit") {
          return editHide.indexOf("hideOnEdit") >= 0;
        }
      }
      return false;
    },
    // 该行是否禁用 true/false/ 'disableOnAdd disableOnView disableOnEdit'
    fieldIsDisable(disable) {
      if (typeof disable == "boolean") {
        return disable;
      }
      if (typeof disable == "string") {
        if (this.modelType == "add") {
          return disable.indexOf("disableOnAdd") >= 0;
        }
        if (this.modelType == "view") {
          return disable.indexOf("disableOnView") >= 0;
        }
        if (this.modelType == "edit") {
          return disable.indexOf("disableOnEdit") >= 0;
        }
      }
      return false;
    },
    // 设置一行显示几列
    handleSetRowColNum(num) {
      this.cardRowColNum = num;
      this.$emit("changeRowColNum", num);
    },

    async queryDetail() {
      let queryParams = this.relateData;
      const { data, code } = await this.option.buttons.queryByPrimarykey.api(
        queryParams
      );
      if (code != "200") return;
      this.editForm = data;
      this.formChange();
    },
    // 校验表单
    validate(callback) {
      this.$refs.editForm.validate(async (valid, obj) => {
        if (callback != null) {
          callback(valid);
        }
      });
    },
    handleSave(callback) {
      this.$refs.editForm.validate(async (valid, obj) => {
        if (valid) {
          if (this.modelType == "add") {
            // 当edit-from是作为关联子表的界面，补全关联属性
            if (typeof this.option.beforeInsert == "function") {
              this.option.beforeInsert(this.relateData, this.editForm);
            }
            const { code, message } = await this.option.buttons.add.api(
              this.editForm
            );
            if (code == "200") {
              if (callback != null) {
                callback();
              }
            } else {
              console.log(`提交表单调用新增接口失败：${message}`);
            }
          } else {
            // 当edit-from是作为关联子表的界面，补全关联属性
            if (typeof this.option.beforeUpdate == "function") {
              this.option.beforeUpdate(this.relateData, this.editForm);
            }
            const { code, message } = await this.option.buttons.edit.api(
              this.editForm
            );
            if (code == "200") {
              if (callback != null) {
                callback();
              }
            } else {
              console.log(`提交表单调用更新接口失败：${message}`);
            }
          }
        } else {
          console.log("表单校验失败");
        }
      });
    },
    // 表单任何一个变动时，通知外部v-model
    formChange(fieldName, fieldVal, fieldExtend) {
      this.$emit("input", this.editForm);
      // 表单变动后，回调option中的formChange事件
      if (typeof this.option.formChange == "function") {
        this.option.formChange(this.editForm, fieldName, fieldVal, fieldExtend);
      }
    }
  }
};
</script>

<style scoped lang="scss">
.input_tips {
  position: absolute;
  margin-top: -8px;
  .svg-icon {
    font-size: 20px;
    color: rgb(71, 8, 8);
  }
}
</style>
