初始版本提交
This commit is contained in:
262
src/views/workflow/task/components/print/FormPrint.vue
Normal file
262
src/views/workflow/task/components/print/FormPrint.vue
Normal file
@ -0,0 +1,262 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user