feat: 书籍导出添加 exportColumns 补全4个缺失字段 + cover formatter

This commit is contained in:
2026-07-03 14:23:31 +08:00
parent b7a9a8fd82
commit c766b3c62b
+36 -2
View File
@@ -16,7 +16,7 @@
tips="请按照模板填写书籍信息,名称为必填项"
/>
<!-- 导出按钮 -->
<cl-export-btn :columns="Table?.columns" filename="书籍列表" />
<cl-export-btn :columns="exportColumns" filename="书籍列表" />
<!-- 分类筛选 -->
<cl-select
:options="categoryOptions"
@@ -68,7 +68,7 @@ defineOptions({
import { useCrud, useTable, useUpsert } from '@cool-vue/crud';
import { useCool } from '/@/cool';
import { h, reactive, ref } from 'vue';
import { computed, h, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { ElMessage } from 'element-plus';
import BookCoverEdit from '../../components/book-cover-edit.vue';
@@ -294,6 +294,40 @@ const Table = useTable({
]
});
// 导出列 - 包含表格列 + 额外字段(不在表格展示,导出时可选)
const exportColumns = computed(() => {
const cols: any[] = Table.value?.columns ? [...Table.value.columns] : [];
const base = cols.filter((e: any) => !['selection', 'expand', 'index', 'op'].includes(e.type));
// 为 cover 列添加 formatter(导出时 render 不会被调用,需要 formatter 将数组转为文本)
const coverCol = base.find((e: any) => e.prop === 'cover');
if (coverCol) {
coverCol.formatter = (_row: any, _col: any, value: any) => {
if (Array.isArray(value)) {
return value.join(', ');
}
if (typeof value === 'string') {
try {
const parsed = JSON.parse(value);
return Array.isArray(parsed) ? parsed.join(', ') : value;
} catch {
return value;
}
}
return String(value || '');
};
}
base.push(
{ label: '内容简介', prop: 'synopsis', minWidth: 300 },
{ label: '背景故事', prop: 'backgroundStory', minWidth: 300 },
{ label: '标签', prop: 'tags', minWidth: 150 },
{ label: '更新时间', prop: 'updateTime', minWidth: 170 }
);
return base;
});
// cl-upsert 配置 - 新增/编辑表单
const Upsert = useUpsert({
dialog: {