# TableList 通用列表组件

基于 Element Plus 和 Vue 3 的高度可配置化列表组件，专为现代化数据管理场景设计，支持灵活的搜索表单、表格配置和丰富的交互功能。

## ✨ 功能特性

- 🎯 **高度可配置**: 搜索表单、表格列、操作按钮全部可配置
- 🔍 **灵活搜索**: 支持基础搜索、高级筛选和响应式布局
- 📋 **丰富表单**: 支持输入框、选择器、日期范围、自定义组件等
- 📊 **多样表格**: 支持字典显示、自定义渲染、操作按钮、列固定等
- 🔄 **拖拽排序**: 支持列设置拖拽排序，跨区域拖拽
- 📺 **全屏模式**: 支持表格局部全屏，提升数据查看体验
- 💾 **数据导出**: 内置 CSV 格式数据导出功能
- 🖨️ **打印功能**: 支持表格数据打印
- 🎨 **样式一致**: 与项目现有样式保持一致
- 📱 **响应式**: 完全响应式布局设计

## 组件结构

```
TableList/
├── index.vue           # 主组件
├── types.ts           # 类型定义
├── configs/
│   ├── search-forms.ts # 搜索表单预设配置
│   └── table-columns.ts # 表格列预设配置
├── example.vue        # 使用示例
└── README.md         # 文档
```

## 🚀 快速开始

### 安装和导入

```typescript
import TableList from '@/components/TableList/index.vue'
import type { TableListConfig } from '@/components/TableList/types'
```

### 基础使用

最简单的使用方式：

```vue
<template>
  <TableList :config="config" />
</template>

<script setup>
import TableList from '@/components/TableList/index.vue'

const config = {
  api: {
    getList: async (params) => {
      // 返回格式: { list: [], total: 0 }
      return await yourApi.getList(params)
    }
  },
  table: {
    columns: [
      { prop: 'id', label: 'ID' },
      { prop: 'name', label: '姓名' },
      { prop: 'email', label: '邮箱' }
    ]
  },
  settings: {
    refresh: true,
    fullscreen: true,
    columns: true
  }
}
</script>
```

## 📖 详细使用说明

### 1. 基本使用

```vue
<template>
  <TableList :config="tableListConfig" />
</template>

<script setup>
import TableList from '@/components/TableList/index.vue'
import {
  copySearchFormConfig,
  copyTableColumns,
  createCopyActions
} from '@/components/TableList/configs'
import * as ProcessInstanceApi from '@/api/bpm/processInstance'

const tableListConfig = {
  searchForm: copySearchFormConfig,
  table: {
    loading: false,
    data: [],
    columns: copyTableColumns,
    actions: createCopyActions((row) => {
      // 处理操作按钮点击
      console.log('点击操作:', row)
    })
  },
  pagination: { show: true, pageSize: 10 },
  api: {
    getList: ProcessInstanceApi.getProcessInstanceCopyPage
  },
  queryParams: {
    processInstanceName: '',
    createTime: []
  }
}
</script>
```

### 2. 自定义搜索表单

```typescript
const customSearchFormConfig = {
  items: [
    {
      field: 'name',
      label: '任务名称',
      type: 'input',
      placeholder: '请输入任务名称',
      width: '240px'
    },
    {
      field: 'category',
      label: '流程分类',
      type: 'select',
      placeholder: '请选择流程分类',
      width: '155px',
      options: categoryList.map((item) => ({
        label: item.name,
        value: item.code
      }))
    }
  ],
  maxItemsPerRow: 4, // 每行显示4个，超过则换行
  collapsed: true, // 默认折叠
  showAdvanced: true,
  advancedItems: [
    {
      field: 'createTime',
      label: '发起时间',
      type: 'date-range',
      width: '240px'
    }
  ]
}
```

### 响应式布局和展开/收起

当搜索表单项数量超过 `maxItemsPerRow` 时，组件会自动显示展开/收起按钮：

