Files
zhxg_pc/src/views/comprehensive/knzzZzqApply/xw.vue

464 lines
15 KiB
Vue
Raw Normal View History

2025-07-28 15:52:07 +08:00
<template>
<div class="app-container">
2025-10-18 17:13:04 +08:00
<el-form ref="queryForm" :model="queryParams" size="small" :inline="true" label-width="140px">
2025-07-28 15:52:07 +08:00
<el-form-item label="学号" prop="stuNo">
2025-10-18 17:13:04 +08:00
<el-input v-model="queryParams.stuNo" placeholder="请输入学号" clearable @keyup.enter.native="handleQuery" />
2025-07-28 15:52:07 +08:00
</el-form-item>
<el-form-item label="姓名" prop="stuName">
<el-input v-model="queryParams.stuName" placeholder="请输入姓名" clearable
2025-10-18 17:13:04 +08:00
@keyup.enter.native="handleQuery"
/>
2025-07-28 15:52:07 +08:00
</el-form-item>
<el-form-item label="学院" prop="deptName">
<el-input v-model="queryParams.deptName" placeholder="请输入学院" clearable
2025-10-18 17:13:04 +08:00
@keyup.enter.native="handleQuery"
/>
2025-07-28 15:52:07 +08:00
</el-form-item>
<el-form-item label="班级" prop="className">
<el-input v-model="queryParams.className" placeholder="请输入班级" clearable
2025-10-18 17:13:04 +08:00
@keyup.enter.native="handleQuery"
/>
2025-07-28 15:52:07 +08:00
</el-form-item>
<el-form-item label="审核状态" prop="applyStatus">
<el-select v-model="queryParams.applyStatus" placeholder="请选择审核状态" clearable>
<el-option v-for="dict in dict.type.knzz_tufa_apply_status" :key="dict.value" :label="dict.label"
2025-10-18 17:13:04 +08:00
:value="dict.value"
/>
2025-07-28 15:52:07 +08:00
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="manyVClick">批量通过</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出execl</el-button>
</el-col>
</el-row>
<el-table v-loading="loading" :data="tableData" @selection-change="handleSelectionChange">
2025-10-18 17:13:04 +08:00
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="#" align="center" prop="id" />
<el-table-column label="学年" align="center" prop="stuYearName" />
<el-table-column label="班级" align="center" prop="className" />
<el-table-column label="学号" align="center" prop="stuNo" />
<el-table-column label="姓名" align="center" prop="stuName" />
2025-07-28 15:52:07 +08:00
<el-table-column label="审核状态" align="center" prop="applyStatus">
<template slot-scope="scope">
2025-10-18 17:13:04 +08:00
<dict-tag :options="dict.type.knzz_tufa_apply_status" :value="scope.row.applyStatus" />
2025-07-28 15:52:07 +08:00
</template>
</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-view" @click="lookVClick(scope.row)">审核</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
2025-10-18 17:13:04 +08:00
:limit.sync="queryParams.pageSize" @pagination="getList"
/>
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
<el-dialog title="审核" :visible.sync="lookV" :fullscreen="true" :destroy-on-close="true" @close="getList">
2025-07-28 15:52:07 +08:00
<el-row>
<el-col :span="12">
2025-10-18 17:13:04 +08:00
<TufaLook v-if="lookV" :form-data="lookForm" />
2025-07-28 15:52:07 +08:00
</el-col>
<el-col :span="12">
2025-10-21 10:56:31 +08:00
<el-form v-if="lookForm.applyFile" label-width="120px">
<el-form-item label="证明材料">
<el-button type="primary" size="mini" icon="el-icon-download" @click="downloadDiploma">下载文件</el-button>
</el-form-item>
<FileUpload v-model="lookForm.applyFile" />
</el-form>
2025-07-28 15:52:07 +08:00
<el-form label-width="200px" size="mini" class="lookForm">
<el-form-item label="是否通过">
2025-10-18 17:13:04 +08:00
<el-select v-model="auditRes" @change="changeAuditRes">
<el-option label="通过" value="通过" />
<el-option label="驳回" value="驳回" />
2025-07-28 15:52:07 +08:00
</el-select>
</el-form-item>
<el-form-item label="意见">
2025-10-18 17:13:04 +08:00
<el-input v-model="auditForm.xwCmt" type="textarea" />
2025-07-28 15:52:07 +08:00
</el-form-item>
<el-form-item label="签名">
<el-upload style="display: inline;" :before-upload="boolImg"
accept="image/jpg,image/jpeg,image/png,image/bmp" :limit="1" class="avatar-uploader"
:action="upload.url" :headers="upload.headers" :show-file-list="false"
2025-10-18 17:13:04 +08:00
:file-list="upload.fileList" :on-success="handleAvatarSuccess"
>
2025-07-28 15:52:07 +08:00
<img v-if="auditForm.xwSign" :src="baseurl + auditForm.xwSign" width="200px"
2025-10-18 17:13:04 +08:00
height="50px" class="avatar"
>
2025-07-28 15:52:07 +08:00
<span v-else> 点击上传</span>
</el-upload>
</el-form-item>
<el-form-item label=" ">
2025-10-18 17:13:04 +08:00
<el-button type="primary" plain @click="doAudit">审核</el-button>
2025-07-28 15:52:07 +08:00
</el-form-item>
</el-form>
2025-10-18 17:13:04 +08:00
<hr>
2025-07-28 15:52:07 +08:00
<el-timeline>
<el-timeline-item v-if="lookForm.fdyCmt && lookForm.fdyDate" :timestamp="lookForm.fdyDate"
2025-10-18 17:13:04 +08:00
color="green" placement="top"
>
2025-07-28 15:52:07 +08:00
<el-card>
<div>
<strong>辅导员审核</strong>
<div>{{ lookForm.fdyCmt }}</div>
<img v-if="lookForm.fdySign" :src="baseurl + lookForm.fdySign" alt="辅导员签名"
2025-10-18 17:13:04 +08:00
style="max-width:100px;margin-top:8px;"
>
2025-07-28 15:52:07 +08:00
</div>
</el-card>
</el-timeline-item>
<el-timeline-item v-if="lookForm.xwCmt && lookForm.xwDate" :timestamp="lookForm.xwDate"
2025-10-18 17:13:04 +08:00
color="green" placement="top"
>
2025-07-28 15:52:07 +08:00
<el-card>
<div>
<strong>院系审核</strong>
<div>{{ lookForm.xwCmt }}</div>
<img v-if="lookForm.xwSign" :src="baseurl + lookForm.xwSign" alt="院系签名"
2025-10-18 17:13:04 +08:00
style="max-width:100px;margin-top:8px;"
>
2025-07-28 15:52:07 +08:00
</div>
</el-card>
</el-timeline-item>
<el-timeline-item v-if="lookForm.xgCmt && lookForm.xgDate" :timestamp="lookForm.xgDate"
2025-10-18 17:13:04 +08:00
color="green" placement="top"
>
2025-07-28 15:52:07 +08:00
<el-card>
<div>
<strong>学工审核</strong>
<div>{{ lookForm.xgCmt }}</div>
<img v-if="lookForm.xgSign" :src="baseurl + lookForm.xgSign" alt="学工签名"
2025-10-18 17:13:04 +08:00
style="max-width:100px;margin-top:8px;"
>
2025-07-28 15:52:07 +08:00
</div>
</el-card>
</el-timeline-item>
</el-timeline>
</el-col>
</el-row>
</el-dialog>
<el-dialog title="批量审核" :visible.sync="manyV" :destroy-on-close="true">
<el-form label-width="120px" size="mini" class="lookForm">
<el-form-item label="是否通过">
2025-10-18 17:13:04 +08:00
<el-select v-model="manyRes" @change="changeManyRes">
<el-option label="通过" value="通过" />
<el-option label="驳回" value="驳回" />
2025-07-28 15:52:07 +08:00
</el-select>
</el-form-item>
<el-form-item label="意见">
2025-10-18 17:13:04 +08:00
<el-input v-model="manyCmt" type="textarea" />
2025-07-28 15:52:07 +08:00
</el-form-item>
<el-form-item label="签名">
<el-upload style="display: inline;" :before-upload="boolImg"
accept="image/jpg,image/jpeg,image/png,image/bmp" :limit="1" class="avatar-uploader"
:action="upload.url" :headers="upload.headers" :show-file-list="false"
2025-10-18 17:13:04 +08:00
:file-list="upload.fileList" :on-success="handleAvatarSuccess1"
>
2025-07-28 15:52:07 +08:00
<img v-if="manySign" :src="baseurl + manySign" width="200px" height="50px" class="avatar">
<span v-else> 点击上传</span>
</el-upload>
</el-form-item>
<el-form-item label=" ">
2025-10-18 17:13:04 +08:00
<el-button type="primary" plain @click="doMany">审核</el-button>
2025-07-28 15:52:07 +08:00
</el-form-item>
</el-form>
</el-dialog>
</div>
</template>
<script>
2025-10-18 17:13:04 +08:00
import {boolImg, CheckImgExists, isEmpty, fullLoading} from '@/api/helpFunc'
import {getTokenKeySessionStorage as getToken} from '@/utils/auth'
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
import TufaApply from '@/views/comprehensive/knzzZzqApply/cpnt/TufaApply.vue'
import TufaLook from '@/views/comprehensive/knzzZzqApply/cpnt/TufaLook.vue'
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
import {listXw as listView, doAudit, doMany} from '@/api/comprehensive/knzzZzqApply'
2025-07-28 15:52:07 +08:00
2025-10-18 17:13:04 +08:00
import {getOwnSign} from '@/api/workstudy/post'
2025-07-28 15:52:07 +08:00
export default {
2025-10-18 17:13:04 +08:00
name: 'TufaXw',
2025-07-28 15:52:07 +08:00
dicts: ['knzz_tufa_apply_status'],
components: {
TufaApply,
TufaLook
},
data() {
return {
loading: true,
tableData: [],
total: 0,
queryParams: {
pageNum: 1,
pageSize: 10,
},
lookForm: {},
lookV: false,
auditForm: {
2025-10-18 17:13:04 +08:00
xwSign: '',
xwCmt: ''
2025-07-28 15:52:07 +08:00
},
auditRes: null,
upload: {
2025-10-18 17:13:04 +08:00
headers: {Authorization: 'Bearer ' + getToken()},
url: process.env.VUE_APP_BASE_API + '/common/upload',
2025-07-28 15:52:07 +08:00
fileList: []
},
2025-10-18 17:13:04 +08:00
baseurl: process.env.VUE_APP_BASE_API + '/',
2025-07-28 15:52:07 +08:00
boolImg,
manyV: false,
ids: [],
manyStatus: null,
2025-10-18 17:13:04 +08:00
manyCmt: '',
2025-07-28 15:52:07 +08:00
manyRes: null,
2025-10-18 17:13:04 +08:00
manySign: '',
2025-07-28 15:52:07 +08:00
}
},
created() {
2025-10-18 17:13:04 +08:00
this.getList()
this.getOwnSign()
2025-07-28 15:52:07 +08:00
},
methods: {
handleQuery() {
2025-10-18 17:13:04 +08:00
this.queryParams.pageNum = 1
this.getList()
2025-07-28 15:52:07 +08:00
},
resetQuery() {
2025-10-18 17:13:04 +08:00
this.resetForm('queryForm')
this.handleQuery()
2025-07-28 15:52:07 +08:00
},
handleAvatarSuccess1(response, file, fileList) {
2025-10-18 17:13:04 +08:00
this.manySign = response.fileName
this.upload.fileList = []
this.$forceUpdate()
2025-07-28 15:52:07 +08:00
},
changeManyRes(v) {
switch (v) {
case '通过':
2025-10-18 17:13:04 +08:00
this.manyStatus = 3
this.manyCmt = '同意推荐该同学申请自治区人民政府奖学金。 '
break
2025-07-28 15:52:07 +08:00
case '驳回':
2025-10-18 17:13:04 +08:00
this.manyStatus = 10
this.manyCmt = '驳回,驳回原因:'
break
2025-07-28 15:52:07 +08:00
default:
2025-10-18 17:13:04 +08:00
this.manyStatus = null
this.manyCmt = ''
break
2025-07-28 15:52:07 +08:00
}
},
manyVClick() {
if (this.ids.length == 0) {
2025-10-18 17:13:04 +08:00
this.$message.info('请至少选择一条数据')
return
2025-07-28 15:52:07 +08:00
} else {
2025-10-18 17:13:04 +08:00
this.manyV = true
2025-07-28 15:52:07 +08:00
}
},
async doMany() {
if (isEmpty(this.manyRes)) {
2025-10-18 17:13:04 +08:00
this.$message.info('请选择是否通过')
return
2025-07-28 15:52:07 +08:00
}
if (isEmpty(this.manyCmt)) {
2025-10-18 17:13:04 +08:00
this.$message.info('请输入意见')
return
2025-07-28 15:52:07 +08:00
}
if (isEmpty(this.manySign)) {
2025-10-18 17:13:04 +08:00
this.$message.info('请上传签名图片')
return
2025-07-28 15:52:07 +08:00
}
2025-10-18 17:13:04 +08:00
let sdata = []
2025-07-28 15:52:07 +08:00
this.ids.map(x => {
let temp = {
id: x,
applyStatus: this.manyStatus,
xwCmt: this.manyCmt,
xwSign: this.manySign
2025-10-18 17:13:04 +08:00
}
sdata.push(temp)
})
let loading = fullLoading(this)
let res = await doMany(sdata)
loading.close()
2025-07-28 15:52:07 +08:00
if (res.code == 200) {
2025-10-18 17:13:04 +08:00
this.$message.success(res.msg)
this.manyV = false
this.getList()
this.ids = []
2025-07-28 15:52:07 +08:00
}
},
handleSelectionChange(selection) {
this.ids = selection.map(item => item.id)
},
async doNext() {
2025-10-18 17:13:04 +08:00
this.loading = true
let res = await listView(this.queryParams)
this.loading = false
2025-07-28 15:52:07 +08:00
if (res.code == 200) {
2025-10-18 17:13:04 +08:00
let data = [...res.rows]
2025-07-28 15:52:07 +08:00
if (data.length > 0) {
2025-10-18 17:13:04 +08:00
let row = data[0]
this.lookVClick(row)
2025-07-28 15:52:07 +08:00
}
}
},
async doAudit() {
2025-10-18 17:13:04 +08:00
let sdata = {...this.auditForm}
2025-07-28 15:52:07 +08:00
if (isEmpty(sdata.applyStatus)) {
2025-10-18 17:13:04 +08:00
this.$message.info('请选择是否通过')
return
2025-07-28 15:52:07 +08:00
}
if (isEmpty(sdata.xwCmt)) {
2025-10-18 17:13:04 +08:00
this.$message.info('请输入意见')
return
2025-07-28 15:52:07 +08:00
}
if (isEmpty(sdata.xwSign)) {
2025-10-18 17:13:04 +08:00
this.$message.info('请上传签名图片')
return
2025-07-28 15:52:07 +08:00
}
2025-10-18 17:13:04 +08:00
let loading = fullLoading(this)
let res = await doAudit(sdata)
loading.close()
2025-07-28 15:52:07 +08:00
if (res.code == 200) {
2025-10-18 17:13:04 +08:00
this.$message.success('审核成功')
this.lookV = false
await this.doNext()
2025-07-28 15:52:07 +08:00
}
},
async getOwnSign() {
2025-10-18 17:13:04 +08:00
let res = await getOwnSign()
2025-07-28 15:52:07 +08:00
if (res.code == 200) {
2025-10-18 17:13:04 +08:00
let data = {...res.data}
2025-07-28 15:52:07 +08:00
if (isEmpty(data.signature)) {
this.$confirm('您的签名尚未上传', '提示', {
confirmButtonText: '点我前往',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
2025-10-18 17:13:04 +08:00
this.$router.push('/user/profile')
2025-07-28 15:52:07 +08:00
}).catch(() => {
2025-10-18 17:13:04 +08:00
})
2025-07-28 15:52:07 +08:00
} else {
2025-10-18 17:13:04 +08:00
this.auditForm.xwSign = data.signature
this.manySign = data.signature
2025-07-28 15:52:07 +08:00
}
}
},
handleAvatarSuccess(response, file, fileList) {
2025-10-18 17:13:04 +08:00
this.auditForm.xwSign = response.fileName
this.upload.fileList = []
this.$forceUpdate()
2025-07-28 15:52:07 +08:00
},
async getList() {
2025-10-18 17:13:04 +08:00
this.loading = true
let res = await listView(this.queryParams)
this.loading = false
2025-07-28 15:52:07 +08:00
if (res.code == 200) {
2025-10-18 17:13:04 +08:00
this.tableData = [...res.rows]
this.total = res.total
2025-07-28 15:52:07 +08:00
}
},
async lookVClick(row) {
2025-10-18 17:13:04 +08:00
this.auditRes = null
this.lookForm = {}
this.lookForm = {...row}
2025-07-28 15:52:07 +08:00
this.auditForm = {
2025-10-18 17:13:04 +08:00
xwSign: '',
xwCmt: ''
}
this.auditForm.id = row.id
await this.getOwnSign()
this.lookV = true
2025-07-28 15:52:07 +08:00
},
changeAuditRes(v) {
switch (v) {
case '通过':
2025-10-18 17:13:04 +08:00
this.auditForm.applyStatus = 3
this.auditForm.xwCmt = '同意推荐该同学申请自治区人民政府奖学金。'
break
2025-07-28 15:52:07 +08:00
case '驳回':
2025-10-18 17:13:04 +08:00
this.auditForm.applyStatus = 10
this.auditForm.xwCmt = '驳回,驳回原因:'
break
2025-07-28 15:52:07 +08:00
default:
2025-10-18 17:13:04 +08:00
this.auditForm.applyStatus = null
this.auditForm.xwCmt = ''
break
2025-07-28 15:52:07 +08:00
}
},
/** 导出按钮操作 */
handleExport() {
this.download('/comprehensive/knzzZzqApply/export', {
...this.queryParams
}, `apply_${new Date().getTime()}.xlsx`)
2025-10-21 10:56:31 +08:00
},
downloadDiploma() {
const raw = this.lookForm.applyFile
if (!raw) return
// 支持逗号分隔的多个文件
const files = String(raw)
.split(',')
.map((s) => s.trim())
.filter(Boolean)
const triggerDownload = (href, filename) => {
const link = document.createElement('a')
link.href = href
// 设置下载文件名(跨域时可能被浏览器忽略,但不影响触发下载/打开)
link.download = filename || ''
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}
files.forEach((file, idx) => {
const isAbsoluteUrl = /^https?:\/\//i.test(file)
const url = isAbsoluteUrl ? file : `${this.baseurl}${file}`
const name = this.getFileName(file)
// 轻微延时,避免浏览器对一次事件同时触发多个下载的限制
setTimeout(() => triggerDownload(url, name), idx * 200)
})
},
2025-07-28 15:52:07 +08:00
}
}
</script>
<style scoped lang="scss">
.lookForm {
.el-form-item {
margin-bottom: 5px;
}
}
</style>