学生信息页面完善
This commit is contained in:
274
src/views/basic/basicstudent/components/StudentIdCardPrint.vue
Normal file
274
src/views/basic/basicstudent/components/StudentIdCardPrint.vue
Normal file
@@ -0,0 +1,274 @@
|
||||
<template>
|
||||
<el-dialog title="学生证件照打印" v-model="visible" :close-on-click-modal="false" draggable fullscreen>
|
||||
<div class="print-container" ref="printRef">
|
||||
<div class="print-actions" v-if="!isPrinting">
|
||||
<el-button type="primary" icon="Printer" @click="handlePrint">打印</el-button>
|
||||
<el-button @click="visible = false">关闭</el-button>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading" class="print-content">
|
||||
<div class="print-page" v-for="(page, pageIndex) in printPages" :key="pageIndex">
|
||||
<div class="card-wrapper" v-for="(item, cardIndex) in page" :key="cardIndex" :style="getBackgroundStyle(item)">
|
||||
<!-- 头像区域 -->
|
||||
<div class="photo-area">
|
||||
<img :src="item.photo || defaultAvatar" class="student-photo" />
|
||||
</div>
|
||||
|
||||
<!-- 二维码和学生信息区域 -->
|
||||
<div class="info-area">
|
||||
<div class="qrcode-wrapper">
|
||||
<img :src="item.ava || item.qrCode" class="qrcode-img" />
|
||||
</div>
|
||||
<div class="student-info">
|
||||
<ul>
|
||||
<li>姓名:{{ item.realName || '-' }}</li>
|
||||
<li>班级:{{ item.className || '-' }}</li>
|
||||
<li>系部:{{ item.deptName || '-' }}</li>
|
||||
<li>学号:{{ item.stuNo || '-' }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="StudentIdCardPrint">
|
||||
import { ref, computed } from 'vue';
|
||||
import { preBatchPrint, prePrint } from '/@/api/basic/basicstudent';
|
||||
import { useMessage } from '/@/hooks/message';
|
||||
|
||||
// 默认头像
|
||||
const defaultAvatar = '/img/avatar-default.png';
|
||||
|
||||
// 定义变量
|
||||
const visible = ref(false);
|
||||
const loading = ref(false);
|
||||
const isPrinting = ref(false);
|
||||
const printRef = ref();
|
||||
const studentList = ref<any[]>([]);
|
||||
|
||||
// 计算打印页面(每页4个学生)
|
||||
const printPages = computed(() => {
|
||||
const pages: any[][] = [];
|
||||
const students = studentList.value;
|
||||
const totalPages = Math.ceil(students.length / 4);
|
||||
|
||||
for (let i = 0; i < totalPages; i++) {
|
||||
const pageStudents = students.slice(i * 4, (i + 1) * 4);
|
||||
pages.push(pageStudents);
|
||||
}
|
||||
|
||||
return pages;
|
||||
});
|
||||
|
||||
// 获取背景样式
|
||||
const getBackgroundStyle = (item: any) => {
|
||||
if (item.roomNo) {
|
||||
return "background-image: url('/img/bg/zss.jpeg');";
|
||||
}
|
||||
return "background-image: url('/img/bg/userphotobg.jpg');";
|
||||
};
|
||||
|
||||
// 打开弹窗 - 批量打印(传入选中的学生完整JSON数据)
|
||||
const openDialog = async (selectedRows: any[]) => {
|
||||
if (!selectedRows || selectedRows.length === 0) {
|
||||
useMessage().warning('请先选择要打印的学生');
|
||||
return;
|
||||
}
|
||||
|
||||
visible.value = true;
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
// 调用后端接口,传入选中的学生完整数据
|
||||
const res = await preBatchPrint(selectedRows);
|
||||
if (res.data && Array.isArray(res.data)) {
|
||||
studentList.value = res.data;
|
||||
} else {
|
||||
// 如果后端没有返回数据,直接使用前端数据
|
||||
studentList.value = selectedRows;
|
||||
}
|
||||
} catch (err: any) {
|
||||
// 如果接口报错,直接使用前端数据
|
||||
studentList.value = selectedRows;
|
||||
console.warn('获取打印数据失败,使用前端数据', err);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 打开弹窗 - 单个学生打印
|
||||
const openSingleDialog = async (row: any) => {
|
||||
if (!row.stuNo) {
|
||||
useMessage().warning('学号不存在');
|
||||
return;
|
||||
}
|
||||
|
||||
visible.value = true;
|
||||
loading.value = true;
|
||||
|
||||
try {
|
||||
const res = await prePrint(row.stuNo);
|
||||
if (res.data) {
|
||||
studentList.value = [res.data];
|
||||
} else {
|
||||
studentList.value = [row];
|
||||
}
|
||||
} catch (err: any) {
|
||||
studentList.value = [row];
|
||||
console.warn('获取打印数据失败,使用前端数据', err);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 执行打印
|
||||
const handlePrint = () => {
|
||||
isPrinting.value = true;
|
||||
setTimeout(() => {
|
||||
window.print();
|
||||
isPrinting.value = false;
|
||||
}, 100);
|
||||
};
|
||||
|
||||
// 暴露方法
|
||||
defineExpose({
|
||||
openDialog,
|
||||
openSingleDialog,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.print-container {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.print-actions {
|
||||
position: fixed;
|
||||
top: 80px;
|
||||
right: 80px;
|
||||
z-index: 100;
|
||||
background: #fff;
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.print-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.print-page {
|
||||
width: 29.7cm;
|
||||
height: 19.2cm;
|
||||
margin: 0 auto 20px;
|
||||
page-break-after: always;
|
||||
|
||||
&:last-child {
|
||||
page-break-after: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.card-wrapper {
|
||||
width: 7cm;
|
||||
height: 10cm;
|
||||
border: 1px #0508b8 solid;
|
||||
margin-left: 5cm;
|
||||
margin-top: 0.3cm;
|
||||
margin-bottom: 0.3cm;
|
||||
float: left;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 100% auto;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.photo-area {
|
||||
width: 2.5cm;
|
||||
margin: 0 auto;
|
||||
height: 5.8cm;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.student-photo {
|
||||
width: 2.5cm;
|
||||
height: 3cm;
|
||||
object-fit: cover;
|
||||
margin-top: 2cm;
|
||||
}
|
||||
|
||||
.info-area {
|
||||
width: 6.5cm;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.qrcode-wrapper {
|
||||
width: 2.5cm;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.qrcode-img {
|
||||
width: 2.5cm;
|
||||
height: 2.5cm;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.student-info {
|
||||
width: 4cm;
|
||||
flex-shrink: 0;
|
||||
|
||||
ul {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
line-height: 23px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
.print-actions {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__header),
|
||||
:deep(.el-dialog__footer) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
:deep(.el-dialog) {
|
||||
margin: 0 !important;
|
||||
max-width: 100% !important;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.print-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.print-page {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
-webkit-print-color-adjust: exact;
|
||||
-moz-print-color-adjust: exact;
|
||||
-ms-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -226,6 +226,9 @@
|
||||
<!-- 简单信息维护对话框 -->
|
||||
<SimpleEditDialog ref="simpleEditDialogRef" @refresh="getDataList(false)" />
|
||||
|
||||
<!-- 学生证件照打印 -->
|
||||
<PrintDialog ref="printDialogRef" />
|
||||
|
||||
<!-- 段段清证书导入对话框 -->
|
||||
<el-dialog title="段段清证书导入" v-model="importCertificateDialogVisible" :close-on-click-modal="false" draggable width="500px">
|
||||
<el-upload
|
||||
@@ -335,7 +338,7 @@ import {
|
||||
preBatchPrint,
|
||||
importCertificate,
|
||||
exportStuInfoCard,
|
||||
exportCertificate,
|
||||
makeExportSkillLevelTask,
|
||||
resetPassWord,
|
||||
editIsleader,
|
||||
updateInout,
|
||||
@@ -355,12 +358,14 @@ import { makeExportClassRoomHygieneMonthlyTask } from '/@/api/stuwork/file';
|
||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||
const DetailDialog = defineAsyncComponent(() => import('./components/StudentDetail.vue'));
|
||||
const SimpleEditDialog = defineAsyncComponent(() => import('./components/SimpleEdit.vue'));
|
||||
const PrintDialog = defineAsyncComponent(() => import('./components/StudentIdCardPrint.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const route = useRoute();
|
||||
const formDialogRef = ref();
|
||||
const detailDialogRef = ref();
|
||||
const simpleEditDialogRef = ref();
|
||||
const printDialogRef = ref();
|
||||
const searchFormRef = ref();
|
||||
const uploadRef = ref();
|
||||
const columnControlRef = ref();
|
||||
@@ -731,8 +736,12 @@ const handleExportAvatar = async () => {
|
||||
};
|
||||
|
||||
// 批量打印
|
||||
const handleBatchPrint = async () => {
|
||||
useMessage().warning('功能开发中');
|
||||
const handleBatchPrint = () => {
|
||||
if (selectedRows.value.length === 0) {
|
||||
useMessage().warning('请先选择要打印的学生');
|
||||
return;
|
||||
}
|
||||
printDialogRef.value?.openDialog(selectedRows.value);
|
||||
};
|
||||
|
||||
// 段段清证书导入
|
||||
@@ -808,7 +817,15 @@ const handleExportStudentCard = async () => {
|
||||
|
||||
// 证书导出
|
||||
const handleExportCertificate = async () => {
|
||||
useMessage().warning('功能开发中');
|
||||
try {
|
||||
await makeExportSkillLevelTask({
|
||||
deptCode: searchForm.deptCode,
|
||||
classCode: searchForm.classCode,
|
||||
});
|
||||
useMessage().success('导出任务已创建,请在文件管理中下载');
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '创建导出任务失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 简单信息维护
|
||||
@@ -822,38 +839,8 @@ const handleViewDetail = (row: any) => {
|
||||
};
|
||||
|
||||
// 打印证件照
|
||||
const handlePrintPhoto = async (row: any) => {
|
||||
if (!row.stuNo) {
|
||||
useMessage().warning('学号不存在');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const res = await prePrint(row.stuNo);
|
||||
if (res.data) {
|
||||
// 打开新窗口进行打印
|
||||
const printWindow = window.open('', '_blank');
|
||||
if (printWindow) {
|
||||
printWindow.document.write(`
|
||||
<html>
|
||||
<head><title>学生证件照打印</title></head>
|
||||
<body>
|
||||
<h2 style="text-align:center;">学生证打印</h2>
|
||||
<div style="text-align:center;">
|
||||
<p><strong>姓名:</strong>${res.data.realName || row.realName || '-'}</p>
|
||||
<p><strong>学号:</strong>${res.data.stuNo || row.stuNo || '-'}</p>
|
||||
<p><strong>班级:</strong>${res.data.className || row.className || '-'}</p>
|
||||
<p><strong>身份证号:</strong>${res.data.idCard || row.idCard || '-'}</p>
|
||||
</div>
|
||||
<script>window.onload = function() { window.print(); }<\/script>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
printWindow.document.close();
|
||||
}
|
||||
}
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '获取打印信息失败');
|
||||
}
|
||||
const handlePrintPhoto = (row: any) => {
|
||||
printDialogRef.value?.openSingleDialog(row);
|
||||
};
|
||||
|
||||
// 重置密码
|
||||
|
||||
Reference in New Issue
Block a user