<!--
 * @Author       : xh
 * @Date         : 2022-12-05 10:44:04
 * @LastEditors: y001554
 * @FileName     :   主页面列表组件  管理 api 、 列表请求、还有表格吸顶
-->

<template>
  <div class="pageContainer" :style="containerStyle">
    <div id="container__header" class="pageContainer__header">
      <slot name="BasicPageHeader" />
    </div>
    <div id="container__searchBar" class="pageContainer__searchBar" :class="tableMode ? 'hiddenSearch' : ''">
      <slot name="pageTop" />
      <gen-search ref="form" :size="$attrs.size || 'small'" :search-model="filterSearchModel" :search-data="searchData" :more-condition-num="moreConditionNum" @search="handleSearch" @reset="handleReset" @more-show="doTableLayout">
        <template v-for="name in formSlots" v-slot:[name]="{ item }">
          <slot :name="name" v-bind="item" />
        </template>
        <slot name="FrActions" />
      </gen-search>
      <slot name="pageMiddle" />
    </div>
    <div id="container__content" class="pageContainer__content">
      <gen-table ref="table" :sticky="searchH" :loading="loading" :table-model="tableModel" :table-data="tableData" :table-options="tableOptions" :table-options-width="tableOptionsWidth" :table-data-count="tableDataCount" :search-data="searchData" :refresh="refresh" v-bind="tableProps" :has-selec-items="value" @scrolltoggle="toggle" @select="select" v-on="$listeners">
        <template v-for="name in allSlots" v-slot:[name]="{ row }">
          <slot :name="name" v-bind="row" />
        </template>
        <!-- <template
          v-for="name in optionsSlots"
          v-slot:[name]="{ row }"
        >
          <slot
            :name="name"
            v-bind="row"
          />
        </template> -->
        <template #bottomBar>
          <slot name="bottomBar" />
        </template>
        <!-- bottomBar -->
      </gen-table>
    </div>
    <div v-if="$slots['pageFooter']" class="pageContainer__footer flex">
      <div style="flex: 1">
        <slot name="pageFooter" />
      </div>
    </div>
    <div v-if="showTips" class="toggleIcon flex">
      <span>表格撑满</span>
      <div class="actions">
        <el-switch v-model="tableMode" />
      </div>
    </div>
  </div>
</template>

