学生信息页面完善

This commit is contained in:
yaojian
2026-03-10 18:32:48 +08:00
parent 33b228da9a
commit 15d9ca27eb
75 changed files with 301 additions and 42 deletions

BIN
public/img/bg/003.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 419 KiB

BIN
public/img/bg/12345.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

BIN
public/img/bg/bf.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
public/img/bg/bfnew.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
public/img/bg/cglz.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
public/img/bg/cgsq.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
public/img/bg/city.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
public/img/bg/cloud.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
public/img/bg/czLogin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

BIN
public/img/bg/db.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

BIN
public/img/bg/inExam.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
public/img/bg/lyys.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
public/img/bg/outExam.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

BIN
public/img/bg/ten_logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
public/img/bg/ten_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

BIN
public/img/bg/ybf.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

BIN
public/img/bg/zss.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

BIN
public/img/chartImg/1.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
public/img/chartImg/2.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

BIN
public/img/chartImg/3.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

BIN
public/img/chartImg/4.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
public/img/chartImg/5.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
public/img/chartImg/6.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
public/img/chartImg/7.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
public/img/chartImg/8.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
public/img/chartImg/9.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
public/img/dormRoom/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
public/img/enroll/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

BIN
public/img/login/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

BIN
public/img/pdf/more_big.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/img/pdf/pre_icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

BIN
public/img/test/bydkl.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 KiB

BIN
public/img/test/bylcl.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

BIN
public/img/test/gwlx.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

BIN
public/img/test/jyxstj.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

BIN
public/img/test/qddk.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

BIN
public/img/test/shpxrs.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 294 KiB

BIN
public/img/test/xszcrs.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

BIN
public/img/test/xydsjjc.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 KiB

BIN
public/img/test/zbtj.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

View File

@@ -530,15 +530,13 @@ export const importCertificate = (formData: FormData) => {
}; };
/** /**
* 证书导出 * 创建证书导出异步任务
* @param data * @param data 查询参数
* TODO: 接口文档中未找到此接口,请提供正确的接口地址
*/ */
export const exportCertificate = (data: any) => { export const makeExportSkillLevelTask = (data?: any) => {
return request({ return request({
url: '/basic/basicstudent/exportCertificate', // TODO: 接口文档中未找到此接口 url: '/ems/file/makeExportSkillLevelTask',
method: 'post', method: 'post',
data: data, data: data,
responseType: 'blob',
}); });
}; };

View 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>

View File

@@ -226,6 +226,9 @@
<!-- 简单信息维护对话框 --> <!-- 简单信息维护对话框 -->
<SimpleEditDialog ref="simpleEditDialogRef" @refresh="getDataList(false)" /> <SimpleEditDialog ref="simpleEditDialogRef" @refresh="getDataList(false)" />
<!-- 学生证件照打印 -->
<PrintDialog ref="printDialogRef" />
<!-- 段段清证书导入对话框 --> <!-- 段段清证书导入对话框 -->
<el-dialog title="段段清证书导入" v-model="importCertificateDialogVisible" :close-on-click-modal="false" draggable width="500px"> <el-dialog title="段段清证书导入" v-model="importCertificateDialogVisible" :close-on-click-modal="false" draggable width="500px">
<el-upload <el-upload
@@ -335,7 +338,7 @@ import {
preBatchPrint, preBatchPrint,
importCertificate, importCertificate,
exportStuInfoCard, exportStuInfoCard,
exportCertificate, makeExportSkillLevelTask,
resetPassWord, resetPassWord,
editIsleader, editIsleader,
updateInout, updateInout,
@@ -355,12 +358,14 @@ import { makeExportClassRoomHygieneMonthlyTask } from '/@/api/stuwork/file';
const FormDialog = defineAsyncComponent(() => import('./form.vue')); const FormDialog = defineAsyncComponent(() => import('./form.vue'));
const DetailDialog = defineAsyncComponent(() => import('./components/StudentDetail.vue')); const DetailDialog = defineAsyncComponent(() => import('./components/StudentDetail.vue'));
const SimpleEditDialog = defineAsyncComponent(() => import('./components/SimpleEdit.vue')); const SimpleEditDialog = defineAsyncComponent(() => import('./components/SimpleEdit.vue'));
const PrintDialog = defineAsyncComponent(() => import('./components/StudentIdCardPrint.vue'));
// 定义变量内容 // 定义变量内容
const route = useRoute(); const route = useRoute();
const formDialogRef = ref(); const formDialogRef = ref();
const detailDialogRef = ref(); const detailDialogRef = ref();
const simpleEditDialogRef = ref(); const simpleEditDialogRef = ref();
const printDialogRef = ref();
const searchFormRef = ref(); const searchFormRef = ref();
const uploadRef = ref(); const uploadRef = ref();
const columnControlRef = ref(); const columnControlRef = ref();
@@ -731,8 +736,12 @@ const handleExportAvatar = async () => {
}; };
// 批量打印 // 批量打印
const handleBatchPrint = async () => { const handleBatchPrint = () => {
useMessage().warning('功能开发中'); if (selectedRows.value.length === 0) {
useMessage().warning('请先选择要打印的学生');
return;
}
printDialogRef.value?.openDialog(selectedRows.value);
}; };
// 段段清证书导入 // 段段清证书导入
@@ -808,7 +817,15 @@ const handleExportStudentCard = async () => {
// 证书导出 // 证书导出
const handleExportCertificate = 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) => { const handlePrintPhoto = (row: any) => {
if (!row.stuNo) { printDialogRef.value?.openSingleDialog(row);
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 || '获取打印信息失败');
}
}; };
// 重置密码 // 重置密码