# scExport 异步导出组件

异步导出组件，支持表单参数配置、字段选择、格式选择、自定义文件名等功能。

## 基本使用

```vue
<template>
	<a-button type="primary" @click="showExport = true"> <export-outlined /> 导出数据 </a-button>

	<sc-export v-model:open="showExport" :api="authApi.users.export.post" title="导出用户" filename="用户数据" @success="handleExportSuccess" @error="handleExportError" />
</template>

<script setup>
import { ref } from 'vue'
import authApi from '@/api/auth'

const showExport = ref(false)

const handleExportSuccess = (data) => {
	console.log('导出成功', data)
}

const handleExportError = (message) => {
	console.log('导出失败', message)
}
</script>
```

## Props

| 参数             | 说明             | 类型     | 默认值     |
| ---------------- | ---------------- | -------- | ---------- |
| open             | 是否显示弹窗     | Boolean  | false      |
| title            | 弹窗标题         | String   | '导出数据' |
| api              | 导出API接口      | Function | 必填       |
| showOptions      | 是否显示导出选项 | Boolean  | true       |
| showFieldSelect  | 是否显示字段选择 | Boolean  | false      |
| fieldOptions     | 字段选项         | Array    | []         |
| showFormatSelect | 是否显示格式选择 | Boolean  | false      |
| defaultFormat    | 默认导出格式     | String   | 'xlsx'     |
| defaultFilename  | 默认文件名       | String   | ''         |
| tip              | 提示信息         | String   | ''         |

## Events

| 事件名      | 说明             | 回调参数           |
| ----------- | ---------------- | ------------------ |
| update:open | 弹窗显示状态变化 | (visible: Boolean) |
| success     | 导出成功         | (exportParams)     |
| error       | 导出失败         | (message, error)   |
| change      | 导出参数变化     | (params)           |

## Slots

### formParams

自定义表单参数插槽，可用于添加额外的表单字段。

```vue
<template>
	<sc-export v-model:open="showExport" :api="exportApi" @success="handleSuccess">
		<template #formParams="{ formData }">
			<a-form layout="vertical">
				<a-form-item label="时间范围">
					<a-range-picker v-model:value="formData.date_range" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
				</a-form-item>
				<a-form-item label="状态">
					<a-select v-model:value="formData.status" placeholder="请选择状态" :options="statusOptions" />
				</a-form-item>
			</a-form>
		</template>
	</sc-export>
</template>
```

## 完整示例

### 示例1：简单导出

```vue
<template>
	<a-button type="primary" @click="handleExport"> <export-outlined /> 导出用户 </a-button>

	<sc-export v-model:open="exportVisible" :api="authApi.users.export.post" title="导出用户数据" filename="用户数据" tip="将导出当前筛选条件下的所有用户数据" @success="handleExportSuccess" @error="handleExportError" />
</template>

<script setup>
import { ref } from 'vue'
import { message } from 'ant-design-vue'
import { ExportOutlined } from '@ant-design/icons-vue'
import authApi from '@/api/auth'

const exportVisible = ref(false)

const handleExport = () => {
	exportVisible.value = true
}

const handleExportSuccess = (params) => {
	message.success('导出成功')
}

const handleExportError = (errorMessage) => {
	message.error('导出失败：' + errorMessage)
}
</script>
```

### 示例2：带表单参数的导出

```vue
<template>
	<a-button type="primary" @click="handleExport"> <export-outlined /> 导出用户 </a-button>

	<sc-export v-model:open="exportVisible" :api="authApi.users.export.post" title="导出用户数据" filename="用户数据" :show-options="false" :show-field-select="false" :show-format-select="false" @success="handleExportSuccess" @error="handleExportError">
		<template #formParams="{ formData }">
			<a-form layout="vertical">
				<a-form-item label="时间范围">
					<a-range-picker v-model:value="formData.date_range" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%" />
				</a-form-item>
				<a-form-item label="部门">
					<a-select v-model:value="formData.department_id" placeholder="请选择部门" :options="departmentOptions" :field-names="{ label: 'name', value: 'id' }" allow-clear />
				</a-form-item>
				<a-form-item label="状态">
					<a-select
						v-model:value="formData.status"
						placeholder="请选择状态"
						:options="[
							{ label: '启用', value: 1 },
							{ label: '禁用', value: 0 },
						]"
						allow-clear
					/>
				</a-form-item>
				<a-form-item label="角色">
					<a-select v-model:value="formData.role_ids" mode="multiple" placeholder="请选择角色" :options="roleOptions" :field-names="{ label: 'name', value: 'id' }" />
				</a-form-item>
			</a-form>
		</template>
	</sc-export>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { message } from 'ant-design-vue'
import { ExportOutlined } from '@ant-design/icons-vue'
import authApi from '@/api/auth'

const exportVisible = ref(false)
const departmentOptions = ref([])
const roleOptions = ref([])

// 加载选项数据
onMounted(async () => {
	try {
		const [deptRes, roleRes] = await Promise.all([authApi.departments.all.get(), authApi.roles.all.get()])
		departmentOptions.value = deptRes.data || []
		roleOptions.value = roleRes.data || []
	} catch (error) {
		console.error('加载选项失败', error)
	}
})

const handleExport = () => {
	exportVisible.value = true
}

const handleExportSuccess = (params) => {
	message.success('导出成功')
	console.log('导出参数', params)
}

const handleExportError = (errorMessage) => {
	message.error('导出失败：' + errorMessage)
}
</script>
```

