feat(crm): align product export with ListExportDropdown

Add ids/columns support and unify toolbar export UX.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-08-21 17:06:01 +08:00
1 parent 09827fdbf3
commit 5c7210facc
5 files changed
+77 -34

No files matched your search

+25 -30
View File
@@ -101,10 +101,14 @@
<el-icon><Upload /></el-icon>
导入
</el-button>
<el-button class="btn-ghost" @click="handleExport">
<el-icon><Download /></el-icon>
导出
</el-button>
<ListExportDropdown
:export-fn="fetchExportProducts"
:get-filter-params="getProductExportFilterParams"
:has-selection="true"
:selected-ids="selectedRows.map((r) => r.id)"
:visible-columns="productExportColumns"
filename="产品列表.xlsx"
/>
<el-button class="btn-ghost" @click="categoryMaintainVisible = true">
<el-icon><Folder /></el-icon>
产品分类
@@ -421,6 +425,7 @@
allRowsDeletableByCreator,
CREATOR_DELETE_TIP
} from '@/utils/creator-delete'
import ListExportDropdown from '@/components/business/list-export-dropdown/index.vue'
import ListToolbarEndActions from '@/components/business/list-toolbar-end-actions/index.vue'
import ListQuickSearchInput from '@/components/business/list-quick-search-input/index.vue'
import { usePersistedListColumns } from '@/composables/usePersistedListColumns'
@@ -482,6 +487,22 @@
const { visibleColumns, checkAll, isIndeterminate, isColumnVisible, resetToDefault } =
usePersistedListColumns('crm-product-list-columns-v2', listColumnDefs)
function getProductExportFilterParams() {
const quickKeyword = quickSearchKeyword.value?.trim()
return {
keyword: quickKeyword || searchForm.keyword || undefined,
categoryId: searchForm.categoryId || undefined,
status: searchForm.status || undefined
}
}
/** 产品名称列始终展示,需并入导出 columns;cost 映射后端 costPrice */
const productExportColumns = computed(() => {
const cols = [...visibleColumns.value]
if (!cols.includes('productName')) cols.unshift('productName')
return cols
})
const selectedRows = ref<any[]>([])
const pagination = reactive({ page: 1, pageSize: 20, total: 0 })
@@ -781,32 +802,6 @@
}
}
async function handleExport() {
try {
const params: Record<string, any> = {}
const quickKeyword = quickSearchKeyword.value?.trim()
if (quickKeyword) {
params.keyword = quickKeyword
} else if (searchForm.keyword) {
params.keyword = searchForm.keyword
}
if (searchForm.categoryId) params.categoryId = searchForm.categoryId
if (searchForm.status) params.status = searchForm.status
const res = await fetchExportProducts(params)
const blob = new Blob([res as any], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
})
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = `产品列表_${new Date().getTime()}.xlsx`
link.click()
URL.revokeObjectURL(url)
} catch {
ElMessage.error('导出失败')
}
}
watchDebounced(
searchForm,
() => {