feat(ui): 所有列表页加CSV导出按钮(全量拉取+中文BOM兼容Excel)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2,11 +2,13 @@
|
||||
import { computed, onMounted, reactive, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { Download } from '@element-plus/icons-vue'
|
||||
import { getAccounts, getCustomers, getStaffChatStats } from '@/api'
|
||||
import type { Account, Channel, Page, StaffChatCustomer, StaffChatStats } from '@/api/types'
|
||||
import YkStaffDetailModal from '@/components/YkStaffDetailModal.vue'
|
||||
import { useChannelStore } from '@/stores/channel'
|
||||
import { channelLabel, formatTime } from '@/utils/format'
|
||||
import { exportListToCsv } from '@/utils/csvExport'
|
||||
import { buildAccountSections, formatBytes, readField } from '@/utils/accountFields'
|
||||
|
||||
/**
|
||||
@@ -502,6 +504,41 @@ function onTabChange(name: string | number): void {
|
||||
if (!tabState[ch].loaded) loadTab(ch)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Header 导出:当前 tab 渠道全量员工账号 CSV
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const exporting = ref(false)
|
||||
|
||||
async function exportStaff(): Promise<void> {
|
||||
const channel = activeTab.value // 'wechat' | 'whatsapp'
|
||||
if (tabState[channel].total === 0) {
|
||||
ElMessage.warning('当前列表为空,无数据可导出')
|
||||
return
|
||||
}
|
||||
exporting.value = true
|
||||
try {
|
||||
const result = await exportListToCsv({
|
||||
fetchPage: (page, pageSize) => getAccounts({ channel, page, page_size: pageSize }),
|
||||
columns: [
|
||||
{ key: 'user_name', label: '员工姓名' },
|
||||
{ key: 'nickname', label: '微信昵称' },
|
||||
{ key: 'account_id', label: '微信号' },
|
||||
{ key: 'phone', label: '手机' },
|
||||
{ key: 'contacts_num', label: '好友数' },
|
||||
{ key: 'group_num', label: '群数' },
|
||||
{ key: 'channel', label: '渠道', format: (r) => channelLabel(r.channel) },
|
||||
],
|
||||
filename: `${channel === 'wechat' ? '微信员工' : 'WhatsApp员工'}列表`,
|
||||
})
|
||||
ElMessage.success(`已导出 ${result.rows} 条`)
|
||||
} catch (e) {
|
||||
ElMessage.error(`导出失败:${(e as Error).message}`)
|
||||
} finally {
|
||||
exporting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Drawer
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -550,6 +587,11 @@ onMounted(() => {
|
||||
按渠道展示员工账号(微信号 / WhatsApp 号),列布局对齐云客后台,点击行查看全部字段。
|
||||
</span>
|
||||
</div>
|
||||
<div class="yk-staff__filters">
|
||||
<el-button size="small" :loading="exporting" @click="exportStaff">
|
||||
<el-icon><Download /></el-icon> 导出
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-tabs v-model="activeTab" class="yk-staff__tabs" @tab-change="onTabChange">
|
||||
@@ -955,6 +997,13 @@ onMounted(() => {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.yk-staff__filters {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.yk-staff__tabs {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user