<template>
  <section class="ces-table-page">
    <!-- 数据表格 -->
    <section class="ces-table">
      <div class="ces_toolbar">
        <el-button
          v-if="filterList && filterList.length"
          style="float: left;"
          @click="showFliterList = !showFliterList"
        >
          {{ showFliterList ? "收起" : "筛选" }}
          <i
            class="el-icon--right"
            :class="
              showFliterList ? 'el-icon-caret-bottom' : 'el-icon-caret-top'
            "
          ></i>
        </el-button>
        <el-button
          v-if="getSelectBtn"
          icon="el-icon-plus"
          size="small"
          type="primary"
          @click="getSelect()"
          class="ces_toolbar_btn"
        >获取勾选项</el-button>
        <el-button
          v-if="addRowBtn"
          icon="el-icon-plus"
          size="small"
          type="primary"
          @click="addRow()"
          class="ces_toolbar_btn"
        >新增</el-button>
        <el-input
          prefix-icon="el-icon-search"
          v-if="searchShow"
          v-model="search"
          :placeholder="inputPlaceholder"
          style="width:180px;"
          @input="searchVal"
          class="ces_toolbar_inp"
        ></el-input>
      </div>
      <v-apaas-table-filter
        :show="showFliterList"
        :filter-list="filterList"
        @filter-change="filterChange"
      ></v-apaas-table-filter>
      <el-table
        :data="selectedTabsPage"
        :size="size"
        :border="border"
        @select="select"
        @select-all="selectAll"
        :defaultSelections="defaultSelections"
        element-loading-text="加载中..."
        :empty-text="emptyText"
        :stripe="stripe"
        row-key="id"
        :show-header="showHeader"
        default-expand-all
        :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        ref="cesTable"
        :class="radius ? 'table_radius' : ''"
        :header-cell-class-name="headerCellClassName"
        v-cloak
      >
        <el-table-column v-if="isSelection" type="selection" align="center"></el-table-column>
        <!-- 序号 -->
        <el-table-column v-if="isIndex" type="index" :label="indexLabel" width="80" align="center"></el-table-column>

        <!-- 数据栏 -->
        <el-table-column
          v-for="(item, index) in headers"
          :key="index"
          :prop="item.prop"
          :label="item.label"
          :width="item.width"
          :align="item.align"
          :min-width="item.minWidth"
          :render-header="item.require ? renderHeader : null"
        >
          <template slot-scope="scope">
            <!-- 操作按钮 -->
            <span v-if="item.type === 'Button'">
              <b v-for="(btn, key) in item.btnList" :key="key">
                <em v-if="btn.label == '分配'">
                  <em
                    v-if="btn.label == '分配' && scope.row.state == 0"
                    class="cur_pointer"
                    style="color: #0f2683"
                    @click="handleClick(btn.type, scope.row)"
                  >分配</em>
                  <em v-if="btn.label == '分配' && scope.row.state == 1">已分配</em>
                </em>

                <em v-if="btn.type == 'goods-shelf'">
                  <em
                    v-if="scope.row.state == 0"
                    class="cur_pointer"
                    style="color: #0f2683"
                    @click="handleClick(btn.type, scope.row)"
                  >上架</em>
                  <em
                    v-if="scope.row.state == 1"
                    class="cur_pointer"
                    style="color: #0f2683"
                    @click="handleClick(btn.type, scope.row)"
                  >下架</em>
                  <em v-if="scope.row.state == 2">下架</em>
                </em>

                <em
                  class="cur_pointer"
                  v-else-if="btn.label == '删除' && btn.local"
                  :class="btn.type"
                  :style="{
                    color: btn.label == '删除' ? '#830f53' : '#0f2683',
                  }"
                  @click="deleteLocal(scope)"
                >{{ btn.label }}</em>

                <em
                  class="cur_pointer"
                  v-else
                  :class="btn.type"
                  :style="{
                    color: btn.label == '删除' ? '#830f53' : '#0f2683',
                  }"
                  @click="handleClick(btn.type, scope.row)"
                >{{ btn.label }}</em>

                <em v-if="btn.line" style="padding:0 20px;color:#edf0ff">{{ btn.line }}</em>
              </b>
            </span>
            <!--href 链接-->
            <v-apaas-table-umhref
              v-else-if="item.type == 'href'"
              :header="item"
              :row="scope.row"
              :detailsUrl="detailsUrl"
            ></v-apaas-table-umhref>
            <!-- could edit -->
            <v-apaas-table-input
              v-else-if="item.type === 'input' || item.type === 'upload'"
              :item="helper.GetProperty(scope.row, item.prop)"
              :header="item.prop"
              :id="scope.row.id"
              :name="scope.row.name"
              :rowId="scope.$index"
              :type="scope.row[item.uploadKey] ? scope.row[item.uploadKey] : ''"
              :typeHead="item.type"
              :couldNotEdit="couldNotEdit"
              @changeInputValue="changeInputValue"
              @changeUpFile="changeUpFile"
            ></v-apaas-table-input>
            <!-- could select -->
            <v-apaas-table-select
              v-else-if="item.type === 'select'"
              :item="helper.GetProperty(scope.row, item.prop)"
              :header="item.prop"
              :id="scope.row.id"
              :name="scope.row.name"
              :selectArr="item.selectArr"
              :rowId="scope.$index"
              :couldNotEdit="couldNotEdit"
              @changeInputValue="changeInputValue"
            ></v-apaas-table-select>
            <!-- popover -->
            <el-popover
              v-else-if="item.type === 'popover'"
              placement="top-start"
              trigger="hover"
              :content="scope.row[item.prop]"
            >
              <div slot="reference" class="overlit">{{ scope.row[item.prop] }}</div>
            </el-popover>
            <!-- 排名图标替换 -->
            <span v-else-if="item.type === 'rank'">
              <img src="../assets/imgs/list_ic_topone.png" alt v-if="scope.row[item.prop]==1" />
              <img src="../assets/imgs/list_ic_toptwo.png" alt v-if="scope.row[item.prop]==2" />
              <img src="../assets/imgs/list_ic_topthree.png" alt v-if="scope.row[item.prop]==3" />
              {{ [1,2,3].indexOf(scope.row[item.prop])!==-1?'':scope.row[item.prop] }}
            </span>
            <!-- 服务添加图标 -->
            <span
              v-else-if="item.type === 'hot'"
              :style="scope.row['hot']?{marginLeft:'-10px'}:{paddingLeft:'2px'}"
            >
              <img src="../assets/imgs/list_ic_hot.png" alt v-if="scope.row['hot']" />
              {{ scope.row[item.prop] }}
            </span>
            <!-- others -->
            <span v-else>{{ scope.row[item.prop] }}</span>
          </template>
        </el-table-column>
      </el-table>
    </section>
    <!-- 分页 -->
    <section class="ces-pagination" v-if="paginationShow">
      <div class="ces_page_total">共 {{ pagination.total }} 个条目</div>
      <div class="ces_page_item">
        <div class="ces_page_num" v-if="pageSizeShow">
          <div>每页行数：</div>
          <div class="ces_page_num_sel">
            <el-select
              v-model="pagination.rowsPerPage"
              placeholder="请选择"
              size="small"
              @change="handleSizeChange"
            >
              <el-option
                v-for="item in pageOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </div>
        </div>
        <div class="ces_page_control">
          <el-button
            icon="el-icon-arrow-left"
            circle
            size="mini"
            @click="handleCurrentChange(-1)"
            :disabled="pagination.page == 1"
          ></el-button>
          &nbsp;&nbsp;第{{ pagination.page }}页 / 共{{
          Math.ceil(pagination.total / pagination.rowsPerPage)
          }}页
          <el-button
            icon="el-icon-arrow-right"
            circle
            size="mini"
            @click="handleCurrentChange(1)"
            :disabled="
              pagination.page >=
                Math.ceil(pagination.total / pagination.rowsPerPage)
            "
          ></el-button>
        </div>
      </div>
    </section>
  </section>