```typescript
const searchFormConfig = {
  items: [
    // 6个搜索项，超过默认的4个
    { field: 'name', label: '名称', type: 'input' },
    { field: 'type', label: '类型', type: 'select', options: [...] },
    { field: 'status', label: '状态', type: 'select', options: [...] },
    { field: 'category', label: '分类', type: 'input' },
    { field: 'dateRange', label: '日期范围', type: 'date-range' },
    { field: 'keyword', label: '关键词', type: 'input' }
  ],
  maxItemsPerRow: 4, // 每行4个，第5、6个会换行显示
  collapsed: true  // 默认只显示前4个，点击展开显示全部
}
```

组件特性：

- 使用 `el-row` 和 `el-col` 实现响应式布局
- 当 items 数量 > maxItemsPerRow 时显示展开/收起按钮
- 折叠状态下只显示前 `maxItemsPerRow` 个items
- 展开状态显示所有items
- 每个item自动计算 `span` 值：`24 / maxItemsPerRow`

### 3. 自定义表格列

```typescript
const customTableColumns = [
  {
    prop: 'processInstance.name',
    label: '流程',
    width: 180,
    align: 'center'
  },
  {
    prop: 'status',
    label: '状态',
    width: 120,
    dictType: DICT_TYPE.BPM_TASK_STATUS // 使用字典
  },
  {
    prop: 'duration',
    label: '耗时',
    width: 160,
    render: (h, { row }) => {
      return h('span', {}, formatPast2(row.duration))
    }
  }
]
```

### 4. 操作按钮配置

#### 表格行操作按钮

```typescript
const actions = [
  {
    label: '办理',
    type: 'primary',
    link: true,
    handler: (row) => {
      // 处理点击事件
      console.log('办理任务:', row)
    }
  },
  {
    label: '删除',
    type: 'danger',
    link: true,
    show: (row) => row.canDelete, // 条件显示
    handler: (row) => {
      // 处理删除
    }
  }
]
```

#### 表格顶部操作按钮

```typescript
const tableActions = [
  {
    label: '新增',
    type: 'primary',
    plain: true,
    icon: 'ep:plus',
    permission: 'system:role:create',
    handler: () => openForm('create')
  },
  {
    label: '导出',
    type: 'success',
    plain: true,
    icon: 'ep:download',
    loading: exportLoading, // 直接传递 ref 响应式值
    permission: 'system:role:export',
    handler: () => handleExport()
  },
  {
    label: '批量删除',
    type: 'danger',
    plain: true,
    icon: 'ep:delete',
    disabled: computed(() => checkedIds.value.length === 0), // 直接传递 computed 响应式值
    permission: 'system:role:delete',
    handler: () => handleDeleteBatch()
  }
]
```

## 配置说明

### SearchFormItem 搜索表单项

| 属性        | 类型                                            | 说明       |
| ----------- | ----------------------------------------------- | ---------- |
| field       | string                                          | 字段名     |
| label       | string                                          | 标签文本   |
| type        | 'input' \| 'select' \| 'date-range' \| 'custom' | 表单类型   |
| placeholder | string                                          | 占位符     |
| width       | string                                          | 宽度       |
| options     | Array<{ label: string; value: any }>            | 选择器选项 |
| component   | any                                             | 自定义组件 |
| props       | Record<string, any>                             | 组件属性   |

### SearchFormConfig 搜索表单配置

| 属性           | 类型             | 说明                           |
| -------------- | ---------------- | ------------------------------ |
| items          | SearchFormItem[] | 表单项数组                     |
| showAdvanced   | boolean          | 是否显示高级筛选               |
| advancedItems  | SearchFormItem[] | 高级筛选项数组                 |
| maxItemsPerRow | number           | 每行最大显示的items数量，默认4 |
| collapsed      | boolean          | 是否默认折叠，默认false        |

### TableColumn 表格列配置

| 属性                | 类型                          | 说明           |
| ------------------- | ----------------------------- | -------------- |
| prop                | string                        | 属性名         |
| label               | string                        | 列标题         |
| width               | string \| number              | 列宽度         |
| minWidth            | string \| number              | 最小宽度       |
| align               | 'left' \| 'center' \| 'right' | 对齐方式       |
| fixed               | boolean \| 'left' \| 'right'  | 固定列         |
| showOverflowTooltip | boolean                       | 显示溢出提示   |
| formatter           | Function                      | 格式化函数     |
| render              | Function                      | 自定义渲染函数 |
| dictType            | string                        | 字典类型       |

