<!--
 * @name    查询页面组件
 * @authors pen (you@example.org)
 * @date    2022-03-02
 * @version 1.0.1
 *
 -->
 <template>
  <div>
    <!-- 头部组件 -->
    <header-view
      v-if="showPageHead"
      ref="headerView"
      v-bind="$attrs"
      v-on="$listeners"
      :toolsColumns="
        columns.length || Object.keys(columns).length ? columns : toolsColumns
      "
      :exportUrl="exportUrl"
      :buttons="buttons"
      @tools-check-event="toolsCheckEvent"
      @tools-click="toolsClick"
      @button-click="buttonClick"
    >
      <template #titleSlot>
        <slot name="titleSlot"></slot>
      </template>
      <template #titleRightSlot>
        <slot name="titleRightSlot"></slot>
      </template>
      <template #buttonSlot>
        <slot name="buttonSlot"></slot>
      </template>
      <template
        v-for="item in buttons.length ? buttons.filter(p => p.customSlot) : []"
        v-slot:[item.customSlot]="slotProps"
      >
        <slot
          :name="item.customSlot"
          v-bind:customSlotData="slotProps.customSlotData"
        ></slot>
      </template>
    </header-view>
    <slot name="pageHeadSlot"></slot>
    <!-- 查询组件 -->
    <div
      class="form_box"
      :style="{ 'margin-bottom': showPageHead ? '10px' : '0px' }"
      v-if="queryFormItems.length"
    >
      <div class="page_view_query_box">
        <query-form-view
          :style="pageQueryStyle"
          class="query_form_box"
          ref="queryFormView"
          v-bind="$attrs"
          v-on="$listeners"
          :queryFormItems="queryFormItems"
          @check="checkEvent"
          @collapse-search="collapseSearch"
          @query-update-form="queryUpdateForm"
          @keyup-enter="keyupEnter"
        >
          <template #button>
            <slot name="button"></slot>
          </template>
          <template
            v-for="item in queryFormItems.length
              ? queryFormItems.filter(p => p.customSlot)
              : []"
            v-slot:[item.customSlot]="slotProps"
          >
            <slot
              :name="item.customSlot"
              v-bind:customSlotData="slotProps.customSlotData"
            ></slot>
          </template>
        </query-form-view>
        <slot name="queryFormSlot"></slot>
      </div>
    </div>
    <slot name="pageMiddleSlot"></slot>
    <!-- 分页表格组件 -->
    <page-table-view
      ref="pageTableView"
      v-bind="$attrs"
      v-on="$listeners"
      :isPageView="true"
      :data="list"
      :height="tableHeigth"
      :columns="columns"
      @row-dblclick="rowDblclick"
      @tool-bar-click="toolbarClick"
      :totalCount="totalCount"
      :page-size="query.size"
      :currentPage="query.start"
      @page-size-change="pageSizeChange"
      @page-current-change="pageCurrentChange"
    >
      <template #columns>
        <slot name="columns"></slot>
      </template>
      <template v-for="item in columns" v-slot:[item.customSlot]="slotProps">
        <slot
          :name="item.customSlot"
          v-bind:customSlotData="slotProps.customSlotData"
        ></slot>
      </template>
      <template v-slot:expandSlot="slotProps">
        <slot
          name="expandSlot"
          v-bind:customSlotData="slotProps.customSlotData"
        ></slot>
      </template>
      <template #pageSlot>
        <slot name="pageSlot"></slot>
      </template>
      <template #paginationSlot>
        <slot name="paginationSlot"></slot>
      </template>
      <template #pageTableBottomSlot>
        <slot name="pageTableBottomSlot"></slot>
      </template>
    </page-table-view>
    <!-- 导入组件 -->
    <import-file-view
      v-if="!!importFileUrl || showImportFile"
      :importFileUrl="importFileUrl"
      ref="importFileDialog"
      v-bind="$attrs"
      v-on="$listeners"
    >
      <template #importHeadSlot>
        <slot name="importHeadSlot"></slot>
      </template>
    </import-file-view>
  </div>
</template>

