doum
2025-09-26 9057e04efad1b7d61c77a72e5c37a504d0aee935
admin/src/components/base/BaseTable.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,266 @@
<script>
import BasePage from './BasePage'
import { isFunction } from 'element-ui'
export default {
  name: 'BaseTable',
  extends: BasePage,
  data () {
    return {
      // æŽ¥å£
      api: null,
      // æ¨¡å—名称
      module: '数据',
      // é…ç½®æ•°æ®
      configData: {
        // id字段
        'field.id': 'id',
        // ä¸»å­—段
        'field.main': 'name'
      },
      // æ˜¯å¦æ­£åœ¨æ‰§è¡Œ
      isWorking: {
        // æœç´¢ä¸­
        search: false,
        // åˆ é™¤ä¸­
        delete: false,
        // å¯¼å‡ºä¸­
        export: false
      },
      // è¡¨æ ¼æ•°æ®
      tableData: {
        // å·²é€‰ä¸­çš„æ•°æ®
        selectedRows: [],
        // æŽ’序的字段
        sorts: [],
        // å½“前页数据
        list: [],
        // åˆ†é¡µ
        pagination: {
          pageIndex: 1,
          pageSize: 10,
          total: 0
        }
      }
    }
  },
  methods: {
    /**
     * é…ç½®
     *
     * @param extParams é…ç½®å‚æ•°
     */
    config (extParams) {
      if (extParams == null) {
        throw new Error('Parameter can not be null of method \'config\' .')
      }
      if (extParams.api == null) {
        throw new Error('Missing config option \'api\'.')
      }
      this.api = require('@/api' + extParams.api)
      extParams.module && (this.module = extParams.module)
      extParams['field.id'] && (this.configData['field.id'] = extParams['field.id'])
      extParams['field.main'] && (this.configData['field.main'] = extParams['field.main'])
      this.tableData.sorts = extParams.sorts
    },
    /**
     * æœç´¢ï¼ˆç‚¹å‡»æœç´¢æŒ‰é’®æ—¶è§¦å‘)
     */
    search () {
      this.handlePageChange(1)
    },
    /**
     * å¯¼å‡ºExcel(点击导出按钮时触发)
     */
    exportExcel () {
      this.__checkApi()
      this.$dialog.exportConfirm('确认导出吗?')
        .then(() => {
          this.isWorking.export = true
          this.api.exportExcel({
            page: this.tableData.pagination.pageIndex,
            capacity: 1000000,
            model: this.searchForm,
            sorts: this.tableData.sorts
          })
            .then(response => {
              this.download(response)
            })
            .catch(e => {
              this.$tip.apiFailed(e)
            })
            .finally(() => {
              this.isWorking.export = false
            })
        })
        .catch(() => {})
    },
    /**
     * é‡ç½®æœç´¢æ¡ä»¶ï¼ˆç‚¹å‡»é‡ç½®æŒ‰é’®æ—¶è§¦å‘)
     */
    reset () {
      this.$refs.searchForm.resetFields()
      this.search()
    },
    refresh () {
     window.location.reload()
    },
    /**
     * é¡µå®¹é‡å˜æ›´å¤„理(切换页容量时触发)
     *
     * @param pageSize é¡µå®¹é‡
     */
    handleSizeChange (pageSize) {
      this.tableData.pagination.pageSize = pageSize
      this.search()
    },
    /**
     * è¡Œé€‰ä¸­å¤„理(点击选中列时触发)
     *
     * @param selectedRows å·²é€‰ä¸­çš„行数组
     */
    handleSelectionChange (selectedRows) {
      this.tableData.selectedRows = selectedRows
    },
    /**
     * æŽ’序(点击列头排序时触发)
     *
     * @param sortData æŽ’序参数
     */
    handleSortChange (sortData) {
      this.tableData.sorts = []
      if (sortData.order != null) {
        this.tableData.sorts.push({
          property: sortData.column.sortBy,
          direction: sortData.order === 'descending' ? 'DESC' : 'ASC'
        })
      }
      this.handlePageChange()
    },
    /**
     * é¡µç å˜æ›´å¤„理(分页时触发)
     *
     * @param pageIndex æ–°é¡µç 
     */
    handlePageChange (pageIndex) {
      this.__checkApi()
      this.tableData.pagination.pageIndex = pageIndex || this.tableData.pagination.pageIndex
      this.isWorking.search = true
      this.api.fetchList({
        page: this.tableData.pagination.pageIndex,
        capacity: this.tableData.pagination.pageSize,
        model: this.searchForm,
        sorts: this.tableData.sorts
      })
        .then(data => {
          this.tableData.list = data.records
          this.tableData.pagination.total = data.total
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
        .finally(() => {
          this.isWorking.search = false
        })
    },
    /**
     * åˆ é™¤ï¼ˆç‚¹å‡»è¡Œæ“ä½œ/删除时触发)
     *
     * @param row è¡Œå¯¹è±¡
     * @param childConfirm åˆ é™¤å­èŠ‚ç‚¹æ—¶æ˜¯å¦è¿›è¡ŒäºŒæ¬¡ç¡®è®¤
     */
    deleteById (row, childConfirm = true, call) {
      this.__checkApi()
      let message = `确认删除${this.module}吗?`
      if (childConfirm && row.children != null && row.children.length > 0) {
        message = `确认删除${this.module}【${row[this.configData['field.main']]}】及其子${this.module}吗?`
      }
      this.$dialog.deleteConfirm(message)
        .then(() => {
          this.isWorking.delete = true
          this.api.deleteById(row[this.configData['field.id']])
            .then(() => {
              this.__afterDelete()
              if (call) {
                call()
              }
            })
            .catch(e => {
              this.$tip.apiFailed(e)
            })
            .finally(() => {
              this.isWorking.delete = false
            })
        })
        .catch(() => {})
    },
    /**
     * æ‰¹é‡åˆ é™¤ï¼ˆç‚¹å‡»æ‰¹é‡åˆ é™¤æ—¶è§¦å‘)
     *
     * @param childConfirm åˆ é™¤å­èŠ‚ç‚¹æ—¶æ˜¯å¦è¿›è¡ŒäºŒæ¬¡ç¡®è®¤
     */
    deleteByIdInBatch (childConfirm = true, call) {
      this.__checkApi()
      if (this.tableData.selectedRows.length === 0) {
        this.$tip.warning('请至少选择一条数据')
        return
      }
      let message = `确认删除已选中的 ${this.tableData.selectedRows.length} æ¡${this.module}记录吗?`
      if (childConfirm) {
        const containChildrenRows = []
        for (const row of this.tableData.selectedRows) {
          if (row.children != null && row.children.length > 0) {
            containChildrenRows.push(row[this.configData['field.main']])
          }
        }
        if (containChildrenRows.length > 0) {
          message = `本次将删除${this.module}【${containChildrenRows.join('、')}】及其子${this.module}记录,确认删除吗?`
        }
      }
      this.$dialog.deleteConfirm(message)
        .then(() => {
          this.isWorking.delete = true
          this.api.deleteByIdInBatch(this.tableData.selectedRows.map(row => row[this.configData['field.id']]).join(','))
            .then(() => {
              this.__afterDelete(this.tableData.selectedRows.length)
              if (call) {
                call()
              }
            })
            .catch(e => {
              this.$tip.apiFailed(e)
            })
            .finally(() => {
              this.isWorking.delete = false
            })
        })
        .catch(() => {})
    },
    /**
     * åˆ é™¤åŽå¤„理,在单行删除或多行删除后调用
     *
     * @param deleteCount åˆ é™¤æ•°é‡
     * @private
     */
    __afterDelete (deleteCount = 1) {
      this.$tip.apiSuccess('删除成功')
      // åˆ é™¤å½“前页最后一条记录时查询上一页数据
      if (this.tableData.list.length - deleteCount === 0) {
        this.handlePageChange(this.tableData.pagination.pageIndex - 1 === 0 ? 1 : this.tableData.pagination.pageIndex - 1)
      } else {
        this.handlePageChange(this.tableData.pagination.pageIndex)
      }
    },
    /**
     * æ£€æŸ¥æŽ¥å£æ˜¯å¦é…ç½®ï¼Œåœ¨è°ƒç”¨æŽ¥å£æ—¶è°ƒç”¨
     *
     * @private
     */
    __checkApi () {
      if (this.api == null) {
        throw new Error('The page is not initialized, you can use method \'this.config\' to initialize this page.')
      }
    }
  }
}
</script>