<!--
 * @Author: zhaojinfeng 121016171@qq.com
 * @Date: 2023-07-18 12:30:07
 * @LastEditors: zhaojinfeng 121016171@qq.com
 * @LastEditTime: 2023-07-21 21:39:13
 * @FilePath: \vue3\packages\select-table-modal\index.vue
 * @Description: 模态框选择表格
 *
-->
<template>
  <span @click="showDialog = true">
    <slot>
      <el-button @click="showDialog = true">点击选择</el-button>
    </slot>
  </span>
  <el-config-provider :locale="locale">
    <el-dialog v-model="showDialog" :title="title" :width="width" append-to-body @open="getList" @closed="closed">
      <el-form ref="queryRef" :modal="queryParams" inline>
        <el-form-item v-for="formItem in formItems" :key="formItem.prop" :label="formItem.label" :prop="formItem.prop">
          <el-select v-if="formItem.selectOptions" :placeholder="formItem.placeholder">
            <el-option v-for="option in formItem.selectOptions" :key="option.value" :value="option.value">
              {{ option.label }}
            </el-option>
          </el-select>
          <el-input v-else v-model="queryParams[formItem.prop]" :placeholder="formItem.placeholder" />
        </el-form-item>
        <el-form-item>
          <el-button type="primary" :loading="loading" @click="getList">
            查询
          </el-button>
          <el-button :loading="loading" @click="resetQuery">
            重置
          </el-button>
        </el-form-item>
      </el-form>
      <el-table
        v-loading="loading"
        border
        :data="tableData"
        highlight-current-row
        :row-key="rowKey"
        :empty-text="emptyText"
        @current-change="handleCurrentChange"
      >
        <el-table-column v-for="column in columns" :key="column.prop" :align="column.align || 'center'" :label="column.label" :prop="column.prop" :formatter="column.formatter" />
      </el-table>
      <div w-full h-70px relative>
        <el-pagination
          v-model:current-page="queryParams.pageNum"
          v-model:page-size="queryParams.pageSize"
          absolute
          right-50px
          top-20px
          background
          hide-on-single-page
          :layout="layout"
          :page-sizes="pageSizes"
          :pager-count="pagerCount"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="getList"
        />
      </div>
      <template #footer>
        <el-space>
          <el-button type="primary" @click="confirm">
            确定
          </el-button>
          <el-button @click="showDialog = false">
            取消
          </el-button>
        </el-space>
      </template>
    </el-dialog>
  </el-config-provider>
</template>

<script lang="ts" setup name="ThSelectTableModal">
import type { FormInstance, TableColumnCtx, TableInstance } from 'element-plus'
import locale from 'element-plus/lib/locale/lang/zh-cn'

const props = withDefaults(
  defineProps<{
    emptyText?: string
    value?: any
    rowKey?: string
    show: boolean
    columns: Partial<TableColumnCtx<any>>[]
    formItems: FormItem[]
    defaultParams?: Record<string, any>
    request: (args: any) => Promise<Page>
    layout?: string
    pageSizes?: number[]
    pagerCount?: number
    hideButton?: boolean
    hidePagination?: boolean
    title?: string
    width?: string | number
  }>(),
  {
    hidePagination: false,
    layout: 'total, sizes, prev, pager, next, jumper',
    rowKey: 'id',
    pageSizes: () => [10, 20, 30, 50],
    pagerCount: () => document.body.clientWidth < 992 ? 5 : 7,
    hideButton: false,
    width: '1000px',
    title: '选择',
    emptyText: '暂无数据',
  },
)
const emit = defineEmits<{
  (event: 'update:show', show: boolean): void
  (event: 'update:value', show: any): void
  (event: 'confirm', row: any): void
}>()
interface FormItem {
  label: string
  prop: string
  placeholder?: string
  selectOptions?: {
    label: string
    value: string
  }[]
}
const showDialog = useVModel(props, 'show')

let tableData = $ref<any[]>([])
let selection = $ref<any>()
function confirm() {
  emit('confirm', selection)
  showDialog.value = false
}
let total = $ref(0)

function handleCurrentChange(val?: any) {
  selection = val
}

/* 表单绑定的ref */
const queryRef = $ref<FormInstance>(null)
const tableRef = $ref<TableInstance>(null)

/* 初始加载 */
let loading = $ref(false)

/* 查询参数 */
const queryParams = reactive({
  pageNum: 1,
  pageSize: 10,
})

/** 查询表格数据 */
async function getList() {
  loading = true
  tableData = []
  try {
    const response = await props.request({
      ...props.defaultParams,
      ...queryParams,
    })
    tableData = response.rows
    const row = tableData.find(row => row[props.rowKey] === props.value)
    total = response.total
    if (row)
      tableRef?.setCurrentRow(row)
  }
  finally {
    loading = false
  }
}
/** 重置按钮操作 */
function resetQuery() {
  queryRef?.resetFields()
  queryParams.pageNum = 1
  getList()
}
function handleSizeChange(val: number) {
  if (queryParams.pageNum * val > total)
    queryParams.pageNum = 1
}

function closed() {
  queryRef?.resetFields()
  tableData = []
  queryParams.pageNum = 1
  selection = undefined
}
</script>