</template>

<script>
import services from "@/services";
import TableInput from "@/components/table-input";
import TableSelect from "@/components/table-select";
import helper from "@/services/helper";
import DConfirm from "@/components/dialog-remove";
import TableUmhref from "@/components/table-umhref";
import TableFilter from "@/components/table-filter";
export default {
  components: {
    "v-apaas-table-input": TableInput,
    "v-apaas-table-select": TableSelect,
    "v-apaas-table-umhref": TableUmhref,
    "d-confirm": DConfirm,
    "v-apaas-table-filter": TableFilter
  },
  props: {
    // 表格型号：mini,medium,small
    size: { type: String, default: "medium" },
    loading: { type: Boolean, default: false },
    // 表格数据
    headers: { type: Array, default: () => [] },
    // 是否显示表格复选框
    isSelection: { type: Boolean, default: false },
    defaultSelections: { type: [Array, Object], default: () => null },
    // 是否显示表格索引
    isIndex: { type: Boolean, default: false },
    indexLabel: { type: String, default: "序号" },
    searchShow: {
      type: Boolean,
      default: false
    },
    inputPlaceholder: {
      type: String,
      default: "请输入账号、中文名"
    },
    url: {
      type: String,
      default: ""
    },
    detailsUrl: {
      type: String,
      default: ""
    },
    rowprop: {
      type: String,
      default: ""
    },
    ready: {
      type: Boolean,
      default: false
    },
    addRowBtn: {
      type: Boolean,
      default: false
    },
    couldNotEdit: {
      type: Boolean,
      default: false
    },
    refreshInit: { type: Boolean },
    sortBy: {
      type: String,
      default: ""
    },
    searchNoName: { type: Boolean, default: false },
    emptyText: {
      type: String,
      default: "暂无数据"
    },
    autoAdd: {
      type: Boolean,
      default: false
    },
    border: {
      type: Boolean,
      default: false
    },
    stripe: {
      type: Boolean,
      default: false
    },
    radius: {
      type: Boolean,
      default: false
    },
    pageSizeShow: {
      type: Boolean,
      default: false
    },
    paginationShow: {
      type: Boolean,
      default: false
    },
    headerCellClassName: {
      type: String,
      default: ""
    },
    filterList: {
      type: Array,
      default: null
    },
    showHeader: {
      type: Boolean,
      default: true
    },
    datas: {
      type: Array,
      default: null
    },
    getSelectBtn: {
      type: Boolean,
      default: false
    },
    params: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      pagination: {
        rowsPerPage: 10,
        page: 1,
        total: 0
      },
      delSelect: null,
      helper: helper,
      label: null,
      selectedTabsPage: [],
      metaData: [],
      pageOptions: [
        {
          value: "10",
          label: "10"
        },
        {
          value: "20",
          label: "20"
        },
        {
          value: "50",
          label: "50"
        }
      ],
      search: "",
      times: null,
      showFliterList: false
    };
  },
  mounted() {
    this.getDataFromApiSync();
  },
  watch: {
    refreshInit: {
      handler(val) {
        if (val) {
          this.getDataFromApiSync();
        }
      }
    },
    url: {
      handler(val) {
        this.getDataFromApiSync();
      },
      deep: true
    },
    datas: {
      handler(val) {
        this.getDataFromApiSync();
      },
      deep: true
    },
    params: {
      handler(val) {
        this.getDataFromApiSync();
      },
      deep: true
    }
  },
  methods: {
    //本地删除
    deleteLocal(val) {
      this.selectedTabsPage.splice(val.$index, 1);
    },
    // get data
    getDataFromApiSync() {
      console.log("get data >>>");
      this.getDataFromApi().then(
        data => {
          this.selectedTabsPage = JSON.parse(JSON.stringify(data.newArr));
          this.pagination.total = data.total;
          if (this.autoAdd) {
            this.addRow();
          }
          if (this.selectedTabsPage[0] && this.selectedTabsPage[0].id) {
          } else {
            let arrs = this.selectedTabsPage;
            this.addId(arrs, "00000000");
            this.selectedTabsPage = arrs;
          }
          this.metaData = [...this.selectedTabsPage];
        },
        err => {
          console.log("失败" + err);
        }
      );
    },
    addId(arr, id) {
      let self = this;
      for (let i = 0; i < arr.length; i++) {
        arr[i].id =
          parseInt(Math.random() * 100000, 10) +
          "" +
          parseInt(Math.random() * 100000, 10);
        arr[i].parentId = id;
        if (arr[i].children && arr[i].children.length != 0) {
          self.addId(arr[i].children, arr[i].id);
        }
      }
    },
    // get data from api
    getDataFromApi() {
      return new Promise((resolve, reject) => {
        const { page, rowsPerPage } = this.pagination;
        if (this.url == "") {
          let newArr = [];
          if (this.datas) {
            newArr = this.datas;
          }
          let total = newArr.length;
          resolve({ newArr, total });
        } else {
          let query = this.params;
          query.Page = this.pagination.page;
          query.Size = this.pagination.rowsPerPage;
          let arr = this.url.split(".");
          let obj = this.$api;
          arr.forEach(item => {
            obj = obj[item];
          });
          console.log(query);
          obj(query)
            .then(response => {
              let newArr = response.data.data;
              // if it is true url, total is response's total
              let total = response.data.total;
              resolve({ newArr, total });
            })
            .catch(function(response) {
              // this.loading = false;
              reject(response);
            });
        }
      });
    },
    getSelect() {
      console.log(JSON.stringify(this.metaData));
    },
    // search debonce 500ms
    searchVal() {
      if (this.times !== null) clearTimeout(this.times);
      this.times = setTimeout(() => {
        this.resetPageNumber();
        this.getDataFromApiSync();
      }, 500);
    },
    // 表格勾选
    select(rows, row) {
      if (rows.indexOf(row) != -1) {
        let arrs = this.metaData;
        this.setMeta(arrs, row, 1);
        if (row.parentId && row.parentId != "00000000") {
          this.getParent(arrs, row.parentId);
        }
      } else {
        let arrs = this.metaData;
        this.setMeta(arrs, row, 0);
      }
      this.$emit("select", rows, row);
    },
    // 全选
    selectAll(rows) {
      let arrs = this.metaData;
      if (rows.length == arrs.length) {
        this.setAllMeta(arrs, 1);
      } else {
        this.setAllMeta(arrs, 0);
      }
      this.$emit("select", rows);
    },
    // 设置元素select
    setMeta(arr, row, state) {
      let self = this;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].id == row.id) {
          if (arr[i].selected) {
            arr[i].selected = state;
          } else {
            arr[i].selected = 1;
          }
          if (arr[i].children && arr[i].children.length != 0) {
            self.setChildren(arr[i].children, state);
          }
          return false;
        } else if (arr[i].children && arr[i].children.length != 0) {
          self.setMeta(arr[i].children, row, state);
        }
      }
    },
    // 设置每一个子元素的状态
    setChildren(arr, state) {
      let self = this;
      for (let i = 0; i < arr.length; i++) {
        arr[i].selected = state;
        self.$refs.cesTable.toggleRowSelection(arr[i], state);
        if (arr[i].children && arr[i].children.length != 0) {
          self.setChildren(arr[i].children, state);
        }
      }
    },
    // 设置所有元素的状态
    setAllMeta(arr, state) {
      let self = this;
      for (let i = 0; i < arr.length; i++) {
        self.$refs.cesTable.toggleRowSelection(arr[i], state);
        arr[i].selected = state;
        if (arr[i].children && arr[i].children.length != 0) {
          self.setAllMeta(arr[i].children, state);
        }
      }
    },
    // 获取父元素
    getParent(arr, id) {
      let self = this;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].id == id) {
          arr[i].selected = 1;
          self.$refs.cesTable.toggleRowSelection(arr[i], 1);
          if (arr[i].parentId && arr[i].parentId != "00000000") {
            self.getParent(arr, arr[i].parentId);
          }
        }
        if (arr[i].children && arr[i].children.length != 0) {
          self.getParent(arr[i].children, id);
        }
      }
    },
    handleCurrentChange(val) {
      this.pagination.page += val;
      this.getDataFromApiSync();
      this.$emit("refresh");
    },
    handleSizeChange(val) {
      this.pagination.rowsPerPage = val;
      this.getDataFromApiSync();
      this.$emit("refresh");
    },
    renderHeader(h, obj) {
      return h("span", { class: "ces-table-require" }, obj.column.label);
    },
    refreshuseList() {
      this.$message({
        showClose: true,
        message: this.label + "成功",
        type: "success"
      });
    },
    switchChange(val) {
      this.$emit("handleSwitch", val);
    },
    reftableList() {},
    // another button in options
    handleClick(type, val) {
      this.$emit(type, val);
    },
    // 表格编辑修改数据
    changeInputValue(val) {
      // You can delete the row when the row of data is empty, but I didn't do that
      // console.log(this.$refs.cesTable)
      let arr = this.selectedTabsPage;
      this.changeInput(arr, val.id, val.inputValue, val.header);
      this.selectedTabsPage = arr;
      this.$emit("changeTable", this.selectedTabsPage);
      if (
        this.autoAdd &&
        val.inputValue != "" &&
        val.rowId + 1 == this.selectedTabsPage.length
      ) {
        this.addRow();
      }
    },
    // 根据id修改该行数据
    changeInput(arr, id, input, header) {
      let self = this;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].id == id) {
          arr[i][header] = input;
          return false;
        }
        if (arr[i].children && arr[i].children.length != 0) {
          self.changeInput(arr[i].children, id, input, header);
        }
      }
    },
    // 新增表格行
    addRow() {
      // at first, you should promise all colum in your table could be edit
      // this code is low level, you could make it stronger
      // use tableData[0] as template to edit
      let newRow = {};
      let arr = this.headers;
      arr.forEach(item => {
        newRow[item.prop] = "";
      });
      newRow.flag = true; //新增标记
      newRow.id =
        parseInt(Math.random() * 100000, 10) +
        "" +
        parseInt(Math.random() * 100000, 10);
      this.selectedTabsPage.push(newRow);
    },
    // get now table data
    getTableData() {
      return this.selectedTabsPage;
    },
    filterChange(filter) {
      this.resetPageNumber();
      console.log(filter);
    },
    // 上传文件事件
    changeUpFile(val) {
      let arr = this.selectedTabsPage;
      this.changeUp(arr, val.id, val.inputValue, val.fileUrl, val.header);
      this.selectedTabsPage = arr;
      this.$emit("changeTable", this.selectedTabsPage);
      console.log(arr, this.selectedTabsPage);
      if (
        this.autoAdd &&
        val.inputValue != "" &&
        val.rowId + 1 == this.selectedTabsPage.length
      ) {
        this.addRow();
      }
    },
    // 根据id修改该行上传文件数据
    changeUp(arr, id, input, url, header) {
      let self = this;
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].id == id) {
          arr[i][header] = input;
          arr[i].file_url = url;
          return false;
        }
        if (arr[i].children && arr[i].children.length != 0) {
          self.changeUp(arr[i].children, id, input, header);
        }
      }
    },
    // 重置页码
    resetPageNumber() {
      this.pagination.page = 1;
    }
  }
};
</script>

