Merge remote-tracking branch 'origin/main'

# Conflicts:
#	src/views/sta/index.vue
This commit is contained in:
yy2205 2025-04-22 15:08:20 +08:00
commit 8a6350f102
3 changed files with 514 additions and 1 deletions

View File

@ -21,6 +21,9 @@
<el-button type="primary" @click="getList" style="margin-left: 20px;"> <el-button type="primary" @click="getList" style="margin-left: 20px;">
<Icon icon="ep:search" class="mr-5px" /> 查询 <Icon icon="ep:search" class="mr-5px" /> 查询
</el-button> </el-button>
<el-button type="primary" @click="printData" style="margin-left: 20px;">
<Icon icon="ep:printer" class="mr-5px" /> 打印
</el-button>
<el-button type="primary" @click="exportExcel" style="margin-left: 20px;" <el-button type="primary" @click="exportExcel" style="margin-left: 20px;"
:loading="exportLoading"> :loading="exportLoading">
<Icon icon="ep:search" class="mr-5px" /> 导出excel <Icon icon="ep:search" class="mr-5px" /> 导出excel
@ -55,10 +58,12 @@ import {StatisticsApi} from "@/api/inspect/statistics";
import dayjs from "dayjs"; import dayjs from "dayjs";
import {PatientApi} from "@/api/inspect/inspectpatient"; import {PatientApi} from "@/api/inspect/inspectpatient";
import {formatDate} from "@/utils/formatTime"; import {formatDate} from "@/utils/formatTime";
import workload from './workload';
import { hiprint } from "vue-plugin-hiprint";
import { newHiprintPrintTemplate, preparePrintData } from './printHelper';
import download from "@/utils/download"; import download from "@/utils/download";
const message = useMessage() // const message = useMessage() //
const { t } = useI18n() // const { t } = useI18n() //
const loading = ref(true) // const loading = ref(true) //
const time = ref() // const time = ref() //
const data = ref([ const data = ref([
@ -229,6 +234,106 @@ const exportExcel =async () => {
exportLoading.value = false exportLoading.value = false
} }
} }
/**
* 打印数据
*/
const printData = () => {
try {
//
const hiprintTemplate = newHiprintPrintTemplate("workload", {
template: workload,
settingContainer: "#workloadPrintElementOptionSetting",
});
//
const printData = preparePrintData(data1.value, time.value);
console.log('打印数据:', printData); //
//
const options = {
leftOffset: 0,
topOffset: 0,
paperType: 'A4',
enableColumnsMerge: true,
enableRowsMerge: true,
firstPageTitle: true,
onlyFirstTitle: true,
notAllowRepeat: ['title'],
firstPanelPageOnly: true,
pageMode: 'single',
displayMode: {
title: 'firstPage'
},
printPanelIndex: 0,
noRepeatPrint: false,
disableHeaderRepeat: false
};
//
const ext = {
callback: () => {
console.log("打印窗口已打开");
//
setTimeout(() => {
const table = document.querySelector('.hiprint-printPanel table');
if (table) {
const ths = table.querySelectorAll('th');
ths.forEach((th, index) => {
});
}
}, 100);
},
styleHandler: () => {
return `<style>
@page {
size: A4;
margin: 0;
}
@media print {
body {
margin: 0;
padding: 0;
}
.hiprint-printPanel table th:nth-child(1) b,
.hiprint-printPanel table th:nth-child(2) b {
font-weight: bold !important;
font-size: 10px !important;
}
.hiprint-printPanel table td {
font-size: 10px;
}
td[colspan="0"],
td[rowspan="0"] {
display: none;
}
/* 强制隐藏除第一页外的标题 */
.hiprint-printPanel:not(:first-of-type) [data-options*='"title":"体检工作量统计表"'] {
display: none !important;
visibility: hidden !important;
height: 0 !important;
overflow: hidden !important;
position: absolute !important;
z-index: -1 !important;
}
/* 隐藏除第一页外的表头 */
.hiprint-printPanel:not(:first-of-type) .hiprint-table-header-row {
display: none !important;
}
}
</style>`;
},
};
//
hiprintTemplate.print(printData, options, ext);
console.log('打印成功');
} catch (error) {
console.error('打印失败:', error);
}
}
onMounted(()=>{ onMounted(()=>{
changeRadio(3) changeRadio(3)
// getList() // getList()

View File

@ -0,0 +1,143 @@
import { hiprint } from "vue-plugin-hiprint";
const templateMap = {};
/**
* 创建打印模板
* @param {string} key - 模板唯一标识
* @param {object} options - 模板配置
* @returns {object} 打印模板对象
*/
export function newHiprintPrintTemplate(key, options) {
let template = new hiprint.PrintTemplate(options);
// 添加表头样式
template.on('beforePrint', (data) => {
const table = document.querySelector('.hiprint-printPanel table');
if (table) {
const ths = table.querySelectorAll('th');
ths.forEach(th => {
th.style.fontWeight = 'bold';
th.style.fontSize = '12px';
});
}
});
templateMap[key] = template;
return template;
}
/**
* 获取打印模板
* @param {string} key - 模板唯一标识
* @returns {object} 打印模板对象
*/
export function getHiprintPrintTemplate(key) {
return templateMap[key];
}
/**
* 准备打印数据
* @param {Array} data - 原始数据
* @param {Array} timeRange - 时间范围
* @returns {object} 格式化后的打印数据
*/
export function preparePrintData(data, timeRange) {
// 防错处理
if (!data || !Array.isArray(data)) {
console.error('打印数据格式错误:', data);
return {
table: [],
dateRange: timeRange ? `${timeRange[0]}${timeRange[1]}` : '',
printDate: formatDate(new Date(), 'YYYY-MM-DD'),
printUser: '管理员',
title: '体检工作量统计表'
};
}
try {
// 将树形结构展平为表格结构
const flattenedData = [];
// 处理每个卫生院及其下属的行政村
data.forEach(org => {
if (!org || typeof org !== 'object') return; // 跳过无效数据
// 确保orgname存在
const orgname = org.orgname || '未知卫生院';
// 计算该卫生院下的行政村数量
const villageCount = org.children ? org.children.length : 0;
// 添加卫生院汇总行
flattenedData.push({
orgname: orgname,
districtname: '汇总',
oldmanflag: org.oldmanflag || 0,
htnflag: org.htnflag || 0,
diaflag: org.diaflag || 0,
smiflag: org.smiflag || 0,
pulflag: org.pulflag || 0,
sum: org.sum || 0,
rowspan: villageCount + 1, // 包括汇总行
isFirstRow: true
});
// 添加该卫生院下的所有行政村
if (org.children && Array.isArray(org.children) && org.children.length > 0) {
// 先对子项进行排序,保持数据一致性
const sortedChildren = [...org.children]
.filter(village => village && typeof village === 'object') // 过滤无效数据
.sort((a, b) => (b.sum || 0) - (a.sum || 0));
sortedChildren.forEach((village, index) => {
flattenedData.push({
orgname: '', // 空字符串,不显示卫生院名称
districtname: village.districtname || '未知行政村',
oldmanflag: village.oldmanflag || 0,
htnflag: village.htnflag || 0,
diaflag: village.diaflag || 0,
smiflag: village.smiflag || 0,
pulflag: village.pulflag || 0,
sum: village.sum || 0,
isChild: true
});
});
}
});
console.log('处理后的打印数据:', flattenedData);
return {
table: flattenedData,
dateRange: timeRange ? `${timeRange[0]}${timeRange[1]}` : '',
printDate: formatDate(new Date(), 'YYYY-MM-DD'),
printUser: '管理员',
title: '体检工作量统计表'
};
} catch (error) {
console.error('准备打印数据出错:', error);
return {
table: [],
dateRange: timeRange ? `${timeRange[0]}${timeRange[1]}` : '',
printDate: formatDate(new Date(), 'YYYY-MM-DD'),
printUser: '管理员',
title: '体检工作量统计表'
};
}
}
/**
* 格式化日期
* @param {Date} date - 日期对象
* @param {string} format - 格式
* @returns {string} 格式化后的日期字符串
*/
function formatDate(date, format) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return format
.replace('YYYY', year)
.replace('MM', month)
.replace('DD', day);
}

265
src/views/sta/workload.js Normal file
View File

@ -0,0 +1,265 @@
export default {
panels: [
{
index: 0,
name: 1,
paperType: "A4",
height: 297,
width: 210,
paperHeader: 24,
paperFooter: 805.5,
paperNumberLeft: 565.5,
paperNumberTop: 814.5,
paperNumberDisabled: true,
paperNumberContinue: true,
watermarkOptions: {},
panelLayoutOptions: {
firstPanelTitle: true,
onlyShowFirstPageTitle: true,
tableHeaderOnlyOnFirst: true,
disablePageRepeat: true,
disableHeaderRepeat: true
},
printElements: [
{
options: {
left: 174,
top: 15,
height: 27,
width: 204,
title: "体检工作量统计表",
fontSize: 19,
fontWeight: "600",
textAlign: "center",
lineHeight: 26,
showInPage: "first",
pageIndex: 0,
fixed: true,
onlyShowInFirstPage: true,
panelPaperRule: "first"
},
printElementType: {
title: "自定义文本",
type: "text"
}
},
{
options: {
left: 20,
top: 40,
height: 20,
width: 180,
title: "统计时间",
field: "dateRange",
testData: "2023-01-01 至 2023-12-31",
fontFamily: "微软雅黑",
fontSize: 9,
fontWeight: "600",
textAlign: "left",
repeat: "first"
},
printElementType: { title: "文本", type: "text" }
},
{
options: {
left: 15,
top: 70,
height: 64.5,
width: 555,
field: "table",
coordinateSync: false,
widthHeightSync: false,
right: 565,
bottom: 96,
vCenter: 290,
hCenter: 69,
tableHeaderRowHeight: 30,
tableBodyRowHeight: 30,
tableHeaderRepeat: "first",
noRepeat: false,
tableHeaderStyle: { fontWeight: "bold", fontSize: "12px" },
tableStyle: { border: "1px solid #000" },
rowsColumnsMerge: null,
rowsColumnsMergeClean: true,
columns: [
[
{
width: 70,
title: "<b>卫生院</b>",
field: "orgname",
checked: true,
columnId: "orgname",
fixed: false,
align: "center",
tableColumnHeight: "30",
tableTextType: "text",
tableBarcodeMode: "CODE128A",
tableQRCodeLevel: 0,
tableSummaryTitle: true,
tableSummary: "",
tableHeaderStyle: { fontSize: "10px" },
tableBodyStyle: { fontSize: "10px" }
},
{
width: 70,
title: "<b>行政村</b>",
field: "districtname",
checked: true,
columnId: "districtname",
fixed: false,
align: "center",
tableColumnHeight: "30",
tableTextType: "text",
tableBarcodeMode: "CODE128A",
tableQRCodeLevel: 0,
tableSummaryTitle: true,
tableSummary: "",
tableHeaderStyle: { fontSize: "10px" },
tableBodyStyle: { fontSize: "10px" }
},
{
width: 40,
title: "<b>老年人</b>",
field: "oldmanflag",
checked: true,
columnId: "oldmanflag",
fixed: false,
align: "center",
tableColumnHeight: "30",
tableTextType: "text",
tableBarcodeMode: "CODE128A",
tableQRCodeLevel: 0,
tableSummaryTitle: true,
tableSummary: "",
tableHeaderStyle: { fontSize: "10px" },
tableBodyStyle: { fontSize: "10px" }
},
{
width: 40,
title: "<b>高血压</b>",
field: "htnflag",
checked: true,
columnId: "htnflag",
fixed: false,
align: "center",
tableColumnHeight: "30",
tableTextType: "text",
tableBarcodeMode: "CODE128A",
tableQRCodeLevel: 0,
tableSummaryTitle: true,
tableSummary: "",
tableHeaderStyle: { fontSize: "10px" },
tableBodyStyle: { fontSize: "10px" }
},
{
width: 40,
title: "<b>糖尿病</b>",
field: "diaflag",
checked: true,
columnId: "diaflag",
fixed: false,
align: "center",
tableColumnHeight: "30",
tableTextType: "text",
tableBarcodeMode: "CODE128A",
tableQRCodeLevel: 0,
tableSummaryTitle: true,
tableSummary: "",
tableHeaderStyle: { fontSize: "10px" },
tableBodyStyle: { fontSize: "10px" }
},
{
width: 40,
title: "<b>精神病</b>",
field: "smiflag",
checked: true,
columnId: "smiflag",
fixed: false,
align: "center",
tableColumnHeight: "30",
tableTextType: "text",
tableBarcodeMode: "CODE128A",
tableQRCodeLevel: 0,
tableSummaryTitle: true,
tableSummary: "",
tableHeaderStyle: { fontSize: "10px" },
tableBodyStyle: { fontSize: "10px" }
},
{
width: 40,
title: "<b>肺结核</b>",
field: "pulflag",
checked: true,
columnId: "pulflag",
fixed: false,
align: "center",
tableColumnHeight: "30",
tableTextType: "text",
tableBarcodeMode: "CODE128A",
tableQRCodeLevel: 0,
tableSummaryTitle: true,
tableSummary: "",
tableHeaderStyle: { fontSize: "10px" },
tableBodyStyle: { fontSize: "10px" }
},
{
width: 40,
title: "<b>总数</b>",
field: "sum",
checked: true,
columnId: "sum",
fixed: false,
align: "center",
tableColumnHeight: "30",
tableTextType: "text",
tableBarcodeMode: "CODE128A",
tableQRCodeLevel: 0,
tableSummaryTitle: true,
tableSummary: "",
tableHeaderStyle: { fontSize: "10px" },
tableBodyStyle: { fontSize: "10px" }
}
]
]
},
printElementType: {
title: "表格",
type: "table",
editable: true,
columnDisplayEditable: true,
columnDisplayIndexEditable: true,
columnTitleEditable: true,
columnResizable: true,
columnAlignEditable: true,
isEnableEditField: true,
isEnableContextMenu: true,
isEnableInsertRow: true,
isEnableDeleteRow: true,
isEnableInsertColumn: true,
isEnableDeleteColumn: true,
isEnableMergeCell: true
}
},
{
options: {
left: 455,
top: 150,
height: 20,
width: 150,
title: "签字确认:",
fontSize: 12,
fontWeight: "600",
textAlign: "left",
showInPage: "last",
pageIndex: 0,
fixed: false
},
printElementType: {
title: "自定义文本",
type: "text"
}
}
]
}
]
};