<template>
  <!-- 表格公共组件 -->
  <div>
    <!-- 表单搜索 -->
    <el-form
      :model="queryParams"
      ref="queryFormRef"
      size="small"
      :inline="true"
      label-width="100px"
      v-show="showSearch"
      :rules="formRules"
    >
      <el-form-item
        v-for="(item, v) in formLabel"
        :key="v"
        :label="item.f_label"
        :prop="item.f_model"
      >
        <el-input
          v-if="item.f_type === 'ipt'"
          v-model="queryParams[item.f_model]"
          :placeholder="`请输入${item.f_label}`"
          :maxlength="item.f_max || 50"
          clearable
          style="width: 240px"
        />
        <el-select
          v-if="item.f_type === 'sel'"
          v-model="queryParams[item.f_model]"
          clearable
          filterable
          style="width: 240px"
          :placeholder="`请选择${item.f_label}`"
        >
          <el-option
            v-for="(sel, v) in item.f_selList"
            :key="v"
            :label="sel.label"
            :value="sel.value"
          />
        </el-select>
        <el-cascader
          v-if="item.f_type === 'selCasAdd'"
          v-model="queryParams[item.f_model]"
          :options="item.f_selList"
          :props="item.optionProps"
          :show-all-levels="false"
          clearable
          @change="
            handleCasAdd($event, item.f_model, cascaderFunc, extraTableProp)
          "
          style="width: 240px"
        />
        <el-cascader
          v-if="item.f_type === 'selCas'"
          v-model="queryParams[item.f_model]"
          :options="item.f_selList"
          :props="item.optionProps"
          :show-all-levels="false"
          @change="handleCas($event, item.f_model)"
          style="width: 240px"
        />
        <el-date-picker
          v-if="item.f_type === 'date'"
          v-model="queryParams[item.f_model]"
          style="width: 240px"
          value-format="yyyy-MM-dd"
          type="date"
          :placeholder="`请输入${item.f_label}`"
        />
        <el-date-picker
          v-if="item.f_type === 'dateRange'"
          v-model="queryParams[item.f_model]"
          style="width: 240px"
          type="daterange"
          value-format="yyyy-MM-dd"
          range-separator="至"
          start-placeholder="开始日期"
          end-placeholder="结束日期"
          @change="onChangeTime($event, item.dateType)"
        />
        <el-input-number
          v-if="item.f_type === 'num'"
          v-model="queryParams[item.f_model]"
          :min="0"
          style="width: 240px"
        ></el-input-number>
      </el-form-item>
      <el-form-item v-if="showBtnCrews">
        <el-button
          type="primary"
          icon="el-icon-search"
          size="mini"
          @click="handleQuery"
          v-if="showSearchBtn"
          >查询</el-button
        >
        <el-button
          type="success"
          icon="el-icon-edit"
          size="mini"
          @click="handleFill"
          v-if="!showSearchBtn"
          >填充</el-button
        >
        <el-button
          type="warning"
          icon="el-icon-refresh"
          size="mini"
          @click="resetQuery"
          >重置</el-button
        >
      </el-form-item>
    </el-form>
    <!-- 按钮集群 -->
    <el-row class="btn-container">
      <div class="btn-handler">
        <slot name="btn" :queryParams="queryParams"></slot>
      </div>
      <ToolbarModel
        :showSearch.sync="showSearch"
        :indexNumShow.sync="indexNumShow"
        :selectionShow.sync="selectionShow"
        :handleShow.sync="handleShow"
        :columns="columCheckList"
        @queryTable="getTableList"
        v-if="showRightTools"
      />
    </el-row>
    <!-- 表格 -->

    <el-table
      :data="tableList"
      border
      ref="tableRef"
      select-on-indeterminate
      style="width: 100%"
      v-loading="loading"
      @selection-change="handleSelectionChange"
    >
      >
      <el-table-column
        type="selection"
        width="45"
        align="center"
        v-if="showSel"
        :selectable="selectable"
      />
      <el-table-column
        width="55"
        align="center"
        label="序号"
        type="index"
        :index="indexContinuation(queryParams.pageNum, queryParams.pageSize)"
        v-if="showIndex"
      />
      <el-table-column
        v-for="(item, v) in tableColumCheckProps"
        :key="v"
        :label="item.t_label"
        :prop="item.t_props"
        :width="item.t_width"
        align="center"
        show-overflow-tooltip
      >
        <template slot-scope="scope">
          <!-- 判断当前列数据是否需要使用插槽的数据 -->
          <template v-if="item.t_slot">
            <slot :data="scope.row" :name="item.t_slot"></slot>
          </template>
          <template v-else>
            {{ scope.row[item.t_props] || "-" }}
          </template>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        label="操作"
        v-if="handleShow && showOperation"
        :min-width="dynamicWidth"
      >
        <template slot-scope="{ row }">
          <div class="optionDivRef">
            <slot :data="row" name="handle">-</slot>
          </div>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页 -->
    <pagination
      :total="total"
      :page.sync="queryParams.pageNum"
      :limit.sync="queryParams.pageSize"
      @pagination="getTableList"
    />
  </div>