### ActionButton 表格行操作按钮

| 属性    | 类型                                                      | 说明         |
| ------- | --------------------------------------------------------- | ------------ |
| label   | string                                                    | 按钮文本     |
| type    | 'primary' \| 'success' \| 'warning' \| 'danger' \| 'info' | 按钮类型     |
| icon    | string                                                    | 图标         |
| link    | boolean                                                   | 链接样式     |
| handler | Function                                                  | 点击处理函数 |
| show    | Function                                                  | 显示条件函数 |

### TableActionButton 表格顶部操作按钮

| 属性       | 类型                                                      | 说明                   |
| ---------- | --------------------------------------------------------- | ---------------------- |
| label      | string                                                    | 按钮文本               |
| type       | 'primary' \| 'success' \| 'warning' \| 'danger' \| 'info' | 按钮类型               |
| icon       | string                                                    | 图标                   |
| plain      | boolean                                                   | 简约样式               |
| loading    | boolean \| { value: boolean }                             | 加载状态，支持响应式值 |
| disabled   | boolean \| { value: boolean }                             | 禁用状态，支持响应式值 |
| handler    | Function                                                  | 点击处理函数           |
| show       | Function                                                  | 显示条件函数           |
| permission | string                                                    | 权限标识               |

## 预设配置

组件提供了针对不同流程页面的预设配置：

- `copySearchFormConfig` - 抄送我的流程
- `todoSearchFormConfig` - 待办任务
- `doneSearchFormConfig` - 已办任务
- `managerSearchFormConfig` - 管理任务
- `copyTableColumns` - 抄送列表列配置
- `todoTableColumns` - 待办列表列配置
- `doneTableColumns` - 已办列表列配置
- `managerTableColumns` - 管理列表列配置

## 替换现有页面

使用新组件替换现有页面时，只需要：

1. 引入配置和组件
2. 配置API和参数
3. 处理操作按钮事件
4. 替换模板中的搜索和表格部分

这样可以大大减少代码重复，提高维护性。

## 响应式状态管理

TableList 支持响应式的 `loading` 和 `disabled` 状态：

```typescript
// 使用 ref
const exportLoading = ref(false)

// 使用 computed
const checkedIds = ref([])
const canDelete = computed(() => checkedIds.value.length > 0)

const tableActions = [
  {
    label: '导出',
    type: 'success',
    loading: exportLoading, // 直接传递 ref
    handler: () => {
      exportLoading.value = true
      // 执行导出操作
      setTimeout(() => {
        exportLoading.value = false
      }, 2000)
    }
  },
  {
    label: '批量删除',
    type: 'danger',
    disabled: canDelete, // 直接传递 computed
    handler: () => {
      console.log('批量删除')
    }
  }
]
```

组件内部会自动检测响应式对象并获取其 `.value` 值，无需手动处理。

## 🆕 新增功能详解

### 1. 列设置拖拽排序

组件现在支持列设置的拖拽排序功能，用户可以通过拖拽来调整列的顺序和固定状态：

#### 功能特性

- 🔄 **列表内拖拽**: 在同一区域内调整列的顺序
- 🌐 **跨列表拖拽**: 在固定左侧、不固定、固定右侧三个区域间自由拖拽
- 🎯 **智能更新**: 拖拽到不同区域时自动更新列的固定属性
- 🎨 **视觉反馈**: 拖拽过程中提供清晰的视觉反馈

#### 配置方式

```typescript
const tableConfig = {
  // ...其他配置
  settings: {
    refresh: true,
    download: true,
    print: true,
    size: true,
    columns: true, // 启用列设置功能
    fullscreen: true
  }
}
```

#### 使用方式

1. 点击表格右上角的设置图标 ⚙️
2. 在弹出的列设置面板中拖拽列标题
3. 可以在三个区域（固定左侧、不固定、固定右侧）间自由拖拽
4. 点击确定保存配置

### 2. 全屏显示功能

支持表格组件的局部全屏显示，提供更好的数据查看体验：

#### 功能特性

