165 lines
4.7 KiB
Vue
165 lines
4.7 KiB
Vue
<script lang="ts" setup>
|
|
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
|
|
|
import { downloadFileFromBlobPart } from '@vben/utils';
|
|
|
|
import dayjs from 'dayjs';
|
|
|
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
|
import { exportProject, getProgressByProjectPage } from '#/api/report/progress';
|
|
import { ShadowContainer } from '#/components/shadow-container';
|
|
|
|
import { useProjectGridColumns, useProjectGridFormSchema } from '../data';
|
|
|
|
/** 导出表格 */
|
|
async function onExport(body: any) {
|
|
const formValues = await gridApi.formApi.getValues();
|
|
const data = await exportProject({ ...body, ...formValues });
|
|
downloadFileFromBlobPart({
|
|
fileName: `${body.filename}.xlsx`,
|
|
source: data,
|
|
});
|
|
}
|
|
|
|
const [Grid, gridApi] = useVbenVxeGrid({
|
|
formOptions: {
|
|
schema: useProjectGridFormSchema(),
|
|
submitOnEnter: true,
|
|
fieldMappingTime: [['updateTime', ['updateTimeStart', 'updateTimeEnd']]],
|
|
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4',
|
|
},
|
|
gridOptions: {
|
|
columns: useProjectGridColumns(),
|
|
proxyConfig: {
|
|
ajax: {
|
|
query: async ({ page }, formValues) => {
|
|
return await getProgressByProjectPage({
|
|
pageNo: page.currentPage,
|
|
pageSize: page.pageSize,
|
|
...formValues,
|
|
});
|
|
},
|
|
},
|
|
},
|
|
pagerConfig: {
|
|
enabled: true,
|
|
},
|
|
toolbarConfig: {
|
|
refresh: { code: 'query' },
|
|
search: true,
|
|
export: true,
|
|
},
|
|
height: 'auto',
|
|
rowConfig: {
|
|
keyField: 'id',
|
|
isHover: false,
|
|
useKey: true,
|
|
},
|
|
columnConfig: {
|
|
useKey: true,
|
|
},
|
|
border: true,
|
|
virtualXConfig: {
|
|
enabled: false,
|
|
},
|
|
virtualYConfig: {
|
|
enabled: false,
|
|
},
|
|
exportConfig: {
|
|
remote: true,
|
|
type: 'xlsx',
|
|
types: ['xlsx'],
|
|
mode: 'all',
|
|
modes: [
|
|
{ label: '导出全部数据', value: 'all' },
|
|
{ label: '导出当前页数据', value: 'current' },
|
|
],
|
|
filename() {
|
|
return `项目进展数据${dayjs().format('YYYYMMDDHHmmss')}`;
|
|
},
|
|
sheetName() {
|
|
return `项目进展列表`;
|
|
},
|
|
slots: {
|
|
parameter: 'exportParameter',
|
|
},
|
|
async exportMethod({ options, $grid }) {
|
|
const proxyInfo = $grid?.getProxyInfo();
|
|
// 处理条件参数
|
|
const body = {
|
|
filename: options.filename,
|
|
sheetName: options.sheetName,
|
|
isHeader: options.isHeader,
|
|
original: options.original,
|
|
mode: options.mode,
|
|
pageNo: proxyInfo ? proxyInfo.pager.currentPage : null,
|
|
pageSize: proxyInfo ? proxyInfo.pager.pageSize : null,
|
|
ids:
|
|
options.mode === 'selected'
|
|
? options.data.map((item) => item.id)
|
|
: [],
|
|
includeFields: options.columns.map((column) => {
|
|
return column.field;
|
|
}),
|
|
};
|
|
await onExport(body);
|
|
},
|
|
},
|
|
headerCellStyle: { backgroundColor: '#fafafa' },
|
|
spanMethod({ row, rowIndex, column, visibleData }) {
|
|
const spanFields = ['projectName', 'customerName'];
|
|
let columnField = column.field as string;
|
|
const mergeFields = [
|
|
'serialNo',
|
|
'status',
|
|
'businessStatus',
|
|
'businessOwnerName',
|
|
'technicalOwnerAName',
|
|
'technicalOwnerBName',
|
|
'startTime',
|
|
];
|
|
if (mergeFields.includes(columnField)) {
|
|
// 字段与前面的合并方式相同
|
|
columnField = 'projectName';
|
|
}
|
|
const cellValue = (row as Record<string, any>)[columnField];
|
|
if (cellValue && spanFields.includes(columnField)) {
|
|
const prevRow = visibleData[rowIndex - 1];
|
|
let nextRow = visibleData[rowIndex + 1];
|
|
if (
|
|
prevRow &&
|
|
(prevRow as Record<string, any>)[columnField] === cellValue
|
|
) {
|
|
return { rowspan: 0, colspan: 0 };
|
|
} else {
|
|
let countRowspan = 1;
|
|
while (
|
|
nextRow &&
|
|
(nextRow as Record<string, any>)[columnField] === cellValue
|
|
) {
|
|
nextRow = visibleData[++countRowspan + rowIndex];
|
|
}
|
|
if (countRowspan > 1) {
|
|
return { rowspan: countRowspan, colspan: 1 };
|
|
}
|
|
}
|
|
}
|
|
},
|
|
} as VxeTableGridOptions<any>,
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<Grid table-title="项目进展">
|
|
<template #contentDefault="{ row }">
|
|
<!-- <div v-html="row.content" style="white-space: pre-wrap"></div> -->
|
|
<ShadowContainer
|
|
:content="row.content"
|
|
styles="font-family: -apple-system, blinkmacsystemfont, 'Segoe UI', roboto, 'Helvetica Neue',
|
|
arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
|
'Segoe UI Symbol', 'Noto Color Emoji';"
|
|
/>
|
|
</template>
|
|
</Grid>
|
|
</template>
|