移植v3疗休养到这个版本上

This commit is contained in:
2026-09-03 08:48:01 +08:00
parent 7b1e83d33b
commit 0a9d355913
@@ -71,26 +71,51 @@ layout("/layouts/platform.html"){
<el-card shadow="never" class="filter-container">
<el-form :model="pageForm" ref="pageFormRef" label-width="90px" size="medium">
<div class="form-row">
<el-form-item label="年度">
<el-form-item label="开始年度">
<el-date-picker
v-model="pageForm.year"
v-model="pageForm.startYear"
type="year"
placeholder="选择年度"
placeholder="选择开始年度"
value-format="yyyy"
style="width: 100%">
</el-date-picker>
</el-form-item>
<el-form-item label="姓名">
<el-input v-model="pageForm.userName" placeholder="请输入姓名" clearable
prefix-icon="el-icon-user"></el-input>
<el-form-item label="结束年度">
<el-date-picker v-model="pageForm.endYear" type="year" placeholder="选择结束年度"
value-format="yyyy" style="width: 100%"></el-date-picker>
</el-form-item>
<el-form-item label="工号">
<el-input v-model="pageForm.loginName" placeholder="请输入工号" clearable
prefix-icon="el-icon-postcard"></el-input>
<el-form-item label="人员查询">
<el-input v-model="pageForm.searchKeyword" placeholder="请输入姓名或工号" clearable>
<el-select v-model="pageForm.searchName" slot="prepend" style="width: 90px">
<el-option label="姓名" value="userName"></el-option>
<el-option label="工号" value="loginName"></el-option>
</el-select>
</el-input>
</el-form-item>
</div>
<div class="route-line">
<div class="route-line-title">报名状态</div>
<div class="route-line-content">
<el-radio-group v-model="pageForm.signUpStatus" size="small" @change="changeSignUpStatus">
<el-radio-button :label="1">已报名</el-radio-button>
<el-radio-button :label="0">未报名</el-radio-button>
<el-radio-button :label="2">未成团</el-radio-button>
</el-radio-group>
<el-radio-group v-if="pageForm.signUpStatus===1" v-model="pageForm.isTakePartIn"
size="small" class="ml20" @change="doSearch">
<el-radio-button label="">全部</el-radio-button>
<el-radio-button :label="1">已参加</el-radio-button>
<el-radio-button :label="0">未参加</el-radio-button>
</el-radio-group>
<el-radio-group v-if="pageForm.signUpStatus===2" v-model="pageForm.unFormedType"
size="small" class="ml20" @change="doSearch">
<el-radio-button label="line">线路</el-radio-button>
<el-radio-button label="flexible">灵活组团</el-radio-button>
</el-radio-group>
</div>
</div>
<div class="form-row">
<el-form-item label="分工会">
<el-form-item v-if="schoolMode" label="分工会">
<el-select v-model="pageForm.unionId"
@change="doSearch"
placeholder="请选择所属工会"
@@ -106,6 +131,33 @@ layout("/layouts/platform.html"){
</el-select>
</el-form-item>
</div>
<div class="route-line" v-if="pageForm.signUpStatus===1">
<div class="route-line-title">报名类型</div>
<div class="route-line-content">
<el-radio-group v-model="pageForm.state" size="small" @change="changeState">
<el-radio-button :label="1">线路({{categoryCount.xlCount||0}}</el-radio-button>
<el-radio-button :label="2">灵活组团({{categoryCount.lxsCount||0}}</el-radio-button>
<el-radio-button :label="3">定点({{categoryCount.jdCount||0}}</el-radio-button>
</el-radio-group>
</div>
</div>
<div class="form-row" v-if="pageForm.signUpStatus===1">
<el-form-item label="报名时间">
<el-date-picker v-model="signTime" type="daterange" range-separator="至"
start-placeholder="开始日期" end-placeholder="结束日期"
value-format="yyyy-MM-dd" style="width:100%" @change="changeSignTime"></el-date-picker>
</el-form-item>
<el-form-item v-if="pageForm.state===2" label="旅行社">
<el-select v-model="pageForm.agencyId" filterable clearable style="width:100%" @change="doSearch">
<el-option v-for="item in agencyOptions" :key="item.id" :label="item.travelAgencyName" :value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item v-if="pageForm.state===3" label="定点">
<el-select v-model="pageForm.takePartInBaseManagementId" filterable clearable style="width:100%" @change="doSearch">
<el-option v-for="item in baseOptions" :key="item.id" :label="item.baseName" :value="item.id"></el-option>
</el-select>
</el-form-item>
</div>
<div class="route-line">
<div class="route-line-title">区域</div>
<div class="route-line-content">
@@ -150,13 +202,17 @@ layout("/layouts/platform.html"){
</el-card>
<el-card shadow="never" class="mt10">
<table-tool label="人员列表" ref="table_tool">
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="noSignExport">
<el-button icon="el-icon-message" size="small" type="primary" @click="openRemind">一键提醒</el-button>
<el-button v-if="schoolMode&&pageForm.signUpStatus===1" icon="el-icon-upload2" size="small" type="primary"
@click="openImport">参加人员导入</el-button>
<el-button v-if="schoolMode&&pageForm.signUpStatus===1" icon="el-icon-folder-opened" size="small" type="primary" @click="exportZip">导出Zip</el-button>
<el-button v-if="schoolMode" icon="el-icon-s-promotion" size="small" type="primary" @click="noSignExport">
导出未报名人员
</el-button>
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="doExport">
导出
</el-button>
<el-button icon="el-icon-s-promotion" size="small" type="primary"
<el-button v-if="pageForm.signUpStatus===1" icon="el-icon-s-promotion" size="small" type="primary"
@click="openSetUpPart"
>设置参加人员
</el-button>
@@ -210,11 +266,17 @@ layout("/layouts/platform.html"){
{{row.lotName}}
</template>
</el-table-column>
<el-table-column label="操作" width="250px">
<el-table-column v-if="pageForm.signUpStatus===1" label="操作" width="250px">
<template v-slot="{row}">
<el-button @click="openView(row)" size="mini" type="primary">查看</el-button>
<el-button @click="openEdit(row)" size="mini" type="primary">编辑</el-button>
<el-button @click="onDelete(row)" size="mini" type="danger">删除</el-button>
<el-dropdown class="ml10" trigger="click">
<el-button size="mini" type="primary">调整<i class="el-icon-arrow-down el-icon--right"></i></el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="restoreEnroll(row)">保留报名记录</el-dropdown-item>
<el-dropdown-item @click.native="onDelete(row)">删除报名记录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
</el-table-column>
</el-table>
@@ -227,11 +289,32 @@ layout("/layouts/platform.html"){
<enroll-info ref="enrollInfoRef"></enroll-info>
</el-dialog>
<set-up-part ref="setUpRef"></set-up-part>
<set-up-part ref="setUpRef" @refresh="doSearch"></set-up-part>
<edit-form ref="editRef" @refresh="doSearch"></edit-form>
<el-dialog title="发送提醒" :visible.sync="remindVisible" width="560px">
<div class="mb10">将按当前筛选条件提醒人员,请确认提醒内容。</div>
<el-input v-model="remindContent" type="textarea" :rows="5"></el-input>
<template slot="footer">
<el-button @click="remindVisible=false">取消</el-button>
<el-button type="primary" :loading="remindLoading" @click="sendRemind">发送</el-button>
</template>
</el-dialog>
<el-dialog title="参加人员导入" :visible.sync="importVisible" width="700px" append-to-body>
<el-button type="primary" size="small" class="mb20" @click="downloadImportTemplate">下载导入模板</el-button>
<el-upload ref="importUpload" drag :action="queryBase+'/enrollImport'" name="file" :auto-upload="false" :limit="1" :on-success="importSuccess" :on-error="importError" accept=".xls,.xlsx">
<i class="el-icon-upload"></i><div class="el-upload__text">将 Excel 文件拖到此处,或<em>点击选择</em></div><div slot="tip" class="el-upload__tip">按参加时间所属年度匹配省外线路报名</div>
</el-upload>
<el-alert v-if="importResult.totalCount" class="mt20" :closable="false" type="info" :title="'总记录 '+importResult.totalCount+',成功 '+importResult.successCount+',失败 '+importResult.errorCount"></el-alert>
<el-button v-if="importResult.errorCount" type="text" @click="importErrorVisible=true">查看错误记录</el-button>
<template slot="footer"><el-button @click="importVisible=false">关闭</el-button><el-button type="primary" :loading="importLoading" @click="submitImport">开始导入</el-button></template>
</el-dialog>
<el-dialog title="导入错误记录" :visible.sync="importErrorVisible" width="900px" append-to-body><el-table :data="importResult.errorList||[]"><el-table-column prop="no" label="Excel行" width="80"></el-table-column><el-table-column prop="loginName" label="工号"></el-table-column><el-table-column prop="userName" label="姓名"></el-table-column><el-table-column prop="takePartInTime" label="参加时间"></el-table-column><el-table-column prop="lotName" label="标段时间"></el-table-column><el-table-column prop="errors" label="失败原因" min-width="260"></el-table-column></el-table></el-dialog>
</div>
<script nonce="${cspNonce!}">
const queryBase = "${queryBase!'/platform/recuperation/schoolUnionUserQuery'}"
const schoolMode = ${schoolMode!true}
<!--#include('setUpPart.js'){}#-->
<!--#include('editForm.js'){}#-->
<!--#include('../line/info.js'){}#-->
@@ -248,12 +331,20 @@ layout("/layouts/platform.html"){
data() {
return {
pageForm: {
year: new Date().getFullYear().toString(),
loginName: '',
userName: '',
startYear: new Date().getFullYear().toString(),
endYear: new Date().getFullYear().toString(),
searchName: 'userName',
searchKeyword: '',
signUpStatus: 1,
state: 1,
isTakePartIn: '',
unFormedType: 'line',
takePartInLineId: '',
unionId: '',
signUpMode: 1,
agencyId: '',
takePartInBaseManagementId: '',
// 校工会旧版默认查询全部组织形式;分工会仍默认查询分工会组织线路。
signUpMode: schoolMode ? '' : 1,
lotId: '',
regionalNature: ''
},
@@ -270,28 +361,49 @@ layout("/layouts/platform.html"){
],
viewVisible: false,
unionOptions: [],
config: {}
config: {},
categoryCount: {},
agencyOptions: [],
baseOptions: [],
signTime: [],
remindVisible: false,
remindLoading: false,
remindContent: '',
schoolMode: schoolMode,
queryBase: queryBase,
importVisible: false,
importLoading: false,
importErrorVisible: false,
importResult: {totalCount:0,successCount:0,errorCount:0,errorList:[]}
}
},
methods: {
resetQuery() {
this.pageForm = {
year: new Date().getFullYear().toString(),
loginName: '',
userName: '',
this.$set(this, 'pageForm', {
startYear: new Date().getFullYear().toString(),
endYear: new Date().getFullYear().toString(),
searchName: 'userName',
searchKeyword: '',
signUpStatus: 1,
state: 1,
isTakePartIn: '',
unFormedType: 'line',
takePartInLineId: '',
unionId: '',
signUpMode: 1,
agencyId: '',
takePartInBaseManagementId: '',
// 重置后保持与页面初始查询口径一致,避免校工会被隐藏条件 signUpMode=1 限制。
signUpMode: schoolMode ? '' : 1,
lotId: '',
regionalNature: '',
pageNumber: 1,
pageSize: 10,
totalCount: 0,
}
})
this.doSearch()
},
openView(row) {
this.viewVisible = true
this.$set(this, 'viewVisible', true)
this.$nextTick(() => {
this.$refs.enrollInfoRef.onOpen(row.id)
})
@@ -305,23 +417,27 @@ layout("/layouts/platform.html"){
cancelButtonText: '取消',
dangerouslyUseHTMLString: true,
type: 'warning'
}).then(async () => {
const {code, msg} = await this.$axios.post('/platform/recuperation/schoolUnionUserQuery/deleteMyEnrollInfoById', {
}).then(() => {
this.$axios.post(queryBase + '/deleteMyEnrollInfoById', {
id: row.id
}).then((res) => {
if (res.code === 0) {
this.doSearch()
this.$message.success(res.msg)
} else {
this.$message.warning(res.msg)
}
})
if (code === 0) {
this.doSearch()
this.$message.success(msg)
} else {
this.$message.warning(msg)
}
})
},
noSignExport() {
this.$downLoad('/platform/recuperation/schoolUnionUserQuery/noSignExport')
this.$downLoad(queryBase + '/noSignExport')
},
doExport() {
this.$downLoad('/platform/recuperation/schoolUnionUserQuery/exportXlsx', this.pageForm)
this.$downLoad(queryBase + '/exportManagement', this.pageForm)
},
exportZip() {
this.$downLoad(queryBase + '/exportZip', this.pageForm)
},
openSetUpPart() {
const selection = this.$refs.tableRef.selection
@@ -335,33 +451,135 @@ layout("/layouts/platform.html"){
getConfig() {
this.$axios.post('/platform/recuperation/config/fetchOne').then((res) => {
if (res.code === 0) {
this.config = res.data
const config = res.data || {}
const lots = (config.lots || []).filter((item, index, list) => {
// 标段 ID 是业务主键,同一 ID 只保留首次出现的数据,避免 Vue 生成重复 key 和重复选项。
return item && item.id && list.findIndex((lot) => lot && lot.id === item.id) === index
})
this.$set(config, 'lots', lots)
this.$set(this, 'config', config)
}
})
}).catch(() => { this.$message.error('疗休养配置接口请求失败') })
},
getLines() {
this.$axios.post('/platform/recuperation/schoolUnionUserQuery/listLine', {
year: this.pageForm.year,
if (this.pageForm.state !== 1) {
return
}
this.$axios.post(queryBase + '/listLine', {
year: this.pageForm.startYear,
unionId: this.pageForm.unionId,
signUpMode: this.pageForm.signUpMode,
regionalNature: this.pageForm.regionalNature
}).then(res => {
if (res.code === 0) {
this.takePartInLines = res.data
this.$set(this, 'takePartInLines', res.data)
} else {
this.$message.warning(res.msg)
}
}).catch(() => { this.$message.error('线路选项接口请求失败') })
},
changeSignUpStatus() {
this.$set(this.pageForm, 'pageNumber', 1)
this.doSearch()
},
changeState() {
this.$set(this.pageForm, 'takePartInLineId', '')
this.$set(this.pageForm, 'agencyId', '')
this.$set(this.pageForm, 'takePartInBaseManagementId', '')
this.doSearch()
},
changeSignTime(value) {
this.$set(this.pageForm, 'signStartTime', value && value.length ? value[0] : '')
this.$set(this.pageForm, 'signEndTime', value && value.length ? value[1] + ' 23:59:59' : '')
this.doSearch()
},
getCategoryCount() {
this.$axios.post(queryBase + '/getCategoryCount', this.pageForm).then((res) => {
if (res.code === 0) this.$set(this, 'categoryCount', res.data || {})
}).catch(() => { this.$message.error('报名分类统计接口请求失败') })
},
getManagementOptions() {
if (this.pageForm.state === 2) {
this.$axios.post('/platform/recuperation/travelAgency/selectTravelAgencyByYears', {
startYear: this.pageForm.startYear,
endYear: this.pageForm.endYear
}).then((res) => { if (res.code === 0) this.$set(this, 'agencyOptions', res.data || []) })
}
if (this.pageForm.state === 3) {
this.$axios.post('/platform/recuperation/baseManagement/listAllBase', this.pageForm).then((res) => {
if (res.code === 0) this.$set(this, 'baseOptions', res.data || [])
})
}
},
restoreEnroll(row) {
this.$axios.post(queryBase + '/restoreEnroll', {id: row.id}).then((res) => {
if (res.code === 0) { this.$message.success(res.msg); this.doSearch() }
})
},
openImport() {
this.$set(this, 'importResult', {totalCount:0,successCount:0,errorCount:0,errorList:[]})
this.$set(this, 'importVisible', true)
this.$nextTick(() => { if (this.$refs.importUpload) this.$refs.importUpload.clearFiles() })
},
downloadImportTemplate() {
this.$downLoad(queryBase + '/downloadImportTemplate')
},
submitImport() {
if (!this.$refs.importUpload || !this.$refs.importUpload.uploadFiles.length) { this.$message.warning('请选择Excel文件'); return }
this.$set(this, 'importLoading', true)
this.$refs.importUpload.submit()
},
importSuccess(res) {
this.$set(this, 'importLoading', false)
if (res.code === 0) { this.$set(this, 'importResult', res.data || {}); this.$message.success(res.msg); this.doSearch() }
else { this.$message.warning(res.msg); this.$refs.importUpload.clearFiles() }
},
importError() {
this.$set(this, 'importLoading', false)
this.$message.warning('文件上传失败')
},
openRemind() {
this.$set(this, 'remindContent', this.config.remindContent || '')
this.$set(this, 'remindVisible', true)
},
sendRemind() {
this.$set(this, 'remindLoading', true)
this.$axios.post(queryBase + '/remindUsers', Object.assign({}, this.pageForm, {
content: this.remindContent,
loginNames: this.$refs.tableRef.selection.map((item) => item.loginName).join(',')
})).then((res) => {
if (res.code === 0) { this.$message.success(res.msg); this.$set(this, 'remindVisible', false) }
else this.$message.warning(res.msg)
}).finally(() => { this.$set(this, 'remindLoading', false) })
},
doSearch(){
this.getLines()
this.tableKey = new Date().getTime()
this.pageForm.pageNumber = 1
this.getManagementOptions()
this.getCategoryCount()
this.$set(this, 'tableKey', new Date().getTime())
this.$set(this.pageForm, 'pageNumber', 1)
this.pageData()
},
// 共用模板必须使用 Controller 下发的接口前缀,避免 Pjax 场景下 loc() 取到外层页面地址。
pageData() {
this.$set(this, 'tableLoading', true)
this.$axios.post(queryBase + '/pageData', this.pageForm).then((res) => {
if (res.code === 0) {
this.$set(this, 'tableData', res.data.list || [])
this.$set(this.pageForm, 'totalCount', res.data.totalCount || 0)
} else {
this.$message.warning(res.msg)
}
}).catch(() => {
this.$message.error('人员分页接口请求失败')
}).finally(() => {
this.$set(this, 'tableLoading', false)
})
}
},
async created() {
this.$businessTool.listUnion().then((res) => (this.unionOptions = res))
created() {
this.$businessTool.listUnion().then((res) => this.$set(this, 'unionOptions', res || []))
.catch(() => { this.$message.error('工会选项接口请求失败') })
this.doSearch()
this.getConfig()
}