- 📺 **局部全屏**: 只让表格组件进入全屏，不影响页面其他部分
- 🔄 **图标切换**: 全屏时显示退出图标，非全屏时显示进入图标
- ⌨️ **键盘支持**: 支持 ESC 键退出全屏
- 📱 **响应式**: 全屏状态下表格自适应屏幕高度
- 💫 **平滑过渡**: 添加 CSS 过渡动画效果

#### 配置方式

```typescript
const tableConfig = {
  // ...其他配置
  settings: {
    refresh: true,
    download: true,
    print: true,
    size: true,
    columns: true,
    fullscreen: true // 启用全屏功能
  }
}
```

#### 使用方式

1. 点击表格右上角的全屏图标 📊
2. 表格组件进入全屏模式
3. 再次点击或按 ESC 键退出全屏

### 3. 数据导出功能

内置 CSV 格式的数据导出功能，支持自定义导出逻辑：

#### 功能特性

- 📊 **CSV 导出**: 内置 CSV 格式导出，支持中文显示
- 🎯 **自定义导出**: 支持传递自定义导出函数
- 📋 **格式化支持**: 自动处理字典类型和自定义渲染
- 🌐 **编码优化**: 添加 BOM 以支持 Excel 正确显示中文

#### 配置方式

```typescript
const tableConfig = {
  // ...其他配置
  settings: {
    download: true, // 启用下载功能
    // 或者使用自定义下载函数
    download: (data) => {
      // 自定义导出逻辑
      console.log('导出数据:', data)
    }
  }
}
```

### 4. 数据打印功能

支持表格数据的打印功能，自动生成打印友好的格式：

#### 功能特性

- 🖨️ **打印优化**: 自动生成打印友好的 HTML 格式
- 📊 **完整信息**: 包含打印时间、数据条数等元信息
- 🎨 **样式优化**: 针对打印场景优化的 CSS 样式
- 🌐 **新窗口**: 在新窗口中打开打印预览，不影响当前页面

#### 配置方式

```typescript
const tableConfig = {
  // ...其他配置
  settings: {
    print: true // 启用打印功能
  }
}
```

### 5. 表格尺寸调整

支持表格尺寸的动态调整，提供三种预设尺寸：

#### 可选尺寸

- `large`: 宽松型 - 适合数据量较少的场景
- `default`: 默认 - 标准尺寸
- `small`: 紧凑型 - 适合数据密集的场景

#### 配置方式

```typescript
const tableConfig = {
  // ...其他配置
  settings: {
    size: true // 启用尺寸调整功能
  }
}
```

### 6. 刷新功能

支持表格数据的快速刷新，重新加载当前页数据：

#### 配置方式

```typescript
const tableConfig = {
  // ...其他配置
  settings: {
    refresh: true // 启用刷新功能
  }
}
```

## 🎯 Settings 配置详解

| 属性       | 类型                | 说明                             | 默认值 |
| ---------- | ------------------- | -------------------------------- | ------ |
| refresh    | boolean             | 是否显示刷新按钮                 | true   |
| download   | boolean \| Function | 是否显示下载按钮或自定义下载函数 | true   |
| print      | boolean             | 是否显示打印按钮                 | false  |
| size       | boolean             | 是否显示尺寸调整按钮             | false  |
| columns    | boolean             | 是否显示列设置按钮               | false  |
| fullscreen | boolean             | 是否显示全屏按钮                 | false  |

## 🧪 测试和演示

组件提供了完整的测试和演示文件：

- `example.vue` - 基础使用示例
- `drag-test.vue` - 拖拽功能测试
- `fullscreen-demo.vue` - 全屏功能完整演示

您可以直接运行这些文件来体验各项功能。

## 🎯 完整配置示例

下面是一个完整的 TableList 配置示例，展示了所有常用功能：

