Compare commits

...

31 Commits

Author SHA1 Message Date
95e7379cfa 入伍保留学籍、外宿申请-审批人修改成电子签名 2025-12-19 15:30:44 +08:00
8f084c2990 Merge branch 'main' of http://47.112.118.149:10082/xgxt_sd/zhxg_pc 2025-12-18 14:28:05 +08:00
9eca505b80 退伍复学表单数据显示 2025-12-18 14:27:52 +08:00
2e5cbc3fa1 入伍申请通过后清除班级功能删除 2025-12-18 12:49:01 +08:00
004e4c5e64 学生鉴定页面解决错别字 2025-12-17 15:58:27 +08:00
b1ad52aa33 入伍申请通过后将班级清空 2025-12-16 11:21:05 +08:00
6ee21d3d98 入伍和外宿申请-已办任务的详情表单数据哦 2025-12-16 10:49:40 +08:00
0ffbd2d804 把上传作证校验去掉了 2025-12-16 00:45:23 +08:00
d8c9f6072a 退伍复学修改 2025-12-15 21:41:44 +08:00
18173200a2 Merge branch 'main' of http://47.112.118.149:10082/xgxt_sd/zhxg_pc 2025-12-15 21:15:27 +08:00
c563cb9536 消息发布代码提交 2025-12-15 21:15:06 +08:00
962704835@qq.com
c75e1a1691 外宿申请-修复附件要上传两次 2025-12-15 20:14:49 +08:00
84146cb9e5 个人画像大屏修改 2025-12-15 13:35:14 +08:00
449172f99d 退伍复学状态按钮调整 2025-12-14 20:49:10 +08:00
b8154312c5 退伍复学状态修改 2025-12-14 17:22:19 +08:00
a1f45eeb1c Merge remote-tracking branch 'origin/main' 2025-12-14 10:42:29 +08:00
4e4978cd32 个人画像大屏修改 2025-12-14 10:41:59 +08:00
962704835@qq.com
a8a3754fce 外宿和入伍申请-状态显示调整 2025-12-12 22:20:27 +08:00
24152cd849 退伍府学退回驳回 2025-12-12 17:56:33 +08:00
d113daae1c 个人画像大屏修改 2025-12-12 17:32:39 +08:00
126f3e6f46 外宿申请-已经有申请记录不能继续申请 2025-12-12 17:13:40 +08:00
18d98cc4df 外宿申请-退回或驳回 2025-12-12 17:09:14 +08:00
241d70bbf7 外宿申请-申请表调整 2025-12-12 16:59:57 +08:00
2b7725ab91 外宿申请-附件回显bug 2025-12-12 11:51:17 +08:00
962704835@qq.com
8042c3d821 外宿申请-审批生成审批记录 2025-12-11 23:41:55 +08:00
962704835@qq.com
c16d4701c2 外宿申请-流程表单 2025-12-11 22:02:38 +08:00
8bf7526b7b 入伍保留学籍-申请表详细 2025-12-11 17:49:22 +08:00
1fa5bcfaa6 调整工作流页面样式 2025-12-11 09:47:23 +08:00
c27c163cf4 入伍保留学籍-附件操作 2025-12-10 17:30:05 +08:00
ce38a6c08d 入伍保留学籍-附件操作 2025-12-10 17:13:41 +08:00
7138f2c394 在校证明表格水印添加 2025-12-10 10:46:26 +08:00
28 changed files with 2827 additions and 1023 deletions

View File

@@ -26,6 +26,15 @@ export function addOutsideAccommodationApproval(data) {
})
}
// 新增或修改外宿申请审批记录
export function addOrUpdateAccommodationApproval(data) {
return request({
url: '/dormitory/outsideAccommodationApproval/addOrUpdate',
method: 'post',
data: data
})
}
// 修改外宿申请审批记录
export function updateOutsideAccommodationApproval(data) {
return request({

View File

@@ -26,6 +26,15 @@ export function addOutsideAccommodationAttachment(data) {
})
}
// 批量外宿申请附件
export function batchAddOutsideAccommodationAttachment(data) {
return request({
url: '/dormitory/outsideAccommodationAttachment/batchAdd',
method: 'post',
data: data
})
}
// 修改外宿申请附件
export function updateOutsideAccommodationAttachment(data) {
return request({
@@ -42,3 +51,12 @@ export function delOutsideAccommodationAttachment(id) {
method: 'post'
})
}
// 删除外宿申请附件
export function deleteOutsideAccommodationAttachmentNameAndStuName(query) {
return request({
url: '/dormitory/outsideAccommodationAttachment/OutsideAccommodationAttachment',
method: 'post',
params: query
})
}

View File

@@ -111,14 +111,6 @@ export function listStuFive(stuNo, params) {
})
}
export function getOwn() {
return request({
method: 'get',
url: '/system/cqScore/getOwn'
})
}
export function listOwnRecord(query) {
return request({
method: 'get',
@@ -177,3 +169,47 @@ export function delCqScore(id) {
method: 'post'
})
}
//查询个人加分项申请
export function getcphiamByOne(stuNo) {
return request({
url: '/system/cqScore/getcphiamByOne/' + stuNo,
method: 'post'
})
}
export function getOwncphiamByOne() {
return request({
url: '/system/cqScore/getOwncphiamByOne',
method: 'get'
})
}
//查询个人素质综合信息
export function getStuData(stuNo) {
return request({
url: '/system/cqScore/getStuData?stuNo=' + stuNo,
method: 'get'
})
}
export function getOwnData() {
return request({
url: '/system/cqScore/getOwnData',
method: 'get'
})
}
//查询综合素质分数
export function getOwn() {
return request({
url: '/system/cqScore/getOwn',
method: 'get'
})
}
export function getStu(stuNo) {
return request({
url: '/system/cqScore/getStu?stuNo='+stuNo,
method: 'get'
})
}

View File

@@ -147,10 +147,3 @@ export function cancelAudit(id) {
})
}
//查询个人加分项申请
export function getcphiamByOne(stuNo) {
return request({
url: '/comprehensive/auditDetails/getcphiamByOne/'+stuNo,
method: 'post'
})
}

View File