<style>
.ces-table .el-table::before {
  height: 0 !important;
}
.ces-table .el-table th.gutter {
  display: table-cell !important;
}
.ces-table .el-table colgroup.gutter {
  display: table-cell !important;
}
.ces-table .el-table td,
.ces-table .el-table th.is-leaf {
  border-bottom: none !important;
}
.ces-table .el-table--border td,
.ces-table .el-table th.is-leaf {
  border-bottom: 1px solid #ebeef5 !important;
}
.ces-table .el-table--border {
  border: 1px solid #ebeef5;
}
/* .ces-table .el-table--enable-row-hover, */
.ces-table .el-table tbody tr:hover > td {
  background-color: #e4ecf8 !important;
  /* border-top: 1px solid #b9cefa !important;
  border-bottom: 1px solid #b9cefa !important; */
}
.ces-table .theme--light.el-table tbody tr:not(:last-child) {
  border-bottom: none;
}
.ces-table .el-table th > .cell {
  color: #1a2236;
}
.ces-table .el-table th > .cell,
.ces-table .el-table td > .cell {
  /* text-align: center; */
  font-size: 14px;
}
.ces-table .el-table tr {
  color: #58617a;
}
.ces-table .el-table__empty-text {
  color: #58617a;
  font-size: 14px;
}
em {
  font-style: normal;
  user-select: none;
}
.cur_pointer {
  cursor: pointer;
}
.ces-table .el-table--mini td,
.ces-table .el-table--mini th {
  padding: 11px 0 !important;
}
.ces-table .el-table--border::after,
.ces-table .el-table--group::after,
.ces-table .el-table::before {
  background: #fff;
}
.ces-table .switchStyle .el-switch__label {
  position: absolute;
  display: none;
  color: #fff;
}
.ces-table .switchStyle .el-switch__label--left {
  z-index: 9;
  left: 6px;
  top: -1px;
}
.ces-table .switchStyle .el-switch__label--right {
  z-index: 9;
  left: -14px;
  top: -1px;
}
.ces-table .switchStyle .el-switch__label.is-active {
  display: block;
}
.ces-table .switchStyle.el-switch .el-switch__core,
.ces-table .el-switch .el-switch__label {
  width: 50px !important;
}
.ces-table .el-switch__core {
  background: #f8f9fd !important;
  border: 1px solid #8890a7 !important;
}
.ces-table .el-switch__core:after {
  background: #8890a7 !important;
}
.ces-table .el-switch.is-checked .el-switch__core {
  background: #f8f9fd !important;
  border: 1px solid #5c82ff !important;
}
.ces-table .el-switch.is-checked .el-switch__core:after {
  background: #5c82ff !important;
}
.ces-table .el-switch__label * {
  font-size: 10px !important;
  font-weight: 800;
}
.ces-table .el-switch .el-switch__label {
  color: #8890a7 !important;
}
.ces-table .el-switch.is-checked .el-switch__label {
  color: #5c82ff !important;
}
.ces-table .el-switch:hover {
  opacity: 0.8;
}
.chName.is-dark {
  background: #5c82ff !important;
}
.chName[x-placement^="top"] .popper__arrow,
.chName[x-placement^="top"] .popper__arrow::after {
  border-top-color: #5c82ff !important;
}
.el-table__row--striped td {
  background: #f8f9fd !important;
}
/* .el-table th>.cell {
  padding-left: 14px;
} */
.el-table__placeholder {
  display: inline-block;
  width: 40px;
}
.th_pink {
  background-color: #faf2e2 !important;
}
.ces_page_control .el-button {
  border: 0;
}
.ces_page_num .el-input__inner {
  border: 0;
  padding: 0;
}
</style>
<style scoped>
.ces-table {
  position: relative;
}
.ces_toolbar {
  position: absolute;
  top: -50px;
  right: 0;
  left: 0;
  text-align: right;
}
.ces_toolbar .ces_toolbar_btn {
  margin-right: 10px;
}
.ces-pagination {
  margin-top: 20px;
  font-size: 14px;
  padding: 0 5%;
  display: flex;
  justify-content: space-between;
  align-items: center;
}
/* .ces_page_total {
} */
.ces_page_num {
  width: 140px;
  margin-right: 20px;
  display: flex;
  justify-content: space-around;
  align-items: center;
}
.ces_page_num_sel {
  width: 50px;
  font-size: 14px;
  position: relative;
  top: 1px;
}
.table_radius {
  border-radius: 8px;
}
.overlit {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ces_page_item {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
</style>