```typescript
import type { TableListConfig } from '@/components/TableList/types'

const config: TableListConfig = {
  // 1. 搜索表单配置
  searchForm: {
    items: [
      {
        field: 'name',
        label: '姓名',
        type: 'input',
        placeholder: '请输入姓名',
        width: '200px'
      },
      {
        field: 'status',
        label: '状态',
        type: 'select',
        placeholder: '请选择状态',
        options: [
          { label: '在职', value: 'active' },
          { label: '离职', value: 'inactive' }
        ]
      },
      {
        field: 'dateRange',
        label: '创建时间',
        type: 'date-range'
      }
    ],
    maxItemsPerRow: 3,
    collapsed: true
  },

  // 2. 表格顶部操作按钮
  actions: [
    {
      label: '新增',
      type: 'primary',
      icon: 'ep:plus',
      permission: 'system:user:create',
      handler: () => handleAdd()
    },
    {
      label: '批量删除',
      type: 'danger',
      plain: true,
      icon: 'ep:delete',
      disabled: computed(() => selectedIds.value.length === 0),
      permission: 'system:user:delete',
      handler: () => handleBatchDelete()
    },
    {
      label: '导出',
      type: 'success',
      plain: true,
      icon: 'ep:download',
      loading: exportLoading,
      permission: 'system:user:export',
      handler: () => handleExport()
    }
  ],

  // 3. 表格配置
  table: {
    selection: true, // 多选
    index: true, // 序号
    columns: [
      { prop: 'id', label: 'ID', width: 80, fixed: 'left', required: true },
      { prop: 'name', label: '姓名', width: 120, fixed: 'left' },
      { prop: 'email', label: '邮箱', width: 200 },
      {
        prop: 'status',
        label: '状态',
        width: 100,
        dictType: 'USER_STATUS', // 字典类型
        formatter: (row) => (row.status === 'active' ? '在职' : '离职')
      },
      {
        prop: 'avatar',
        label: '头像',
        width: 100,
        render: (h, { row }) => {
          return h('img', {
            src: row.avatar,
            style: { width: '40px', height: '40px', borderRadius: '50%' }
          })
        }
      },
      { prop: 'createTime', label: '创建时间', width: 180 }
    ],
    // 表格行操作按钮
    actions: [
      {
        label: '编辑',
        type: 'primary',
        link: true,
        permission: 'system:user:update',
        handler: (row) => handleEdit(row)
      },
      {
        label: '删除',
        type: 'danger',
        link: true,
        show: (row) => row.canDelete, // 条件显示
        permission: 'system:user:delete',
        handler: (row) => handleDelete(row)
      }
    ]
  },

  // 4. 设置按钮配置
  settings: {
    refresh: true, // 刷新
    download: true, // 导出
    print: true, // 打印
    size: true, // 尺寸调整
    columns: true, // 列设置（拖拽排序）
    fullscreen: true // 全屏显示
  },

  // 5. 分页配置
  pagination: {
    show: true,
    pageSize: 20,
    layout: 'total, sizes, prev, pager, next, jumper'
  },

  // 6. API 配置
  api: {
    getList: async (params) => {
      const response = await api.getList(params)
      return {
        list: response.data.records,
        total: response.data.total
      }
    }
  },

  // 7. 查询参数
  queryParams: reactive({
    name: '',
    status: '',
    dateRange: [],
    pageNo: 1,
    pageSize: 20
  }),

  // 8. 事件回调
  onSearch: (params) => {
    console.log('搜索参数:', params)
  },
  onReset: () => {
    console.log('重置表单')
  },
  onSelectionChange: (selection) => {
    selectedIds.value = selection.map((item) => item.id)
  }
}
```

## 🛠️ 开发建议

### 1. 性能优化

- 使用 `computed` 处理复杂的响应式状态
- 合理设置 `pageSize` 避免一次加载过多数据
- 大数据量时考虑虚拟滚动

### 2. 用户体验

- 合理使用 `fixed` 列，避免影响响应式布局
- 配置适当的 `width` 和 `minWidth`
- 利用 `showOverflowTooltip` 显示长文本

### 3. 代码维护

- 将配置提取到单独的文件中
- 使用 TypeScript 类型定义确保类型安全
- 统一 API 响应格式

## 📞 技术支持

如果您在使用过程中遇到问题，可以：

1. 查看示例文件 `example.vue`
2. 查看测试文件 `drag-test.vue`、`fullscreen-demo.vue`
3. 检查浏览器控制台日志
4. 确认 API 返回数据格式是否正确

---

**TableList 组件** - 让表格开发更简单、更高效！ 🎉
