<template>
|
<el-dialog
|
:model-value="modelValue"
|
@update:model-value="handleDialogChange"
|
title="巡查单据下载打印"
|
class="dialog-wrapper"
|
v-loading="loading"
|
>
|
<el-scrollbar
|
ref="scrollbarRef"
|
height="50vh"
|
v-loading="loading"
|
:always="true"
|
>
|
<el-checkbox-group v-model="checkList">
|
<el-space direction="vertical" alignment="flex-start" fill>
|
<el-checkbox
|
v-for="(item, index) in sceneInfoList"
|
:key="item.scense.guid"
|
:value="index"
|
:class="(item.invalid ? 'checkbox-invalid' : '') + ' checkbox'"
|
>
|
<div>
|
<el-text size="large">{{ item.scense.name }}</el-text>
|
</div>
|
<div class="m-t-4">
|
<el-text size="small">{{
|
'地址:' + item.scense.location
|
}}</el-text>
|
</div>
|
<el-row justify="space-between">
|
<el-space class="m-t-4">
|
<el-tag>
|
{{
|
item.scense.cityname +
|
item.scense.districtname +
|
item.scense.townname
|
}}
|
</el-tag>
|
<el-tag>{{ item.scense.type }}</el-tag>
|
</el-space>
|
<el-button
|
type="default"
|
size="small"
|
class="m-t-4"
|
icon="IconPrinter"
|
@click="handlePreview(item)"
|
>
|
</el-button>
|
</el-row>
|
</el-checkbox>
|
</el-space>
|
</el-checkbox-group>
|
</el-scrollbar>
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button type="danger" @click="cancel" icon="CloseBold"
|
>取消</el-button
|
>
|
<el-button
|
type="primary"
|
:loading="docLoading"
|
icon="Download"
|
:disabled="checkList.length == 0"
|
@click="handelDownload"
|
>
|
下载所选
|
</el-button>
|
<el-button
|
type="default"
|
:loading="docLoading"
|
:disabled="checkList.length == 0"
|
@click="handlePreview()"
|
icon="IconPrinter"
|
>
|
<el-space>
|
打印所选
|
</el-space>
|
</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
<el-dialog v-model="previewVisible" :show-close="false" fullscreen>
|
<template #header="{ close, titleId, titleClass }">
|
<el-row justify="end">
|
<el-button type="danger" @click="close" icon="CircleCloseFilled">
|
关闭
|
</el-button>
|
<el-button
|
type="primary"
|
@click="handelPrint(refWord)"
|
icon="IconPrinter"
|
>
|
打印
|
</el-button>
|
</el-row>
|
</template>
|
<div ref="refWord">
|
<div
|
:id="`word-preview-${i}`"
|
v-for="(item, i) in previewList"
|
:key="item"
|
></div>
|
</div>
|
<!-- <iframe ref="pdfPreview" width="100%" height="100vh" style="height: calc(100vh - 60px);"></iframe> -->
|
</el-dialog>
|
</template>
|
<script setup>
|
/**
|
* 场景巡查单据自动下载
|
*/
|
import { ref, watch } from 'vue';
|
import { useRouter } from 'vue-router';
|
import {
|
exportDocx,
|
prepareDocxBlob,
|
preparePdf,
|
previewDocx,
|
downloadDocx,
|
print
|
} from '@/utils/doc';
|
import sceneApi from '@/api/fysp/sceneApi';
|
|
const props = defineProps({
|
// 对话框开关
|
modelValue: Boolean,
|
// 场景基础信息数组
|
value: Array,
|
previewElement: String
|
});
|
|
const emits = defineEmits(['update:modelValue']);
|
|
const router = useRouter();
|
|
const refWord = ref(null);
|
const pdfPreview = ref(null);
|
|
const loading = ref(false);
|
const scrollbarRef = ref();
|
const sceneInfoList = ref([]);
|
const checkList = ref([]);
|
const docLoading = ref(false);
|
|
// 预览对话框开关
|
const previewVisible = ref(false);
|
// 预览的文档
|
const previewList = ref([]);
|
|
watch(
|
() => [props.modelValue, props.value],
|
(nV, oV) => {
|
if (nV[0] && nV[1] && nV[1] != oV[1]) {
|
fetchSceneInfo(nV[1]);
|
}
|
}
|
);
|
|
function fetchSceneInfo(sceneIdList) {
|
loading.value = true;
|
sceneInfoList.value = [];
|
checkList.value = [];
|
sceneIdList.forEach((sid) => {
|
sceneApi
|
.getSceneDetail(sid)
|
.then((res) => {
|
sceneInfoList.value.push(res.data);
|
checkList.value.push(sceneInfoList.value.length - 1);
|
|
//场景
|
// if (res.data.scense) sceneInfoList.value = res.data.scense;
|
// if (res.data.subScene) {
|
// formSubScene.value = res.data.subScene;
|
// } else {
|
// formSubScene.value = {
|
// sGuid: formScene.value.guid
|
// };
|
// }
|
})
|
.finally(() => {
|
loading.value = false;
|
scrollbarRef.value.setScrollTop(0);
|
});
|
});
|
}
|
|
function handleDialogChange(value) {
|
emits('update:modelValue', value);
|
}
|
|
function setParam(value, length) {
|
const _value = value ? value : '';
|
const offset = length - _value.length;
|
if (offset > 0) {
|
let str = _value;
|
for (let i = 0; i < offset; i++) {
|
str += ' ';
|
}
|
return str;
|
} else {
|
return _value;
|
}
|
}
|
|
// 格式化场景信息,生成参数结构
|
function parseParam(item) {
|
const selected = item
|
? [item]
|
: sceneInfoList.value.filter((v, i) => {
|
return checkList.value.indexOf(i) != -1;
|
});
|
const param = selected.map((v) => {
|
switch (v.scense.typeid) {
|
// 工地
|
case 1:
|
return {
|
type: v.scense.typeid,
|
params: {
|
district: v.scense.districtname,
|
name: setParam(v.scense.name, 57),
|
employerUnit: setParam(v.scense.csEmployerUnit, 60),
|
constructionUnit: setParam(
|
v.subScene ? v.subScene.csConstructionUnit : '',
|
60
|
),
|
timeRange: setParam(
|
v.subScene && v.subScene.csStartTime
|
? `${v.subScene.csStartTime}至${v.subScene.csEndTime}`
|
: '',
|
40
|
),
|
stage: setParam(v.subScene ? v.subScene.siExtension1 : '', 40),
|
contacts: setParam(v.scense.contacts, 40),
|
contactsTel: setParam(v.scense.contactst, 40),
|
location: setParam(v.scense.location, 90)
|
}
|
};
|
// 餐饮
|
case 5:
|
return {
|
type: v.scense.typeid,
|
params: {
|
district: v.scense.districtname,
|
location: setParam(v.scense.location, 63),
|
name: setParam(v.scense.name, 64),
|
contacts: setParam(v.scense.contacts, 67),
|
contactsTel: setParam(v.scense.contactst, 62)
|
}
|
};
|
// default:
|
// v.invalid = true;
|
// return undefined;
|
}
|
});
|
|
return param;
|
}
|
|
// 根据场景类型,生成对应的word文档
|
function generateDoc(param, callback) {
|
param.map((p, index) => {
|
let template, _param;
|
switch (p.type) {
|
// 工地
|
case 1:
|
template = '/工地巡查单据模板-简版.docx';
|
_param = p.params;
|
break;
|
// 餐饮
|
case 5:
|
template = '/餐饮巡查单据模板.docx';
|
_param = p.params;
|
break;
|
default:
|
break;
|
}
|
prepareDocxBlob(template, _param).then((blob) => {
|
callback(blob, `${_param.name}巡查单据.docx`, index);
|
});
|
});
|
}
|
|
function filePrepare(callback) {
|
const param = parseParam();
|
if (param) {
|
return generateDoc(param, callback);
|
}
|
}
|
|
// 点击下载按钮操作, 下载word文档
|
function handelDownload() {
|
filePrepare((blob, name) => {
|
downloadDocx(blob, name);
|
});
|
}
|
|
// 点击打印按钮操作
|
function handelPrint(ref) {
|
if (ref) {
|
print({
|
ref,
|
// 根据目前使用的docx-preview组件,设置打印样式,主要去除多余的margin和padding,以及阴影效果
|
style: `
|
@page{size:A4;margin: 0 !important;padding:0 !important;}
|
body {margin: 0 !important;padding:0 !important;}
|
header {color: rgb(182, 182, 182);}
|
footer {color: rgb(182, 182, 182);}
|
.docx-wrapper {padding: 0 !important;}
|
.docx {margin-bottom: 0 !important; box-shadow: none !important;}
|
.docx_5 {
|
display: flex;
|
justify-content: space-between;
|
align-items: flex-end;
|
}
|
`
|
});
|
}
|
}
|
|
function handlePreview(item) {
|
// 预览的文档,区分单独打印和打印全部
|
previewList.value = item ? ['0'] : checkList.value;
|
const param = item ? parseParam(item) : parseParam();
|
if (param) {
|
generateDoc(param, (blob, name, index) => {
|
previewVisible.value = true;
|
setTimeout(() => {
|
previewDocx(blob, document.getElementById(`word-preview-${index}`));
|
}, 200);
|
});
|
}
|
}
|
|
// 取消操作
|
function cancel() {
|
// 关闭对话框
|
handleDialogChange(false);
|
}
|
</script>
|
<style scoped>
|
.checkbox {
|
border: var(--el-border);
|
padding: 8px;
|
}
|
.checkbox-invalid {
|
border-color: var(--el-color-error);
|
}
|
:deep(.el-checkbox) {
|
height: auto;
|
}
|
:deep(.el-checkbox__label) {
|
width: 100%;
|
}
|
|
/* 文档字体 */
|
:deep(section.docx) {
|
font-family: '黑体' !important;
|
}
|
/* 文档标题 */
|
:deep(header) {
|
color: rgb(182, 182, 182);
|
}
|
:deep(.docx_5) {
|
display: flex;
|
justify-content: space-between;
|
align-items: flex-end;
|
}
|
|
/* */
|
:deep(footer) {
|
color: rgb(182, 182, 182);
|
}
|
</style>
|