<script>
import headerView from './header.vue'
import tableView from './table.vue'
import paginationView from './baseView/pagination.vue'
import queryFormView from './queryForm.vue'
import importFileView from './importFile.vue'
import pageTableView from './pageTable.vue'
import tools from '../utils/tools.js'
export default {
  name: 'page-view',
  props: {
    showPageHead: {
      type: Boolean,
      default: true
    },
    // showPagination: {
    //   type: Boolean,
    //   default: true
    // }, //显示分页
    buttons: {
      type: Array,
      default: () => []
    }, //按钮组
    pageQueryStyle: {
      type: String
    },
    queryFormItems: {
      type: Array,
      default: () => []
    },
    //查询接口url
    requestUrl: {
      type: String
      // required: true
    },
    apiName: {
      type: String
    },
    toolsColumns: {
      type: [Object, Array],
      // default: () => {
      //   return {} || []
      // }
    },
    tableHeigth: {
      type: [String, Number],
      default: 'calc(100vh - 253px)'
    },
    //表格列
    columns: {
      type: [Object, Array],
      default: () => {
        return {} || []
      }
    },
    pageSize: {
      type: Number,
      default: 20
    },
    //当前页
    currentPage: {
      type: Number,
      default: 1
    },
    //拓展的查询接口参数
    extendQuery: {
      type: Object,
      default: () => ({})
    },
    exportUrl: {
      type: String
    },
    importFileUrl: {
      type: String
    },
    showImportFile: {
      type: Boolean
    },
    isGetListData: {
      type: Boolean,
      default: true
    },
    // 是否执行默认的双击事件
    isDefaultRowDblclick: {
      type: Boolean,
      default: true
    },
    // 删除接口的参数
    deleteParams: {
      type: Object,
      default: () => ({})
    },
    // 编辑权限
    editPermission: String,
    // 导入方法是否使用get请求
    isGetExportUrl: Boolean
  },
  data() {
    return {
      loading: false,
      list: [],
      totalCount: 0,
      query: {
        size: 20,
        start: 1
      }
    }
  },
  components: {
    paginationView,
    headerView,
    tableView,
    queryFormView,
    importFileView,
    pageTableView
  },
  created() {
    this.query.size = this.pageSize
    this.query.start = this.currentPage
  },
  // activated() {
  //   //缓存期间调接口数据，可能编辑页修改了
  //   this.getList()
  // },
  mounted() {
    if (this.isGetListData) this.getList()
    window.addEventListener('resize', tools.debounce(this.resizeTable, 300))
    this.$nextTick(() => {
      this.resizeTable()
    })
  },
  beforeDestroy() {
    window.removeEventListener('resize', tools.debounce(this.resizeTable, 300))
  },
  computed: {
    permissionsData() {
      return this.$store.state.permissions
    }
  },
  methods: {
    // 清除表格选中数据
    clearSelection() {
      this.$refs.pageTableView.$refs.tableView.$refs.table.clearSelection() //清除之前的选中状态
    },
    toolsCheckEvent(val) {
      this.resizeTable()
    },
    // 对 Table 进行重新布局 以防止表格错位
    resizeTable() {
      this.$nextTick(() => {
        if (
          this.$refs.pageTableView &&
          this.$refs.pageTableView.$refs.tableView &&
          this.$refs.pageTableView.$refs.tableView.$refs.table
        ) {
          console.log('进行重新布局')
          this.$refs.pageTableView.$refs.tableView.$refs.table.doLayout()
        }
      })
    },
    collapseSearch() {
      this.checkEvent()
    },
    checkEvent() {
      this.query.start = 1
      this.getList()
    },
    // 查询条件更新数据方法
    queryUpdateForm(arg, val, item) {
      this.query = Object.assign(this.query, arg, this.extendQuery)
      this.$emit('query-update-form', arg, val, item)
      console.log(
        'queryUpdateForm',
        this.query,
        'this.extendQuery:',
        this.extendQuery
      )
    },
    keyupEnter() {
      this.$nextTick(() => {
        console.log(this.query)
        this.getList()
      })
    },
    // 工具栏点击事件
    toolsClick(item) {
      switch (item.id) {
        case 'refresh':
          this.reset()
          break
        case 'export':
          this.exportUrl && this.exportData()
          break
        default:
          break
      }
    },
    // 表格操作栏按钮组事件
    toolbarClick(row, item, index) {
      switch (item.id) {
        case 'delete':
          this.remove(row.id)
          break
        default:
          this.$emit('toolbar-click', row, item, index)
          break
      }
    },
    // 导出
    exportData() {
      if (this.isGetExportUrl) {
        this.$api.fileDownload(this.exportUrl)
        return
      }
      let colData = this.toolsColumns || this.columns
      let col = Array.isArray(colData)
        ? colData.filter(
            p => (p.visible || p.visible === undefined) && !p.type
          )
        : Object.keys(colData).filter(
            p => colData[p].visible && !colData[p].type
          )
      console.log('col', col)
      let parmas = Object.assign({}, this.query, { exportFiledNames: col })
      this.$api.filePostDownload(this.exportUrl, parmas)
    },
    // 分页
    pageSizeChange(arg) {
      this.query.start = 1
      this.query.size = arg
      this.getList()
    },
    // 分页
    pageCurrentChange(arg) {
      this.query.start = arg
      this.getList()
    },
    // 重置
    reset() {
      this.getList(() => {
        this.$api.success('操作成功')
      })
    },
    //初始化列表
    getList(callback) {
      if (this.requestUrl || this.apiName) {
        if (Object.keys(this.extendQuery).length)
          this.query = Object.assign({}, this.query, this.extendQuery)
        console.log(
          '请求api',
          this.requestUrl,
          this.apiName,
          '请求参数',
          this.query,
          '拓展参数',
          this.extendQuery
        )
        // this.loading = true
        this.list = []
        this.$api
          .post(
            this.requestUrl ? this.requestUrl : `${this.apiName}/page`,
            this.query
          )
          .then(res => {
            if (res) {
              this.list = res.list
              this.totalCount = Number(res.totalCount)
              // window.setPageMarker("")
              typeof callback === 'function' && callback()
            }
            this.$emit('get-list-callback', res)
            // this.loading = false
          })
      }
    },
    // 删除
    remove(id) {
      this.$confirm('确定要删除该数据吗?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          let params = Object.keys(this.deleteParams).length
            ? this.deleteParams
            : { id: id }
          this.$api.post(`${this.apiName}/delete`, params).then(res => {
            if (res) {
              this.$api.success()
              this.getList()
            }
            this.$emit('remove-callback', res)
          })
        })
        .catch(err => {})
    },
    // 判断是否有编辑权限
    judgePrem() {
      if (this.editPermission) {
        return this.permissionsData[this.editPermission]
      } else {
        return true
      }
    },
    // 表格行双击事件
    rowDblclick(row, column, event) {
      if (this.judgePrem() && this.isDefaultRowDblclick && this.$parent) {
        let params = { type: 'edit', row: row }
        this.autoOpenDialog(params)
      }
      this.$emit('row-dbl-click', row, column, event)
    },
    // 按钮组事件
    buttonClick(arg) {
      switch (arg.id) {
        // 新增
        case 'add':
          if (this.$parent) {
            // 自动打开新增弹窗 兼容弹窗组件在同一页面或是在同级的另一页面
            let params = { type: 'add' }
            this.autoOpenDialog(params)
          }
          break
        default:
          break
      }
    },
    autoOpenDialog(params) {
      // 自动打开新增弹窗 兼容弹窗组件在同一页面或是在同级的另一页面
      let simple = this.$parent.$refs.simpleDialogView
      if (simple) {
        simple.open && simple.open(params)
        simple.$refs.simpleDialogView &&
          simple.$refs.simpleDialogView.open &&
          simple.$refs.simpleDialogView.open(params)
      }
      let master = this.$parent.$refs.masterDialogView
      if (master) {
        master.open && master.open(params)
        master.$refs.masterDialogView &&
          master.$refs.masterDialogView.open &&
          master.$refs.masterDialogView.open(params)
      }
    },
    // 打开导入弹窗
    openImportDialog() {
      this.$refs.importFileDialog.open()
    }
  }
}
</script>
<style lang="less" scoped>
.form_box {
  padding: 0px 20px !important;
  border-radius: 8px;
  overflow: hidden;
  background: #fff;
}
.page_view_query_box {
  width: 100%;
  display: flex;
  align-items: center;
  .query_form_box {
    flex: 1;
  }
}
.page_view_table {
  background: #fff;
  border-radius: 8px;
}
</style>
