feat(web-admin): add archive data-and-attachments ZIP export menu.

Extend ListExportDropdown with additional items and wire archive_zip on the plan-archive page.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
wuzilongandCursor committed 2026-09-23 12:47:14 +08:00
1 parent d5c2e1f1a4
commit 2f3756eab8
2 files changed
+56 -7

No files matched your search

@@ -16,6 +16,14 @@
<el-dropdown-item command="selected" :disabled="!selectedCount">
{{ selectedCount ? `导出已选(${selectedCount})` : '导出已选' }}
</el-dropdown-item>
<el-dropdown-item
v-for="item in additionalMenuItems"
:key="item.command"
:command="item.command"
:disabled="item.disabled || (item.withIds && !selectedCount)"
>
{{ item.label }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
@@ -50,6 +58,14 @@
columns?: string[]
}
export type ListExportAdditionalMenuItem = {
command: string
label: string
withIds?: boolean
disabled?: boolean
payloadExtra?: Record<string, any>
}
const props = withDefaults(
defineProps<{
exportFn: (payload: ListExportPayload) => Promise<any>
@@ -59,13 +75,15 @@
visibleColumns?: string[]
filename?: string
disabled?: boolean
additionalMenuItems?: ListExportAdditionalMenuItem[]
}>(),
{
selectedIds: () => [],
hasSelection: false,
visibleColumns: undefined,
filename: '导出.xlsx',
disabled: false
disabled: false,
additionalMenuItems: () => []
}
)
@@ -73,8 +91,14 @@
const selectedCount = computed(() => props.selectedIds?.length || 0)
function buildPayload(withIds: boolean): ListExportPayload {
const payload: ListExportPayload = { ...props.getFilterParams() }
function buildPayload(
withIds: boolean,
payloadExtra?: Record<string, any>
): ListExportPayload {
const payload: ListExportPayload = {
...props.getFilterParams(),
...(payloadExtra || {})
}
if (props.visibleColumns?.length) {
payload.columns = [...props.visibleColumns]
}
@@ -84,12 +108,12 @@
return payload
}
async function runExport(withIds: boolean) {
async function runExport(withIds: boolean, payloadExtra?: Record<string, any>) {
if (exporting.value || props.disabled) return
if (withIds && !(props.selectedIds?.length > 0)) return
exporting.value = true
try {
const res = await props.exportFn(buildPayload(withIds))
const res = await props.exportFn(buildPayload(withIds, payloadExtra))
const { blob, filenameHeader } = pickBlobFromExportResponse(res)
const name = filenameFromContentDisposition(filenameHeader, props.filename)
triggerBlobDownload(blob, name)
@@ -107,8 +131,17 @@
}
function handleCommand(cmd: string) {
if (cmd === 'filtered') void runExport(false)
if (cmd === 'selected') void runExport(true)
if (cmd === 'filtered') {
void runExport(false)
return
}
if (cmd === 'selected') {
void runExport(true)
return
}
const extra = props.additionalMenuItems?.find((item) => item.command === cmd)
if (!extra) return
void runExport(!!extra.withIds, extra.payloadExtra)
}
</script>
@@ -40,6 +40,7 @@
:get-filter-params="getPlanArchiveExportFilterParams"
:has-selection="true"
:selected-ids="selectedRows.map((r) => r.id)"
:additional-menu-items="archiveZipMenuItems"
filename="计划归档.xlsx"
/>
<el-dropdown trigger="click" @command="handleBatchErpCommand">
@@ -1088,6 +1089,21 @@ function getPlanArchiveExportFilterParams() {
return { exportFormat: 'archive', ...buildListQueryParams() }
}
const archiveZipMenuItems = [
{
command: 'filtered-zip',
label: '导出筛选结果(数据及附件 ZIP)',
withIds: false,
payloadExtra: { exportFormat: 'archive_zip' }
},
{
command: 'selected-zip',
label: '导出已选(数据及附件 ZIP)',
withIds: true,
payloadExtra: { exportFormat: 'archive_zip' }
}
]
const viewingPlan = ref<Plan | null>(null)
function syncViewingPlanFromList() {