### 示例3：带字段和格式选择的导出

```vue
<template>
	<a-button type="primary" @click="handleExport"> <export-outlined /> 导出数据 </a-button>

	<sc-export
		v-model:open="exportVisible"
		:api="exportApi"
		title="导出数据"
		filename="数据报表"
		:show-options="true"
		:show-field-select="true"
		:field-options="fieldOptions"
		:show-format-select="true"
		default-format="xlsx"
		tip="请选择需要导出的字段和格式"
		@success="handleExportSuccess"
		@error="handleExportError"
	>
		<template #formParams="{ formData }">
			<a-form layout="vertical">
				<a-form-item label="数据类型">
					<a-radio-group v-model:value="formData.type">
						<a-radio value="all">全部数据</a-radio>
						<a-radio value="filtered">筛选数据</a-radio>
						<a-radio value="selected">选中数据</a-radio>
					</a-radio-group>
				</a-form-item>
			</a-form>
		</template>
	</sc-export>
</template>

<script setup>
import { ref } from 'vue'
import { message } from 'ant-design-vue'
import { ExportOutlined } from '@ant-design/icons-vue'

const exportVisible = ref(false)

// 字段选项
const fieldOptions = ref([
	{ label: '用户名', value: 'username' },
	{ label: '姓名', value: 'name' },
	{ label: '邮箱', value: 'email' },
	{ label: '手机号', value: 'phone' },
	{ label: '部门', value: 'department' },
	{ label: '角色', value: 'roles' },
	{ label: '状态', value: 'status' },
	{ label: '创建时间', value: 'created_at' },
	{ label: '最后登录', value: 'last_login_at' },
])

// 导出API
const exportApi = async (params) => {
	// 这里调用实际的导出接口
	// 示例：
	// return await authApi.users.export.post(params)
	console.log('导出参数', params)
	// 返回一个 blob 对象
	return new Blob(['test data'], { type: 'application/vnd.ms-excel' })
}

const handleExport = () => {
	exportVisible.value = true
}

const handleExportSuccess = (params) => {
	message.success('导出成功')
}

const handleExportError = (errorMessage) => {
	message.error('导出失败：' + errorMessage)
}
</script>
```

## 注意事项

1. 组件会自动处理文件下载、表单参数合并等逻辑
2. 表单参数会作为普通对象发送到后端
3. 后端接口应返回 Blob 类型的响应
4. 文件名会自动添加对应的扩展名（.xlsx、.xls、.csv）
5. 字段选择功能需要在后端支持按字段过滤数据
6. 格式选择功能需要在后端支持不同格式的导出

## 与表格组件结合使用

```vue
<template>
	<sc-table :columns="columns" :data-source="dataSource" :loading="loading" :pagination="pagination">
		<template #toolbar>
			<a-space>
				<a-button type="primary" @click="handleExport"> <export-outlined /> 导出数据 </a-button>
			</a-space>
		</template>
	</sc-table>

	<sc-export v-model:open="exportVisible" :api="exportApi" title="导出用户数据" filename="用户数据" :show-options="false" @success="handleExportSuccess">
		<template #formParams="{ formData }">
			<a-form layout="vertical">
				<a-form-item label="导出范围">
					<a-radio-group v-model:value="formData.scope">
						<a-radio value="all">全部数据</a-radio>
						<a-radio value="current">当前页</a-radio>
						<a-radio value="selected">选中项</a-radio>
					</a-radio-group>
				</a-form-item>
				<a-form-item label="包含筛选条件">
					<a-switch v-model:checked="formData.with_filter" />
				</a-form-item>
			</a-form>
		</template>
	</sc-export>
</template>

<script setup>
import { ref } from 'vue'
import { ExportOutlined } from '@ant-design/icons-vue'
import authApi from '@/api/auth'

const exportVisible = ref(false)

const handleExport = () => {
	exportVisible.value = true
}

const exportApi = async (params) => {
	return await authApi.users.export.post(params)
}

const handleExportSuccess = () => {
	// 导出成功后的处理
}
</script>
```
