305 lines
8.5 KiB
Vue
305 lines
8.5 KiB
Vue
<!-- PrintTemplate.vue -->
|
||
<template>
|
||
<div>
|
||
<base-dialog v-model="showPrint" title="打印预览" wdith="210mm">
|
||
<div v-loading="showLoading" element-loading-text="正在准备打印数据...">
|
||
<div ref="printContainer" class="print-container" id="print-container">
|
||
<!-- 告知书部分 -->
|
||
<div class="title">文明节俭治丧告知书</div>
|
||
<div class="content">尊敬的服务对象:</div>
|
||
<div class="content" style="text-indent: 7rem">
|
||
您好!感谢您的信任,选择到我司办理治丧业务。为深化殡葬改革,推进移风易俗,现就推行文明节俭治丧有关事宜向您倡导如下:
|
||
</div>
|
||
<div
|
||
class="content"
|
||
style="text-indent: 5rem; padding-right: 15px"
|
||
id="first-content">
|
||
一、文明治丧,节俭办事,革除陈规陋习,抵制封建迷信,提倡厚养薄葬,弘扬精神美德;
|
||
</div>
|
||
<div class="content" style="text-indent: 5rem; padding-right: 15px">
|
||
二、我司为满足个性化需求,提供优质的非基本服务和丧葬用品,请您在自主选择时杜绝铺张浪费,树立文明新风。
|
||
</div>
|
||
|
||
<!-- 服务清单表格 -->
|
||
<div class="title">殡仪服务项目清单</div>
|
||
<table class="service-table service-table-header">
|
||
<tr>
|
||
<td style="width: 60pt">逝者姓名</td>
|
||
<td style="width: 90pt">
|
||
{{ deceased.name || deceased.deceased?.name }}
|
||
</td>
|
||
<td style="width: 60pt">逝者年龄</td>
|
||
<td style="width: 70pt">
|
||
{{ deceased.age ?? deceased.deceased?.age }}
|
||
</td>
|
||
<td style="width: 50pt">购买人</td>
|
||
<td style="width: 80pt">
|
||
{{ deceased.familyName || deceased.deceased?.familyName }}
|
||
</td>
|
||
<td style="width: 80pt">购买人电话</td>
|
||
<td>
|
||
{{ deceased.familyPhone ?? deceased.deceased?.familyPhone }}
|
||
</td>
|
||
</tr>
|
||
</table>
|
||
<table class="service-table">
|
||
<thead>
|
||
<tr>
|
||
<th style="width: 40pt">序号</th>
|
||
<th style="width: 80pt">服务项目</th>
|
||
<th style="width: 35pt">单位</th>
|
||
<th style="width: 35pt">数量</th>
|
||
<th style="width: 60pt">收费标准</th>
|
||
<th style="width: 60pt">小计</th>
|
||
<th colspan="3">备注</th>
|
||
</tr>
|
||
</thead>
|
||
|
||
<tr v-for="(item, index) in services" :key="index">
|
||
<td>{{ index + 1 }}</td>
|
||
<td>{{ item.name }}</td>
|
||
<td>{{ item.unit }}</td>
|
||
<td>{{ item.quantity }}</td>
|
||
<td>{{ item.price }}元</td>
|
||
<td>{{ (item.quantity * item.price).toFixed(2) }}</td>
|
||
<td colspan="3">{{ item.remark }}</td>
|
||
</tr>
|
||
<tr>
|
||
<td colspan="5">总计:{{ total }}元</td>
|
||
<td colspan="2">服务引导员</td>
|
||
<td style="width: 125pt">
|
||
{{ deceased.guide || deceased.deceased?.guide }}
|
||
</td>
|
||
<td style="width: 125px">家属签字</td>
|
||
</tr>
|
||
</table>
|
||
<table class="service-table service-table-footer">
|
||
<tr>
|
||
<td style="width: 60pt">消费确认</td>
|
||
<td>
|
||
<div>
|
||
<span
|
||
class="confirm-text no-border"
|
||
v-for="text in confirmText">
|
||
{{ text }}
|
||
</span>
|
||
</div>
|
||
|
||
<div>
|
||
<span class="confirm-text" v-for="text in confirmText2">
|
||
{{ text }}
|
||
</span>
|
||
<span class="confirm-text">,</span>
|
||
<span
|
||
class="confirm-text"
|
||
style="position: relative; top: 5px"></span>
|
||
<span
|
||
class="confirm-text"
|
||
style="position: relative; top: 5px"></span>
|
||
<span
|
||
class="confirm-text"
|
||
style="position: relative; top: 5px"></span>
|
||
<span class="confirm-text">。</span>
|
||
</div>
|
||
</td>
|
||
<td style="width: 125px"></td>
|
||
</tr>
|
||
</table>
|
||
<div style="width: 100%; text-align: right">
|
||
服务时间:{{ deceased.retail.checkoutDate.split(" ")[0] }}
|
||
</div>
|
||
<!-- 打印按钮 -->
|
||
</div>
|
||
<button class="print-btn" v-print="print">打印单据</button>
|
||
</div>
|
||
</base-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { defaultRetail } from "@/defaultForm/defaultRetail";
|
||
import { computed, nextTick, onMounted, ref, watch } from "vue";
|
||
import api from "@/lib/request";
|
||
|
||
let printContainer = ref();
|
||
let showLoading = ref(true);
|
||
const print = {
|
||
id: "print-container",
|
||
beforeOpenCallback: () => {
|
||
showLoading.value = true;
|
||
},
|
||
closeCallback() {
|
||
showLoading.value = false;
|
||
},
|
||
};
|
||
|
||
let services = ref([]);
|
||
|
||
let total = computed(() => {
|
||
const sum = services.value.reduce((sum, item) => {
|
||
return sum + parseFloat(parseFloat(item.price).toFixed(2)) * item.quantity;
|
||
}, 0);
|
||
return parseFloat(sum.toFixed(2)).toFixed(2); // 最终结果保留两位小数
|
||
});
|
||
|
||
let confirmText = "以上消费项目我已经认真审核,无异议。";
|
||
let confirmText2 = "以上消费项目我已经认真审核";
|
||
|
||
let props = withDefaults(
|
||
defineProps<{
|
||
deceased: RegisForm;
|
||
serviceUrl: string;
|
||
}>(),
|
||
{
|
||
deceased: () => defaultRetail(),
|
||
serviceUrl: "/deceased-retail/selected-service",
|
||
}
|
||
);
|
||
let showPrint = defineModel();
|
||
|
||
watch(
|
||
() => showPrint.value,
|
||
() => {
|
||
showLoading.value = true;
|
||
api()
|
||
.get(props.serviceUrl)
|
||
.then((res) => {
|
||
if (res.code === 200) {
|
||
showLoading.value = false;
|
||
services.value = res.data.list;
|
||
}
|
||
});
|
||
},
|
||
{
|
||
deep: true,
|
||
immediate: true,
|
||
}
|
||
);
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.service-table-header {
|
||
tr td {
|
||
border-bottom: none !important;
|
||
page-break-inside: avoid;
|
||
}
|
||
margin-bottom: -10pt !important;
|
||
}
|
||
.service-table-footer {
|
||
tr td {
|
||
border-top: none !important;
|
||
page-break-inside: avoid;
|
||
}
|
||
margin-top: -10pt !important;
|
||
}
|
||
/* 基础样式 */
|
||
.print-container {
|
||
width: 230mm;
|
||
margin: 0 auto;
|
||
font-size: 14pt;
|
||
color: #000 !important;
|
||
font-family: Microsoft YaHei, "SimSun", serif !important;
|
||
padding: 0 5mm;
|
||
box-sizing: border-box; /* 包含边框计算 */
|
||
size: auto;
|
||
|
||
/* 移除可能引起居中的属性 */
|
||
display: block !important;
|
||
align-items: unset !important;
|
||
justify-content: unset !important;
|
||
}
|
||
|
||
.title {
|
||
font-size: 20pt;
|
||
text-align: center;
|
||
margin-top: 5pt;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.service-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
margin: 10pt 0;
|
||
|
||
td,
|
||
th {
|
||
border: 1pt solid #000; // 使用pt单位
|
||
padding: 0.8mm 1.2mm; // 使用mm单位
|
||
font-size: 10.5pt;
|
||
line-height: 1.5;
|
||
text-align: center;
|
||
}
|
||
}
|
||
|
||
.total {
|
||
font-weight: bold;
|
||
margin: 20px 0;
|
||
text-align: right;
|
||
}
|
||
|
||
.print-btn {
|
||
display: block;
|
||
width: 120px;
|
||
margin: 30px auto;
|
||
padding: 10px;
|
||
background: #007bff;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* 打印媒体查询 */
|
||
@media print {
|
||
/* 重置body和html的布局方式 */
|
||
body,
|
||
html {
|
||
display: block !important;
|
||
height: auto !important;
|
||
margin: 0 !important;
|
||
padding: 0 !important;
|
||
}
|
||
|
||
/* 确保打印容器从顶部开始 */
|
||
.print-container {
|
||
min-height: 297mm; /* A4纸高度 */
|
||
display: block !important;
|
||
vertical-align: top !important;
|
||
position: relative;
|
||
top: 0;
|
||
transform: none !important;
|
||
}
|
||
@page {
|
||
padding: 0 !important;
|
||
margin: 0 !important;
|
||
}
|
||
|
||
/* 移除可能存在的flex布局影响 */
|
||
.el-dialog__wrapper,
|
||
.el-dialog,
|
||
.el-dialog__body {
|
||
display: block !important;
|
||
height: auto !important;
|
||
}
|
||
|
||
/* 移除对话框的padding */
|
||
:deep(.el-dialog__body) {
|
||
padding: 0 !important;
|
||
}
|
||
}
|
||
.confirm-text {
|
||
border: 1px solid #000;
|
||
margin: 0 3px;
|
||
display: inline-block;
|
||
width: 20px;
|
||
height: 20px;
|
||
line-height: 18px;
|
||
}
|
||
.no-border {
|
||
border: 1px solid #fff;
|
||
}
|
||
:deep(.base-dialog .el-dialog__header) {
|
||
padding-bottom: none;
|
||
}
|
||
</style>
|