Files
geg-gas-web/src/views/workflow/task/components/print/FormPrint.vue

263 lines
7.8 KiB
Vue
Raw Normal View History

2024-02-05 09:15:37 +08:00
<template>
<a-modal
v-model:visible="visible"
title="打印预览"
width="100%"
wrap-class-name="full-modal"
:bodyStyle="{ padding: '10px' }"
@cancel="emits('update:isShowPrint', false)"
>
<div class="btn-box">
<a-button style="color: #606266; font-size: 13px" @click="handlePrint">
<template #icon>
<PrinterOutlined />
</template>
打印
</a-button>
</div>
<div v-if="printData?.style === '1' && !!configs?.formProps">
<SimpleForm
class="print-style1-box"
:formProps="configs?.formProps"
:formModel="configs?.formModel"
:isWorkFlow="true"
/>
</div>
<div :class="`print-style${props.printData?.style}-box`" v-else>
<template v-for="(item, index) in formInfo" :key="index">
<TableStyle :item="item" :componentType="item.type" />
</template>
</div>
</a-modal>
</template>
<script lang="ts" setup>
import { ref, computed, Ref, StyleValue, provide, inject, onMounted } from 'vue';
import SimpleForm from '/@/components/SimpleForm/src/SimpleForm.vue';
import TableStyle from './TableStyle.vue';
import { getUserMulti } from '/@/api/system/user';
import { getDicItemDetail } from '/@/api/system/dic';
import { getDepartment } from '/@/api/system/department';
import { getAreaMulti } from '/@/api/system/area';
import { PrinterOutlined } from '@ant-design/icons-vue';
import { buildComponentType } from '/@/utils/helper/designHelper';
import html2canvas from 'html2canvas';
import printJS from 'print-js';
import { cloneDeep, isNil } from 'lodash-es';
import domtoimage from 'dom-to-image';
const props = defineProps({
formConfigs: Object,
printData: Object,
isShowPrint: Boolean,
});
const emits = defineEmits(['update:isShowPrint']);
const configs = ref({
formProps: {} as any,
formModel: {},
});
const formInfo = ref<any>([]);
const activeKey = inject<Ref<number>>('tabActiveKey');
const visible = ref<boolean>(props.isShowPrint);
const borderColorStyle = computed(() => {
return { 'border-color': `${props.printData?.borderColor} !important` };
});
const underlineStyle = computed(() => {
return { 'border-bottom': props.printData?.underline === '1' ? '1px solid' : 0 };
});
provide<Ref<StyleValue>>('borderColorStyle', borderColorStyle);
provide<Ref<StyleValue>>('underlineStyle', underlineStyle);
onMounted(async () => {
configs.value.formProps = cloneDeep(props.formConfigs?.formProps);
formInfo.value = [];
if (props.printData?.style !== '1') {
await changeFormat(configs.value.formProps.schemas, formInfo.value);
}
});
configs.value.formModel = cloneDeep(props.formConfigs?.formModel);
const handlePrint = async () => {
let element: HTMLElement = window.document.querySelector(
`.print-style${props.printData?.style || 1}-box`,
)!;
let url;
if (props.printData?.style === '1') {
url = await domtoimage.toPng(element);
} else {
let canvas = await html2canvas(element, {
backgroundColor: null,
useCORS: true,
windowHeight: document.body.scrollHeight,
});
url = canvas.toDataURL();
}
printJS({
printable: url,
type: 'image',
documentTitle: '打印',
});
};
const changeFormat = async (schemas, info) => {
if (!configs.value) return;
const keys = Object.keys(configs.value.formModel);
for (const item of schemas) {
if (['tab', 'grid', 'card'].includes(item.type)) {
const layoutChildren = {};
for (let index = 0; index < item.children.length; index++) {
const name =
item.type === 'grid'
? index
: item.type === 'card'
? item.componentProps?.title
: item.children[index].name;
layoutChildren[name] = [];
if ((index === activeKey?.value && item.type === 'tab') || item.type !== 'tab') {
await changeFormat(item.children[index].list, layoutChildren[name]);
}
}
info.push({
type: item.type,
value: layoutChildren,
});
} else if (item.type === 'form') {
if (keys.includes(item.componentProps.mainKey)) {
// const children: object[] = [];
// configs.value.formModel[item.componentProps.mainKey].forEach((sub) => {
// const subInfo = {};
// item.componentProps.columns.forEach((col) => {
// if (Object.keys(sub).includes(col.dataIndex) && !!col.show) {
// subInfo[col.title] = sub[col.dataIndex];
// }
// });
// children.push(subInfo);
// });
const columns: any[] = [];
const value: any[] = [];
configs.value.formModel[item.componentProps.mainKey].forEach((sub) => {
let val = {};
item.componentProps.columns.forEach(async (col) => {
if (Object.keys(sub).includes(col.dataIndex) && !!col.show) {
if (!columns.map((x) => x.key).includes(col.dataIndex)) {
columns.push({
title: col.title,
key: col.dataIndex,
dataIndex: col.dataIndex,
});
}
val[col.dataIndex] = await changeValue(col, sub[col.dataIndex]);
}
});
value.push(val);
});
info.push({
type: item.type,
label: item.label,
value,
columns,
});
}
} else if (keys.includes(item.field) && !!item.show) {
let value = await changeValue(item, configs.value.formModel[item.field]);
info.push({
label: item.label,
type: item.type,
componentProps: item.componentProps,
value,
});
}
}
};
const changeValue = async (item, fieldValue) => {
const type = item.type ? buildComponentType(item.type) : item.componentType;
if (isNil(fieldValue)) return fieldValue;
if (type === 'User' || (type === 'Info' && item.componentProps?.infoType === 0)) {
const res = await getUserMulti(fieldValue);
return res?.map((x) => x.name).toString();
} else if (type === 'Dept' || (type === 'Info' && item.componentProps?.infoType === 1)) {
const res = await getDepartment(fieldValue);
return res?.name;
} else if (type === 'Area') {
const res = await getAreaMulti(fieldValue);
return res?.map((x) => x.name).join(' / ');
} else if (item.componentProps?.datasourceType === 'dic') {
const res = await getDicItemDetail(item.componentProps?.params.itemId, fieldValue);
return res?.map((x) => x.name).toString();
}
return fieldValue;
};
</script>
<style lang="less" scoped>
.btn-box {
width: 100%;
text-align: right;
margin-bottom: 10px;
}
.borderClass {
border: 0 !important;
}
.print-style2-box,
.print-style3-box,
.print-style4-box {
margin: 10px 20px;
:deep(.ant-row) {
font-size: 16px;
border: 1px solid !important;
.ant-col {
padding: 15px 5px;
}
}
}
.print-style3-box {
:deep(.ant-col:last-child) {
border-left: 0 !important;
}
}
.print-style2-box {
:deep(.ant-col:first-child) {
border-right: 1px solid;
}
}
.print-style4-box {
:deep(.ant-row) {
border-left: 0 !important;
border-right: 0 !important;
border-top: 0 !important;
}
}
</style>
<style lang="less">
.full-modal {
.ant-modal {
max-width: 100%;
top: 0 !important;
padding-bottom: 0;
margin: 0;
height: 100%;
}
.ant-modal-content {
display: flex;
flex-direction: column;
min-height: 100%;
}
.ant-modal-body {
flex: 1;
}
.ant-modal-footer {
display: none !important;
}
}
</style>