</template>

<script>
import ToolbarModel from "../ToolbarModel";
export default {
  components: { ToolbarModel },
  props: {
    /** 表单查询条件 */
    formLabel: {
      type: Array,
      default: () => [],
    },
    /** 列表请求接口 */
    requestApi: {
      type: Function,
      default: () => function () {},
    },
    /** 列表配置项 */
    columnsList: {
      type: Array,
      default: () => [],
    },
    /** 是否显示选择框 */
    showSel: {
      type: Boolean,
      default: true,
    },
    /** 传递参数 */
    sendParams: {
      type: Object,
      default: () => null,
    },
    sendId: {
      type: Number,
      default: () => null,
    },
    /** 是否显示查询按钮 */
    showSearchBtn: {
      type: Boolean,
      default: true,
    },
    showBtnCrews: {
      type: Boolean,
      default: true,
    },
    cascaderFunc: {
      type: Function,
      default: () => null,
    },
    extraTableProp: {
      type: Object,
      default: () => null,
    },
    showOperation: {
      type: Boolean,
      default: true,
    },
    showRightTools: {
      type: Boolean,
      default: true,
    },
    selectable: {
      type: Function,
      default: () => {
        return true;
      },
    },
    selSingle: {
      type: Boolean,
      default: false,
    },
    showIndex: {
      type: Boolean,
      default: true,
    },
  },
  computed: {
    /* 根据操作栏控制表头是否显示 */
    tableColumCheckProps() {
      return this.columCheckList.filter((e) => {
        return e.checked != false;
      });
    },
  },
  watch: {
    handleShow: {
      handler(newValue) {
        if (!newValue) {
          this.dynamicWidth = 0;
        }
      },
    },
    columnsList: {
      handler(nv, ov) {
        if (nv !== ov) {
          this.columnsList = nv;
          this.columCheckList = this.columnsList.map((e) => {
            this.$set(e, "checked", true);
            return e;
          });
        }
      },
      deep: true,
    },
    /* sendParams: {
          handler(nv, ov) {
            console.log(nv, ov)
            if(nv !== ov) {
              Object.assign(this.queryParams, nv)
              this.getTableList()
            }
          },
          deep: true,
          immediate: true
      } */
  },
  data() {
    return {
      // 表单校验
      formRules: {},
      loading: false,
      // 列表接口查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
      },
      // 列表数据源
      tableList: [],
      // 导出传递数据
      msgList: undefined,
      // 列表数据条数
      total: 0,
      // 搜索区域是否隐藏
      showSearch: true,
      // 是否显示复选框
      selectionShow: true,
      // 是否显示序号
      indexNumShow: true,
      // 是否显示操作列
      handleShow: true,
      // 列表每列 label
      columCheckList: [],
      // 操作列最小宽度
      dynamicWidth: 0,
      idCount: 1,
      typeList: [],
    };
  },

  created() {
    this.columCheckList = this.columnsList.map((e) => {
      this.$set(e, "checked", true);
      return e;
    });
    /* 生成查询参数 */
    this.formLabel.map((e) => {
      if (e.f_type === "dateRange") {
        this.$set(this.queryParams, e.dateType[0], "");
        this.$set(this.queryParams, e.dateType[1], "");
        this.typeList = e.dateType;
      } else {
        this.$set(this.queryParams, e.f_model, "");
      }
      // 设置表单必填
      if (e.f_rule) {
        this.$set(this.formRules, e.f_rule, [
          {
            required: true,
            message: `请填写${e.f_label}`,
            trigger: "blur",
          },
        ]);
      }
    });
    if (this.sendParams !== null) {
      Object.assign(this.queryParams, this.sendParams);
      /* for(let key in this.sendParams) {
            console.log(key, this.sendParams[key])
            this.$set(this.queryParams, key, this.sendParams[key])
          } */
    }
    if (this.sendId !== null) this.queryParams.id = this.sendId;
    this.getTableList();
  },
  updated() {
    // 更新时重新计算操作列需要的最小宽度 确保展示无误
    this.dynamicWidth = this.getOperatorWidth();
  },
  methods: {
    /** 获取列表数据 */
    async getTableList() {
      if (this.queryParams.time && this.queryParams.time.length !== 0) {
        this.queryParams.startTime = this.queryParams.time[0];
        this.queryParams.endTime = this.queryParams.time[1];
        // delete this.queryParams.time;
      }
      console.log(this.queryParams);
      if (Object.keys(this.formRules).length !== 0) {
        this.$refs.queryFormRef.validate(async (valid) => {
          if (valid) {
            this.loading = true;
            const res = await this.requestApi(this.queryParams);
            this.loading = false;
            console.log(res, "列表数据");
            if (res.code === 200) {
              if (res.data) {
                this.tableList = res.data.rows || res.data;
                this.total = res.data.total || res.data.length;
              } else {
                this.tableList = res.rows || res.data;
                this.total = res.data.total || res.rows.length;
              }
            }
          }
        });
      } else {
        this.loading = true;
        const res = await this.requestApi(this.queryParams);
        this.loading = false;
        console.log(res, "列表数据2");
        if (res.code === 200) {
          if (res.data) {
            this.tableList = res.data.rows || res.data;
            this.total = res.data.total || res.data.length
          } else {
            this.tableList = res.rows || res.data;
            this.total = res.total || res.rows.length;
          }
        }
      }
    },
    /** 查询按钮 */
    handleQuery() {
      this.getTableList();
    },
    /** 填充按钮 */
    handleFill() {
      /* this.tableList.forEach(obj => {
            Object.assign(obj, this.formLabel)
          }) */
    },
    /** 重置按钮 */
    resetQuery() {
      this.$refs.queryFormRef.resetFields();

      if (this.typeList.length > 0) {
        this.queryParams[this.typeList[0]] = "";
        this.queryParams[this.typeList[1]] = "";
      }
      this.queryParams.pageNum = 1;
      this.queryParams.pageSize = 10;
      this.getTableList();
    },
    /** 级联选择 */
    handleCas(e, val) {
      this.queryParams[val] = e[e.length - 1];
    },
    /** 级联选择只选最后一级 */
    handleCasAdd(e, val, func, prop) {
      if (e.length !== 0) {
        this.queryParams[val] = e[e.length - 1];
        let setObj = {};
        // 合并
        if (prop) {
          Object.assign(setObj, prop);
        }
        // 设置id自增
        this.$set(setObj, "id", this.idCount);
        this.idCount++;
        // 获取单位
        func({
          id: e[e.length - 1],
        })
          .then((res) => {
            this.$set(setObj, "name", res.data.parentName);
            this.$set(setObj, "unitName", res.data.unitName);
            this.$set(setObj, "typeName", res.data.name);
          })
          .catch((err) => {});
        for (let key in this.queryParams) {
          this.$set(setObj, key, this.queryParams[key]);
        }
        this.tableList.unshift(setObj);
        console.log(this.tableList);
      }
    },
    /** 动态设置操作列的列宽 */
    getOperatorWidth() {
      const operatorColumn = document.getElementsByClassName("optionDivRef");

      // 默认宽度
      let width = 100;
      // 内间距
      let paddingSpacing = 0;
      // 按钮数量
      let buttonCount = 0;

      if (operatorColumn.length > 0) {
        Array.prototype.forEach.call(operatorColumn, function (item) {
          // 最宽的宽度
          width = width > item.offsetWidth ? width : item.offsetWidth;
          const buttons = item.getElementsByClassName("el-button");
          buttonCount = buttons.length;
          buttonCount =
            buttonCount > buttons.length ? buttonCount : buttons.length;
        });
        return width;
      }
    },

    queryTableList(params) {
      Object.assign(this.queryParams, params);
      this.getTableList();
    },

    handleSelectionChange(e) {
      console.log(e, "e");
      this.msgList = e;
      this.$emit("transIdList", this.msgList);
    },

    /* 时间change事件 */
    onChangeTime(e, type) {
      // console.log(e, "时间", type);
      const [_1, _2] = type;
      const [_time1, _time2] = e;
      if (e.length > 0) {
        this.queryParams[_time1] = _1;
        this.queryParams[_time2] = _2;
      }
    },
  },
};
</script>

<style scoped lang="scss">
.btn-container {
  margin-bottom: 6px;
  display: flex;
  align-items: center;
}
::v-deep .btn-handler {
  display: flex;
  flex: 1;

  .el-button {
    padding: 6px 18px;
  }
}

::v-deep .optionDivRef {
  white-space: nowrap;
  display: inline-block;

  .el-button {
    padding: 6px 12px;
  }
}
</style>