<script>
const DEFAULT_SEARCH_MODEL = {
  currentPage: 1,
  pageSize: 20
}
// import style from '~/style/e-variables.scss'
export default {
  name: 'BasicPage',
  components: {},
  props: {
    tableOptionsWidth: {
      type: [String, Number]
    },
    // hasSelecItems: {
    //   type: Array,
    //   default: () => []
    // },
    //@备注:自动加载一次数据
    //@取值:
    auto: {
      type: Boolean,
      default: true
    },
    // 请求配置
    api: {
      type: Object,
      required: true,
      default: () => ({})
    },

    moreConditionNum: {
      type: Number,
      default: 4
    },
    // 搜索栏模型
    searchModel: {
      type: Array,
      default: () => []
    },

    // 表格数据模型
    tableModel: {
      type: Array,
      default: () => []
    },
    // 表格操作项
    tableOptions: {
      type: Array,
      default: () => []
    },
    tableProps: {
      type: Object,
      default: () => ({
        height: '100%'
      })
    },
    showTips: {
      type: Boolean,
      default: false
    },
    value: {
      type: Array,
      default: () => []
    }
    // searchParams: {
    //   type: Object,
    //   default: () => Object.assign({}, DEFAULT_SEARCH_MODEL)
    // }
  },
  data() {
    return {
      loading: true,
      tableMode: false, //不显示全表格
      searchData: Object.assign({}, DEFAULT_SEARCH_MODEL),
      // tableData: [],
      // tableSlots: [],
      tableDataCount: 0,
      tableData: [],
      // headerH: 0,
      searchH: 0,
      containerStyle: {},
      mode: true
    }
  },
  computed: {
    filterSearchModel() {
      return this.searchModel.filter((item) => {
        if (typeof item.hidden === 'boolean' && item.hidden) {
          return false
        }
        if (typeof item.hidden === 'function') {
          const h = item.hidden()
          if (h) {
            return false
          }
        }

        return true
      })
    },
    formSlots() {
      return this.searchModel.filter((m) => !!m.template).map((s) => s.template)
    },
    filterTableSlots() {
      return this.tableModel.filter((m) => !!m.template)
    },
    filterOptionsSlots() {
      return this.tableOptions.filter((m) => !!m.template)
    },
    tableSlots() {
      return this.filterTableSlots.map((s) => s.template)
    },
    optionsSlots() {
      return this.filterOptionsSlots.map((s) => s.template)
    },
    allSlots() {
      const arr = [...(this.tableSlots || []), ...(this.optionsSlots || [])]
      // console.log('34534', this.filterTableSlots, arr)
      return arr
    }
  },
  watch: {
    value: {
      handler: function (v = []) {
        // debugger
        if (v && v.length != this.value.length) {
          this.setSelection(v)
        }
      }
    },
    searchData: {
      handler(val) {
        this.$emit('update:searchData', val)
      },
      deep: true
    }
    // 'api.list': {
    //   handler(val) {
    //     if (val) {
    //       if (this.auto) {
    //         this.getList()
    //       }
    //     }
    //   },
    //   deep: true
    // }
  },
  mounted() {
    this.init()
    if (this.auto) {
      this.getList()
    } else {
      this.loading = false
    }
  },
  methods: {
    clearSelection() {
      if (this.$refs.table && this.$refs.table.clearSelection) {
        this.$refs.table.clearSelection()
      }
    },
    init() {
      // this.loading = true
      const that = this
      const h = window.innerHeight
      this.getSearchData()
      this.$nextTick(() => {
        // const headerH = document.querySelector('#container__header').offsetHeight
        // this.searchData = JSON.parse(JSON.stringify(this.searchParams))
        const searchH = document.querySelector('#container__searchBar').offsetHeight
        // that.headerH = headerH
        that.searchH = searchH
        // that.loading = false
      })
    },
    // 如果有form-item中有默认值value 按value給值
    getSearchData() {
      const arr = this.searchModel.filter((t) => !!t.value)
      if (!arr) return
      const values = {}
      arr.forEach((item) => {
        values[item.prop] = item.value
        if (item.type.includes('range') && item.rangeKeys && item.rangeKeys.length == 2) {
          values[item.rangeKeys[0]] = item.value ? item.value[0] : ''
          values[item.rangeKeys[1]] = item.value ? item.value[1] : ''
        }
      })
      this.searchData = { ...DEFAULT_SEARCH_MODEL, ...values }
    },
    toggleScroll(e) {
      this.tableMode = e
    },
    toggle(e) {
      // this.tableMode = !this.tableMode
      if (e != !this.tableMode) {
        this.tableMode = !e
      }
      // this.init()
    },

    //构建最后的searchDate参数
    createParams() {
      const extra = []
      const delect = []
      let arr = this.filterSearchModel.map((it) => {
        if (it.rangeKeys && it.rangeKeys.length == 2) {
          extra.push(it.rangeKeys[0])
          extra.push(it.rangeKeys[1])
          delect.push(it.prop)
        }
        return it.prop
      })
      arr = arr.concat(extra)
      const validData = { ...this.searchData }
      Object.keys(validData).forEach((k) => {
        if (!arr.includes(k) && k !== 'currentPage' && k !== 'pageSize') {
          delete validData[k]
        }
      })
      const params = Object.assign({}, validData, this.api.listParams || {})
      Object.keys(params).forEach((k) => {
        if (params[k] === '' || params[k] === null || params[k] === undefined || delect.includes(k)) delete params[k]
      })
      return params
    },
    async getList() {
      try {
        this.loading = true
        if (!this.api.list) return

        const params = this.createParams()

        this.$emit('SearchTop', params)
        const { data } = await this.$request(this.api.list, params)
        this.tableData = (data && data.list) || []
        this.tableDataCount = (data && data.count) || 0
        this.$emit('listAfter', data, params)
      } catch (error) {
        this.tableData = []
        console.log('getList 错误', error)
      } finally {
        this.loading = false
      }
    },
    refresh(reset = false) {
      // alert(reset)
      if (reset) {
        this.searchData.currentPage = 1
      }
      this.getList()
      // if (this.$refs.table) {
      //   this.$refs.table.clearSelection()
      // }
    },

    handleSearch() {
      this.searchData.currentPage = 1
      this.clearSelection()
      this.getList()
    },
    handleReset() {
      this.getSearchData('reset')
      this.$refs.table.clearSort()
      this.clearSelection()
      // 点击顶部筛选栏重置时，发送一个事件出去，如果筛选栏有联动组件，那就用得上，具体的请看genForm.vue
      this.$bus.$emit('searchReset')
      this.getList()
    },
    doTableLayout() {
      this.$refs.table.doLayout()
    },
    //@备注:表格多选 回调
    //@取值:
    select(e) {
      // debugger
      this.$emit('input', e)
    },
    setSelection(e) {
      // alert(0)
      if (this.$refs['table']) {
        this.$refs['table'].setSelection(e)
      }
    }
  }
}
</script>
<style lang="scss" scoped>
@import '~/style/e-variables';