@@ -31,9 +31,9 @@
<div v-if="item.status===2" class="el-icon-download file-download" title="下载" @click="downloadFile(item)" />
<div v-if="item.status===2" class="el-icon-delete file-delete" title="删除" @click="deleteFile(item)" />
<div v-if="isImageURL(item.name) && item.status === 2" class="el-icon-picture" title="预览" @click="preview(item)" />
</div>
</div>
<el-image v-show="false" ref="preview"
@@ -41,7 +41,7 @@
:src="hiddenSrc"
:preview-src-list="previewList"
/>
</div>
</template>
@@ -113,7 +113,7 @@ export default {
// 预览
preview(item){
this.hiddenSrc = item.savePath
this.$refs.preview.showViewer = true
},
isImageURL(url) {
@@ -149,9 +149,9 @@ export default {
fileType: this.getFileType(res.trueName), // 文件类型
originalFile: file.file // 原始文件对象(可选)
});
}
}
@@ -254,7 +254,7 @@ export default {
// 关键:触发自定义事件,传递被删除的文件名
// 事件名建议delete-file参数file.name文件名
this.$emit('delete-file', file.name);
this.$emit('delete-file', file.name);
} else {
this.$message.error(res.message)
}
@@ -310,7 +310,7 @@ export default {
width: 100%;
}
.file-item {
white-space: nowrap;
display: flex;
justify-content: start;
@@ -328,7 +328,7 @@ export default {
.file-download, .file-delete{
font-size: 18px;
cursor: pointer;
}
.file-download:hover, .file-delete:hover {
color: #409EFF;
@@ -342,17 +342,17 @@ export default {
color: #fafbfd;
}
.preview .file-preview{
font-size: 19px;
cursor: pointer;
}
.preview >>>.el-image__inner{
width: 18px;
height: 18px;
}
</style>

View File

@@ -70,11 +70,10 @@
<script>
import { nowTime } from '../../../utils/index.js'
import { getUserProfile } from '@/api/system/user'
import { listOwnFive, listStuFive } from '@/api/stuCQS/info-fill/cqScore'
import { listOwnFive, listStuFive, getcphiamByOne, getOwncphiamByOne, getStuData, getOwnData, getOwn, getStu } from '@/api/stuCQS/info-fill/cqScore'
import { getOwnInfo, getStuInfo } from '@/api/stuCQS/basedata/stuInfoView'
import { getOwnInfo as getExtraInfo, } from '@/api/stuCQS/basedata/extraInfo'
import { listCourseScore } from '@/api/stuCQS/basedata/course'
import { getcphiamByOne } from '@/api/stuCQS/process-center/auditDetails'
export default {
props: {
stuNo: {
@@ -115,7 +114,7 @@ export default {
this.timeFn()
this.getUserInfo()
this.getExtraInfo()
this.getcphiamByOne()
this.getUserCphiamByOne()
},
mounted() {
if (this.stuNo == null) {
@@ -131,13 +130,17 @@ export default {
clearInterval(this.timing)
},
methods: {
getcphiamByOne() {
getcphiamByOne(this.stuNo).then(res => {
this.cphiams = res.rows
})
getUserCphiamByOne() {
if (this.stuNo != null) {
getcphiamByOne(this.stuNo).then(res => {
this.cphiams = res.rows
})
} else {
getOwncphiamByOne().then(res => {
this.cphiams = res.rows
})
}
},
doFull() {
this.$store.dispatch('app/toggleSideBarHide', true)
document.querySelector('.navbar').style.display = 'none'
@@ -191,7 +194,7 @@ export default {
},
async getExtraInfo() {
let res = await getExtraInfo()
console.log(res)
//console.log(res)
if (res.code == 200) {
this.extraForm = {
...res.data
@@ -205,7 +208,52 @@ export default {
const chart = this.$echarts.init(document.getElementById(chartId))
chart.setOption(option)
},
qualityChart() {
async qualityChart() {
let stuData = []
if (this.stuNo != null) {
let res = await getStuData(this.stuNo)
stuData = [...res.rows]
} else {
let res = await getOwnData()
stuData = [...res.rows]
}
let stuYearNames = []
let stuYearDatas = []
if (stuData != null) {
for (let i = 0; i < stuData.length; i++) {
let stuYearName = {};//存储学年名称
stuYearName.name = stuData[i].stuYearName;
stuYearName.itemStyle = {};
if (i <= 0) {
stuYearName.itemStyle.color = '#EE6666';
}
if (i >= 1 && i < stuData.length) {
stuYearName.itemStyle.color = null;
}
stuYearNames.push(stuYearName);
let stuYearData = {};//存储学年数据
let stus = [];
stus.push(stuData[i].classtwoScore);
stus.push(stuData[i].ceScore);
stus.push(stuData[i].sportScore);
stus.push(stuData[i].iamScore);
stus.push(stuData[i].stuScore);
stuYearData.value = stus;
stuYearData.name = stuData[i].stuYearName;
stuYearData.symbol = 'none';
stuYearData.lineStyle = {};
if (i <= 0) {
stuYearData.lineStyle.color = '#EE6666';
}
if (i >= 1 && i < stuData.length) {
stuYearData.lineStyle.color = null;
}
stuYearDatas.push(stuYearData);
}
}
const option = {
legend: {
icon: 'circle',
@@ -214,23 +262,16 @@ export default {
color: '#ffffff',
fontSize: 14
},
// 设置图例的颜色与班级线条的颜色一致
data: [{
name: '班级',
itemStyle: {
color: '#EE6666' // 图例的颜色设置为红色,与班级线条一致
}
}, {
name: '个人',
}]
data: [...stuYearNames]
},
radar: {
indicator: [
{ name: '第二课堂', color: '#fff' },
{ name: '综合评价', color: '#fff' },
{ name: '体', color: '#fff' },
{ name: '体能素质', color: '#fff' },
{ name: '思想品德', color: '#fff' },
{ name: '平均学分绩', color: '#fff' },
{ name: '科学文化素质', color: '#fff' },
],
axisLine: {
lineStyle: {
@@ -251,21 +292,7 @@ export default {
series: [
{
type: 'radar',
data: [
{
value: [4200, 3000, 20000, 35000, 50000, 18000],
name: '班级',
symbol: 'none',
lineStyle: {
color: '#EE6666' // 修改班级线条颜色为红色
},
},
{
value: [5000, 14000, 28000, 26000, 42000, 21000],
name: '个人',
symbol: 'none'
}
]
data: [...stuYearDatas]
}
]
}
@@ -280,10 +307,12 @@ export default {
let data = []
///ownRecordParams
if (this.stuNo == null) {
let res = await listOwnFive(ownRecordParams)
//let res = await listOwnFive(ownRecordParams)
let res = await getOwn()
data = [...res.rows]
} else {
let res = await listStuFive(this.stuNo, ownRecordParams)
//let res = await listStuFive(this.stuNo, ownRecordParams)
let res = await getStu(this.stuNo)
data = [...res.rows]
}
//console.log(res);
@@ -292,8 +321,10 @@ export default {
for (let i = 0; i < data.length; i++) {
typeList.push(data[i].typeName)
scoreList.push(data[i].score)
//typeList.push(data[i].typeName)
//scoreList.push(data[i].score)
typeList.push(data[i].stuYearName)
scoreList.push(data[i].totalScore)
}
const option = {
@@ -330,9 +361,9 @@ export default {
data: [
{ value: scoreList[0], itemStyle: { color: '#4A90E2' } },
{ value: scoreList[1], itemStyle: { color: '#50E3C2' } },
{ value: scoreList[2], itemStyle: { color: '#5EABE1' } },
{ value: scoreList[3], itemStyle: { color: '#7ED321' } },
{ value: scoreList[4], itemStyle: { color: '#57D9E3' } }
{ value: scoreList[2], itemStyle: { color: '#5EABE1' } }
// { value: scoreList[3], itemStyle: { color: '#7ED321' } },
// { value: scoreList[4], itemStyle: { color: '#57D9E3' } }
],
type: 'bar'
}
@@ -340,14 +371,31 @@ export default {
}
this.createChart('grade', option)
},
rankingChart() {
async rankingChart() {
let data = []
if (this.stuNo == null) {
let res = await getOwn()
data = [...res.rows]
} else {
let res = await getStu(this.stuNo)
data = [...res.rows]
}
let typeList = []
let rankList = []
for (let i = 0; i < data.length; i++) {
typeList.push(data[i].stuYearName)
rankList.push(data[i].majorRank)
}
console.log(this.stuNo);
const option = {
xAxis: {
type: 'category',
data: ['第一学期', '第二学期', '第三学期', '第四学期', '第五学期', '第六学期'], // 这里填入你的数据
data: [...typeList], // 这里填入你的数据
axisLabel: {
color: 'white',
fontSize: 12,
rotate: 35,
}
},
yAxis: {
@@ -377,7 +425,7 @@ export default {
color: '#154A89',
opacity: 0.5,
},
data: [56, 45, 34, 7, 20, 7],
data: [...rankList],
}],
grid: {
left: 0,
@@ -652,7 +700,8 @@ html {
}
}
tr:gt(0) td:gt(1){
tr:gt(0) td:gt(1) {
padding-left: 100px;
}
}

View File

@@ -102,8 +102,8 @@
<el-form-item label="所属班级" prop="studentClass">
<el-input v-model="getStudentClass" placeholder="请输入所属班级" :readonly="redingData" />
</el-form-item>
<el-form-item label="族" prop="nation">
<el-input v-model="getNation" placeholder="请输入族" :readonly="redingData" />
<el-form-item label="族" prop="nation">
<el-input v-model="getNation" placeholder="请输入族" :readonly="redingData" />
</el-form-item>
<el-form-item label="出生日期" prop="birthData">
<span v-if="form.birthData != null" class="readonly-label">{{ formatDate(form.birthData) }}</span>

View File

@@ -11,7 +11,7 @@
</el-alert>
<!-- 核心表单 -->
<el-form :model="form" :rules="formRules" ref="formRef" class="form-wrapper" v-loading="loading">
<el-form ref="formRef" v-loading="loading" :model="form" :rules="formRules" class="form-wrapper">
<!-- 基本信息卡片 -->
<el-card shadow="hover" style="margin-bottom: 20px">
<el-descriptions title="基本信息" :column="3" border label-width="120px">
@@ -33,8 +33,8 @@
<el-descriptions-item label="性别" required>
<el-form-item prop="gender" class="no-label-form-item">
<el-select v-model="form.gender" placeholder="请选择性别" clearable style="width: 100%">
<el-option label="男" value="1"></el-option>
<el-option label="女" value="0"></el-option>
<el-option label="男" value="1" />
<el-option label="女" value="0" />
</el-select>
</el-form-item>
</el-descriptions-item>
@@ -85,10 +85,15 @@
<!-- 宿费交纳情况 -->
<el-descriptions-item label="宿费交纳情况" required>
<el-form-item prop="accommodationFeeStatus" class="no-label-form-item">
<el-radio-group v-model="form.accommodationFeeStatus">
<el-radio :label="1" disabled>已交当前学年住宿费</el-radio>
<el-radio :label="0" disabled>未交当前学年住宿费</el-radio>
</el-radio-group>
<div style="display: flex;">
<!-- <div>
<el-radio-group v-model="form.accommodationFeeStatus">
<el-radio :label="1" disabled>已交当前学年住宿费</el-radio>
<el-radio :label="0" disabled>未交当前学年住宿费</el-radio>
</el-radio-group>
</div> -->
<div>{{ form.accommodationFee }}</div>
</div>
</el-form-item>
</el-descriptions-item>
</el-descriptions>
@@ -106,8 +111,8 @@
<!-- 佐证附件 -->
<el-descriptions-item label="佐证附件" required>
<el-form-item prop="reasonFileList" class="no-label-form-item">
<Affix v-model="form.affixId" @input="handleAffix" @fileUploaded="handleAffix"
<el-form-item prop="affixId" class="no-label-form-item">
<AffixIndex ref="affixComponent" v-model="form.affixId" @input="getffix" @fileUploaded="handleAffix"
@delete-file="handleDeleteFile" />
<div class="el-upload__tip">
支持上传jpg/png/pdf格式文件单个文件不超过10MB如病例住房证明等
@@ -126,8 +131,7 @@
<!-- <img :src="baseUrl + form.studentSignature" alt="电子签名"
style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee" /> -->
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + form.studentSignature" :preview-src-list="[baseUrl + form.studentSignature]">
</el-image>
:src="baseUrl + form.studentSignature" :preview-src-list="[baseUrl + form.studentSignature]" />
</div>
</div>
</el-form-item>
@@ -191,7 +195,7 @@
<!-- <file-upload v-model="form.parentSignAttachment" :text="`上传文件`" /> -->
<el-upload class="upload-demo" :action="uploadImgUrl" :on-success="handleAvatarSuccess"
:before-upload="beforeAvatarUpload" :file-list="fileList" list-type="picture">
<el-button size="small" type="primary"><i class='el-icon-upload2'></i>点击上传</el-button>
<el-button size="small" type="primary"><i class="el-icon-upload2" />点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过2M</div>
</el-upload>
</el-form-item>
@@ -227,15 +231,15 @@
<el-card shadow="hover" style="margin-bottom: 20px">
<el-descriptions title="本人承诺" :column="1" border label-width="120px">
<el-descriptions-item label="承诺内容">
<el-card shadow="none" class="promise-card">
<el-card v-if="form.promiseContent == ''" shadow="none" class="promise-card">
<p>1. 自觉遵守国家法律法规</p>
<p>2. 自觉遵守学生行为规范和学校的规章制度遵守社会公德</p>
<p>3. 自觉遵守外宿住址所在社区的有关管理规定</p>
<p>
4.
本人申请外宿属个人自愿行为外宿期间发生的一切事故造成本人他人或集体的人身财产损害的学校不负责任
4. 本人申请外宿属个人自愿行为外宿期间发生的一切事故造成本人他人或集体的人身财产损害的学校不负责任
</p>
</el-card>
<el-card v-else shadow="none" class="promise-card" v-html="form.promiseContent" />
</el-descriptions-item>
<!-- 承诺签名 -->
@@ -249,8 +253,7 @@
<!-- <img :src="baseUrl + form.studentPromiseSign" alt="承诺签名"
style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee" /> -->
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + form.studentPromiseSign" :preview-src-list="[baseUrl + form.studentPromiseSign]">
</el-image>
:src="baseUrl + form.studentPromiseSign" :preview-src-list="[baseUrl + form.studentPromiseSign]" />
</div>
<el-form-item prop="promiseDate" class="no-label-form-item date-item">
<el-date-picker v-model="form.promiseDate" type="date" value-format="yyyy-MM-dd" placeholder="签署日期"
@@ -268,11 +271,11 @@
<i class="el-icon-folder" />
保存
</el-button>
<el-button type="primary" size="medium" @click="submitForm(1)">
<el-button v-if="form.status == 0" type="primary" size="medium" @click="submitForm(1)">
<i class="el-icon-check" />
提交申请
</el-button>
<el-button type="default" size="medium" @click="resetForm" style="margin-left: 10px" v-if="!currentId">
<el-button v-if="!currentId" type="default" size="medium" style="margin-left: 10px" @click="resetForm">
<i class="el-icon-refresh" />
重置表单
</el-button>
@@ -288,7 +291,7 @@
</div>
<div class="sign-modal-body">
<!-- 纯原生Canvas无任何框架包裹 -->
<canvas id="studentCanvas" width="400" height="200" style="border: 1px solid #ccc; background: #fff"></canvas>
<canvas id="studentCanvas" width="400" height="200" style="border: 1px solid #ccc; background: #fff" />
</div>
<div class="sign-modal-footer">
<button class="btn-clear" @click="clearStudentCanvas">清除</button>
@@ -305,7 +308,7 @@
<span class="close-btn" @click="closePromiseSignModal">×</span>
</div>
<div class="sign-modal-body">
<canvas id="promiseCanvas" width="400" height="200" style="border: 1px solid #ccc; background: #fff"></canvas>
<canvas id="promiseCanvas" width="400" height="200" style="border: 1px solid #ccc; background: #fff" />
</div>
<div class="sign-modal-footer">
<button class="btn-clear" @click="clearPromiseCanvas">清除</button>
@@ -317,20 +320,24 @@
</template>
<script>
import { getOwnLog } from '@/api/dormitory/new/stuDom'
import {
addOutsideAccommodationApply,
getOutsideAccommodationApply,
getOwnInfo,
listStudent,
getOutsideAccommodationApply,
updateOutsideAccommodationApply,
addOutsideAccommodationApply
updateOutsideAccommodationApply
} from '@/api/dormitory/outsideAccommodation/outsideAccommodationApply'
import { getUserProfile } from '@/api/system/user' // 获取当前登录用户
import { batchAddOutsideAccommodationAttachment, deleteOutsideAccommodationAttachmentNameAndStuName } from '@/api/dormitory/outsideAccommodation/outsideAccommodationAttachment'
import { getUserProfile } from '@/api/system/user'; // 获取当前登录用户
import AffixIndex from '@/views/dormitory/outsideAccommodation/outsideAccommodationApply/components/affix/index'
import {
pcaTextArr // 省市区联动数据,纯汉字
} from 'element-china-area-data'
export default {
name: 'OutsideAccommodationApply',
components: { AffixIndex },
data() {
return {
// 遮罩层
@@ -360,7 +367,11 @@ export default {
studentSignature: '',
studentPromiseSign: '',
promiseDate: '',
parentSignAttachment: ''
parentSignAttachment: '',
promiseContent: '',
accommodationFee: '',
affixId: '',
status: 0
},
formRules: {
originalDormitory: [{ required: true, message: '原宿舍号不能为空', trigger: 'blur' }],
@@ -397,13 +408,7 @@ export default {
promiseDate: [{ required: true, message: '请选择签署日期', trigger: 'change' }],
studentSignature: [{ required: true, message: '请完成电子签名', trigger: 'change' }],
studentPromiseSign: [{ required: true, message: '请完成承诺签名', trigger: 'change' }],
reasonFileList: [
{
required: true,
validator: (r, v, c) =>
this.reasonFileList.length ? c() : c(new Error('请上传佐证附件'))
}
],
affixId: [{ required: true, message: '请上传佐证材料', trigger: 'change' }],
parentSignAttachment: [
{
required: true,
@@ -434,12 +439,12 @@ export default {
},
watch: {
// 监听路由参数变化,只要有新的 id 就更新
"$route.query.id": {
'$route.query.id': {
immediate: true, // 初始化时立即执行一次
handler(newId, oldId) {
if (newId) {
this.loading = true;
this.currentId = newId;
this.loading = true
this.currentId = newId
// 调用接口加载数据
getOutsideAccommodationApply(this.currentId).then(res => {
this.form = {
@@ -447,37 +452,20 @@ export default {
// 字符串转回数组(按后端存储的分隔符拆分),地址
address: res.data.address ? res.data.address.split('/') : [],
parentAddress: res.data.parentAddress ? res.data.parentAddress.split('/') : []
};
this.reasonFileList = this.form.affixId
}
const fileName = this.form.parentSignAttachment.split('/').pop()
// 回显家长签字附件
this.fileList = [{ name: fileName, url: this.baseUrl + this.form.parentSignAttachment }]
// 处理审批意见列表,添加意见类型
// if (this.form?.enlistmentReserveApprovalList) {
// // 定义意见类型数组与索引对应0=辅导员1=学务2=二级学院3=学籍管理科4=教务处主管领导)
// const opinionTypes = [
// "辅导员意见",
// "学务意见",
// "二级学院意见",
// "学籍管理科意见",
// "教务处主管领导意见"
// ];
// // 遍历审批列表,为每条数据添加 opinionType 字段
// this.formData.enlistmentReserveApprovalList.forEach((item, index) => {
// // 只处理前5条数据超出部分不添加或可根据实际需求调整
// if (index < opinionTypes.length) {
// item.opinionType = opinionTypes[index];
// } else {
// // 若超过5条可设置默认值或不设置
// item.opinionType = "其他意见";
// }
// });
// }
this.loading = false
})
} else {
// 若 id 为空,可做清空处理
this.currentId = null;
this.currentId = null
// 延迟执行重置,确保 formRef 已挂载
this.$nextTick(() => {
this.resetForm()
})
this.getUser()
}
}
@@ -510,7 +498,41 @@ export default {
this.form.teacherName = res.data.teacherName
this.form.studentPhone = res.data.stuPhone
this.form.birthDate = res.data.birthday
this.form.accommodationFee = "wu"
// 获取学生宿舍缴费记录
getOwnLog().then(response => {
// 1. 提取当前学生的宿舍ID
const currentDormId = response.data.dormStu.dormitoryId
// 2. 从record中找到roomId匹配的第一条数据提取基准学年
const matchedRecord = response.data.record.find(item => item.roomId === currentDormId)
// 3. 核心逻辑判断全量record是否同年度 + 汇总费用
if (matchedRecord) {
// 提取匹配记录的基准学年
const baseStuYearName = matchedRecord.stuYearName || ''
if (baseStuYearName) {
// 检查整个record数组中所有数据的学年是否和基准学年一致
const isAllSameYear = response.data.record.every(item => {
return (item.stuYearName || '') === baseStuYearName
})
if (isAllSameYear) {
// 所有记录同年度,汇总全部费用
const totalMoney = response.data.record.reduce((sum, item) => {
return sum + Number(item.needMoney || 0) // 确保金额为数字避免NaN
}, 0)
this.form.accommodationFee = `已交${baseStuYearName}年度住宿费${totalMoney || 0}人民币`
} else {
// 存在不同年度的记录,仅展示基准年度+提示
this.form.accommodationFee = `已交${baseStuYearName}年度住宿费 存在不同年度费用数据,暂无法汇总`
}
} else {
// 匹配记录无学年名称
this.form.accommodationFee = '已交未知年度住宿费 暂无有效学年信息'
}
} else {
// 无匹配roomId的记录兜底处理
const firstStuYearName = response.data.record[0]?.stuYearName || ''
this.form.accommodationFee = `已交${firstStuYearName || '未知'}年度住宿费 暂无匹配宿舍费用数据`
}
})
this.getStuDom()
}
this.loading = false
@@ -524,9 +546,9 @@ export default {
(response) => {
this.form.originalDormitory =
response.rows[0].campusName +
'-' +
' ' +
response.rows[0].parkName +
'-' +
' ' +
response.rows[0].buildingName +
response.rows[0].roomNo
this.loading = false
@@ -682,55 +704,54 @@ export default {
submitForm(status) {
this.$refs.formRef.validate((valid) => {
if (valid) {
// 生成申请编号
// 生成申请编号等逻辑不变
if (!this.form.applyNo) {
const year = new Date().getFullYear();
const randomNo = Math.floor(Math.random() * 1000000).toString().padStart(6, '0');
this.form.applyNo = `WS${year}${randomNo}`; // 获取申请编号
const year = new Date().getFullYear()
const randomNo = Math.floor(Math.random() * 1000000).toString().padStart(6, '0')
this.form.applyNo = `WS${year}${randomNo}`
}
// 生成外宿结束时间默认次年8月31日
this.form.endDate = this.getOutsideDefaultEndTime()
// 生成本人承诺内容
this.form.promiseContent = `
1. 自觉遵守国家法律、法规;
2. 自觉遵守学生行为规范和学校的规章制度,遵守社会公德;
3. 自觉遵守外宿住址所在社区的有关管理规定;
4. 本人申请外宿,属个人自愿行为,外宿期间发生的一切事故,造成本人、他人或集体的人身、财产损害的,学校不负责任。
<p>1.自觉遵守国家法律、法规;</p>
<p>2.自觉遵守学生行为规范和学校的规章制度,遵守社会公德;</p>
<p>3.自觉遵守外宿住址所在社区的有关管理规定;</p>
<p>4.本人申请外宿,属个人自愿行为,外宿期间发生的一切事故,造成本人、他人或集体的人身、财产损害的,学校不负责任。</p>
`
// 将地址数组转为字符串(用 / 拼接,后端可按此分隔解析)
const submitForm = {
...this.form,
address: this.form.address ? this.form.address.join('/') : '', // 数组转字符串
parentAddress: this.form.parentAddress ? this.form.parentAddress.join('/') : '', // 家长地址同理
status: status
};
this.loading = true;
if (this.form.id != null) {
updateOutsideAccommodationApply(submitForm).then((response) => {
this.loading = false;
this.$modal.msgSuccess('修改成功')
this.goBack()
}).catch(error => {
this.loading = false;
this.goBack()
})
} else {
addOutsideAccommodationApply(submitForm).then((response) => {
this.loading = false;
this.$modal.msgSuccess('新增成功')
this.goBack()
}).catch(error => {
this.loading = false;
this.goBack()
})
address: this.form.address ? this.form.address.join('/') : '',
parentAddress: this.form.parentAddress ? this.form.parentAddress.join('/') : '',
status: this.form.status != 0 ? this.form.status : status
}
this.resetForm()
this.loading = true
// 封装请求逻辑为Promise确保完成后再操作
const requestPromise = this.form.id != null
? updateOutsideAccommodationApply(submitForm)
: addOutsideAccommodationApply(submitForm)
requestPromise.then((response) => {
// 附件处理逻辑不变
if (this.reasonFileList && this.reasonFileList.length > 0) {
this.reasonFileList.forEach(element => {
element.applyId = this.form.id || response.data.id
})
batchAddOutsideAccommodationAttachment(this.reasonFileList)
}
this.loading = false
this.$modal.msgSuccess(this.form.id ? '修改成功' : '新增成功')
// 延迟跳转:给后端数据落地留时间(关键!)
setTimeout(() => {
this.goBack()
}, 800) // 800ms延迟确保后端写入完成
}).catch(error => {
this.loading = false
this.$message.error('提交失败:' + (error.msg || '服务器处理异常'))
// 失败时不跳转,避免用户重复操作
// this.goBack();
})
} else {
this.loading = false;
this.loading = false
this.$message.error('表单填写有误,请检查!')
}
})
@@ -738,61 +759,77 @@ export default {
// 重置表单
resetForm() {
this.$refs.formRef.resetFields()
// 先判断 formRef 是否存在,再调用 resetFields
if (this.$refs.formRef) {
this.$refs.formRef.resetFields()
}
this.reasonFileList = []
this.fileList = []
this.form.affixId = ''
this.form.studentSignature = ''
this.form.studentPromiseSign = ''
this.clearStudentCanvas()
this.clearPromiseCanvas()
},
handleAffix(affixId) {
getffix(affixId) {
this.form.affixId = affixId
},
// 处理组件传递的文件信息
handleAffix(fileInfo) {
// 处理 AffixIndex 组件回传:支持文件信息对象
handleAffix(payload) {
// if (typeof payload === 'string' || typeof payload === 'number') {
// this.form.affixId = payload
// return
// }
const fileInfo = payload
if (!fileInfo || !fileInfo.fileName || !fileInfo.filePath) {
console.warn('无效的文件信息,跳过添加')
return // 不添加空数据
this.$message.warning('附件标识异常或文件信息缺失,请重新上传')
return
}
// 构建与后端实体匹配的data对象
let data = {
const data = {
// id: null, // 主键(后端自增)
applyId: this.form.id || null, // 关联申请表ID从主表单获取
attachmentName: fileInfo.fileName, // 文件名(从组件传递的信息中获取)
attachmentUrl: fileInfo.filePath, // 文件路径相对路径关联sys_file表
filePath: fileInfo.filePath, // 文件路径相对路径关联sys_file表
fileSize: fileInfo.originalFile?.size || 0, // 若需要可从fileInfo.originalFile.size获取单位字节
fileSuffix: fileInfo.fileType, // 文件类型如docx、pdf
processInstanceId: this.form.processInstanceId || '', // 申请编号(从主表单获取)
studentName: this.form.studentName || '', // 学生姓名(从主表单获取)
studentNo: this.form.studentNo || '' // 学号(从主表单获取)
}
}
// 避免重复添加根据filePath去重
const isDuplicate = this.reasonFileList.some((item) => item.filePath === data.filePath)
if (!isDuplicate) {
this.reasonFileList.push(data)
console.log('附件添加成功:', this.reasonFileList)
} else {
if (isDuplicate) {
this.$message.warning('该文件已添加,请勿重复上传')
return
}
console.log(this.reasonFileList)
this.reasonFileList.push(data)
},
// 处理子组件传递的删除文件事件
handleDeleteFile(fileName) {
// 接收文件名后,可执行后续逻辑,删除在数据库的数据
// if (fileName) {
// deleteRtEnlistmentReserveAttachByFileNameAndStuName({fileName:fileName, studentName: this.formData.studentName}).then(res => {
// this.$message.success(`成功删除文件:${fileName}`);
// })
// }
if (fileName) {
deleteOutsideAccommodationAttachmentNameAndStuName({ attachmentName: fileName, studentName: this.form.studentName }).then(res => {
this.$message.success(`成功删除文件:${fileName}`)
})
}
},
goBack() {
// 关闭当前标签页并返回上个页面
// const obj = { path: 'disciplinaryApplication', query: { t: Date.now() } }
// this.$tab.closeOpenPage(obj)
this.$router.back()
// 关闭窗体 index 当前层索引
this.$tab.closePage()
// 1. 先清空附件组件数据(主动触发清理)
this.$nextTick(() => {
// 如果Affix组件有ref比如ref="affixComponent"主动调用clearData
if (this.$refs.affixComponent) {
this.$refs.affixComponent.clearData()
}
// 2. 优化退出逻辑先关闭tab再返回避免重复操作
this.$tab.closePage().then(() => {
// 仅当需要返回上一页时执行(根据业务场景选择)
// this.$router.back();
})
})
},
// 保存学生签名
saveStudentSignature() {
@@ -922,30 +959,30 @@ export default {
}
},
beforeAvatarUpload(file) {
const isJPG = file.type === 'image/jpeg' || 'image/png';
const isLt2M = file.size / 1024 / 1024 < 2;
const isJPG = file.type === 'image/jpeg' || 'image/png'
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
this.$message.error('上传头像图片只能是 JPG、PNG 格式!');
this.$message.error('上传头像图片只能是 JPG、PNG 格式!')
}
if (!isLt2M) {
this.$message.error('上传头像图片大小不能超过 2MB!');
this.$message.error('上传头像图片大小不能超过 2MB!')
}
return isJPG && isLt2M;
return isJPG && isLt2M
},
/**
* 生成外宿默认结束时间次年8月31日
* @returns {String} 格式化日期yyyy-MM-dd
*/
getOutsideDefaultEndTime() {
const now = new Date();
const currentYear = now.getFullYear();
const now = new Date()
const currentYear = now.getFullYear()
// 计算次年(当前年+1
const nextYear = currentYear + 1;
// 生成次年8月31日月份从0开始8月对应9
const endDate = new Date(nextYear, 8, 31);
const nextYear = currentYear + 1
// 8月对应的索引是70=1月1=2月...7=8月
const endDate = new Date(nextYear, 7, 31) // 次年8月31日
// 格式化为 yyyy-MM-dd适配 el-date-picker 的 value-format
return this.formatDate(endDate);
return this.formatDate(endDate)
},
/**
@@ -954,10 +991,10 @@ export default {
* @returns {String} yyyy-MM-dd
*/
formatDate(date) {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份补零
const day = String(date.getDate()).padStart(2, '0'); // 日期补零
return `${year}-${month}-${day}`;
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0') // 月份补零
const day = String(date.getDate()).padStart(2, '0') // 日期补零
return `${year}-${month}-${day}`
}
}
}
@@ -1108,4 +1145,4 @@ li {
text-align: center !important;
width: 120px;
}
</style>
</style>

View File

@@ -0,0 +1,575 @@
<template>
<div>
<el-upload :style="uploadStyle" action="" :class="['cm-affix', { 'is-disabled': inputDisabled }]"
:disabled="inputDisabled" :multiple="true" :http-request="handleUpload" :file-list="fileList" :accept="accpet"
:show-file-list="false" :before-upload="handleBeforeUpload">
<el-button v-if="inputDisabled !== true" id="affix1" :disabled="notupload" size="small" type="primary">
<i class="el-icon-upload2"></i>点击上传
</el-button>
<el-button v-if="affixId !== null && affixId !== '' && fileList.length > 0" id="affix2" size="small"
@click.stop="downloadPack()">
<div v-if="downloading" class="el-icon-loading file-upload"
style="margin-left: 0px;margin-right: 3px;font-size: 14px;" />
打包下载
</el-button>
</el-upload>
<div v-for="(item, index) in fileList" :key="`${item.id || item.uid || item.name}_${index}_${affixId}`"
class="file">
<div class="file-item" :class="[{ 'is-disabled': inputDisabled }]">
<div class="file-name">{{ item.name }}</div>
<div v-if="item.status === 1" class="el-icon-loading file-upload" title="上传中..." />
<div v-if="item.status === 2" class="el-icon-download file-download" title="下载" @click="downloadFile(item)" />
<div v-if="item.status === 2" class="el-icon-delete file-delete" title="删除" @click="deleteFile(item)" />
<div v-if="isImageURL(item.name) && item.status === 2" class="el-icon-picture" title="预览"
@click="preview(item)" />
</div>
</div>
<el-image v-show="false" ref="preview" class="preview" :src="hiddenSrc" :preview-src-list="previewList" />
</div>
</template>
<script>
import { deleteAffix, download, downloadAll, queryAffixs, upload } from '@/api/affix/affix'
// 若有创建affix主记录的接口需引入根据后端实际情况调整
// import { createAffix } from '@/api/affix/affix'
export default {
name: 'CmAffix',
inject: {
elForm: {
default: ''
}
},
props: {
notupload: {
type: Boolean,
default: false
},
value: String,
disabled: Boolean,
maxSize: {
type: Number,
default: 20
},
accpet: {
type: String,
default: '*'
},
uploadStyle: {
type: String,
default: ''
},
},
data() {
return {
uploadCnt: 0,
affixId: '',
fileList: [],
downloading: false,
baseurl: process.env.VUE_APP_BASE_API,
hiddenSrc: '',
previewList: [],
requestLock: false, // 全局请求锁
retryTimes: 0, // 重试次数
cacheData: {}, // 缓存已查询的附件数据
uploadQueue: [], // 上传队列(解决并发问题)
isUploading: false, // 是否正在上传(串行控制)
uploadRetryTimes: 0 // 上传重试次数
}
},
computed: {
inputDisabled() {
return this.disabled || (this.elForm || {}).disabled
}
},
watch: {
value: {
immediate: true,
handler(newVal) {
if (!newVal) {
this.fileList = []
this.affixId = ''
return
}
// 优先使用缓存,避免重复请求
if (this.cacheData[newVal]) {
this.fileList = JSON.parse(JSON.stringify(this.cacheData[newVal].fileList))
this.previewList = JSON.parse(JSON.stringify(this.cacheData[newVal].previewList))
this.affixId = newVal
return
}
// 无缓存则请求,加锁防重复
if (!this.requestLock) {
this.loadData(newVal)
}
}
},
// 关键监听affixId变化确保外部能捕获
affixId: {
immediate: true,
handler(newVal, oldVal) {
if (newVal !== oldVal || newVal) {
// 使用$nextTick确保DOM更新后再emit
this.$nextTick(() => {
this.$emit('input', newVal)
// 额外触发change事件方便外部监听
this.$emit('affixId-change', newVal)
// 更新v-model绑定兼容不同Vue版本
this.$emit('update:value', newVal)
})
}
}
}
},
beforeUnmount() {
this.requestLock = false
this.retryTimes = 0
this.isUploading = false
this.uploadQueue = []
},
methods: {
preview(item) {
this.hiddenSrc = item.savePath
this.$refs.preview.showViewer = true
},
isImageURL(url) {
// 正则:原正则会匹配以这些字符结尾
const regex = /(\.jpg|\.jpeg|\.png|\.gif|\.webp)$/i
return regex.test(url)
},
// 处理上传请求(修复队列立即执行逻辑)
handleUpload(file) {
// 生成统一的UID确保和beforeUpload中的UID一致
const fileUid = file.file.uid || Date.now() + Math.random()
file.file.uid = fileUid
// 将文件加入上传队列
this.uploadQueue.push(file)
// 立即执行队列(修复第一次上传不触发的问题)
this.$nextTick(() => {
if (!this.isUploading) {
this.processUploadQueue()
}
})
},
// 串行处理上传队列(核心修复第一次上传问题)
async processUploadQueue() {
// 队列为空则结束
if (this.uploadQueue.length === 0) {
this.isUploading = false
this.uploadRetryTimes = 0 // 重置重试次数
return
}
this.isUploading = true
// 取出队列第一个文件
const file = this.uploadQueue.shift()
// 使用文件自带的UID和beforeUpload中保持一致
const currentFileUid = file.file.uid
// 确保affixId存在
if (!this.affixId) {
this.affixId = this.$tool.uuid()
}
try {
// 调用上传接口
const res = await upload({ 'file': file.file, 'affixId': this.affixId })
this.uploadCnt--
if (res.code === 200) {
// 通过uid匹配文件修复匹配不到的问题
const fileIndex = this.fileList.findIndex(item =>
item.uid === currentFileUid && item.status === 1
)
if (fileIndex > -1) {
const savePath = this.baseurl + res.savePath
// 更新文件信息
this.fileList.splice(fileIndex, 1, {
...this.fileList[fileIndex],
id: res.id,
status: 2,
savePath: savePath,
trueName: res.trueName
})
// 预览列表去重添加
if (this.isImageURL(savePath) && !this.previewList.includes(savePath)) {
this.previewList.push(savePath)
}
// 向外传递上传成功事件
this.$emit('fileUploaded', {
fileId: res.id,
fileName: res.trueName,
filePath: res.savePath,
fullPath: savePath,
fileType: this.getFileType(res.trueName),
originalFile: file.file
})
// 更新缓存(深拷贝避免引用问题)
this.cacheData[this.affixId] = {
fileList: JSON.parse(JSON.stringify(this.fileList)),
previewList: JSON.parse(JSON.stringify(this.previewList))
}
// 强制更新视图
this.$forceUpdate()
}
} else {
this.$message.error(res.message || '上传失败')
// 上传失败重新加入队列最多重试1次
if (this.uploadRetryTimes < 1) {
this.uploadRetryTimes++
this.uploadQueue.unshift(file)
setTimeout(() => {
this.processUploadQueue()
}, 1000)
return
} else {
this.uploadRetryTimes = 0
// 移除上传失败的文件
this.removeFailedFile(currentFileUid)
}
}
} catch (err) {
this.uploadCnt--
this.$message.error(`文件 ${file.file.name} 上传失败:${err.message || '网络异常'}`)
// 上传失败重新加入队列最多重试1次
if (this.uploadRetryTimes < 1) {
this.uploadRetryTimes++
this.uploadQueue.unshift(file)
setTimeout(() => {
this.processUploadQueue()
}, 1000)
return
} else {
this.uploadRetryTimes = 0
// 移除上传失败的文件
this.removeFailedFile(currentFileUid)
}
}
// 立即处理下一个文件(移除异步延迟)
this.processUploadQueue()
},
// 移除上传失败的文件
removeFailedFile(uid) {
const fileIndex = this.fileList.findIndex(item =>
item.uid === uid && item.status === 1
)
if (fileIndex > -1) {
this.fileList.splice(fileIndex, 1)
this.$forceUpdate() // 确保视图更新
}
},
// 创建affix主记录根据后端实际情况调整可选
async createAffixRecord(affixId) {
try {
// await createAffix({ affixId: affixId })
// 创建成功后自动触发watch
} catch (err) {
this.$message.error('创建附件记录失败:' + err.message)
}
},
getFileType(fileName) {
if (!fileName) return ''
const lastDotIndex = fileName.lastIndexOf('.')
return lastDotIndex > -1 ? fileName.substring(lastDotIndex + 1).toLowerCase() : ''
},
handleBeforeUpload(file) {
// 生成affixId若不存在
if (!this.affixId) {
this.affixId = this.$tool.uuid()
}
// 校验文件大小
const isLt20M = file.size / 1024 / 1024 < this.maxSize
if (!isLt20M) {
this.$message.error(`上传大小不能超过 ${this.maxSize}MB!`)
return false // 显式阻止上传
} else {
// 生成统一的UID确保和handleUpload中一致
const fileUid = file.uid || Date.now() + Math.random()
file.uid = fileUid
// 立即添加文件到列表(确保视图能及时显示)
const newFile = {
name: file.name,
status: 1,
uid: fileUid,
rawFile: file
}
// 先清空同名未上传文件(避免重复)
this.fileList = this.fileList.filter(item => !(item.name === file.name && item.status === 1))
this.fileList.push(newFile)
// 立即更新视图
this.$forceUpdate()
this.uploadCnt++
return true
}
},
getFileName(id) {
const item = this.fileList.find(item => item.id === id)
return item ? item.name : ''
},
downloadFile(file) {
download(file.id).then((res) => {
let fileName = this.getFileName(file.id).replace(/"/g, '')
const blob = new Blob([res], { type: 'application/octet-stream;' })
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob)
downloadElement.href = href
downloadElement.download = decodeURI(fileName)
document.body.appendChild(downloadElement)
downloadElement.click()
document.body.removeChild(downloadElement)
window.URL.revokeObjectURL(href)
}).catch((res) => {
this.$message.error(res.message || '下载失败')
})
},
downloadPack() {
if (!this.affixId) {
this.$message.error('暂无附件!')
return
}
if (this.fileList.length === 1) {
this.downloadFile(this.fileList[0])
} else {
this.downloading = true
downloadAll(this.affixId).then((res) => {
const blob = new Blob([res], { type: 'application/octet-stream' })
const downloadElement = document.createElement('a')
const href = window.URL.createObjectURL(blob)
downloadElement.href = href
downloadElement.download = decodeURI('download.zip')
document.body.appendChild(downloadElement)
downloadElement.click()
document.body.removeChild(downloadElement)
window.URL.revokeObjectURL(href)
this.downloading = false
}).catch(() => {
this.downloading = false
this.$message.error('打包下载失败')
})
}
},
deleteFile(file) {
this.$confirm('请确认是否删除此文件?', '提示', { type: 'info' }).then(() => {
deleteAffix(file.id).then((res) => {
if (res.code === 200) {
// 过滤删除的文件
this.fileList = this.fileList.filter(item => item.id !== file.id)
// 过滤预览列表
this.previewList = this.previewList.filter(item => item !== file.savePath)
// 若文件列表为空清空affixId和缓存
if (this.fileList.length === 0) {
delete this.cacheData[this.affixId]
this.affixId = ''
} else {
// 更新缓存(深拷贝)
this.cacheData[this.affixId] = {
fileList: JSON.parse(JSON.stringify(this.fileList)),
previewList: JSON.parse(JSON.stringify(this.previewList))
}
}
// 触发删除事件
this.$emit('delete-file', file.name)
this.$forceUpdate()
} else {
this.$message.error(res.message || '删除失败')
}
}).catch(() => {
this.$message.error('删除失败')
})
})
},
// 加载附件数据
async loadData(targetVal) {
if (this.requestLock || !targetVal) return
this.requestLock = true
// 若缓存存在但文件列表为空,清空缓存
if (this.cacheData[targetVal] && this.cacheData[targetVal].fileList.length === 0) {
delete this.cacheData[targetVal]
}
try {
const res = await queryAffixs(targetVal)
if (res.code === 200) {
this.affixId = targetVal
const newFileList = []
const newPreviewList = []
res.data.forEach(item => {
const savePath = this.baseurl + item.savePath
// 为历史文件添加uid
const fileUid = Date.now() + Math.random() + item.id
newFileList.push({
name: item.trueName,
id: item.id,
status: 2,
savePath: savePath,
uid: fileUid,
trueName: item.trueName
})
if (this.isImageURL(savePath)) {
newPreviewList.push(savePath)
}
})
this.fileList = newFileList
this.previewList = newPreviewList
// 缓存数据(深拷贝)
this.cacheData[targetVal] = {
fileList: JSON.parse(JSON.stringify(newFileList)),
previewList: JSON.parse(JSON.stringify(newPreviewList))
}
this.retryTimes = 0
} else {
this.$message.error(res.msg || '查询附件失败')
}
} catch (err) {
// 处理重复提交错误
if (err.message?.includes('数据正在处理,请勿重复提交')) {
if (this.retryTimes < 1) {
this.retryTimes++
setTimeout(() => {
this.requestLock = false
this.loadData(targetVal)
}, 1000)
} else {
this.requestLock = false
this.retryTimes = 0
this.$message.warning('附件处理中,请稍后再试')
}
} else {
this.$message.error(err.message || '查询附件失败')
this.requestLock = false
}
} finally {
if (this.retryTimes === 0) {
this.requestLock = false
}
}
},
// 清空数据
clearData() {
this.affixId = ''
this.fileList = []
this.previewList = []
this.requestLock = false
this.retryTimes = 0
this.uploadQueue = []
this.isUploading = false
// 清空缓存
delete this.cacheData[this.affixId]
},
// 手动获取affixId的方法供外部调用
getAffixId() {
return new Promise((resolve) => {
if (this.affixId) {
resolve(this.affixId)
} else {
// 监听affixId变化直到有值
const unwatch = this.$watch('affixId', (newVal) => {
if (newVal) {
resolve(newVal)
unwatch() // 取消监听
}
}, { immediate: true })
}
})
}
}
}
</script>
<style scoped>
.cm-affix>>>.el-upload {
padding: 0px 10px;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
margin-bottom: 10px;
}
.file {
width: 100%;
}
.file-item {
white-space: nowrap;
display: flex;
justify-content: start;
align-items: center;
gap: 8px;
margin-bottom: 6px;
/* 增加间距,优化显示 */
}
.file-item div {
display: inline-block;
white-space: nowrap;
}
.file-upload {
font-size: 18px;
margin-left: 5px;
}
.file-download,
.file-delete,
.el-icon-picture {
/* 新增预览图标样式 */
font-size: 18px;
cursor: pointer;
}
.file-download:hover,
.file-delete:hover,
.el-icon-picture:hover {
/* 预览图标hover效果 */
color: #409EFF;
}
.file-item[class~=is-disabled] .file-delete {
display: none;
}
.preview>>>.el-image__inner {
width: 18px;
height: 18px;
}
/* 优化文件名显示,超出省略 */
.file-name {
max-width: 200px;
/* 可根据需求调整 */
overflow: hidden;
text-overflow: ellipsis;
}
</style>

View File

@@ -1,80 +1,91 @@
<!-- 详细外宿申请表 -->
<template>
<div v-loading="loading">
<!-- 详细入伍保留学籍表单 -->
<el-descriptions class="margin-top" title="" :column="4" size="medium" border style="width: 100%">
<el-descriptions-item>
<template slot="label"> 原宿舍号 </template>
{{ renderData.originalDormitory }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 姓名 </template>
{{ renderData.studentName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 性别 </template>
<span v-if="renderData.gender == 1"></span>
<span v-else></span>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 出生年月 </template>
{{ renderData.birthDate }}
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 专业系 </template>
{{ renderData.majorName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 班级 </template>
{{ renderData.className }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 学号 </template>
{{ renderData.studentNo }}
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 宿费交纳情况只填写当年度交费情况 </template>
<!-- {{ renderData.familyAddress }} -->
已交 绑定当前学年年度住宿费 人民币
</el-descriptions-item>
<div class="application-form-container" v-loading="loading" :style="isShwo ? 'width: 70%' : ''">
<el-card class="box-card">
<div slot="header" class="clearfix" v-if="isShwo">
<span class="el-icon-document">外宿申请详情</span>
<el-button style="float: right;margin-left: 10px;" size="mini" type="danger" @click="goBack">关闭</el-button>
<el-button v-print="printobj" style="float: right" size="mini" type="success">打印</el-button>
</div>
<div id="outsideAccommodationApply" class="el-container">
<div class="table-container" style="width: 100%;">
<h2 style="text-align: center">广西水利电力职业技术学院外宿申请表</h2>
<div class="block">
<!-- 详细入伍保留学籍表单 -->
<el-descriptions class="margin-top" title="" :column="4" size="medium" border style="width: 100%">
<el-descriptions-item>
<template slot="label"> 原宿舍号 </template>
{{ renderData.originalDormitory }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 姓名 </template>
{{ renderData.studentName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 性别 </template>
<span v-if="renderData.gender == 1"></span>
<span v-else></span>
</el-descriptions-item>
<el-descriptions-item class="birthDate">
<template slot="label"> 出生年月 </template>
{{ renderData.birthDate }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 专业系 </template>
{{ renderData.majorName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 班级 </template>
{{ renderData.className }}
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 学号 </template>
{{ renderData.studentNo }}
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 宿费交纳情况</template>
{{ renderData.accommodationFee }}
<!-- 已交 绑定当前学年年度住宿费 人民币 -->
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 身份证号码 </template>
{{ renderData.idCard }}
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 身份证号码 </template>
{{ renderData.idCard }}
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 学生联系电话 </template>
{{ renderData.studentPhone }}
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 学生联系电话 </template>
{{ renderData.studentPhone }}
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 附件材料 </template>
<Affix v-model="renderData.affixId" :disabled="true" />
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 附件材料 </template>
<AffixIndex ref="affixComponent" v-model="renderData.affixId" :disabled="true" />
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 申请原因 </template>
<div style="padding-top: 10px;">
{{ renderData.applyReason }}
</div>
<div style="padding: 20px;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div style="padding: 0 10px;display: flex;justify-content: flex-end;align-items: center;">
<div>申请人 </div>
<div>
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + renderData.studentSignature" :preview-src-list="[baseUrl + renderData.studentSignature]">
</el-image>
</div>
</div>
<div style="padding: 0 10px;">日期 {{ renderData.createTime }}</div>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 申请原因 </template>
<div>
{{ renderData.applyReason }}
</div>
<div style="padding: 0 20px;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div>申请人 </div>
<div>
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + renderData.studentSignature"
:preview-src-list="[baseUrl + renderData.studentSignature]">
</el-image>
</div>
</div>
<div style="margin-left: 10px;">日期 {{ renderData.createTime }}</div>
</div>
</div>
</el-descriptions-item>
<!-- <el-descriptions-item span="4" v-for="item in formData.enlistmentReserveApprovalList">
<!-- <el-descriptions-item span="4" v-for="item in formData.enlistmentReserveApprovalList">
<template slot="label"> {{ item.opinionType }} </template>
<div style="padding-top: 10px;">
{{ item.approvalOpinion || "暂无意见" }}
@@ -92,54 +103,148 @@
</div>
</el-descriptions-item> -->
<el-descriptions-item span="2">
<template slot="label"> 外宿详细地址具体到门牌号 </template>
{{ renderData.address + renderData.outsideAddress }}
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 外宿居所紧急联系电话 </template>
{{ renderData.emergencyPhone }}
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 家长意见 </template>
<div style="padding-top: 10px;">
<el-image style="width: 200px; height: 150px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + renderData.parentSignAttachment" :preview-src-list="[baseUrl + renderData.parentSignAttachment]">
</el-image>
</div>
<div style="padding: 20px;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div style="padding: 0 10px;display: flex;justify-content: flex-end;align-items: center;">
<div>申请人 </div>
<div>
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + renderData.parentSignAttachment" :preview-src-list="[baseUrl + renderData.parentSignAttachment]">
</el-image>
</div>
</div>
<div style="padding: 0 10px;">日期 {{ renderData.createTime }}</div>
<el-descriptions-item span="2">
<template slot="label"> 外宿详细地址</template>
{{ renderData.address + renderData.outsideAddress }}
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 紧急联系电话 </template>
{{ renderData.emergencyPhone }}
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 家长意见 </template>
<div>
<el-image style="width: 200px; height: 150px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + renderData.parentSignAttachment"
:preview-src-list="[baseUrl + renderData.parentSignAttachment]">
</el-image>
</div>
<div style="padding: 0 20px;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div>申请人 </div>
<div>
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + renderData.parentSignAttachment"
:preview-src-list="[baseUrl + renderData.parentSignAttachment]">
</el-image>
</div>
</div>
<div style="margin-left: 10px;">日期 {{ renderData.createTime }}</div>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item span="4" class="parent parent-contact-item">
<template slot="label"> 家长联系方式 </template>
<div style="margin: -10px;">
<div style="display: flex;align-items: center;border-bottom: 1px solid #e6ebf5;">
<div class="parentLabel">通讯地址</div>
<div>{{ renderData.parentAddress + renderData.parentDetailAddress }}</div>
</div>
<div style="display: flex;align-items: center;">
<div class="parentLabel">
联系电话</div>
<div>{{ renderData.parentPhone }}</div>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 本人承诺 </template>
<div v-html="renderData.promiseContent">
<!-- {{ renderData.promiseContent }} -->
</div>
<div style="padding: 0 20px;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div>申请人 </div>
<div>
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + renderData.studentPromiseSign"
:preview-src-list="[baseUrl + renderData.studentPromiseSign]">
</el-image>
</div>
</div>
<div style="margin-left: 10px;">日期 {{ renderData.createTime }}</div>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item span="4" v-for="item in renderData.outsideAccommodationApprovals">
<template slot="label"> {{ item.opinionType }} </template>
<div>{{ item.approvalOpinion }}</div>
<div style="padding: 0 20px;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div style="margin-right: 10px;">
<span>
审批结果
<el-tag v-if="item.approvalResult == 1" type="success">通过</el-tag>
<el-tag v-else type="danger">驳回</el-tag>
</span>
</div>
<div
style="display: flex;justify-content: center;align-items: center;min-width: 130px;text-align: left;">
<div>签名 </div>
<div>
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + item.signature"
:preview-src-list="[baseUrl + item.signature]" :alt="item.approverName">
</el-image>
<!-- {{ item.approverName }} -->
</div>
</div>
<div style="margin-left: 10px;">日期 {{ item.approvalTime }}</div>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 申请编号 </template>
{{ renderData.applyNo }}
</el-descriptions-item>
</el-descriptions>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 家长联系方式 </template>
<div>
<div style="display: flex;align-items: center;">
<div>通讯地址</div>
<div>{{ renderData.parentAddress + renderData.parentDetailAddress }}</div>
</div>
<div style="display: flex;align-items: center;">
<div>联系电话</div>
<div>{{ renderData.parentPhone }}</div>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 保留学籍时间和编号 </template>
{{ renderData.reserveNo }}
</el-descriptions-item>
</el-descriptions>
</div>
<div style="margin-top: 20px;" v-if="isShwo">
<el-timeline>
<el-timeline-item v-for="(item, index) in flowRecordList" :key="index" :icon="setIcon(item.finishTime)"
:color="setColor(item.finishTime)">
<p style="font-weight: 700">{{ item.taskName }}</p>
<el-card :body-style="{ padding: '10px' }">
<el-descriptions class="margin-top" :column="1" size="small" border>
<el-descriptions-item v-if="item.assigneeName" label-class-name="my-label">
<template slot="label"><i class="el-icon-user" />办理人</template>
{{ item.assigneeName }}
<el-tag type="info" size="mini">{{ item.deptName }}</el-tag>
</el-descriptions-item>
<el-descriptions-item v-if="item.candidate" label-class-name="my-label">
<template slot="label"><i class="el-icon-user" />候选办理</template>
{{ item.candidate }}
</el-descriptions-item>
<el-descriptions-item label-class-name="my-label">
<template slot="label"><i class="el-icon-date" />接收时间</template>
{{ item.createTime }}
</el-descriptions-item>
<el-descriptions-item v-if="item.finishTime" label-class-name="my-label">
<template slot="label"><i class="el-icon-date" />处理时间</template>
{{ item.finishTime }}
</el-descriptions-item>
<el-descriptions-item v-if="item.duration" label-class-name="my-label">
<template slot="label"><i class="el-icon-time" />耗时</template>
{{ item.duration }}
</el-descriptions-item>
<el-descriptions-item v-if="item.comment" label-class-name="my-label">
<template slot="label"><i class="el-icon-tickets" />处理意见</template>
{{ item.comment.comment }}
</el-descriptions-item>
<!-- <el-descriptions-item v-if="item.finishTime" label-class-name="my-label">
<template slot="label"><i class="el-icon-date" />签名</template>
<img :src="baseurl + item.assigneeSign" width="300px" height="200px" class="avatar">
</el-descriptions-item> -->
</el-descriptions>
</el-card>
</el-timeline-item>
</el-timeline>
</div>
</el-card>
</div>
</template>
@@ -147,14 +252,22 @@
import {
getOutsideAccommodationApply,
} from '@/api/dormitory/outsideAccommodation/outsideAccommodationApply'
import { flowRecord } from '@/api/flowable/finished'
import AffixIndex from "@/views/dormitory/outsideAccommodation/outsideAccommodationApply/components/affix/index"
export default {
props: {
// props类型定义Object类型+默认空对象)
formData: {
type: Object, // 正确的对象类型声明
default: () => ({}) // 函数返回空对象(避免所有实例共享同一个对象)
},
isShwo: {
type: Boolean,
default: true
}
},
components: { AffixIndex },
data() {
return {
loading: false,
@@ -162,6 +275,25 @@ export default {
// formData: {} // 注释/删除这一行
detailData: {}, // 用独立变量存储接口返回的详情数据
baseUrl: process.env.VUE_APP_BASE_API,
//打印
printobj: {
id: 'outsideAccommodationApply',
popTitle: '打印', // 打印配置页上方标题
extraHead: '', //最上方的头部文字,附加在head标签上的额外标签,使用逗号分隔
preview: '', // 是否启动预览模式,默认是false(开启预览模式,可以先预览后打印)
previewTitle: '', // 打印预览的标题(开启预览模式后出现),
previewPrintBtnLabel: '', // 打印预览的标题的下方按钮文本,点击可进入打印(开启预览模式后出现)
zIndex: '', // 预览的窗口的z-index,默认是 20002(此值要高一些,这涉及到预览模式是否显示在最上面)
previewBeforeOpenCallback() { }, //预览窗口打开之前的callback(开启预览模式调用)
previewOpenCallback() { }, // 预览窗口打开之后的callback(开启预览模式调用)
beforeOpenCallback() { }, // 开启打印前的回调事件
openCallback() { }, // 调用打印之后的回调事件
closeCallback() { }, //关闭打印的回调事件(无法确定点击的是确认还是取消)
url: '',
standard: '',
extraCss: '',
},
flowRecordList: [], // 流程流转数据
}
},
// 计算属性判断优先级
@@ -169,9 +301,28 @@ export default {
renderData() {
// 规则有接口数据detailData有内容则用detailData否则用props的formData
// Object.keys(this.detailData).length > 0 表示detailData非空
return Object.keys(this.detailData).length > 0
? this.detailData
: this.formData;
let data = Object.keys(this.detailData).length > 0 ? this.detailData : this.formData
// 处理外宿审批意见列表,添加意见类型
if (data?.outsideAccommodationApprovals) {
// 定义外宿审批意见类型数组(与索引严格对应)
const opinionTypes = [
"辅导员意见",
"二级学院书记意见",
"学工处意见",
"学校领导意见"
];
// 遍历审批列表,为每条数据添加 opinionType 字段
data.outsideAccommodationApprovals.forEach((item, index) => {
// 前4条数据按索引匹配意见类型超出部分设为默认值
if (index < opinionTypes.length) {
item.opinionType = opinionTypes[index];
} else {
// 超出4条时的兜底值
item.opinionType = "其他审批意见";
}
});
}
return data
}
},
watch: {
@@ -187,7 +338,8 @@ export default {
.then(res => {
// 修正Promise语法逗号改分号/换行)
this.detailData = { ...res.data }; // 接口数据存入独立变量
this.loading = false;
this.getFlowRecordList(this.detailData.processInstanceId, this.detailData.deployId)
// this.loading = false;
console.log(this.detailData);
})
// 添加异常捕获避免接口报错导致loading一直显示
@@ -204,7 +356,53 @@ export default {
}
}
},
methods: {},
methods: {
goBack() {
// 1. 先清空附件组件数据(主动触发清理)
this.$nextTick(() => {
// 如果Affix组件有ref比如ref="affixComponent"主动调用clearData
if (this.$refs.affixComponent) {
this.$refs.affixComponent.clearData();
}
// 2. 优化退出逻辑先关闭tab再返回避免重复操作
this.$tab.closePage().then(() => {
// 仅当需要返回上一页时执行(根据业务场景选择)
// this.$router.back();
});
});
},
/** 流程流转记录 */
getFlowRecordList(processInstanceId, deploy) {
let procInsId = processInstanceId
let deployId = deploy
const that = this
const params = { procInsId: procInsId, deployId: deployId }
flowRecord(params)
.then((res) => {
that.flowRecordList = res.data.flowList
this.loading = false
})
.catch((res) => {
this.loading = false
this.goBack()
})
},
setIcon(val) {
if (val) {
return 'el-icon-check'
} else {
return 'el-icon-time'
}
},
setColor(val) {
if (val) {
return '#2bc418'
} else {
return '#b3bdbb'
}
},
},
created() { },
mounted() { },
destroyed() { }
@@ -212,4 +410,29 @@ export default {
</script>
<style scoped>
/* @import url(); 引入css类 */
.application-form-container {
margin: auto;
padding: 30px;
box-sizing: border-box;
font-family: "Source Han Sans CN", "PingFang SC", "Microsoft YaHei", sans-serif;
}
.el-container ::v-deep .el-descriptions-item__label {
text-align: center !important;
width: 80px;
}
.el-container .birthDate ::v-deep .el-descriptions-item__label {
width: 50px;
}
.parentLabel {
margin-right: 10px;
border-right: 1px solid #e6ebf5;
background: #fafafa;
padding: 10px;
width: 100px;
text-align: center;
color: #909399;
}
</style>

View File

@@ -1,24 +1,25 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px" :label-position="`left`">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px"
:label-position="`left`">
<el-form-item label="学号" prop="studentNo">
<el-input v-model="queryParams.studentNo" placeholder="请输入学号" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="学生姓名" prop="studentName">
<el-form-item label="学生姓名" prop="studentName" v-if="!roleGroup.includes('学生')">
<el-input v-model="queryParams.studentName" placeholder="请输入学生姓名" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="性别" prop="gender">
<!-- <el-form-item label="性别" prop="gender">
<el-input v-model="queryParams.gender" placeholder="请输入性别" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
</el-form-item> -->
<!-- <el-form-item label="出生年月" prop="birthDate">
<el-date-picker clearable v-model="queryParams.birthDate" type="date" value-format="yyyy-MM-dd"
placeholder="请选择出生年月">
</el-date-picker>
</el-form-item> -->
<!-- <el-form-item label="学院名称" prop="deptName">
<el-form-item label="学院名称" prop="deptName" v-if="!roleGroup.includes('二级学院')">
<el-input v-model="queryParams.deptName" placeholder="请输入学院名称" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="专业名称" prop="majorName">
<!-- <el-form-item label="专业名称" prop="majorName">
<el-input v-model="queryParams.majorName" placeholder="请输入专业名称" clearable @keyup.enter.native="handleQuery" />
</el-form-item> -->
<el-form-item label="班级名称" prop="className">
@@ -37,7 +38,7 @@
<!-- <el-form-item label="是否有效" prop="isValid">
<el-input v-model="queryParams.isValid" placeholder="请输入是否有效" clearable @keyup.enter.native="handleQuery" />
</el-form-item> -->
<el-form-item label="辅导员姓名" prop="teacherName" label-width="88px">
<el-form-item label="辅导员姓名" prop="teacherName" label-width="88px" v-if="!roleGroup.includes('辅导员')">
<el-input v-model="queryParams.teacherName" placeholder="请输入辅导员姓名" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
@@ -107,30 +108,36 @@
</el-table-column>
<el-table-column label="外宿详细地址" align="center" prop="outsideAddress">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.address + ' ' + scope.row.outsideAddress" placement="top">
<el-tooltip class="item" effect="dark" :content="scope.row.address + ' ' + scope.row.outsideAddress"
placement="top">
<div class="text-ellipsis">{{ scope.row.address + " " + scope.row.outsideAddress }}</div>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="外宿开始时间" align="center" prop="startDate" width="100px">
<el-table-column label="外宿开始时间" align="center" prop="startDate" width="100px">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.startDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="外宿结束时间" align="center" prop="endDate" width="100px">
<el-table-column label="外宿结束时间" align="center" prop="endDate" width="100px">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.endDate, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="申请状态" align="center" prop="status" width="110px">
<template slot-scope="scope">
<el-tag v-if="scope.row.status == 0 && scope.row.status == ''" type="info">待提交</el-tag>
<el-tag v-if="scope.row.status == 6" type="info">审批驳回</el-tag>
<el-tag v-if="scope.row.status == 1">待辅导员审批</el-tag>
<el-tag v-if="scope.row.status == 2">待学院书记审批</el-tag>
<el-tag v-if="scope.row.status == 3">待学工处审批</el-tag>
<el-tag v-if="scope.row.status == 4">待学校领导审批</el-tag>
<el-tag v-if="scope.row.status == 5" type="success">审核通过</el-tag>
<!-- 优先判断是否驳回只要有一条审批结果为0就显示驳回 -->
<!-- 动态显示驳回节点 + 驳回文字 -->
<el-tag v-if="getRejectInfo(scope.row.outsideAccommodationApprovals).isReject" type="danger">
{{ getRejectInfo(scope.row.outsideAccommodationApprovals).rejectText }}
</el-tag>
<!-- 调整顺序驳回优先级最高 -->
<el-tag v-else-if="scope.row.status == 0 || scope.row.status == ''" type="info">待提交</el-tag>
<el-tag v-else-if="scope.row.status == 1">待辅导员审批</el-tag>
<el-tag v-else-if="scope.row.status == 2">待学院书记审批</el-tag>
<el-tag v-else-if="scope.row.status == 3">待学工处审批</el-tag>
<el-tag v-else-if="scope.row.status == 4">待学校领导审批</el-tag>
<el-tag v-else-if="scope.row.status == 5" type="success">审核通过</el-tag>
</template>
</el-table-column>
<el-table-column label="是否有效" align="center" prop="isValid">
@@ -142,10 +149,11 @@
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['dormitory:outsideAccommodationApply:edit']" v-if="scope.row.status == 0 || scope.row.status == 6">修改</el-button>
v-hasPermi="['dormitory:outsideAccommodationApply:edit']"
v-if="scope.row.status == 0 || getRejectInfo(scope.row.outsideAccommodationApprovals).isReject">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['dormitory:outsideAccommodationApply:remove']" v-if="scope.row.status == 0">删除</el-button>
<el-button v-if="scope.row.applyStatus != 0" size="mini" type="text" icon="el-icon-info"
v-hasPermi="['dormitory:outsideAccommodationApply:remove']" v-if="scope.row.status == 0 || roleGroup.includes('管理员')">删除</el-button>
<el-button v-if="scope.row.applyStatus != 0" size="mini" type="text" icon="el-icon-info"
@click="detail(scope.row)">详情</el-button>
</template>
</el-table-column>
@@ -287,6 +295,7 @@
<script>
import { listOutsideAccommodationApply, getOutsideAccommodationApply, delOutsideAccommodationApply, addOutsideAccommodationApply, updateOutsideAccommodationApply } from "@/api/dormitory/outsideAccommodation/outsideAccommodationApply";
import { getUserProfile } from '@/api/system/user' // 获取当前登录用户
export default {
name: "OutsideAccommodationApply",
@@ -466,11 +475,20 @@ export default {
teacherName: [
{ required: true, message: "辅导员姓名不能为空", trigger: "blur" }
],
}
},
roleGroup: '',
user: ''
};
},
created() {
this.getList();
// this.getList();
},
// 路由守卫:当路由进入该组件时触发(解决返回后不刷新问题)
beforeRouteEnter(to, from, next) {
next(vm => {
// vm 是组件实例,这里调用数据加载方法
vm.getUser();
});
},
methods: {
/** 查询外宿申请列表 */
@@ -482,6 +500,24 @@ export default {
this.loading = false;
});
},
getUser() {
getUserProfile().then(response => {
this.user = response.data
this.roleGroup = response.roleGroup;
// this.postGroup = response.postGroup;
if (this.roleGroup) {
if (this.roleGroup.includes("学生")) {
this.queryParams.studentName = this.user.nickName
} else if (this.roleGroup.includes("辅导员")) {
this.queryParams.teacherName = this.user.nickName
} else if (this.roleGroup.includes("二级学院")) {
this.queryParams.deptName = this.user.dept.deptName
}
this.getList()
}
})
},
// 取消按钮
cancel() {
this.open = false;
@@ -611,13 +647,44 @@ export default {
},
// 跳转申请表
openForm() {
// 利用some方法快速判断是否存在重复申请找到匹配项后立即终止遍历
const isDuplicate = this.outsideAccommodationApplyList?.some(element =>
element.studentName === this.user?.nickName && element.studentNo === this.user?.userName
) || false;
if (isDuplicate) {
this.$message.error('您已经申请过了,请勿重新申请!');
} else {
this.$router.push("/dormitory/outsideAccommodation/applicationForm");
}
},
detail(row) {
this.$router.push({
path: "/dormitory/outsideAccommodation/detailApply",
query: { id: row.id } // 将 row.id 放在 query 中
});
},
/**
* 获取驳回信息(是否驳回 + 驳回文字)
* @param {Array} approvalList 审批意见列表
* @returns {Object} { isReject: 布尔值, rejectText: 驳回文字 }
*/
getRejectInfo(approvalList) {
// 空值保护:列表不存在/非数组/为空时,返回未驳回
if (!approvalList || !Array.isArray(approvalList) || approvalList.length === 0) {
return { isReject: false, rejectText: '' };
}
// 找到第一个审批结果为0驳回的记录
const rejectItem = approvalList.find(item => item.approvalResult === 0);
if (rejectItem) {
// 提取审批节点名称(如「辅导员审批」→ 截取「辅导员」)
const nodeName = rejectItem.approvalNode.replace('审批', '');
// 拼接驳回文字(如「辅导员驳回」)
return { isReject: true, rejectText: `${nodeName}驳回` };
} else {
// 无驳回记录
return { isReject: false, rejectText: '' };
}
}
}
};

View File

@@ -8,7 +8,7 @@
<el-input v-model="queryParams.approvalNode" placeholder="请输入审批节点" clearable
@keyup.enter.native="handleQuery" />
</el-form-item> -->
<el-form-item label="审批人" prop="approverName">
<el-form-item label="审批人" prop="approverName" v-if="roleGroup.includes('管理员')">
<el-input v-model="queryParams.approverName" placeholder="请输入审批人姓名" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
@@ -30,7 +30,7 @@
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- <el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['dormitory:outsideAccommodationApproval:add']">新增</el-button>
</el-col>
@@ -45,7 +45,7 @@
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
v-hasPermi="['dormitory:outsideAccommodationApproval:export']">导出</el-button>
</el-col>
</el-col> -->
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
@@ -75,10 +75,11 @@
<!-- <el-table-column label="流程实例ID" align="center" prop="processInstanceId" /> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
<!-- <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['dormitory:outsideAccommodationApproval:edit']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['dormitory:outsideAccommodationApproval:remove']">删除</el-button>
v-hasPermi="['dormitory:outsideAccommodationApproval:remove']">删除</el-button> -->
<el-button size="mini" type="text" icon="el-icon-info" @click="detail(scope.row)">详情</el-button>
</template>
</el-table-column>
</el-table>
@@ -89,18 +90,18 @@
<!-- 添加或修改外宿申请审批记录对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="外宿申请ID" prop="applyId">
<!-- <el-form-item label="外宿申请ID" prop="applyId">
<el-input v-model="form.applyId" placeholder="请输入外宿申请ID" />
</el-form-item>
<el-form-item label="申请编号" prop="applyNo">
</el-form-item> -->
<!-- <el-form-item label="申请编号" prop="applyNo">
<el-input v-model="form.applyNo" placeholder="请输入申请编号" />
</el-form-item>
</el-form-item> -->
<el-form-item label="审批节点" prop="approvalNode">
<el-input v-model="form.approvalNode" placeholder="请输入审批节点" />
</el-form-item>
<el-form-item label="审批人ID" prop="approverId">
<!-- <el-form-item label="审批人ID" prop="approverId">
<el-input v-model="form.approverId" placeholder="请输入审批人ID" />
</el-form-item>
</el-form-item> -->
<el-form-item label="审批人姓名" prop="approverName">
<el-input v-model="form.approverName" placeholder="请输入审批人姓名" />
</el-form-item>
@@ -118,9 +119,9 @@
placeholder="请选择审批时间">
</el-date-picker>
</el-form-item>
<el-form-item label="流程实例ID" prop="processInstanceId">
<!-- <el-form-item label="流程实例ID" prop="processInstanceId">
<el-input v-model="form.processInstanceId" placeholder="请输入流程实例ID" />
</el-form-item>
</el-form-item> -->
<el-form-item label="学生姓名" prop="studentName">
<el-input v-model="form.studentName" placeholder="请输入学生姓名" />
</el-form-item>
@@ -138,7 +139,7 @@
<script>
import { listOutsideAccommodationApproval, getOutsideAccommodationApproval, delOutsideAccommodationApproval, addOutsideAccommodationApproval, updateOutsideAccommodationApproval } from "@/api/dormitory/outsideAccommodation/outsideAccommodationApproval";
import { getUserProfile } from '@/api/system/user' // 获取当前登录用户
export default {
name: "OutsideAccommodationApproval",
data() {
@@ -212,11 +213,13 @@ export default {
studentNo: [
{ required: true, message: "学生学号不能为空", trigger: "blur" }
]
}
},
roleGroup: '',
user: ''
};
},
created() {
this.getList();
this.getUser();
},
methods: {
/** 查询外宿申请审批记录列表 */
@@ -228,6 +231,20 @@ export default {
this.loading = false;
});
},
getUser() {
getUserProfile().then(response => {
this.user = response.data
this.roleGroup = response.roleGroup;
// this.postGroup = response.postGroup;
if (this.roleGroup) {
if (!this.roleGroup.includes("管理员")) {
this.queryParams.approverName = this.user.nickName
}
this.getList()
}
})
},
// 取消按钮
cancel() {
this.open = false;
@@ -319,7 +336,13 @@ export default {
this.download('dormitory/outsideAccommodationApproval/export', {
...this.queryParams
}, `outsideAccommodationApproval_${new Date().getTime()}.xlsx`)
}
},
detail(row) {
this.$router.push({
path: "/dormitory/outsideAccommodation/detailApply",
query: { id: row.applyId } // 将 row.id 放在 query 中
});
},
}
};
</script>

View File

@@ -5,8 +5,8 @@
<el-input v-model="queryParams.attachmentName" placeholder="请输入附件名称" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="学生姓名" prop="studentName">
<el-input v-model="queryParams.studentName" placeholder="请输入学生姓名" clearable @keyup.enter.native="handleQuery" />
<el-form-item label="学生姓名" prop="studentName" v-if="!roleGroup.includes('学生')">
<el-input v-model="queryParams.studentName" placeholder="请输入学生姓名" clearable @keyup.enter.native="handleQuery"/>
</el-form-item>
<el-form-item label="学生学号" prop="studentNo">
<el-input v-model="queryParams.studentNo" placeholder="请输入学生学号" clearable @keyup.enter.native="handleQuery" />
@@ -18,22 +18,22 @@
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- <el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['dormitory:outsideAccommodationAttachment:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
</el-col> -->
<!-- <el-col :span="1.5">
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
v-hasPermi="['dormitory:outsideAccommodationAttachment:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
</el-col> -->
<!-- <el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
v-hasPermi="['dormitory:outsideAccommodationAttachment:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
</el-col> -->
<!-- <el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
v-hasPermi="['dormitory:outsideAccommodationAttachment:export']">导出</el-button>
</el-col>
</el-col> -->
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
@@ -43,18 +43,41 @@
<!-- <el-table-column label="外宿申请ID" align="center" prop="applyId" /> -->
<el-table-column label="学生姓名" align="center" prop="studentName" />
<el-table-column label="学生学号" align="center" prop="studentNo" />
<el-table-column label="附件名称" align="center" prop="attachmentName" />
<el-table-column label="附件存储URL" align="center" prop="attachmentUrl" />
<el-table-column label="附件类型" align="center" prop="attachmentType" />
<el-table-column label="附件名称" align="center" prop="attachmentName">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="scope.row.attachmentName" placement="top">
<div class="text-ellipsis">{{ scope.row.attachmentName }}</div>
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="附件路径" align="center" prop="attachmentUrl">
<template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="`点击可下载文件`" placement="top">
<div class="text-ellipsis">
<el-link :href="`${baseUrl}${scope.row.attachmentUrl}`" :underline="false" target="_blank">
<span style="color: #007AFF;">{{ scope.row.attachmentUrl }}</span>
</el-link>
</div>
</el-tooltip>
</template>
</el-table-column>
<!-- <el-table-column label="附件类型" align="center" prop="attachmentType" /> -->
<el-table-column label="附件大小" align="center" prop="fileSize" />
<el-table-column label="附件后缀" align="center" prop="fileSuffix" />
<el-table-column label="流程实例ID" align="center" prop="processInstanceId" />
<el-table-column label="上传时间" align="center" prop="createTime" width="100px">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<!-- <el-table-column label="流程实例ID" align="center" prop="processInstanceId" /> -->
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-if="getRejectInfo(scope.row.outsideAccommodationApplies[0].outsideAccommodationApprovals).isReject"
v-hasPermi="['dormitory:outsideAccommodationAttachment:edit']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['dormitory:outsideAccommodationAttachment:remove']">删除</el-button>
<!-- <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['dormitory:outsideAccommodationAttachment:remove']">删除</el-button> -->
<el-button size="mini" type="text" icon="el-icon-info" @click="detail(scope.row)">详情</el-button>
</template>
</el-table-column>
</el-table>
@@ -100,11 +123,12 @@
<script>
import { listOutsideAccommodationAttachment, getOutsideAccommodationAttachment, delOutsideAccommodationAttachment, addOutsideAccommodationAttachment, updateOutsideAccommodationAttachment } from "@/api/dormitory/outsideAccommodation/outsideAccommodationAttachment";
import { getUserProfile } from '@/api/system/user' // 获取当前登录用户
export default {
name: "OutsideAccommodationAttachment",
data() {
return {
baseUrl: process.env.VUE_APP_BASE_API,
// 遮罩层
loading: true,
// 选中数组
@@ -159,11 +183,13 @@ export default {
studentNo: [
{ required: true, message: "学生学号不能为空", trigger: "blur" }
]
}
},
roleGroup: '',
user: ''
};
},
created() {
this.getList();
this.getUser();
},
methods: {
/** 查询外宿申请附件列表 */
@@ -175,6 +201,20 @@ export default {
this.loading = false;
});
},
getUser() {
getUserProfile().then(response => {
this.user = response.data
this.roleGroup = response.roleGroup;
// this.postGroup = response.postGroup;
if (this.roleGroup) {
if (this.roleGroup.includes("学生")) {
this.queryParams.studentName = this.user.nickName
}
this.getList()
}
})
},
// 取消按钮
cancel() {
this.open = false;
@@ -221,12 +261,16 @@ export default {
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset();
const id = row.id || this.ids
getOutsideAccommodationAttachment(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改外宿申请附件";
// this.reset();
// const id = row.id || this.ids
// getOutsideAccommodationAttachment(id).then(response => {
// this.form = response.data;
// this.open = true;
// this.title = "修改外宿申请附件";
// });
this.$router.push({
path: "/dormitory/outsideAccommodation/applicationForm",
query: { id: row.outsideAccommodationApplies[0].id } // 将 row.id 放在 query 中
});
},
/** 提交按钮 */
@@ -264,7 +308,45 @@ export default {
this.download('dormitory/outsideAccommodationAttachment/export', {
...this.queryParams
}, `outsideAccommodationAttachment_${new Date().getTime()}.xlsx`)
}
},
/**
* 获取驳回信息(是否驳回 + 驳回文字)
* @param {Array} approvalList 审批意见列表
* @returns {Object} { isReject: 布尔值, rejectText: 驳回文字 }
*/
getRejectInfo(approvalList) {
// 空值保护:列表不存在/非数组/为空时,返回未驳回
if (!approvalList || !Array.isArray(approvalList) || approvalList.length === 0) {
return { isReject: false, rejectText: '' };
}
// 找到第一个审批结果为0驳回的记录
const rejectItem = approvalList.find(item => item.approvalResult === 0);
if (rejectItem) {
// 提取审批节点名称(如「辅导员审批」→ 截取「辅导员」)
const nodeName = rejectItem.approvalNode.replace('审批', '');
// 拼接驳回文字(如「辅导员驳回」)
return { isReject: true, rejectText: `${nodeName}驳回` };
} else {
// 无驳回记录
return { isReject: false, rejectText: '' };
}
},
detail(row) {
this.$router.push({
path: "/dormitory/outsideAccommodation/detailApply",
query: { id: row.outsideAccommodationApplies[0].id } // 将 row.id 放在 query 中
});
},
}
};
}
</script>
<style scoped>
.text-ellipsis {
white-space: nowrap;
/* 防止文本换行 */
overflow: hidden;
/* 隐藏溢出的内容 */
text-overflow: ellipsis;
/* 显示省略号 */
}
</style>

View File

@@ -313,6 +313,317 @@
{{ form.instructionSchoolHours }}
</el-descriptions-item>
</el-descriptions>
<!-- 入伍保留学籍表单 -->
<el-descriptions v-if="enlistmentReserveForm" class="margin-top" title="" :column="4" size="medium" border style="width: 100%">
<el-descriptions-item>
<template slot="label"> 姓名 </template>
{{ form.studentName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 性别 </template>
<span v-if="form.gender == 1"></span>
<span v-else></span>
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 民族 </template>
<!-- {{ form.nation }} -->
<dict-tag :options="dict.type.rt_nation" :value="form.nation" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 年级 </template>
{{ form.grade }}
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 专业名称 </template>
{{ form.major }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 学号 </template>
{{ form.studentNo }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 班级 </template>
{{ form.className }}
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 家庭地址 </template>
{{ form.familyAddress }}
</el-descriptions-item>
<el-descriptions-item span="2">
<template slot="label"> 家长电话 </template>
{{ form.parentPhone }}
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 附件材料 </template>
<Affix v-model="form.affixId" :disabled="true" />
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 申请原因 </template>
<div style="padding-top: 10px;">
{{ form.applyReason }}
</div>
<div style="padding: 20px;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div style="padding: 0 10px;">申请人 {{ form.studentName }}</div>
<div style="padding: 0 10px;">日期 {{ form.createTime }}</div>
</div>
</div>
</el-descriptions-item>
<el-descriptions-item span="4" v-for="item in form.enlistmentReserveApprovalList" >
<template slot="label"> {{ item.opinionType }} </template>
<div style="padding-top: 10px;">
{{ item.approvalOpinion || "暂无意见" }}
</div>
<div style="padding: 20px;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div style="padding: 0 10px;">
审批结果
<el-tag v-if="item.approvalResult == 1" type="success">通过</el-tag>
<el-tag v-else type="danger">驳回</el-tag>
</div>
<div
style="display: flex;justify-content: center;align-items: center;min-width: 130px;text-align: left;">
<div>签名 </div>
<div>
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + item.signature" :preview-src-list="[baseUrl + item.signature]"
:alt="item.approverName">
</el-image>
</div>
</div>
<div style="padding: 0 10px;">日期 {{ item.approvalTime }}</div>
</div>
</div>
</el-descriptions-item>
<!-- <el-descriptions-item span="3">
<template slot="label"> 辅导员联系情况 </template>
{{ form.ideologicalEducation }}
</el-descriptions-item> -->
<el-descriptions-item span="4">
<template slot="label"> 保留学籍时间和编号 </template>
{{ form.reserveNo }}
</el-descriptions-item>
</el-descriptions>
<!-- 外宿申请表单 -->
<div v-if="outsideAccommodationForm"><detailApply :formData="form" :isShwo="false"></detailApply></div>
<!-- 退伍复学表单 -->
<el-descriptions v-if="basicForm" class="margin-top" title="退伍复学申请表" :column="4" size="medium" border
style="width: 100%; ">
<el-descriptions-item>
<template slot="label"> 姓名 </template>
{{ form.stName }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 性别 </template>
{{ form.sex }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 民族 </template>
<!-- {{ form.nation }} -->
<dict-tag :options="dict.type.rt_nation" :value="form.nations" />
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 年级 </template>
{{ form.grade }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 班级 </template>
{{ form.stClass }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 学号 </template>
{{ form.stId }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 专业 </template>
{{ form.majors }}
</el-descriptions-item>
<el-descriptions-item>
<template slot="label"> 联系电话 </template>
{{ form.datab }}
</el-descriptions-item>
<el-descriptions-item span="4">
<template slot="label"> 申请理由 </template>
<div style="padding-top: 10px; line-height: 1.8;">
<p class="reason-text">本人于 {{ form.rwTime | formatDate }} 应征入伍 {{ form.dataa | formatDate }}
日退役退役后申请复学</p>
<p class="reason-text" v-if="form.conversion == 'Y'">是否申请转专业 </p>
<p class="reason-text" v-else>是否申请转专业 ×</p>
<p v-if="form.conversion === 'Y'" class="reason-text" style="color: red;">
原年级和专业:__{{ form.maList.length > 0 ? form.maList[0].oldgrade : '' }}__{{ form.maList.length > 0 ?
form.maList[0].oldmajor : '' }}__
申请转入年级和专业__{{ saveGradeName }}__{{ saveClassName }}__
</p>
<!-- 附件预览区域 -->
<div style="margin: 10px 0; display: flex; gap: 10px; flex-wrap: wrap;">
<image-preview v-if="form.maList.length > 0 && form.maList[0].proof" :src="form.maList[0].proof"
:width="240" :height="160" />
<image-preview v-if="form.maList.length > 0 && form.maList[0].idcard" :src="form.maList[0].idcard"
:width="240" :height="160" />
<image-preview v-if="form.maList.length > 0 && form.maList[0].material"
:src="form.maList[0].material" :width="240" :height="160" />
</div>
<!-- 申请人信息 -->
<div class="applicant-info right-align" style="padding: 20px 0 0 0;">
<span>申请人</span>
{{ form.stName }}
<span class="date-label" style="margin-left: 10px;">日期</span>
{{ form.times | formatDate }}
</div>
</div>
</el-descriptions-item>
<!-- 招生与就业处意见仅转专业时显示 -->
<el-descriptions-item span="4" v-if="form.conversion === 'Y'">
<template slot="label"> 招生与就业处意见 </template>
<div style="padding-top: 10px; line-height: 1.8;">
<p class="reason-text" style="color: red;">
符合转专业条件拟同意转入年级和专业__{{ saveGradeName }}__{{ saveClassName }}__
</p>
<div class="signature-area right-align" style="padding: 10px 0 0 0;">
<span>审批结果</span>
<el-select v-model="form.zsStatus" placeholder="" class="short-select" disabled
style="width: 100px; margin: 0 5px;">
<el-option label="重新审核" value="0"></el-option>
<el-option label="通过" value="1"></el-option>
<el-option label="退回" value="2"></el-option>
<el-option label="驳回" value="3"></el-option>
</el-select>
<span class="date-label">签名</span>
{{ form.zsIdea || '无' }}
<span class="date-label" style="margin-left: 10px;">日期</span>
{{ form.zsTime | formatDate }}
</div>
</div>
</el-descriptions-item>
<!-- 辅导员意见 -->
<el-descriptions-item span="4">
<template slot="label"> 辅导员意见 </template>
<div style="padding-top: 10px; line-height: 1.8;">
{{ form.fdIdea || '暂无意见' }}
<div class="signature-area right-align" style="padding: 10px 0 0 0;">
<span>审批结果</span>
<el-select v-model="form.fdStatus" placeholder="待审核" class="short-select" disabled
style="width: 100px; margin: 0 5px;">
<el-option label="重新审核" value="0"></el-option>
<el-option label="通过" value="1"></el-option>
<el-option label="退回" value="2"></el-option>
<el-option label="驳回" value="3"></el-option>
</el-select>
<span class="date-label">签名</span>
{{ form.fdQm || '无' }}
<span class="date-label" style="margin-left: 10px;">日期</span>
{{ form.fdTime | formatDate }}
</div>
</div>
</el-descriptions-item>
<!-- 学务意见 -->
<el-descriptions-item span="4">
<template slot="label"> 学务意见 </template>
<div style="padding-top: 10px; line-height: 1.8;">
{{ form.xwIdea || '暂无意见' }}
<div class="signature-area right-align" style="padding: 10px 0 0 0;">
<span>审批结果</span>
<el-select v-model="form.xwStatus" placeholder="待审核" class="short-select" disabled
style="width: 100px; margin: 0 5px;">
<el-option label="重新审核" value="0"></el-option>
<el-option label="通过" value="1"></el-option>
<el-option label="退回" value="2"></el-option>
<el-option label="驳回" value="3"></el-option>
</el-select>
<span class="date-label">签名</span>
{{ form.xwQm || '无' }}
<span class="date-label" style="margin-left: 10px;">日期</span>
{{ form.xwTime | formatDate }}
</div>
</div>
</el-descriptions-item>
<!-- 二级学院意见 -->
<el-descriptions-item span="4">
<template slot="label"> 二级学院意见 </template>
<div style="padding-top: 10px; line-height: 1.8;">
{{ form.twoIdea || '暂无意见' }}
<div class="signature-area right-align" style="padding: 10px 0 0 0;">
<span>审批结果</span>
<el-select v-model="form.twoStatus" placeholder="待审核" class="short-select" disabled
style="width: 100px; margin: 0 5px;">
<el-option label="重新审核" value="0"></el-option>
<el-option label="通过" value="1"></el-option>
<el-option label="退回" value="2"></el-option>
<el-option label="驳回" value="3"></el-option>
</el-select>
<span class="date-label">签名</span>
{{ form.erQm || '无' }}
<span class="date-label" style="margin-left: 10px;">日期</span>
{{ form.twoTime | formatDate }}
</div>
</div>
</el-descriptions-item>
<!-- 学籍管理科意见 -->
<el-descriptions-item span="4">
<template slot="label"> 学籍管理科意见 </template>
<div style="padding-top: 10px; line-height: 1.8;">
{{ form.xjIdea || '暂无意见' }}
<div class="signature-area right-align" style="padding: 10px 0 0 0;">
<span>审批结果</span>
<el-select v-model="form.xjglStatus" placeholder="待审核" class="short-select" disabled
style="width: 100px; margin: 0 5px;">
<el-option label="重新审核" value="0"></el-option>
<el-option label="通过" value="1"></el-option>
<el-option label="退回" value="2"></el-option>
<el-option label="驳回" value="3"></el-option>
</el-select>
<span class="date-label">签名</span>
{{ form.xjQm || '无' }}
<span class="date-label" style="margin-left: 10px;">日期</span>
{{ form.xjTime | formatDate }}
</div>
</div>
</el-descriptions-item>
<!-- 教务处主管领导意见 -->
<el-descriptions-item span="4">
<template slot="label"> 教务处主管领导意见 </template>
<div style="padding-top: 10px; line-height: 1.8;">
{{ form.jwIdea || '暂无意见' }}
<div class="signature-area right-align" style="padding: 10px 0 0 0;">
<span>审批结果</span>
<el-select v-model="form.jwStatus" placeholder="待审核" class="short-select" disabled
style="width: 100px; margin: 0 5px;">
<el-option label="重新审核" value="0"></el-option>
<el-option label="通过" value="1"></el-option>
<el-option label="退回" value="2"></el-option>
<el-option label="驳回" value="3"></el-option>
</el-select>
<span class="date-label">签名</span>
{{ form.jwQm || '无' }}
<span class="date-label" style="margin-left: 10px;">日期</span>
{{ form.jwTime | formatDate }}
</div>
</div>
</el-descriptions-item>
</el-descriptions>
</div>
</el-col>
</el-tab-pane>
@@ -375,7 +686,12 @@ import { getRtStuQuitSchoolByProcInsId } from '@/api/routine/rtStuQuitSchool'
import Parser from '@/components/parser/Parser'
import flow from '@/views/flowable/task/finished/detail/flow'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { getEnlistmentReserveByProcessInstanceId} from "@/api/routine/enlistmentReserve/enlistmentReserve";
import { getOutsideAccommodationApplyByProcessInstanceId } from "@/api/dormitory/outsideAccommodation/outsideAccommodationApply";
import detailApply from "@/views/dormitory/outsideAccommodation/outsideAccommodationApply/components/detailApply" // 外宿申请表详细
import {getStname, getProcessId } from "@/api/routine/basic";
import { listStudent, getClassName } from '@/api/stuCQS/basedata/student'
import { listGrade } from '@/api/stuCQS/basedata/grade'
export default {
name: 'Record',
@@ -383,6 +699,7 @@ export default {
components: {
Parser,
flow,
detailApply
},
props: {},
data () {
@@ -424,6 +741,9 @@ export default {
disposalForm: false, // 处分表单
relieveForm: false, // 解除处分表单
quitSchoolForm: false, // 休学申请表单
enlistmentReserveForm: false, // 入伍保留学籍表单
outsideAccommodationForm: false, // 外宿申请表单
basicForm:false,//退伍复学表单
form: {},
// 学生基础信息
stuInfo: {},
@@ -448,6 +768,15 @@ export default {
} else if (this.category == 'quitSchool') {
this.quitSchoolForm = true
this.getRtStuQuitSchoolByProcInsId(this.taskForm.procInsId)
} else if (this.category == 'enlistmentReserve') { // 应征入伍表单
this.enlistmentReserveForm = true
this.getEnlistmentReserve(this.taskForm.procInsId)
} else if (this.category == 'outsideAccommodation') {
this.outsideAccommodationForm = true
this.getOutsideAccommodation(this.taskForm.procInsId)
}else if (this.category == '退伍复学') {
this.basicForm = true
this.getBasicApplication(this.taskForm.procInsId)
}
// 回显流程记录
// 流程任务重获取变量表单
@@ -491,6 +820,88 @@ export default {
// this.getStuInfo(this.form.stuNo) 先注释,因为已从后台返回给数据,如果没有在放开注释
})
},
// 请求 入伍保留学籍表单数据
getEnlistmentReserve(procInsId) {
getEnlistmentReserveByProcessInstanceId(procInsId.toString()).then((res) => {
this.form = res.data
// 处理审批意见列表,添加意见类型
if (this.form?.enlistmentReserveApprovalList) {
// 定义意见类型数组与索引对应0=辅导员1=学务2=二级学院3=学籍管理科4=教务处主管领导)
const opinionTypes = [
"辅导员意见",
"学务意见",
"二级学院意见",
"学籍管理科意见",
"教务处主管领导意见"
];
// 遍历审批列表,为每条数据添加 opinionType 字段
this.form.enlistmentReserveApprovalList.forEach((item, index) => {
// 只处理前5条数据超出部分不添加或可根据实际需求调整
if (index < opinionTypes.length) {
item.opinionType = opinionTypes[index];
} else {
// 若超过5条可设置默认值或不设置
item.opinionType = "其他意见";
}
});
}
})
},
// 请求 外宿申请表单数据
getOutsideAccommodation(procInsId) {
getOutsideAccommodationApplyByProcessInstanceId(procInsId.toString()).then((res) => {
this.form = res.data
})
},
// 退伍复学申请表单数据
getBasicApplication(procInsId) {
getProcessId(procInsId.toString()).then((res) => {
// console.log("后端返回原始数据:",res.data);
this.form = res.data
this.getClassNameList()
this.listGrade()
});
},
/** 获取班级名称列表 */
getClassNameList() {
getClassName().then(res => {
this.ClassNameList = res.data
// console.log(this.ClassNameList)
if (this.ClassNameList != null) {
this.ClassNameList.forEach(element => {
if (element.value == this.form.maList[0].data1) {
// console.log(element.label)
element.children.forEach(elementTwo => {
if (elementTwo.value == this.form.maList[0].data2) {
// console.log(elementTwo.label)
elementTwo.children.forEach(elementFree => {
this.saveClassName = elementFree.label
// console.log(elementFree.label)
});
}
});
}
});
}
})
},
/** 获取年级列表 */
async listGrade() {
try {
let res = await listGrade()
if (res.code == 200) {
this.grade_list = [...res.rows]
console.log(this.grade_list)
this.grade_list.forEach(element => {
if(element.gradeId == this.form.maList[0].newgrade){
this.saveGradeName = element.gradeName
}
});
}
} catch (error) {
console.error('获取年级列表失败:', error)
}
},
getStuInfo (stuNo) {
getStuInfo(stuNo).then((res) => {
if (res.code == 200) {

View File

@@ -353,7 +353,7 @@
<template slot="label"> 申请原因 </template>
<div style="padding-top: 10px;">
{{ form.applyReason }}
</div>
</div>
<div style="padding: 20px;">
<div style="display: flex;justify-content: flex-end;align-items: center;">
<div style="padding: 0 10px;">申请人 {{ form.studentName }}</div>
@@ -362,7 +362,7 @@
</div>
</el-descriptions-item>
<el-descriptions-item span="4" v-for="item in form.enlistmentReserveApprovalList" >
<el-descriptions-item span="4" v-for="item in form.enlistmentReserveApprovalList" >
<template slot="label"> {{ item.opinionType }} </template>
<div style="padding-top: 10px;">
{{ item.approvalOpinion || "暂无意见" }}
@@ -374,7 +374,16 @@
<el-tag v-if="item.approvalResult == 1" type="success">通过</el-tag>
<el-tag v-else type="danger">驳回</el-tag>
</div>
<div style="padding: 0 10px;">签名 {{ item.approverName }}</div>
<div
style="display: flex;justify-content: center;align-items: center;min-width: 130px;text-align: left;">
<div>签名 </div>
<div>
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + item.signature" :preview-src-list="[baseUrl + item.signature]"
:alt="item.approverName">
</el-image>
</div>
</div>
<div style="padding: 0 10px;">日期 {{ item.approvalTime }}</div>
</div>
</div>
@@ -390,7 +399,8 @@
{{ form.reserveNo }}
</el-descriptions-item>
</el-descriptions>
<!-- 外宿申请表单 -->
<div v-if="outsideAccommodationForm"><detailApply :formData="form" :isShwo="false"></detailApply></div>
</div>
</el-col>
</el-tab-pane>
@@ -455,6 +465,8 @@ import Parser from '@/components/parser/Parser'
import flow from '@/views/flowable/task/myProcess/detail/flow'
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import { getEnlistmentReserveByProcessInstanceId} from "@/api/routine/enlistmentReserve/enlistmentReserve";
import { getOutsideAccommodationApplyByProcessInstanceId } from "@/api/dormitory/outsideAccommodation/outsideAccommodationApply";
import detailApply from "@/views/dormitory/outsideAccommodation/outsideAccommodationApply/components/detailApply" // 外宿申请表详细
export default {
name: 'Record',
@@ -462,6 +474,7 @@ export default {
components: {
Parser,
flow,
detailApply
},
props: {},
data() {
@@ -492,6 +505,7 @@ export default {
relieveForm: false, // 解除处分表单
quitSchoolForm: false, // 休学申请表单
enlistmentReserveForm: false, // 入伍保留学籍表单
outsideAccommodationForm: false, // 外宿申请表单
form: {},
// 学生基础信息
stuInfo: {},
@@ -520,7 +534,10 @@ export default {
} else if (this.category == 'enlistmentReserve') { // 应征入伍表单
this.enlistmentReserveForm = true
this.getEnlistmentReserve(this.taskForm.procInsId)
}
} else if (this.category == 'outsideAccommodation') {
this.outsideAccommodationForm = true
this.getOutsideAccommodation(this.taskForm.procInsId)
}
// 回显流程记录
// 流程任务重获取变量表单
this.processVariables(this.taskForm.taskId)
@@ -589,6 +606,12 @@ export default {
}
})
},
// 请求 外宿申请表单数据
getOutsideAccommodation(procInsId) {
getOutsideAccommodationApplyByProcessInstanceId(procInsId.toString()).then((res) => {
this.form = res.data
})
},
getStuInfo(stuNo) {
getStuInfo(stuNo).then((res) => {
if (res.code == 200) {

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
<template>
<div class="app-container">
<el-form v-show="showSearch" ref="queryForm" :model="queryParams" :inline="true" label-width="68px">
<el-form v-show="showSearch" ref="queryForm" :model="queryParams" :inline="true" label-width="100px">
<el-form-item label="名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入名称" clearable size="small" @keyup.enter.native="handleQuery" />
</el-form-item>

View File

@@ -439,6 +439,7 @@ export default {
this.form.twoStatus=0
this.form.Status=0
this.form.jwStatus=0
this.form.testData=0
this.form.fdIdea=""
this.form.xwIdeaI=""

View File

@@ -205,7 +205,7 @@
<td class="input-cell" colspan="8" rowspan="4">
<!-- <el-input v-model="form.xwIdea" type="textarea" :rows="3" placeholder="请填写意见..."
class="opinion-textarea"></el-input> -->
{{ form.xwIdea }}
{{ form.xwIdea }}拟编入___
<div class="signature-area right-align">
<span>审批结果</span>
<el-select v-model="form.xwStatus" placeholder="待审核" class="short-select" disabled>

View File

@@ -9,7 +9,15 @@
</el-form-item>
<el-form-item label="时间" prop="times">
<el-input v-model="queryParams.times" placeholder="请输入时间" clearable @keyup.enter.native="handleQuery" />
<el-form-item label="时间" prop="times">
<el-date-picker
v-model="queryParams.times"
clearable
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择申请时间"
/>
</el-form-item>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
@@ -65,7 +73,7 @@
<el-tag v-else-if="scope.row.twoStatus == 1 && ( scope.row.xjglStatus == 0 || scope.row.xjglStatus == null)" >学籍管理审核中</el-tag>
<el-tag v-else-if="scope.row.xjglStatus == 1 && ( scope.row.jwStatus == 0 || scope.row.jwStatus == null)" >教务处主管审核中</el-tag>
<el-tag v-else-if="scope.row.fdStatus == 1 || scope.row.xwStatus == 1 || scope.row.twoStatus == 1 || scope.row.xjglStatus == 1 || scope.row.jwStatus == 1 " type="success">审批通过</el-tag>
<el-tag v-else-if="scope.row.zsStatus == 1 && scope.row.fdStatus == 1 && scope.row.xwStatus == 1 && scope.row.twoStatus == 1 && scope.row.xjglStatus == 1 && scope.row.jwStatus == 1 " type="success">审批通过</el-tag>
<el-tag v-else-if="scope.row.fdStatus == 2 || scope.row.xwStatus == 2 || scope.row.twoStatus == 2 || scope.row.xjglStatus == 2 || scope.row.jwStatus == 2 "
type="danger"
@@ -83,8 +91,7 @@
<el-tag v-else-if="scope.row.xwStatus == 1 && ( scope.row.twoStatus == 0 || scope.row.twoStatus == null)" >二级学院审核中</el-tag>
<el-tag v-else-if="scope.row.twoStatus == 1 && ( scope.row.xjglStatus == 0 || scope.row.xjglStatus == null)" >学籍管理审核中</el-tag>
<el-tag v-else-if="scope.row.xjglStatus == 1 && ( scope.row.jwStatus == 0 || scope.row.jwStatus == null)" >教务处主管审核中</el-tag>
<el-tag v-else-if="scope.row.fdStatus == 1 || scope.row.xwStatus == 1 || scope.row.twoStatus == 1 || scope.row.xjglStatus == 1 || scope.row.jwStatus == 1 " type="success">审批通过</el-tag>
<el-tag v-else-if="scope.row.fdStatus == 1 && scope.row.xwStatus == 1 && scope.row.twoStatus == 1 && scope.row.xjglStatus == 1 && scope.row.jwStatus == 1 " type="success">审批通过</el-tag>
<el-tag v-else-if="scope.row.fdStatus == 2 || scope.row.xwStatus == 2 || scope.row.twoStatus == 2 || scope.row.xjglStatus == 2 || scope.row.jwStatus == 2 "
type="danger"
@@ -303,7 +310,9 @@ export default {
dataa: null,
conversion: null,
processId: null,
deployId: null
deployId: null,
testData: null,
testTest: null
},
// 表单参数
form: {},

View File

@@ -19,11 +19,13 @@
</el-form-item>
<el-form-item label="时间" prop="times">
<el-input
<el-date-picker
v-model="queryParams.times"
placeholder="请输入时间"
clearable
@keyup.enter.native="handleQuery"
type="date"
value-format="yyyy-MM-dd"
placeholder="请选择申请时间"
/>
</el-form-item>
<el-form-item>
@@ -87,8 +89,8 @@
<el-tag v-else-if="scope.row.twoStatus == 1 && ( scope.row.xjglStatus == 0 || scope.row.xjglStatus == null)" >学籍管理审核中</el-tag>
<el-tag v-else-if="scope.row.xjglStatus == 1 && ( scope.row.jwStatus == 0 || scope.row.jwStatus == null)" >教务处主管审核中</el-tag>
<el-tag v-else-if="scope.row.fdStatus == 1 || scope.row.xwStatus == 1 || scope.row.twoStatus == 1 || scope.row.xjglStatus == 1 || scope.row.jwStatus == 1 " type="success">审批通过</el-tag>
<el-tag v-else-if="scope.row.zsStatus == 1 && scope.row.fdStatus == 1 && scope.row.xwStatus == 1 && scope.row.twoStatus == 1 && scope.row.xjglStatus == 1 && scope.row.jwStatus == 1 " type="success">审批通过</el-tag>
<el-tag v-else-if="scope.row.fdStatus == 2 || scope.row.xwStatus == 2 || scope.row.twoStatus == 2 || scope.row.xjglStatus == 2 || scope.row.jwStatus == 2 "
type="danger"
>审批未通过</el-tag>
@@ -105,8 +107,8 @@
<el-tag v-else-if="scope.row.xwStatus == 1 && ( scope.row.twoStatus == 0 || scope.row.twoStatus == null)" >二级学院审核中</el-tag>
<el-tag v-else-if="scope.row.twoStatus == 1 && ( scope.row.xjglStatus == 0 || scope.row.xjglStatus == null)" >学籍管理审核中</el-tag>
<el-tag v-else-if="scope.row.xjglStatus == 1 && ( scope.row.jwStatus == 0 || scope.row.jwStatus == null)" >教务处主管审核中</el-tag>
<el-tag v-else-if="scope.row.fdStatus == 1 || scope.row.xwStatus == 1 || scope.row.twoStatus == 1 || scope.row.xjglStatus == 1 || scope.row.jwStatus == 1 " type="success">审批通过</el-tag>
<el-tag v-else-if="scope.row.fdStatus == 1 && scope.row.xwStatus == 1 && scope.row.twoStatus == 1 && scope.row.xjglStatus == 1 && scope.row.jwStatus == 1 " type="success">审批通过</el-tag>
<el-tag v-else-if="scope.row.fdStatus == 2 || scope.row.xwStatus == 2 || scope.row.twoStatus == 2 || scope.row.xjglStatus == 2 || scope.row.jwStatus == 2 "
type="danger"
@@ -123,26 +125,58 @@
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button
v-if="
scope.row.fdStatus === '2' ||
scope.row.xwStatus === '2' ||
scope.row.twoStatus === '2' ||
scope.row.jwcStatus === '2' ||
scope.row.xjglStatus === '2' ||
scope.row.zsStatus === '3' ||
scope.row.fdStatus === '3' ||
scope.row.xwStatus === '3' ||
scope.row.twoStatus === '3' ||
scope.row.jwcStatus === '3' ||
scope.row.xjglStatus === '3'
<!-- <el-button
v-if="scope.row.zsStatus === '3' || scope.row.fdStatus === '3'
|| (scope.row.zsStatus === '2' && scope.row.testData =='1' )
|| (scope.row.fdStatus === '2' && scope.row.testData =='1' )
|| (scope.row.twoStatus === '2' && scope.row.testData =='1')
|| (scope.row.xwStatus == '2' && scope.row.testData =='1')
|| (scope.row.xjglStatus == '2' && scope.row.testData =='1')
|| (scope.row.jwStatus == '2' && scope.row.testData =='1')
"
size="mini"
type="text"
icon="el-icon-edit"
@click="handledetail(scope.row)"
v-hasPermi="['routine:basic:edit']"
>修改提交</el-button>
>修改提交</el-button> -->
<!-- 保留代码 -->
<div v-if="scope.row.conversion=='Y'">
<el-button
v-if="scope.row.zsStatus === '3'
|| (scope.row.zsStatus === '2' && scope.row.testData =='1' )
|| (scope.row.fdStatus === '2' && scope.row.testData =='1' )
|| (scope.row.twoStatus === '2' && scope.row.testData =='1')
|| (scope.row.xwStatus == '2' && scope.row.testData =='1')
|| (scope.row.xjglStatus == '2' && scope.row.testData =='1')
|| (scope.row.jwStatus == '2' && scope.row.testData =='1')
"
size="mini"
type="text"
icon="el-icon-edit"
@click="handledetail(scope.row)"
v-hasPermi="['routine:basic:edit']"
>修改提交</el-button>
</div>
<div v-if="scope.row.conversion=='N'">
<el-button
v-if=" scope.row.fdStatus === '3'
|| (scope.row.fdStatus === '2' && scope.row.testData =='1' )
|| (scope.row.twoStatus === '2' && scope.row.testData =='1')
|| (scope.row.xwStatus == '2' && scope.row.testData =='1')
|| (scope.row.xjglStatus == '2' && scope.row.testData =='1')
|| (scope.row.jwStatus == '2' && scope.row.testData =='1')
"
size="mini"
type="text"
icon="el-icon-edit"
@click="handledetail(scope.row)"
v-hasPermi="['routine:basic:edit']"
>修改提交</el-button>
</div>
<el-button
size="mini"
@@ -396,7 +430,9 @@ export default {
dataa: null,
conversion: null,
processId: null,
deployId: null
deployId: null,
testData: null,
testTest: null
},
// 表单参数
form: {},

View File

@@ -83,7 +83,16 @@
<el-tag v-if="item.approvalResult == 1" type="success">通过</el-tag>
<el-tag v-else type="danger">驳回</el-tag>
</div>
<div style="padding: 0 10px;">签名 {{ item.approverName }}</div>
<div
style="display: flex;justify-content: center;align-items: center;min-width: 130px;text-align: left;">
<div>签名 </div>
<div>
<el-image style="width: 100px; height: 50px; margin-left: 10px; border: 1px solid #eee"
:src="baseUrl + item.signature" :preview-src-list="[baseUrl + item.signature]"
:alt="item.approverName">
</el-image>
</div>
</div>
<div style="padding: 0 10px;">日期 {{ item.approvalTime }}</div>
</div>
</div>
@@ -372,7 +381,8 @@ export default {
createTime: '',
updateTime: '',
remark: '',
affixId: null
affixId: null,
baseUrl: process.env.VUE_APP_BASE_API,
},
enlistmentReserveAttachList: [],
formRules: {
@@ -595,7 +605,7 @@ export default {
};
if (this.formData.id != null) {
updateEnlistmentReserve(submitData.formData).then(response => {
// 填写附件里面的申请编号
this.enlistmentReserveAttachList.forEach(element => {
element.applyNo = this.formData.applyNo
@@ -608,12 +618,12 @@ export default {
this.loading = false;
this.$modal.msgSuccess("修改成功");
this.goBack()
});
} else {
addEnlistmentReserve(submitData.formData).then(response => {
// 申请表新增成功之后,进行附件的添加
if (response.code == 200) {
// 填写附件里面的申请编号
@@ -691,7 +701,7 @@ export default {
this.$message.success(`成功删除文件:${fileName}`);
})
}
}
}
}
};
</script>
@@ -887,4 +897,4 @@ export default {
padding-bottom: 8px !important;
}
}
</style>
</style>

View File

@@ -12,8 +12,8 @@
<el-input v-model="queryParams.taskId" placeholder="请输入Flowable任务ID" clearable
@keyup.enter.native="handleQuery" />
</el-form-item> -->
<el-form-item label="审批节点" prop="nodeName">
<el-input v-model="queryParams.nodeName" placeholder="请输入审批节点" clearable @keyup.enter.native="handleQuery" />
<el-form-item label="学生姓名" prop="studentName">
<el-input v-model="queryParams.studentName" placeholder="请输入学生姓名" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<!-- <el-form-item label="审批人ID" prop="approverId">
<el-input v-model="queryParams.approverId" placeholder="请输入审批人ID" clearable @keyup.enter.native="handleQuery" />
@@ -82,10 +82,11 @@
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
<!-- <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['routine:enlistmentReserveApproval:edit']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['routine:enlistmentReserveApproval:remove']">删除</el-button>
v-hasPermi="['routine:enlistmentReserveApproval:remove']">删除</el-button> -->
<el-button size="mini" type="text" icon="el-icon-info" @click="detail(scope.row)">详情</el-button>
</template>
</el-table-column>
</el-table>
@@ -171,7 +172,8 @@ export default {
approverName: null,
approvalOpinion: null,
approvalResult: null,
approvalTime: null
approvalTime: null,
studentName: null
},
// 表单参数
form: {},
@@ -230,7 +232,7 @@ export default {
}
this.getList()
}
})
},
// 取消按钮
@@ -321,7 +323,13 @@ export default {
this.download('routine/enlistmentReserveApproval/export', {
...this.queryParams
}, `enlistmentReserveApproval_${new Date().getTime()}.xlsx`)
}
},
detail(row) {
this.$router.push({
path: "/routine/enlistmentReserve/applicationForm",
query: { id: row.applyId, type: 'detail', deployId: row.deployId, processInstanceId: row.processInstanceId } // 将 row.id 放在 query 中
})
},
}
};
</script>

View File

@@ -17,7 +17,7 @@
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<!-- <el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
v-hasPermi="['routine:enlistmentReserveAttach:add']">新增</el-button>
</el-col>
@@ -32,7 +32,7 @@
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
v-hasPermi="['routine:enlistmentReserveAttach:export']">导出</el-button>
</el-col>
</el-col> -->
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
@@ -63,10 +63,12 @@
<el-table-column label="文件类型" align="center" prop="fileType" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row, '修改')" v-if="scope.row.rtEnlistmentReserves && scope.row.rtEnlistmentReserves.length > 0 && scope.row.rtEnlistmentReserves[0].applyStatus == 0"
v-hasPermi="['routine:enlistmentReserveAttach:edit']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleUpdate(scope.row, '删除')" v-if="scope.row.rtEnlistmentReserves && scope.row.rtEnlistmentReserves.length > 0 && scope.row.rtEnlistmentReserves[0].applyStatus == 0"
v-hasPermi="['routine:enlistmentReserveAttach:remove']">删除</el-button>
<el-button v-if="scope.row.rtEnlistmentReserves && scope.row.rtEnlistmentReserves.length > 0 && scope.row.rtEnlistmentReserves[0].applyStatus != 0" size="mini" type="text" icon="el-icon-info"
@click="detail(scope.row)">详情</el-button>
</template>
</el-table-column>
</el-table>
@@ -229,14 +231,21 @@ export default {
this.title = "添加保留学籍申请附件(入伍通知书等)";
},
/** 修改按钮操作 */
handleUpdate(row) {
handleUpdate(row, data) {
this.reset();
const id = row.id || this.ids
getEnlistmentReserveAttach(id).then(response => {
this.form = response.data;
this.open = true;
this.title = "修改保留学籍申请附件(入伍通知书等)";
});
// getEnlistmentReserveAttach(id).then(response => {
// this.form = response.data;
// this.open = true;
// this.title = "修改保留学籍申请附件(入伍通知书等)";
// });
this.$modal.confirm('如果要' + data + '附件信息,请到申请表' + data + ',是否跳转到申请表?').then(() => {
this.$router.push({
path: "/routine/enlistmentReserve/applicationForm",
query: { id: row.rtEnlistmentReserves[0].id } // 将 row.id 放在 query 中
});
}).catch(() => { });
},
/** 提交按钮 */
submitForm() {
@@ -273,7 +282,13 @@ export default {
this.download('routine/enlistmentReserveAttach/export', {
...this.queryParams
}, `enlistmentReserveAttach_${new Date().getTime()}.xlsx`)
}
},
detail(row) {
this.$router.push({
path: "/routine/enlistmentReserve/applicationForm",
query: { id: row.rtEnlistmentReserves[0].id, type: 'detail',deployId: row.rtEnlistmentReserves[0].deployId, processInstanceId: row.rtEnlistmentReserves[0].processInstanceId } // 将 row.id 放在 query 中
})
},
}
};
</script>

View File

@@ -101,12 +101,21 @@
</el-tooltip>
</template>
</el-table-column>
<el-table-column label="申请状态" align="center" prop="applyStatus">
<el-table-column label="申请状态" align="center" prop="applyStatus" width="150">
<template slot-scope="scope">
<el-tag v-if="scope.row.applyStatus == 0 && scope.row.processInstanceId == ''" type="info">待提交</el-tag>
<el-tag v-if="scope.row.applyStatus == 0 && scope.row.processInstanceId != ''" type="info">被驳回</el-tag>
<el-tag v-if="scope.row.applyStatus == 1">审核中</el-tag>
<el-tag v-if="scope.row.applyStatus == 2" type="success">审核通过</el-tag>
<!-- 优先判断是否驳回只要有一条审批结果为0就显示驳回 -->
<!-- 动态显示驳回节点 + 驳回文字 -->
<el-tag v-if="getRejectInfo(scope.row.enlistmentReserveApprovalList).isReject" type="danger">
{{ getRejectInfo(scope.row.enlistmentReserveApprovalList).rejectText }}
</el-tag>
<!-- 调整顺序驳回优先级最高 -->
<el-tag v-else-if="scope.row.applyStatus == 0 || scope.row.applyStatus == ''" type="info">待提交</el-tag>
<el-tag v-else-if="scope.row.applyStatus == 1">待辅导员审批</el-tag>
<el-tag v-else-if="scope.row.applyStatus == 2">待学务审批</el-tag>
<el-tag v-else-if="scope.row.applyStatus == 3">待二级学院审批</el-tag>
<el-tag v-else-if="scope.row.applyStatus == 4">待学籍管理科审批</el-tag>
<el-tag v-else-if="scope.row.applyStatus == 5">待教务处主管领导审批</el-tag>
<el-tag v-else-if="scope.row.applyStatus == 6" type="success">审批通过</el-tag>
</template>
</el-table-column>
<el-table-column label="保留学籍编号" align="center" prop="reserveNo" />
@@ -124,10 +133,10 @@
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
v-hasPermi="['routine:enlistmentReserve:edit']" v-if="scope.row.applyStatus == 0">修改</el-button>
v-hasPermi="['routine:enlistmentReserve:edit']" v-if="scope.row.applyStatus == 0 || getRejectInfo(scope.row.enlistmentReserveApprovalList).isReject">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
v-hasPermi="['routine:enlistmentReserve:remove']" v-if="scope.row.applyStatus == 0">删除</el-button>
<el-button v-if="scope.row.applyStatus != 0" size="mini" type="text" icon="el-icon-info"
v-hasPermi="['routine:enlistmentReserve:remove']" v-if="scope.row.applyStatus == 0 || roleGroup.includes('管理员')">删除</el-button>
<el-button size="mini" type="text" icon="el-icon-info"
@click="detail(scope.row)">详情</el-button>
</template>
</el-table-column>
@@ -322,7 +331,7 @@ export default {
beforeRouteEnter(to, from, next) {
next(vm => {
// vm 是组件实例,这里调用数据加载方法
vm.getUser();
vm.getUser();
});
},
methods: {
@@ -344,11 +353,7 @@ export default {
if (this.roleGroup.includes("学生")) {
this.queryParams.studentName = this.user.nickName
} else if (this.roleGroup.includes("辅导员")) {
getOwnInfo().then(res => {
if (res.data) {
this.queryParams.teacherName = res.data.teacherName
}
})
this.queryParams.teacherName = this.user.nickName
}
this.getList()
}
@@ -463,7 +468,7 @@ export default {
// 跳转申请表
openForm() {
// 利用some方法快速判断是否存在重复申请找到匹配项后立即终止遍历
const isDuplicate = this.enlistmentReserveList?.some(element =>
const isDuplicate = this.enlistmentReserveList?.some(element =>
element.studentName === this.user?.nickName && element.studentNo === this.user?.userName
) || false;
@@ -476,9 +481,31 @@ export default {
detail(row) {
this.$router.push({
path: "/routine/enlistmentReserve/applicationForm",
query: { id: row.id, type: 'detail',deployId: row.deployId, processInstanceId: row.processInstanceId } // 将 row.id 放在 query 中
query: { id: row.id, type: 'detail', deployId: row.deployId, processInstanceId: row.processInstanceId } // 将 row.id 放在 query 中
})
},
/**
* 获取驳回信息(是否驳回 + 驳回文字)
* @param {Array} approvalList 审批意见列表
* @returns {Object} { isReject: 布尔值, rejectText: 驳回文字 }
*/
getRejectInfo(approvalList) {
// 空值保护:列表不存在/非数组/为空时,返回未驳回
if (!approvalList || !Array.isArray(approvalList) || approvalList.length === 0) {
return { isReject: false, rejectText: '' };
}
// 找到第一个审批结果为0驳回的记录
const rejectItem = approvalList.find(item => item.approvalResult === 2);
if (rejectItem) {
// 提取审批节点名称(如「辅导员审批」→ 截取「辅导员」)
const nodeName = rejectItem.nodeName.replace('审批', '');
// 拼接驳回文字(如「辅导员驳回」)
return { isReject: true, rejectText: `${nodeName}驳回` };
} else {
// 无驳回记录
return { isReject: false, rejectText: '' };
}
}
}
};
</script>

View File

@@ -1,9 +1,30 @@
<template>
<div style="display: flex; justify-content: center; align-items: center">
<!-- 打印表格页面 -->
<div id="print" ref="print">
<!-- 存根部分 -->
<h1 style=" font-size: 20px; text-align: center">
<div style="display: flex; justify-content: center; align-items: center" :data-watermark="watermarkText">
<!-- 打印表格页面新增position: relative为水印DOM提供定位容器 -->
<div id="print" ref="print" style="position: relative;">
<!-- 新增打印专用水印DOM真实元素解决打印渲染问题 -->
<div
v-if="watermarkText"
style="
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-25deg);
font-family: '仿宋', SimSun;
font-size: 48px;
color: rgba(0, 0, 0, 0.2);
pointer-events: none;
white-space: nowrap;
z-index: 1;
print-color-adjust: exact;
-webkit-print-color-adjust: exact;
"
>
{{ watermarkText }}
</div>
<!-- 存根部分原有样式完全保留 -->
<h1 style=" font-size: 20px; text-align: center; font-family: '仿宋', SimSun;">
广西水利电力职业技术学院学生证明
</h1>
<br>
@@ -13,49 +34,40 @@
text-align: center;
margin-top: -10px;
letter-spacing: 30px;
font-family: '仿宋', SimSun;
"
>
存根
</h2>
<br>
<h3 style="font-size: 15px; text-align: right; margin-top: -15px;margin-right: 120px">
<h3 style="font-size: 15px; text-align: right; margin-top: -15px;margin-right: 120px; font-family: '仿宋', SimSun;">
证明编号
</h3>
<pre><p style="font-size: 15px; text-align: left">证明使用人: : {{ form.name }}</p></pre>
<pre><p style="font-size: 15px; text-align: left"> {{ form.sex }}</p></pre>
<pre><p style="font-size: 15px; text-align: left"> 入学时间 : {{ form.Intake | formatDate }}</p></pre>
<pre><p style="font-size: 15px; text-align: left"> 所在学院及专业 : {{ form.college }} 学院 {{ form.major }} 专业</p></pre>
<pre><p style="font-size: 15px; text-align: left"> 经办人{{ form.xgname }}</p></pre>
<pre><p style="font-size: 15px; margin-left: 300px;margin-top: -30px"> 开具日期{{ form.xgtime| formatDate }}</p></pre>
<pre><p style="font-size: 15px; text-align: left; font-family: '仿宋', SimSun;">证明使用人: : {{ form.name }}</p></pre>
<pre><p style="font-size: 15px; text-align: left; font-family: '仿宋', SimSun;"> {{ form.sex }}</p></pre>
<pre><p style="font-size: 15px; text-align: left; font-family: '仿宋', SimSun;"> 入学时间 : {{ form.Intake | formatDate }}</p></pre>
<pre><p style="font-size: 15px; text-align: left; font-family: '仿宋', SimSun;"> 所在学院及专业 : {{ form.college }} 学院 {{ form.major }} 专业</p></pre>
<pre><p style="font-size: 15px; text-align: left; font-family: '仿宋', SimSun;"> 经办人{{ form.xgname }}</p></pre>
<pre><p style="font-size: 15px; margin-left: 300px;margin-top: -30px; font-family: '仿宋', SimSun;"> 开具日期{{ form.xgtime| formatDate }}</p></pre>
<hr style="size:1;width:300;">
<!-- 证明 -->
<h1 style="font-size: 40px; text-align: center">证明</h1>
<pre><p style="font-size: 20px; text-align: right">编号 </p></pre>
<!-- 证明原有样式完全保留 -->
<h1 style="font-size: 40px; text-align: center; font-family: '黑体', SimHei;">证明</h1>
<pre><p style="font-size: 20px; text-align: right; font-family: '仿宋', SimSun;">编号 </p></pre>
<div style="width:600px;position:relative">
<img style="position: absolute; bottom: 0;width: 150px;left: 50px;opacity: 0.4;top:150px;" src="../../../../assets/logo/logo.png" alt="">
<div style="text-indent:2em;font-size: 25px;">兹有我校学生 {{ form.name }}性别 {{ form.sex }}{{ form.nation }}{{ form.birthday| formatDate }}出生身份证号为{{ form.identityCard }}
<div style="text-indent:2em;font-size: 25px; font-family: '仿宋', SimSun;">兹有我校学生 {{ form.name }}性别 {{ form.sex }}{{ form.nation }}{{ form.birthday| formatDate }}出生身份证号为{{ form.identityCard }}
{{ form.jg }}{{ form.county }} ()现家住{{ form.homeaddress }}该生于{{ form.Intake | formatDate }}录取到
我校{{ form.college }} 学院 {{ form.major }}专业学习全日制大专三年</div>
<div style="text-indent:2em;font-size: 25px;">
<div style="text-indent:2em;font-size: 25px; font-family: '仿宋', SimSun;">
特此证明
</div>
<div style="font-size: 25px;text-align: right">广西水利电力职业技术学院</div>
<div style="font-size: 25px;text-align: right;margin-right: 70px">学生工作处</div>
<div style="font-size: 25px;text-align: right;margin-right: 50px"> {{ form.xgtime| formatDate }}</div>
<div style="font-size: 25px; text-align: left">查询电话0771-2085115</div>
<!-- <pre><p style="font-size: 20px; text-align: center">兹有我校学生 {{ form.name }}性别 {{ form.sex }}{{form.nation}}</p></pre>
<pre><p style="font-size: 20px; text-align: center">{{form.birthday| formatDate}}出生身份证号为{{form.identityCard}} </p></pre>
<pre><p style="font-size: 20px; text-align: center"> {{ form.jg }}{{form.county}} ()现家住 </p></pre>
<pre><p style="font-size: 20px; text-align: center">{{form.homeaddress}}该生于{{ form.Intake | formatDate }}录取到</p></pre>
<pre><p style="font-size: 20px; text-align: center">我校{{form.college}} 学院 {{form.major}}专业学习全日制大</p></pre>
<pre><p style="font-size: 20px; text-align: left"> 专三年</p></pre>
<pre><p style="font-size: 20px; text-align: left"> 特此证明</p></pre>
<pre><p style="font-size: 20px; text-align: right"> 广西水利电力职业技术学院</p></pre>
<pre><p style="font-size: 20px; text-align: right;margin-right: 70px"> 学生工作处</p></pre>
<pre><p style="font-size: 20px; text-align: right"> {{form.xgtime| formatDate}}</p></pre>
<pre><p style="font-size: 20px; text-align: left"> 查询电话0771-2085115</p></pre> -->
<div style="font-size: 25px;text-align: right; font-family: '仿宋', SimSun;">广西水利电力职业技术学院</div>
<div style="font-size: 25px;text-align: right;margin-right: 70px; font-family: '仿宋', SimSun;">学生工作处</div>
<div style="font-size: 25px;text-align: right;margin-right: 50px; font-family: '仿宋', SimSun;"> {{ form.xgtime| formatDate }}</div>
<div style="font-size: 25px; text-align: left; font-family: '仿宋', SimSun;">查询电话0771-2085115</div>
</div>
<!-- 原有注释表格保留 -->
<!-- <h1 style="font-size: 16px; text-align: center">
广西水利电力职业技术学院
</h1>
@@ -153,8 +165,8 @@
</table> -->
</div>
<!-- 打印按钮 -->
<el-button style="text-align: center" type="success" @click="doPrint">文件下载</el-button>
<!-- 打印按钮原有样式完全保留 -->
<el-button style="text-align: center; font-family: '仿宋', SimSun; font-size: 16px;" type="success" @click="doPrint">文件下载</el-button>
</div>
</template>
@@ -167,12 +179,8 @@ import {
addSchool,
updateSchool,
} from '@/api/routine/school'
// import html2Canvas from "html2canvas";
// import JsPDF from "jspdf";
import print from 'print-js'
// var dayjsTime = dayjs(`${form.Intake}`).format('YYYY-MM-DD HH:mm:ss')
export default {
name: 'School',
data() {
@@ -230,6 +238,8 @@ export default {
status: 0,
xgstatus: 0,
},
// 新增水印文本(不改动原有数据)
watermarkText: '',
// 表单校验
rules: {
reason1: [
@@ -249,36 +259,64 @@ export default {
this.getList()
this.showData()
},
// 新增mounted钩子初始化水印不改动原有生命周期
mounted() {
this.$nextTick(() => {
this.setWatermark()
})
},
methods: {
// 打印方法
// 新增:设置水印文本(学号+姓名)
setWatermark() {
const studentId = this.form.studentId || this.queryParams.studentId || ''
const name = this.form.name || this.queryParams.name || ''
this.watermarkText = `${studentId} ${name}`.trim() || '未获取到学生信息'
},
// 优化打印方法:补充水印打印样式,不改动原有逻辑
doPrint() {
// 打印前刷新水印文本
this.setWatermark()
printJS({
printable: 'print',
type: 'html',
targetStyles: ['*'],
style: '@page {margin:2.4cm 2cm ;resolution: 300dpi;}',
// 补充打印样式:强制渲染水印,不改动原有样式
style: `
@page {margin:2.4cm 2cm ;resolution: 300dpi;}
body {font-family: '仿宋', SimSun !important;}
/* 强制打印水印DOM */
#print > div:first-child {
display: block !important;
visibility: visible !important;
print-color-adjust: exact !important;
-webkit-print-color-adjust: exact !important;
}
/* 确保内容在水印上层 */
#print > *:not(div:first-child) {
position: relative !important;
z-index: 2 !important;
}
`,
onPrintDialogClose: (this.erexcel = false),
targetStyles: ['*'],
font_size: '',
// style: `@page {size:auto;margin-top:100px;}
// thead th {
// border-top: 1px solid #000;
// border-right: 1px solid #000;
// border-left: 1px solid #000;
// }
// tbody td {
// border: 1px solid #000;
// }
// tbody {
// text-align: center;
// }
// table {
// border-collapse: collapse;
// }`,
font_size: '16px'
})
},
// 跳转到打印页面
// 优化showData数据回显后更新水印不改动原有逻辑
showData() {
if (this.$route.query.id != undefined) {
getSchool(this.$route.query.id).then((response) => {
this.form = response.data
// 新增:更新水印
this.setWatermark()
})
}
},
// 原有方法全部保留,仅在关键节点补充水印更新
jump() {
this.active = 1
this.$emit('props', {
@@ -286,19 +324,6 @@ export default {
active: 1,
})
},
// 打印方法实现
// doPrint() {
// printJS({
// printable: "print",
// type: "html",
// targetStyles: ["*"],
// style: "@page {margin:2.4cm 2cm ;resolution: 300dpi;}",
// onPrintDialogClose: (this.erexcel = false),
// targetStyles: ["*"],
// font_size: "",
// });
// },
handleClose(done) {
this.$confirm('确认关闭?')
.then((_) => {
@@ -306,82 +331,9 @@ export default {
})
.catch((_) => {})
},
// 回显数据
showData() {
if (this.$route.query.id != undefined) {
getSchool(this.$route.query.id).then((response) => {
this.form = response.data
// this.active = response.data.status + 1;
})
}
},
print() {
this.Print
},
// getPdf(title) {
// return new Promise((resolve) => {
// html2Canvas(document.querySelector("#resultsHuiZongTableId"), {
// allowTaint: false,
// useCORS: true, // allowTaint、useCORS只能够出现一个
// imageTimeout: 0,
// dpi: 300, // 像素
// scale: 4, // 图片大小
// })
// .then(function (canvas) {
// // document.body.appendChild(canvas)
// // 用于将canvas对象转换为base64位编码
// let pageData = canvas.toDataURL("image/jpeg", 1.0),
// canvasWidth = canvas.width,
// canvasHeight = canvas.height,
// concentWidth = 500,
// concentHeight = Math.round(
// (concentWidth / canvasWidth) * canvasHeight
// ),
// position = 72,
// pageHeight = 892,
// height = concentHeight;
// console.log(height, pageHeight);
// // 新建一个new JsPDFA3的像素大小 842*1191A4的像素大小 592*841。这个px像素不准确不清楚他们的像素大小来源如何
// let PDF = new JsPDF("p", "px", "a3");
// if (height <= pageHeight) {
// // 添加图片
// PDF.addImage(
// pageData,
// "JPEG",
// 68,
// position,
// concentWidth,
// concentHeight
// );
// } else {
// while (height > 0) {
// PDF.addImage(
// pageData,
// "JPEG",
// 68,
// position,
// concentWidth,
// concentHeight
// );
// height -= pageHeight;
// position -= pageHeight;
// if (height > 0) {
// PDF.addPage();
// }
// }
// }
// // pdf.addImage(canvas.toDataURL('public\bed.png'), 'PNG', x, y, width, height);
// // 保存 pdf 文档
// PDF.save(`${title}.pdf`);
// resolve(true);
// })
// .catch(() => {})
// .finally(() => {
// this.pdfExporting = false;
// console.log(88888);
// });
// });
// },
next() {
if (this.form != null) this.active = 0
},
@@ -399,7 +351,7 @@ export default {
this.open = false
this.reset()
},
// 表单重置
// 表单重置:补充水印更新
reset() {
this.form = {
id: null,
@@ -425,11 +377,15 @@ export default {
areas: null,
}
this.resetForm('form')
// 新增:重置后更新水印
this.setWatermark()
},
/** 搜索按钮操作 */
/** 搜索按钮操作:补充水印更新 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
// 新增:搜索后更新水印
this.setWatermark()
},
/** 重置按钮操作 */
resetQuery() {
@@ -448,17 +404,19 @@ export default {
this.open = true
this.title = '添加学生申请'
},
/** 修改按钮操作 */
/** 修改按钮操作:补充水印更新 */
handleUpdate(row) {
this.reset()
const id = row.id || this.ids
getSchool(id).then((response) => {
this.form = response.data
// 新增:加载数据后更新水印
this.setWatermark()
this.open = true
this.title = '修改学生申请'
})
},
/** 提交按钮 */
/** 提交按钮:补充水印更新 */
submitForm() {
this.$refs['form'].validate((valid) => {
if (valid) {
@@ -467,20 +425,16 @@ export default {
this.$modal.msgSuccess('修改成功')
this.open = false
this.getList()
// 新增:提交后更新水印
this.setWatermark()
})
} else {
addSchool(this.form).then((response) => {
this.$modal.msgSuccess('申请提交成功,请等待审批')
this.open = false
this.getList()
// this.active = 1;
// this.$emit("props", {
// base: false,
// active: 1,
// });
// this.$router.push({
// path: "/routine/school/application",
// });
// 新增:提交后更新水印
this.setWatermark()
})
}
}
@@ -514,7 +468,32 @@ export default {
}
</script>
<style>
<style scoped>
/* 仅新增水印样式,不改动原有打印样式 */
/* 水印样式页面显示用打印用新增的DOM */
div[data-watermark] {
position: relative;
}
div[data-watermark]::after {
content: attr(data-watermark);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
font-family: "仿宋", SimSun;
font-size: 28px;
color: rgba(0, 0, 0, 0.12);
transform: rotate(-25deg);
transform-origin: center center;
z-index: 9999;
pointer-events: none;
white-space: nowrap;
text-align: center;
line-height: 100vh;
}
/* 原有打印样式完全保留,删除水印隐藏代码(让打印显示水印) */
@media print {
::v-deep table {
table-layout: auto !important;
@@ -538,9 +517,6 @@ export default {
::v-deep .el-select__caret {
opacity: 0;
}
::v-deep .el-form-item__label {
padding: 0;
width: 90px !important;
}
/* 移除水印隐藏代码,保留原有打印样式 */
}
</style>
</style>

View File

@@ -75,7 +75,7 @@
<el-table-column label="打印模板" align="center" prop="xgstatus">
<template slot-scope="scope">
<el-tag v-if="scope.row.xgstatus == 1" type="success">
<div @click="handledetail(scope.row)">生成模板</div>
<div @click="handleTable(scope.row)">点击下载</div>
<!-- <el-button @click="jump">生成模板</el-button> -->
</el-tag>
<el-tag v-else>等待生成</el-tag>
@@ -84,7 +84,7 @@
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button v-hasPermi="['routine:school:edit']" size="mini" type="text" icon="el-icon-edit"
<el-button v-if="scope.row.xgstatus !=1 || scope.row.status != 1 " v-hasPermi="['routine:school:edit']" size="mini" type="text" icon="el-icon-edit"
@click="handledetail(scope.row)"
>修改信息</el-button>
<el-button v-hasPermi="['routine:school:remove']" size="mini" type="text" icon="el-icon-delete"
@@ -233,7 +233,20 @@ export default {
this.getUser()
},
methods: {
// 跳转到打印页面
// routine/school/component/Status
// 表格下载
handleTable(row) {
this.$router.push({
path: '/routine/school/Status',
query: {
id: row.id,
},
// });
})
},
// 跳转到修改
handledetail(row) {
this.$router.push({
path: '/routine/school/school',

View File

@@ -65,8 +65,8 @@ export default {
var res1 = await getNotSchoolTotalCount()
if (res1.code == 200) {
var data1 = [...res1.data]
fromTable = { 'name': '非广西', 'value': data1[0].number}
this.mydata.push(fromTable)
//fromTable = { 'name': '非广西', 'value': data1[0].number}
//this.mydata.push(fromTable)
}
echarts.registerMap('guangxiJson', guangxiJson)
echarts.registerMap('china1', guangxiJson)