.pageContainer {
  width: 100%;
  height: 100%;
  padding: 0 10px;
  background: #fff;
  overflow: hiddenSearch;
  // background: gree
  position: relative;
  box-shadow: 0 0 8px rgb(212, 212, 212);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  transform: all 0.3s ease;
  box-sizing: border-box;
  .toggleIcon {
    position: absolute;
    left: 10px;
    bottom: 4px;
    z-index: 100;
    padding: 10px;
    font-size: 12px;
    color: #5c5c5c;
    transform: scale(0.9);
    display: flex;

    // align-content: center;
    justify-content: flex-start;
    align-items: center;
    span {
      display: block;
    }
    .actions {
      margin-right: 15px;
      margin-left: 4px;
    }
    // width: 30px;
    // height: 30px;
    // color: #fff;
    // background: #d45214;
    // border-radius: 50%;
    // overflow: hiddenSearch;
    // box-shadow: 0 0 8px solid #eee;
  }
  &__searchBar {
    // transition: all ease 0.5s;
    height: auto;
    // overflow: hidden;
    width: 100%;
  }
  &__pad {
    padding-top: $headerHeight + $breadheight;
  }
  &__content {
    width: 100%;
    height: 100%;
    flex: 1;
    // padding-bottom: 48px;
    overflow: hidden;
    // background: red;
    // transition: height ease 0.5s;
    // background: green;
    // overflow: hiddenSearch;
    // .el-scrollbar {
    //   width: 100%;
    //   height: 100%;
    //   overflow-y: auto;
    // }
  }
  &__header {
    // width: 100%;
    // position: fixed;
    z-index: 10;
    top: $headerHeight + $breadheight;
    left: $sideBarWidth + 10px;
    right: 10px;
    background: #fff;
    box-sizing: border-box;
    width: 100%;
    // box-sizing: border-box;
  }

  &__footer {
    width: 100%;
    // position: fixed;
    // z-index: 10;
    // bottom: 0;
    // left: $sideBarWidth + 10px;
    right: 10px;
    background: #fff;
    box-sizing: border-box;
    align-items: center;
    text-align: right;
    width: 100%;
    overflow: hidden;
    // box-sizing: border-box;
  }
  .hiddenSearch {
    height: 1px;
    opacity: 0;
    // transform: scaleY(0);
  }
}
.fr {
  float: right;
}
.hideSidebar {
  .pageContainer__header,
  .pageContainer__footer {
    left: 54px;
  }
}
</style>
