移植v3疗休养到这个版本上
This commit is contained in:
+276
-30
@@ -1,43 +1,289 @@
|
||||
<!--# layout("/layouts/platform.html"){ #-->
|
||||
<style>
|
||||
.query-row {
|
||||
height: 70px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.query-row .el-col { overflow: hidden; }
|
||||
.query-row:not(:last-child) { border-bottom: 1px dashed rgb(230, 230, 230); }
|
||||
.query-row-title { width: 120px; }
|
||||
.el-table-container { padding-top: 0; }
|
||||
</style>
|
||||
<div id="app" v-cloak>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<search @search="doSearch">
|
||||
<search-item label="年度范围"><el-date-picker v-model="yearRange" type="yearrange" value-format="yyyy" range-separator="至" start-placeholder="开始年度" end-placeholder="结束年度" @change="yearChange"></el-date-picker></search-item>
|
||||
<search-item label="灵活组团"><el-select v-model="pageForm.groupName" clearable filterable @change="doSearch"><el-option v-for="item in groupOptions" :key="item.id" :label="item.groupName" :value="item.groupName"></el-option></el-select></search-item>
|
||||
<search-item label="旅行社"><el-select v-model="pageForm.travelAgencyId" clearable filterable @change="doSearch"><el-option v-for="item in agencyOptions" :key="item.id" :label="item.travelAgencyName" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item label="姓名/工号"><el-input v-model="pageForm.searchKeyword" clearable @keyup.enter.native="doSearch"></el-input></search-item>
|
||||
</search>
|
||||
<el-row align="middle" class="query-row" type="flex">
|
||||
<el-col class="query-row-title"></el-col>
|
||||
<el-col class="query-row-content">
|
||||
<el-row><el-col :span="12">
|
||||
<span>年  度:</span>
|
||||
<el-date-picker :clearable="false" v-model="pageForm.startYear" type="year" value-format="yyyy" placeholder="选择年" style="width: 38%" @change="yearChange"></el-date-picker>
|
||||
<span>至</span>
|
||||
<el-date-picker :clearable="false" v-model="pageForm.endYear" type="year" value-format="yyyy" placeholder="请选择年" style="width: 38%" @change="yearChange"></el-date-picker>
|
||||
</el-col></el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row align="middle" class="query-row" type="flex">
|
||||
<el-col class="query-row-title"></el-col>
|
||||
<el-col class="query-row-content">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<span>组团名称:</span>
|
||||
<el-select v-model="pageForm.groupName" placeholder="请选择组团名称" filterable clearable style="width: 80%" @change="doSearch">
|
||||
<el-option v-for="item in flexibleGroupList" :key="item.id" :label="item.groupName" :value="item.groupName"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span>旅 行 社:</span>
|
||||
<el-select v-model="pageForm.travelAgencyId" placeholder="请选择旅行社" filterable clearable style="width: 80%" @change="doSearch">
|
||||
<el-option v-for="item in travelAgencyList" :key="item.id" :label="item.travelAgencyName + (item.serialNumber ? '(' + item.serialNumber + ')' : '')" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row align="middle" class="query-row" type="flex">
|
||||
<el-col class="query-row-title"></el-col>
|
||||
<el-col class="query-row-content">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<span>姓名/工号:</span>
|
||||
<el-input :value="pageForm.searchKeyword" clearable placeholder="请输入姓名或工号" style="width: 80%" @input="personKeywordChange" @clear="clearPersonKeyword" @keyup.enter.native="doSearch"></el-input>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-button icon="el-icon-search" size="small" type="primary" @click="doSearch">查询</el-button>
|
||||
<el-button icon="el-icon-refresh-left" size="small" @click="clearPersonKeyword">重置</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt20">
|
||||
<table-tool label="省内灵活组团查询"><template slot="right"><el-button type="success" size="small" @click="doExport">导出Excel</el-button></template></table-tool>
|
||||
<el-table v-loading="tableLoading" :data="tableData" :size="tableSize">
|
||||
<el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column><el-table-column prop="year" label="年度" width="90"></el-table-column><el-table-column prop="groupName" label="组团名称" min-width="180"></el-table-column><el-table-column prop="travelAgencyName" label="旅行社" min-width="180"></el-table-column><el-table-column prop="groupCount" label="团队数" width="90"></el-table-column><el-table-column prop="signCount" label="报名人数" width="100"></el-table-column><el-table-column label="操作" width="180"><template v-slot="{row}"><el-button size="mini" @click="openGroups(row)">查看团队</el-button><el-button type="primary" size="mini" @click="openAllUsers(row)">全部人员</el-button></template></el-table-column>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="灵活组团查询" :app="this" ref="table_tool">
|
||||
<el-button icon="el-icon-s-promotion" size="small" type="primary" @click="doExport">导出Excel</el-button>
|
||||
</table-tool>
|
||||
<el-table :data="tableData" :row-key="tableRowKey" style="width: 100%" ref="table" v-loading="tableLoading" @sort-change="pageOrder">
|
||||
<el-table-column align="center" header-align="center" type="index" label="序号" width="80" key="#index">
|
||||
<template v-slot="scope"><span>{{scope.$index + (pageForm.pageNumber - 1) * pageForm.pageSize + 1}}</span></template>
|
||||
</el-table-column>
|
||||
<el-table-column v-for="column in tableColumns" v-if="!column.personOnly || pageForm.searchKeyword" :key="column.prop" :label="column.label" :prop="column.prop" :width="column.width" :sortable="column.sortable" align="center" header-align="center" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template v-slot="{row}"><el-button @click="openView(row)" size="mini" type="primary">查看团</el-button><el-button @click="openViewUser(row)" size="mini" type="primary">查看人员</el-button></template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
<el-dialog title="团队列表" :visible.sync="groupVisible" width="900px" append-to-body>
|
||||
<el-table v-loading="dialogLoading" :data="groups"><el-table-column prop="groupLeaderUserName" label="团长姓名"></el-table-column><el-table-column prop="groupLeaderLoginName" label="团长工号"></el-table-column><el-table-column prop="groupLeaderPassword" label="团口令"></el-table-column><el-table-column prop="userCount" label="人数" width="90"></el-table-column><el-table-column label="操作" width="100"><template v-slot="{row}"><el-button type="primary" size="mini" @click="openGroupUsers(row)">人员</el-button></template></el-table-column></el-table>
|
||||
</template>
|
||||
</guava>
|
||||
<el-dialog :visible.sync="userVisible" :close-on-click-modal="false" top="2%" title="报名人员" width="65%">
|
||||
<el-table :data="signUserData" style="width: 100%" ref="userTable" v-loading="userLoading">
|
||||
<el-table-column align="center" header-align="center" type="index" label="序号" width="80"></el-table-column>
|
||||
<el-table-column prop="userName" label="姓名" header-align="center" align="center"></el-table-column>
|
||||
<el-table-column prop="loginName" label="工号" header-align="center" align="center"></el-table-column>
|
||||
<el-table-column prop="unionName" label="所属工会" header-align="center" align="center"></el-table-column>
|
||||
<el-table-column prop="unitName" label="单位" header-align="center" align="center"></el-table-column>
|
||||
<el-table-column prop="sex" label="性别" header-align="center" align="center"></el-table-column>
|
||||
<el-table-column prop="mobile" label="手机号" header-align="center" align="center" width="120"></el-table-column>
|
||||
<el-table-column prop="identity" label="身份" header-align="center" align="center"></el-table-column>
|
||||
<el-table-column prop="isFamily" label="是否有家属" header-align="center" align="center"><template v-slot="{row}"><span v-if="row.isFamily > 0">是</span><span v-else>否</span></template></el-table-column>
|
||||
<el-table-column label="操作" width="100"><template v-slot="{row}"><el-button @click="deleteUser(row)" size="mini" type="danger">删除</el-button></template></el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer"><el-button @click="closeUserDialog" type="primary">取 消</el-button></span>
|
||||
</el-dialog>
|
||||
<el-dialog title="报名人员" :visible.sync="userVisible" width="1050px" append-to-body>
|
||||
<el-table v-loading="userLoading" :data="users"><el-table-column type="index" label="序号" width="60"></el-table-column><el-table-column prop="loginName" label="工号" width="110"></el-table-column><el-table-column prop="userName" label="姓名" width="100"></el-table-column><el-table-column prop="identity" label="身份" width="80"></el-table-column><el-table-column prop="sex" label="性别" width="60"></el-table-column><el-table-column prop="unitName" label="单位" show-overflow-tooltip></el-table-column><el-table-column prop="unionName" label="工会" show-overflow-tooltip></el-table-column><el-table-column prop="mobile" label="联系电话" width="130"></el-table-column><el-table-column prop="isFamily" label="家属人数" width="90"></el-table-column><el-table-column label="操作" width="80"><template v-slot="{row}"><el-button type="danger" size="mini" @click="deleteUser(row)">删除</el-button></template></el-table-column></el-table>
|
||||
<el-pagination class="mt20" background layout="total, sizes, prev, pager, next" :current-page="userPage.pageNumber" :page-size="userPage.pageSize" :total="userPage.totalCount" @current-change="userPageChange" @size-change="userSizeChange"></el-pagination>
|
||||
<el-dialog :visible.sync="groupVisible" :close-on-click-modal="false" top="2%" title="团信息">
|
||||
<el-table :data="groupTableData" max-height="600" v-loading="dialogLoading">
|
||||
<el-table-column label="序号" type="index" header-align="center" align="center" width="50"></el-table-column>
|
||||
<el-table-column prop="groupLeaderUserName" label="团长" header-align="center" align="center" sortable><template v-slot="{row}"><span v-if="row.groupLeaderUserName">{{row.groupLeaderUserName}}({{row.groupLeaderLoginName}})</span><span v-else>未选择</span></template></el-table-column>
|
||||
<el-table-column prop="groupLeaderPassword" label="口令" header-align="center" align="center"><template v-slot="{row}"><span>{{row.groupLeaderPassword || '-'}}</span></template></el-table-column>
|
||||
<el-table-column prop="userCount" label="报名人数" header-align="center" align="center" sortable></el-table-column>
|
||||
<el-table-column label="操作" width="150"><template v-slot="{row}"><el-button @click="openViewUserByTime(row)" size="mini" type="primary">查看人员</el-button></template></el-table-column>
|
||||
</el-table>
|
||||
<span slot="footer" class="dialog-footer"><el-button @click="closeGroupDialog" type="primary">取 消</el-button></span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({
|
||||
el:'#app',mixins:[initTableMixins],data(){const year=new Date().getFullYear().toString();return{yearRange:[year,year],pageForm:{pageNumber:1,pageSize:10,totalCount:0,startYear:year,endYear:year,groupName:'',travelAgencyId:'',searchKeyword:''},agencyOptions:[],groupOptions:[],currentGroup:{},groups:[],users:[],groupVisible:false,userVisible:false,dialogLoading:false,userLoading:false,userPage:{pageNumber:1,pageSize:10,totalCount:0},userQuery:{}}},
|
||||
methods:{
|
||||
pageData(){this.$set(this,'tableLoading',true);this.$axios.post(loc()+'/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)}}).finally(()=>{this.$set(this,'tableLoading',false)})},
|
||||
yearChange(value){this.$set(this.pageForm,'startYear',value&&value.length?value[0]:'');this.$set(this.pageForm,'endYear',value&&value.length?value[1]:'');this.loadOptions();this.doSearch()},
|
||||
loadOptions(){const params={startYear:this.pageForm.startYear,endYear:this.pageForm.endYear};this.$axios.post(loc()+'/selectTravelAgencyList',params).then((res)=>{if(res.code===0)this.$set(this,'agencyOptions',res.data||[])});this.$axios.post(loc()+'/selectFlexibleGroupList',params).then((res)=>{if(res.code===0)this.$set(this,'groupOptions',res.data||[])})},
|
||||
doExport(){window.open(loc()+'/doExport?'+$.param(this.pageForm))},
|
||||
openGroups(row){this.$set(this,'currentGroup',row);this.$set(this,'groupVisible',true);this.$set(this,'dialogLoading',true);this.$axios.post(loc()+'/getGroupInfo',{groupId:row.id}).then((res)=>{if(res.code===0)this.$set(this,'groups',res.data||[])}).finally(()=>{this.$set(this,'dialogLoading',false)})},
|
||||
openAllUsers(row){this.$set(this,'currentGroup',row);this.$set(this,'userQuery',{});this.$set(this.userPage,'pageNumber',1);this.$set(this,'userVisible',true);this.loadUsers()},
|
||||
openGroupUsers(row){this.$set(this,'userQuery',{groupLeaderUserId:row.groupLeaderUserId,groupLeaderLoginName:row.groupLeaderLoginName,noGroupLeader:!row.groupLeaderUserId&&!row.groupLeaderLoginName});this.$set(this.userPage,'pageNumber',1);this.$set(this,'userVisible',true);this.loadUsers()},
|
||||
loadUsers(){this.$set(this,'userLoading',true);const params=Object.assign({groupId:this.currentGroup.id,pageNumber:this.userPage.pageNumber,pageSize:this.userPage.pageSize},this.userQuery);this.$axios.post(loc()+'/getSignUser',params).then((res)=>{if(res.code===0){this.$set(this,'users',res.data.list||[]);this.$set(this.userPage,'totalCount',res.data.totalCount||0)}}).finally(()=>{this.$set(this,'userLoading',false)})},
|
||||
userPageChange(value){this.$set(this.userPage,'pageNumber',value);this.loadUsers()},userSizeChange(value){this.$set(this.userPage,'pageSize',value);this.$set(this.userPage,'pageNumber',1);this.loadUsers()},
|
||||
deleteUser(row){this.$confirm('确定删除该报名人员吗?','提示',{type:'warning'}).then(()=>{this.$axios.post(loc()+'/deleteJoinUser',{id:row.id}).then((res)=>{if(res.code===0){this.$message.success(res.msg);this.loadUsers();this.pageData()}else this.$message.warning(res.msg)})}).catch(()=>{})}
|
||||
},created(){this.loadOptions();this.pageData()}
|
||||
})
|
||||
const vue = new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
const currentYear = moment().format('YYYY')
|
||||
return {
|
||||
groupVisible: false,
|
||||
userVisible: false,
|
||||
userLoading: false,
|
||||
dialogLoading: false,
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
startYear: currentYear,
|
||||
endYear: currentYear,
|
||||
groupName: '',
|
||||
travelAgencyId: '',
|
||||
searchKeyword: ''
|
||||
},
|
||||
tableColumns: [
|
||||
{prop: 'year', label: '年度', width: 60},
|
||||
{prop: 'groupName', label: '组团名称', sortable: true},
|
||||
{prop: 'travelAgencyName', label: '旅行社', sortable: true},
|
||||
{prop: 'groupCount', label: '团数量'},
|
||||
{prop: 'signCount', label: '报名人数'},
|
||||
{prop: 'signUserName', label: '报名人员', personOnly: true},
|
||||
{prop: 'signLoginName', label: '工号', personOnly: true}
|
||||
],
|
||||
travelAgencyList: [],
|
||||
flexibleGroupList: [],
|
||||
groupTableData: [],
|
||||
signUserData: [],
|
||||
currentGroupId: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
pageData() {
|
||||
this.$set(this, 'tableLoading', true)
|
||||
this.$axios.post(loc() + '/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)
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.$set(this, 'tableLoading', false)
|
||||
})
|
||||
},
|
||||
tableRowKey(row) {
|
||||
return row.rowKey || row.id
|
||||
},
|
||||
closeUserDialog() {
|
||||
this.$set(this, 'userVisible', false)
|
||||
},
|
||||
closeGroupDialog() {
|
||||
this.$set(this, 'groupVisible', false)
|
||||
},
|
||||
personKeywordChange(value) {
|
||||
this.$set(this.pageForm, 'searchKeyword', value)
|
||||
},
|
||||
clearPersonKeyword() {
|
||||
this.$set(this.pageForm, 'searchKeyword', '')
|
||||
this.doSearch()
|
||||
},
|
||||
yearChange() {
|
||||
this.getTravelAgency()
|
||||
this.getFlexibleGroupList()
|
||||
this.doSearch()
|
||||
},
|
||||
getTravelAgency() {
|
||||
const params = {
|
||||
startYear: this.pageForm.startYear,
|
||||
endYear: this.pageForm.endYear
|
||||
}
|
||||
this.$axios.post(loc() + '/selectTravelAgencyList', params)
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, 'travelAgencyList', res.data || [])
|
||||
}
|
||||
})
|
||||
},
|
||||
getFlexibleGroupList() {
|
||||
const params = {
|
||||
startYear: this.pageForm.startYear,
|
||||
endYear: this.pageForm.endYear
|
||||
}
|
||||
this.$axios.post(loc() + '/selectFlexibleGroupList', params)
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, 'flexibleGroupList', res.data || [])
|
||||
}
|
||||
})
|
||||
},
|
||||
doExport() {
|
||||
window.open(loc() + '/doExport?' + $.param(this.pageForm))
|
||||
},
|
||||
openView(row) {
|
||||
this.$set(this, 'currentGroupId', row.id)
|
||||
this.$set(this, 'dialogLoading', true)
|
||||
this.$axios.post(loc() + '/getGroupInfo', {groupId: row.id})
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, 'groupTableData', res.data || [])
|
||||
this.$set(this, 'groupVisible', true)
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.$set(this, 'dialogLoading', false)
|
||||
})
|
||||
},
|
||||
openViewUser(row) {
|
||||
this.$set(this, 'currentGroupId', row.id)
|
||||
this.loadAllSignUser()
|
||||
},
|
||||
openViewUserByTime(row) {
|
||||
this.loadSignUserByTime(row.groupLeaderUserId, row.groupLeaderLoginName, !row.groupLeaderUserId && !row.groupLeaderLoginName)
|
||||
},
|
||||
loadAllSignUser() {
|
||||
// groupId 传灵活组团配置主键,接口返回该组团下全部报名人员的分页结构。
|
||||
this.$set(this, 'userLoading', true)
|
||||
this.$axios.post(loc() + '/getAllSignUser', {
|
||||
groupId: this.currentGroupId,
|
||||
pageNumber: 1,
|
||||
pageSize: 1000
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, 'signUserData', res.data.list || [])
|
||||
this.$set(this, 'userVisible', true)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.$set(this, 'userLoading', false)
|
||||
})
|
||||
},
|
||||
loadSignUserByTime(groupLeaderUserId, groupLeaderLoginName, noGroupLeader) {
|
||||
// 参数依次标识团长用户、团长工号和未选团长分组,接口返回对应团内人员分页结构。
|
||||
this.$set(this, 'userLoading', true)
|
||||
this.$axios.post(loc() + '/getSignUser', {
|
||||
groupId: this.currentGroupId,
|
||||
groupLeaderUserId: groupLeaderUserId,
|
||||
groupLeaderLoginName: groupLeaderLoginName,
|
||||
noGroupLeader: noGroupLeader,
|
||||
pageNumber: 1,
|
||||
pageSize: 1000
|
||||
}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, 'signUserData', res.data.list || [])
|
||||
this.$set(this, 'userVisible', true)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.$set(this, 'userLoading', false)
|
||||
})
|
||||
},
|
||||
deleteUser(row) {
|
||||
this.$confirm('您确定要删除该人员吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$axios.post(loc() + '/deleteJoinUser', {id: row.id})
|
||||
.then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$message.success('删除成功')
|
||||
this.$set(this, 'signUserData', this.signUserData.filter((item) => item.id !== row.id))
|
||||
this.pageData()
|
||||
} else {
|
||||
this.$message.error(res.msg)
|
||||
}
|
||||
})
|
||||
}).catch(() => {})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getTravelAgency()
|
||||
this.getFlexibleGroupList()
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--# } #-->
|
||||
|
||||
+425
-20
@@ -1,26 +1,431 @@
|
||||
<!--# layout("/layouts/platform.html"){ #-->
|
||||
<style>
|
||||
.line-statistics-query-row {
|
||||
min-height: 70px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.line-statistics-query-row:not(:last-child) {
|
||||
border-bottom: 1px dashed #e6e6e6;
|
||||
}
|
||||
|
||||
.line-statistics-query-content {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never"><search @search="doSearch">
|
||||
<search-item label="年度范围"><el-date-picker v-model="yearRange" type="yearrange" value-format="yyyy" range-separator="至" @change="yearChange"></el-date-picker></search-item>
|
||||
<search-item label="所属工会"><el-select v-model="pageForm.unionId" filterable clearable @change="doSearch"><el-option v-for="item in unionOptions" :key="item.id" :label="item.name" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item label="线路类型"><el-select v-model="pageForm.regionalNature" clearable @change="filterChange"><el-option label="省内" value="省内"></el-option><el-option label="省外" value="省外"></el-option></el-select></search-item>
|
||||
<search-item label="组织方式"><el-select v-model="pageForm.signUpMode" clearable @change="filterChange"><el-option label="分工会组织" value="1"></el-option><el-option label="校工会组织" value="2"></el-option></el-select></search-item>
|
||||
<search-item label="线路"><el-select v-model="pageForm.takePartInLineId" filterable clearable @change="doSearch"><el-option v-for="item in lineOptions" :key="item.id" :label="item.lineName+'-'+item.regionalNature+'【'+(item.lotName||'')+'】('+item.signUpMode+')'" :value="item.id"></el-option></el-select></search-item>
|
||||
<search-item label="标段"><el-select v-model="pageForm.lotId" filterable clearable @change="doSearch"><el-option v-for="item in lots" :key="item.id" :label="item.lotName" :value="item.id"></el-option></el-select></search-item>
|
||||
</search></el-card>
|
||||
<el-card shadow="never" class="mt20"><table-tool label="线路报名统计"></table-tool>
|
||||
<el-table v-loading="tableLoading" :data="tableData" :size="tableSize"><el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column><el-table-column prop="year" label="年度" width="70"></el-table-column><el-table-column prop="lineName" label="线路名称" min-width="180"></el-table-column><el-table-column prop="linePlayTime" label="出行时间" width="150"></el-table-column><el-table-column prop="travelAgencyName" label="承担旅行社" min-width="150"></el-table-column><el-table-column prop="unionName" label="选择线路工会"></el-table-column><el-table-column prop="regionalNature" label="线路类型" width="90"></el-table-column><el-table-column prop="minimumGroupSize" label="最少成团人数" width="110"></el-table-column><el-table-column label="报名人数(家属)" width="130"><template v-slot="{row}"><el-link type="primary" @click="openUsers(row)">{{Number(row.lineNum||0)+Number(row.signUpUserFamilyNum||0)}}({{row.signUpUserFamilyNum||0}})</el-link></template></el-table-column><el-table-column label="操作" width="300"><template v-slot="{row}"><el-button size="mini" @click="openUsers(row)">查看人员</el-button><el-button type="success" size="mini" @click="notice(row,true,true)">成团通知</el-button><el-dropdown class="ml10"><el-button type="warning" size="mini">未成团通知<i class="el-icon-arrow-down el-icon--right"></i></el-button><el-dropdown-menu slot="dropdown"><el-dropdown-item @click.native="notice(row,false,true)">保留报名记录</el-dropdown-item><el-dropdown-item @click.native="notice(row,false,false)">删除报名记录</el-dropdown-item></el-dropdown-menu></el-dropdown></template></el-table-column></el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
<el-dialog title="线路报名人员" :visible.sync="userVisible" width="1050px" append-to-body><div class="mb10"><el-input v-model="userPage.searchKeyword" placeholder="姓名或工号" clearable style="width:220px" @keyup.enter.native="loadUsers"></el-input><el-button type="primary" class="ml10" @click="loadUsers">查询</el-button></div><el-table v-loading="userLoading" :data="users"><el-table-column type="index" label="序号" width="60"></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="unionName" label="所属工会"></el-table-column><el-table-column prop="unitName" label="所属单位"></el-table-column><el-table-column prop="familyCount" label="家属人数" width="90"></el-table-column><el-table-column prop="linePlayTime" label="出行时间"></el-table-column></el-table><el-pagination class="mt20" background layout="total, sizes, prev, pager, next" :current-page="userPage.pageNumber" :page-size="userPage.pageSize" :total="userPage.totalCount" @current-change="userPageChange" @size-change="userSizeChange"></el-pagination></el-dialog>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<el-row class="line-statistics-query-row" type="flex" align="middle">
|
||||
<el-col class="line-statistics-query-content">
|
||||
<el-row :gutter="30">
|
||||
<el-col :span="12">
|
||||
<span>年  度:</span>
|
||||
<el-date-picker v-model="pageForm.startYear" type="year" value-format="yyyy"
|
||||
:clearable="false" placeholder="选择年" style="width: 38%"
|
||||
@change="yearChange"></el-date-picker>
|
||||
<span>至</span>
|
||||
<el-date-picker v-model="pageForm.endYear" type="year" value-format="yyyy"
|
||||
:clearable="false" placeholder="选择年" style="width: 38%"
|
||||
@change="yearChange"></el-date-picker>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span>所属工会:</span>
|
||||
<el-select v-model="pageForm.unionId" filterable clearable placeholder="请选择所属工会"
|
||||
style="width: 80%" @change="doSearch">
|
||||
<el-option v-for="item in unionOptions" :key="item.id" :label="item.name"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="line-statistics-query-row" type="flex" align="middle">
|
||||
<el-col class="line-statistics-query-content">
|
||||
<el-row :gutter="30">
|
||||
<el-col :span="12">
|
||||
<span>线路类型:</span>
|
||||
<el-select v-model="pageForm.regionalNature" filterable placeholder="请选择线路类型"
|
||||
style="width: 80%" @change="lineTypeChange">
|
||||
<el-option label="全部" value=""></el-option>
|
||||
<el-option label="省内" value="省内"></el-option>
|
||||
<el-option label="省外" value="省外"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span>线  路:</span>
|
||||
<el-select v-model="pageForm.takePartInLineId" filterable clearable
|
||||
placeholder="请选择线路" style="width: 80%" @change="lineChange">
|
||||
<el-option v-for="item in lineOptions" :key="item.id"
|
||||
:label="item.lineName+'-'+item.regionalNature+'【'+(item.lotName||'')+'】('+item.signUpMode+')'"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row class="line-statistics-query-row" type="flex" align="middle">
|
||||
<el-col class="line-statistics-query-content">
|
||||
<el-row :gutter="30">
|
||||
<el-col :span="12">
|
||||
<span>标  段:</span>
|
||||
<el-select v-model="pageForm.lotId" filterable clearable placeholder="请选择标段"
|
||||
style="width: 80%" @change="doSearch">
|
||||
<el-option v-for="item in lots" :key="item.id" :label="item.lotName"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<span>出行时间:</span>
|
||||
<el-select v-model="pageForm.selectId" filterable clearable placeholder="请选择出行时间"
|
||||
style="width: 80%" @change="doSearch">
|
||||
<el-option v-for="item in linePlayTimes" :key="item.selectId" :label="item.times"
|
||||
:value="item.selectId"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<table-tool label="数据列表">
|
||||
<el-button icon="el-icon-s-promotion" size="small" type="primary" class="mr10" @click="doExport">
|
||||
导出成团线路人员
|
||||
</el-button>
|
||||
</table-tool>
|
||||
<el-table ref="table" row-key="lineUId" :data="tableData" v-loading="tableLoading" style="width: 100%"
|
||||
@sort-change="pageOrder">
|
||||
<el-table-column align="center" header-align="center" type="index" label="序号" :index="indexMethod"
|
||||
width="80"></el-table-column>
|
||||
<el-table-column v-for="column in tableColumns" :key="column.prop" align="center"
|
||||
header-align="center" show-overflow-tooltip :label="column.label"
|
||||
:prop="column.prop" :width="column.width" :sortable="column.sortable">
|
||||
<template v-slot="{row}">
|
||||
<el-link v-if="column.prop==='lineName'" type="primary" @click="openLine(row)">
|
||||
{{row.lineName}}
|
||||
</el-link>
|
||||
<el-link v-else-if="column.prop==='lineNum'" type="primary" @click="openUserData(row)">
|
||||
{{Number(row.lineNum||0)+Number(row.signUpUserFamilyNum||0)}}({{row.signUpUserFamilyNum||0}})
|
||||
</el-link>
|
||||
<span v-else>{{row[column.prop]}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="380">
|
||||
<template v-slot="{row}">
|
||||
<el-button size="mini" type="primary" @click="openUserData(row)">查看人员</el-button>
|
||||
<el-button size="mini" type="primary" @click="sendNotice(row,true,true)">发送成团通知
|
||||
</el-button>
|
||||
<el-dropdown class="ml10 mr10" 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="sendNotice(row,false,true)">保留报名记录
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="sendNotice(row,false,false)">删除报名记录
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--#include("/layouts/pagination.html"){}#-->
|
||||
</el-card>
|
||||
</template>
|
||||
<template #public>
|
||||
<line-info ref="viewLineInfo"></line-info>
|
||||
</template>
|
||||
<template #edit>
|
||||
<el-card shadow="never">
|
||||
<div class="search">
|
||||
<div class="search-item">
|
||||
<div class="search-item-label">工号姓名</div>
|
||||
<div class="search-item-option">
|
||||
<el-input v-model="userPage.searchKeyword" maxlength="30" clearable></el-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item" v-if="$auth.hasRole('SYSADMIN') || $auth.hasRole('SCHOOL_UNION_ADMIN')">
|
||||
<div class="search-item-label">所属工会</div>
|
||||
<div class="search-item-option">
|
||||
<el-select v-model="userPage.unionId" filterable clearable style="width: 100%"
|
||||
@change="flushUnits">
|
||||
<el-option v-for="item in unionOptions" :key="item.id" :label="item.name"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-item">
|
||||
<div class="search-item-label">所属单位</div>
|
||||
<div class="search-item-option">
|
||||
<el-select v-model="userPage.unitId" filterable clearable style="width: 100%">
|
||||
<el-option v-for="item in units" :key="item.id" :label="item.name"
|
||||
:value="item.id"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-query">
|
||||
<el-button type="primary" icon="el-icon-search" @click="loadUsers">搜索</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card shadow="never" class="mt10">
|
||||
<el-table :data="users" v-loading="userLoading">
|
||||
<el-table-column v-for="column in userColumns" :key="column.prop" align="center"
|
||||
header-align="center" show-overflow-tooltip :label="column.label"
|
||||
:prop="column.prop" :sortable="column.sortable">
|
||||
<template v-slot="{row}">
|
||||
<el-link v-if="column.prop==='familyCount'" type="primary">
|
||||
{{Number(row.familyCount||0)>0?'携带':'未携带'}}({{row.familyCount||0}})
|
||||
</el-link>
|
||||
<span v-else>{{row[column.prop]}}</span></template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-row class="el-pagination-container" style="margin-bottom: 0">
|
||||
<el-pagination :current-page="userPage.pageNumber" :page-size="userPage.pageSize"
|
||||
:page-sizes="[5,10,20,30,50]" :total="userPage.totalCount"
|
||||
layout="total, sizes, prev, pager, next" @size-change="userSizeChange"
|
||||
@current-change="userPageChange"></el-pagination>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</template>
|
||||
</guava>
|
||||
</div>
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({el:'#app',mixins:[initTableMixins],data(){const year=new Date().getFullYear().toString();return{yearRange:[year,year],pageForm:{pageNumber:1,pageSize:10,totalCount:0,startYear:year,endYear:year,unionId:'',regionalNature:'',signUpMode:'',takePartInLineId:'',lotId:'',selectId:''},unionOptions:[],lineOptions:[],lots:[],userVisible:false,userLoading:false,currentRow:{},users:[],userPage:{pageNumber:1,pageSize:10,totalCount:0,searchKeyword:'',unionId:'',unitId:''}}},methods:{
|
||||
pageData(){this.$set(this,'tableLoading',true);this.$axios.post(loc()+'/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)}}).finally(()=>{this.$set(this,'tableLoading',false)})},
|
||||
yearChange(value){this.$set(this.pageForm,'startYear',value[0]);this.$set(this.pageForm,'endYear',value[1]);this.filterChange()},filterChange(){this.$set(this.pageForm,'takePartInLineId','');this.loadLines();this.doSearch()},
|
||||
loadLines(){this.$axios.post(loc()+'/getLineOptions',{startYear:this.pageForm.startYear,endYear:this.pageForm.endYear,signUpMode:this.pageForm.signUpMode,regionalNature:this.pageForm.regionalNature}).then((res)=>{if(res.code===0)this.$set(this,'lineOptions',res.data||[])})},
|
||||
openUsers(row){this.$set(this,'currentRow',row);this.$set(this.userPage,'pageNumber',1);this.$set(this,'userVisible',true);this.loadUsers()},loadUsers(){this.$set(this,'userLoading',true);const params=Object.assign({},this.userPage,{takePartLineId:this.currentRow.lineUId});this.$axios.post(loc()+'/getUserDateByLine',params).then((res)=>{if(res.code===0){this.$set(this,'users',res.data.list||[]);this.$set(this.userPage,'totalCount',res.data.totalCount||0)}}).finally(()=>{this.$set(this,'userLoading',false)})},userPageChange(value){this.$set(this.userPage,'pageNumber',value);this.loadUsers()},userSizeChange(value){this.$set(this.userPage,'pageSize',value);this.$set(this.userPage,'pageNumber',1);this.loadUsers()},
|
||||
notice(row,success,keep){const countUrl=success?'/countSuccessNotice':'/countFailNotice';this.$axios.post(loc()+countUrl,{id:row.lineUId}).then((res)=>{if(res.code!==0){this.$message.warning(res.msg);return}const data=res.data||{};if(!data.sendCount){this.$message.warning(data.msg);return}this.$prompt('当前将通过'+data.sendTypeName+'发送'+data.sendCount+'人,请确认消息内容。','提示',{inputType:'textarea',inputValue:data.content||'',inputValidator:(value)=>!!(value&&value.trim()),inputErrorMessage:'消息内容不能为空'}).then((prompt)=>{const url=success?'/sendSuccess':'/sendFail';this.$axios.post(loc()+url,{id:row.lineUId,type:keep,content:prompt.value}).then((sendRes)=>{if(sendRes.code===0){const result=sendRes.data||{};this.$message.success(result.msg||'通知发送完成');this.pageData()}else this.$message.warning(sendRes.msg)})}).catch(()=>{})})}
|
||||
},created(){this.$businessTool.listUnion().then((res)=>{this.$set(this,'unionOptions',res||[])});this.$axios.post('/platform/recuperation/config/fetchOne').then((res)=>{if(res.code===0)this.$set(this,'lots',(res.data&&res.data.lots)||[])});this.loadLines();this.pageData()}})
|
||||
<!--#include('../line/info.js'){}#-->
|
||||
new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
components: {'line-info': info},
|
||||
data() {
|
||||
const year = new Date().getFullYear().toString()
|
||||
return {
|
||||
pageForm: {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
startYear: year,
|
||||
endYear: year,
|
||||
unionId: '',
|
||||
regionalNature: '',
|
||||
takePartInLineId: '',
|
||||
lotId: '',
|
||||
selectId: '',
|
||||
signUpMode: ''
|
||||
},
|
||||
tableColumns: [
|
||||
{prop: 'year', label: '年度', width: 60}, {
|
||||
prop: 'lineName',
|
||||
label: '线路名称',
|
||||
sortable: true,
|
||||
width: 200
|
||||
},
|
||||
{prop: 'linePlayTime', label: '出行时间', width: 180}, {
|
||||
prop: 'travelAgencyName',
|
||||
label: '承担旅行社',
|
||||
sortable: true,
|
||||
width: 180
|
||||
},
|
||||
{prop: 'unionName', label: '选择线路工会', sortable: true}, {
|
||||
prop: 'regionalNature',
|
||||
label: '线路类型',
|
||||
sortable: true
|
||||
},
|
||||
{prop: 'contact', label: '联系人', sortable: true, checked: 0}, {
|
||||
prop: 'contactMobileNumber',
|
||||
label: '联系方式',
|
||||
checked: 0
|
||||
},
|
||||
{prop: 'minimumGroupSize', label: '最少成团人数(含家属)', width: 140}, {
|
||||
prop: 'lineNum',
|
||||
label: '报名人数(含家属)',
|
||||
width: 140
|
||||
}
|
||||
],
|
||||
unionOptions: [],
|
||||
lineOptions: [],
|
||||
linePlayTimes: [],
|
||||
lots: [],
|
||||
units: [],
|
||||
lineUId: '',
|
||||
users: [],
|
||||
userLoading: false,
|
||||
userPage: {pageNumber: 1, pageSize: 10, totalCount: 0, searchKeyword: '', unionId: '', unitId: ''},
|
||||
userColumns: [
|
||||
{prop: 'loginName', label: '工号'}, {prop: 'userName', label: '姓名'}, {
|
||||
prop: 'unionName',
|
||||
label: '所属工会'
|
||||
},
|
||||
{prop: 'unitName', label: '所属单位', sortable: true}, {prop: 'familyCount', label: '是否携带家属'},
|
||||
{prop: 'linePlayTime', label: '出行时间', sortable: true}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
pageData() {
|
||||
this.$set(this, 'tableLoading', true)
|
||||
this.$axios.post(loc() + '/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)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.$set(this, 'tableLoading', false)
|
||||
})
|
||||
},
|
||||
yearChange() {
|
||||
this.$set(this.pageForm, 'takePartInLineId', '');
|
||||
this.$set(this.pageForm, 'selectId', '');
|
||||
this.$set(this, 'linePlayTimes', [])
|
||||
this.loadLines();
|
||||
this.doSearch()
|
||||
},
|
||||
lineTypeChange() {
|
||||
this.$set(this.pageForm, 'takePartInLineId', '');
|
||||
this.$set(this.pageForm, 'selectId', '');
|
||||
this.$set(this, 'linePlayTimes', [])
|
||||
this.loadLines();
|
||||
this.doSearch()
|
||||
},
|
||||
lineChange() {
|
||||
this.$set(this.pageForm, 'selectId', '');
|
||||
this.loadLinePlayTimes();
|
||||
this.doSearch()
|
||||
},
|
||||
loadLines() {
|
||||
this.$axios.post(loc() + '/getLineOptions', {
|
||||
startYear: this.pageForm.startYear,
|
||||
endYear: this.pageForm.endYear,
|
||||
signUpMode: '',
|
||||
regionalNature: this.pageForm.regionalNature
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code === 0) this.$set(this, 'lineOptions', res.data || [])
|
||||
})
|
||||
},
|
||||
loadLinePlayTimes() {
|
||||
if (!this.pageForm.takePartInLineId) {
|
||||
this.$set(this, 'linePlayTimes', []);
|
||||
return
|
||||
}
|
||||
this.$axios.post(loc() + '/getLinePlayTimes', {
|
||||
lineId: this.pageForm.takePartInLineId,
|
||||
startYear: this.pageForm.startYear,
|
||||
endYear: this.pageForm.endYear
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code === 0) this.$set(this, 'linePlayTimes', res.data || [])
|
||||
})
|
||||
},
|
||||
doExport() {
|
||||
this.$downLoad(loc() + '/doExport', this.pageForm)
|
||||
},
|
||||
openLine(row) {
|
||||
this.$refs.guava.public()
|
||||
this.$nextTick(() => {
|
||||
this.$refs.viewLineInfo.findOne(row.lineId, row.usUnionId)
|
||||
this.$refs.viewLineInfo.findUnionSelectLineData(row.lineId, row.usUnionId)
|
||||
this.$set(this.$refs.viewLineInfo, 'showTravelTimePeriod', true)
|
||||
})
|
||||
},
|
||||
openUserData(row) {
|
||||
this.$set(this, 'lineUId', row.lineUId)
|
||||
this.$set(this, 'userPage', {
|
||||
pageNumber: 1,
|
||||
pageSize: 10,
|
||||
totalCount: 0,
|
||||
searchKeyword: '',
|
||||
unionId: '',
|
||||
unitId: ''
|
||||
})
|
||||
this.$set(this, 'units', []);
|
||||
this.$refs.guava.edit();
|
||||
this.loadUsers()
|
||||
},
|
||||
flushUnits() {
|
||||
this.$set(this.userPage, 'unitId', '')
|
||||
if (!this.userPage.unionId) {
|
||||
this.$set(this, 'units', []);
|
||||
return
|
||||
}
|
||||
getUnits(this.userPage.unionId).then((res) => {
|
||||
this.$set(this, 'units', res || [])
|
||||
})
|
||||
},
|
||||
loadUsers() {
|
||||
this.$set(this, 'userLoading', true)
|
||||
const params = Object.assign({}, this.userPage, {takePartLineId: this.lineUId})
|
||||
this.$axios.post(loc() + '/getUserDateByLine', params).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, 'users', res.data.list || []);
|
||||
this.$set(this.userPage, 'totalCount', res.data.totalCount || 0)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.$set(this, 'userLoading', false)
|
||||
})
|
||||
},
|
||||
userPageChange(value) {
|
||||
this.$set(this.userPage, 'pageNumber', value);
|
||||
this.loadUsers()
|
||||
},
|
||||
userSizeChange(value) {
|
||||
this.$set(this.userPage, 'pageSize', value);
|
||||
this.$set(this.userPage, 'pageNumber', 1);
|
||||
this.loadUsers()
|
||||
},
|
||||
sendNotice(row, success, keep) {
|
||||
const countUrl = success ? '/countSuccessNotice' : '/countFailNotice'
|
||||
this.$axios.post(loc() + countUrl, {id: row.lineUId}).then((res) => {
|
||||
if (res.code !== 0) {
|
||||
this.$message.warning(res.msg);
|
||||
return
|
||||
}
|
||||
const data = res.data || {}
|
||||
if (!data.sendCount) {
|
||||
this.$message.warning(data.msg || '当前暂无需要发送通知的报名人员');
|
||||
return
|
||||
}
|
||||
const noticeName = success ? '成团通知' : '未成团通知'
|
||||
const recordAction = success ? '' : ',并' + (keep ? '保留' : '删除') + '报名记录'
|
||||
const message = '当前将通过' + (data.sendTypeName || '微信、钉钉') + '发送' + noticeName + data.sendCount + '人' + recordAction + ',请确认或修改消息内容。'
|
||||
this.$prompt(message, '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
inputType: 'textarea',
|
||||
inputValue: data.content || '',
|
||||
inputValidator: (value) => !!(value && value.trim()),
|
||||
inputErrorMessage: '消息内容不能为空'
|
||||
}).then((prompt) => {
|
||||
const url = success ? '/sendSuccess' : '/sendFail'
|
||||
const params = {id: row.lineUId, content: prompt.value.trim()}
|
||||
if (!success) this.$set(params, 'type', keep)
|
||||
this.$axios.post(loc() + url, params).then((sendRes) => {
|
||||
if (sendRes.code === 0) {
|
||||
const result = sendRes.data || {};
|
||||
this.$message.success(result.msg || '通知发送完成');
|
||||
this.pageData()
|
||||
} else this.$message.warning(sendRes.msg)
|
||||
})
|
||||
}).catch(() => {
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$businessTool.listUnion().then((res) => {
|
||||
this.$set(this, 'unionOptions', res || [])
|
||||
})
|
||||
this.$axios.post('/platform/recuperation/config/fetchOne').then((res) => {
|
||||
if (res.code === 0) {
|
||||
const source = (res.data && res.data.lots) || []
|
||||
const lots = source.filter((item, index, list) => item && item.id && list.findIndex((lot) => lot && lot.id === item.id) === index)
|
||||
this.$set(this, 'lots', lots)
|
||||
}
|
||||
})
|
||||
this.loadLines();
|
||||
this.pageData()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--# } #-->
|
||||
|
||||
+684
-15
@@ -1,19 +1,688 @@
|
||||
<!--# layout("/layouts/platform.html"){ #-->
|
||||
<!--#
|
||||
layout("/layouts/platform.html"){
|
||||
#-->
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.center-col {
|
||||
background-color: white;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
width: calc((100% - (20px * 2)) / 2);
|
||||
}
|
||||
|
||||
.col-title {
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 14px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.col-button {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.rating-summary {
|
||||
float: right;
|
||||
color: #ff9900;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.travel-agency-summary {
|
||||
display: flex;
|
||||
padding: 22px 0;
|
||||
}
|
||||
|
||||
.travel-agency-summary-item {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
padding: 0 24px;
|
||||
border-right: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.travel-agency-summary-item:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.travel-agency-summary-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 auto;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
margin-right: 14px;
|
||||
border-radius: 50%;
|
||||
color: #1867b0;
|
||||
background-color: #eef6ff;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.travel-agency-summary-label {
|
||||
color: rgba(0, 0, 0, .65);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.travel-agency-summary-score {
|
||||
margin-top: 2px;
|
||||
color: #1867b0;
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.travel-agency-summary-score span {
|
||||
margin-left: 2px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.travel-agency-summary-count {
|
||||
margin-top: 3px;
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.scheme-service-card {
|
||||
min-height: 360px;
|
||||
}
|
||||
|
||||
.scheme-service-title {
|
||||
margin-bottom: 14px;
|
||||
color: rgba(0, 0, 0, .85);
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.scheme-type-switch {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.scheme-selector {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 12px;
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
.scheme-selector-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: calc((100% - 36px) / 4);
|
||||
min-width: 200px;
|
||||
height: 56px;
|
||||
margin: 0 !important;
|
||||
padding: 0 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.scheme-selector-name {
|
||||
overflow: hidden;
|
||||
margin-right: 12px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.scheme-selector-score {
|
||||
flex: 0 0 auto;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.scheme-detail {
|
||||
padding: 22px 24px;
|
||||
border: 1px solid #e6eef8;
|
||||
border-radius: 4px;
|
||||
background-color: #fcfdff;
|
||||
}
|
||||
|
||||
.scheme-detail-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
|
||||
.scheme-detail-name {
|
||||
color: rgba(0, 0, 0, .85);
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.scheme-detail-agency {
|
||||
margin-top: 8px;
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.scheme-detail-composite {
|
||||
min-width: 130px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.scheme-detail-composite-label {
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.scheme-detail-composite-score {
|
||||
margin-top: 3px;
|
||||
color: #1867b0;
|
||||
font-size: 30px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.scheme-detail-composite-score span {
|
||||
margin-left: 2px;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.scheme-detail-composite-count {
|
||||
margin-top: 3px;
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.scheme-metric-list {
|
||||
display: flex;
|
||||
border-top: 1px solid #edf1f5;
|
||||
}
|
||||
|
||||
.scheme-metric-item {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
padding: 18px 14px 8px;
|
||||
text-align: center;
|
||||
border-right: 1px solid #edf1f5;
|
||||
}
|
||||
|
||||
.scheme-metric-item:last-child {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.scheme-metric-icon {
|
||||
color: #1867b0;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
.scheme-metric-label {
|
||||
margin-top: 8px;
|
||||
color: rgba(0, 0, 0, .65);
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.scheme-metric-score {
|
||||
margin-top: 5px;
|
||||
color: #1867b0;
|
||||
font-size: 23px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.scheme-metric-score span {
|
||||
margin-left: 2px;
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.scheme-metric-count {
|
||||
margin-top: 3px;
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.scheme-feedback-action {
|
||||
padding-top: 18px;
|
||||
text-align: center;
|
||||
border-top: 1px solid #edf1f5;
|
||||
}
|
||||
|
||||
.scheme-feedback-list {
|
||||
max-height: 500px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.scheme-feedback-row {
|
||||
padding: 16px 4px;
|
||||
border-bottom: 1px solid #edf1f5;
|
||||
}
|
||||
|
||||
.scheme-feedback-row:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.scheme-feedback-row:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.scheme-feedback-user {
|
||||
color: rgba(0, 0, 0, .85);
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.scheme-feedback-union {
|
||||
margin-left: 10px;
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 13px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.scheme-feedback-content {
|
||||
margin-top: 9px;
|
||||
color: rgba(0, 0, 0, .65);
|
||||
line-height: 22px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.scheme-empty {
|
||||
padding: 64px 0;
|
||||
color: rgba(0, 0, 0, .45);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.feedback-content {
|
||||
line-height: 22px;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.feedback-summary {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
vertical-align: middle;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.feedback-score-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 0 -6px 14px;
|
||||
}
|
||||
|
||||
.feedback-score-item {
|
||||
box-sizing: border-box;
|
||||
width: 33.33%;
|
||||
padding: 6px;
|
||||
}
|
||||
|
||||
.feedback-score-item-inner {
|
||||
padding: 10px 12px;
|
||||
border-radius: 4px;
|
||||
background-color: #f7faff;
|
||||
}
|
||||
|
||||
.feedback-score-label {
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.feedback-score-value {
|
||||
margin-top: 3px;
|
||||
color: #1867b0;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.feedback-pagination {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div id="app" v-cloak>
|
||||
<el-card shadow="never"><el-row type="flex" align="middle"><el-col :span="8"><span>统计年度:</span><el-date-picker v-model="pageForm.year" type="year" value-format="yyyy" :clearable="false" @change="yearChange"></el-date-picker></el-col><el-col :span="16"><el-tabs v-model="activeTab" @tab-click="tabChange"><el-tab-pane label="满意度统计" name="summary"></el-tab-pane><el-tab-pane label="评价建议明细" name="feedback"></el-tab-pane><el-tab-pane label="评价人员名单" name="users"></el-tab-pane></el-tabs></el-col></el-row></el-card>
|
||||
<template v-if="activeTab==='summary'">
|
||||
<el-row :gutter="20" class="mt20"><el-col :span="8"><el-card shadow="never"><div slot="header">旅行社综合满意度</div><el-table v-loading="summaryLoading" :data="agencyRatings" height="530"><el-table-column type="index" label="排名" width="65"></el-table-column><el-table-column prop="travelAgencyName" label="旅行社" show-overflow-tooltip></el-table-column><el-table-column prop="avg" label="综合评分" width="90"><template v-slot="{row}">{{score(row.avg)}}</template></el-table-column><el-table-column prop="ratingCount" label="评价人数" width="85"></el-table-column></el-table></el-card></el-col><el-col :span="16"><el-card shadow="never"><div slot="header">方案服务评分</div><el-table v-loading="summaryLoading" :data="schemeRatings" height="530"><el-table-column prop="typeName" label="类型" width="85"></el-table-column><el-table-column prop="schemeName" label="方案名称" min-width="150" show-overflow-tooltip></el-table-column><el-table-column prop="travelAgencyName" label="旅行社" min-width="130" show-overflow-tooltip></el-table-column><el-table-column label="旅行社" width="75"><template v-slot="{row}">{{score(row.travelAgencyAvg)}}</template></el-table-column><el-table-column label="行程" width="65"><template v-slot="{row}">{{score(row.journeyAvg)}}</template></el-table-column><el-table-column label="住宿/酒店" width="90"><template v-slot="{row}">{{score(row.accommodationAvg)}}</template></el-table-column><el-table-column label="餐饮" width="65"><template v-slot="{row}">{{score(row.diningAvg)}}</template></el-table-column><el-table-column label="交通" width="65"><template v-slot="{row}">{{score(row.transportationAvg)}}</template></el-table-column><el-table-column label="综合" width="65"><template v-slot="{row}"><strong>{{score(row.compositeAvg)}}</strong></template></el-table-column><el-table-column prop="ratingCount" label="人数" width="65"></el-table-column></el-table></el-card></el-col></el-row>
|
||||
</template>
|
||||
<template v-if="activeTab==='feedback'"><el-card shadow="never" class="mt20"><table-tool label="评价建议"><el-select v-model="feedbackType" size="small" style="width:140px" @change="loadFeedback"><el-option v-for="item in ['全部','线路','灵活组团','定点']" :key="item" :label="item" :value="item"></el-option></el-select><el-button type="primary" size="small" class="ml10" @click="exportFeedback">导出评价明细</el-button></table-tool><el-table v-loading="feedbackLoading" :data="feedbackDetails"><el-table-column type="index" label="序号" width="60"></el-table-column><el-table-column prop="typeName" label="报名方式" width="100"></el-table-column><el-table-column prop="schemeName" label="方案名称" min-width="160"></el-table-column><el-table-column prop="travelAgencyName" label="旅行社" min-width="140"></el-table-column><el-table-column prop="userName" label="评价人" width="100"></el-table-column><el-table-column prop="unitName" label="所属单位" min-width="140"></el-table-column><el-table-column prop="compositeScore" label="综合评分" width="100"></el-table-column><el-table-column prop="feedbackContent" label="评价建议" min-width="240" show-overflow-tooltip></el-table-column><el-table-column label="操作" width="80"><template v-slot="{row}"><el-button type="primary" size="mini" @click="viewFeedback(row)">查看</el-button></template></el-table-column></el-table></el-card></template>
|
||||
<template v-if="activeTab==='users'"><el-card shadow="never" class="mt20"><search @search="doSearch"><search-item label="线路"><el-select v-model="pageForm.lineId" filterable clearable @change="doSearch"><el-option v-for="item in lineList" :key="item.id" :label="item.lineName+'('+item.unionName+')'" :value="item.id"></el-option></el-select></search-item><search-item label="姓名/工号"><el-input v-model="pageForm.searchKeyword" clearable @keyup.enter.native="doSearch"></el-input></search-item><search-item label="所属工会"><el-select v-model="pageForm.unionId" filterable clearable @change="doSearch"><el-option v-for="item in unionList" :key="item.id" :label="item.name" :value="item.id"></el-option></el-select></search-item><search-item label="所属单位"><el-select v-model="pageForm.unitId" filterable clearable @change="doSearch"><el-option v-for="item in unitList" :key="item.id" :label="item.name" :value="item.id"></el-option></el-select></search-item><search-item label="评分"><el-select v-model="pageForm.evaluateScore" clearable @change="doSearch"><el-option v-for="item in ['满意','一般','不满意']" :key="item" :label="item" :value="item"></el-option></el-select></search-item></search><table-tool label="评价人员名单"><el-button type="primary" size="small" @click="exportEvaluate">导出名单</el-button></table-tool><el-table v-loading="tableLoading" :data="tableData"><el-table-column type="index" :index="indexMethod" label="序号" width="60"></el-table-column><el-table-column prop="lineName" label="线路"></el-table-column><el-table-column prop="playStartTime" label="出行时间"></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="unitName" label="所属单位"></el-table-column><el-table-column prop="unionName" label="所属工会"></el-table-column><el-table-column prop="evaluateScore" label="评分"></el-table-column><el-table-column prop="evaluateText" label="评价" show-overflow-tooltip></el-table-column></el-table><!--#include("/layouts/pagination.html"){}#--></el-card></template>
|
||||
<el-dialog title="评价详情" :visible.sync="feedbackVisible" width="650px" append-to-body><el-descriptions :column="2" border><el-descriptions-item label="报名方式">{{feedbackDetail.typeName}}</el-descriptions-item><el-descriptions-item label="综合评分">{{feedbackDetail.compositeScore}}</el-descriptions-item><el-descriptions-item label="旅行社评分">{{feedbackDetail.evaluationForTravelAgency}}</el-descriptions-item><el-descriptions-item label="住宿/酒店评分">{{feedbackDetail.evaluationForAccommodation}}</el-descriptions-item><el-descriptions-item label="行程评分">{{feedbackDetail.evaluationForJourney}}</el-descriptions-item><el-descriptions-item label="餐饮评分">{{feedbackDetail.evaluationForDining}}</el-descriptions-item><el-descriptions-item label="交通评分">{{feedbackDetail.evaluationForTransportation}}</el-descriptions-item><el-descriptions-item label="方案">{{feedbackDetail.schemeName}}</el-descriptions-item></el-descriptions><el-alert class="mt20" :closable="false" :title="feedbackDetail.feedbackContent||'暂无评价建议'" type="info"></el-alert></el-dialog>
|
||||
<guava ref="guava">
|
||||
<template>
|
||||
<el-card shadow="never">
|
||||
<div class="btn-group tool-button">
|
||||
<el-date-picker
|
||||
v-model="year"
|
||||
type="year"
|
||||
value-format="yyyy"
|
||||
placeholder="选择年"
|
||||
style="width: 100%" @change="doSearch">
|
||||
</el-date-picker>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt20">
|
||||
<div class="travel-agency-summary">
|
||||
<div class="travel-agency-summary-item" v-for="item in travelAgencyCompositeRatings" :key="item.travelAgencyName">
|
||||
<div class="travel-agency-summary-icon">
|
||||
<i class="el-icon-guide"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="travel-agency-summary-label">{{item.travelAgencyName}}</div>
|
||||
<div class="travel-agency-summary-score" v-if="hasRatingScore(item.avg)">{{formatRatingScore(item.avg)}}<span>分</span></div>
|
||||
<div class="travel-agency-summary-score" v-else>暂无评价</div>
|
||||
<div class="travel-agency-summary-count">评价数 {{item.ratingCount}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt20 scheme-service-card">
|
||||
<div class="scheme-service-title">方案服务评分</div>
|
||||
<el-radio-group class="scheme-type-switch" :value="schemeType" @input="changeSchemeType" size="medium">
|
||||
<el-radio-button label="线路"></el-radio-button>
|
||||
<el-radio-button label="灵活组团"></el-radio-button>
|
||||
<el-radio-button label="定点"></el-radio-button>
|
||||
</el-radio-group>
|
||||
<div class="scheme-selector" v-if="getSchemeRatingsByType().length">
|
||||
<el-button
|
||||
v-for="item in getSchemeRatingsByType()"
|
||||
:key="item.schemeId"
|
||||
class="scheme-selector-item"
|
||||
:type="isSelectedScheme(item) ? 'primary' : 'default'"
|
||||
:plain="!isSelectedScheme(item)"
|
||||
@click="selectScheme(item)">
|
||||
<span class="scheme-selector-name">{{item.schemeName}}</span>
|
||||
<span class="scheme-selector-score">{{formatRatingScore(item.compositeAvg)}} 分</span>
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="scheme-detail" v-if="getSelectedSchemeRating()">
|
||||
<div class="scheme-detail-header">
|
||||
<div>
|
||||
<div class="scheme-detail-name">{{getSelectedSchemeRating().schemeName}}</div>
|
||||
<div class="scheme-detail-agency">旅行社:{{getSelectedSchemeRating().travelAgencyName || '暂无旅行社信息'}}</div>
|
||||
</div>
|
||||
<div class="scheme-detail-composite">
|
||||
<div class="scheme-detail-composite-label">综合评分</div>
|
||||
<div class="scheme-detail-composite-score">{{formatRatingScore(getSelectedSchemeRating().compositeAvg)}}<span>分</span></div>
|
||||
<div class="scheme-detail-composite-count">评价数 {{getSelectedSchemeRating().ratingCount || 0}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scheme-metric-list">
|
||||
<div class="scheme-metric-item" v-for="item in getSelectedSchemeMetrics()" :key="item.key">
|
||||
<i class="scheme-metric-icon" :class="item.icon"></i>
|
||||
<div class="scheme-metric-label">{{item.label}}</div>
|
||||
<div class="scheme-metric-score">{{formatRatingScore(item.avg)}}<span>分</span></div>
|
||||
<div class="scheme-metric-count">评价数 {{item.count || 0}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scheme-feedback-action">
|
||||
<el-button type="primary" plain @click="openSchemeFeedbackDialog">查看评价建议</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scheme-empty" v-else>暂无可查看的方案评分</div>
|
||||
</el-card>
|
||||
|
||||
<el-card shadow="never" class="mt20">
|
||||
<div class="col-title">
|
||||
评价明细
|
||||
<div style="float: right">
|
||||
<el-button size="medium" type="primary" icon="el-icon-download" style="margin-right: 10px" @click="exportFeedbackDetails">导出</el-button>
|
||||
<el-radio-group :value="feedbackType" @input="changeFeedbackType" size="medium">
|
||||
<el-radio-button label="全部"></el-radio-button>
|
||||
<el-radio-button label="线路"></el-radio-button>
|
||||
<el-radio-button label="灵活组团"></el-radio-button>
|
||||
<el-radio-button label="定点"></el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</div>
|
||||
<el-table :data="getPagedFeedbackDetails()" style="width: 100%">
|
||||
<el-table-column align="center" header-align="center" type="index" label="序号" :index="feedbackIndexMethod" width="80"></el-table-column>
|
||||
<el-table-column align="center" header-align="center" prop="typeName" label="报名方式" width="100"></el-table-column>
|
||||
<el-table-column align="center" header-align="center" prop="projectName" label="方案名称" min-width="160" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column align="center" header-align="center" prop="travelAgencyName" label="旅行社" min-width="140" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column align="center" header-align="center" prop="userName" label="评价人" width="100"></el-table-column>
|
||||
<el-table-column align="center" header-align="center" prop="unitName" label="所属单位" min-width="150" show-overflow-tooltip></el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="综合评分" width="110">
|
||||
<template slot-scope="scope">
|
||||
{{formatFeedbackScore(scope.row.compositeScore)}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="left" header-align="center" label="评价建议" min-width="250">
|
||||
<template slot-scope="scope">
|
||||
<span class="feedback-summary">{{getFeedbackContentSummary(scope.row.feedbackContent)}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" header-align="center" label="操作" width="90">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" size="mini" @click="openFeedbackDetail(scope.row)">查看</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
class="feedback-pagination"
|
||||
:current-page="feedbackPage"
|
||||
:page-size="feedbackPageSize"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="getFilteredFeedbackDetails().length"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@current-change="changeFeedbackPage"
|
||||
@size-change="changeFeedbackPageSize">
|
||||
</el-pagination>
|
||||
</el-card>
|
||||
</template>
|
||||
</guava>
|
||||
|
||||
<el-dialog title="评价详情" :visible="feedbackDetailVisible" width="620px" @close="closeFeedbackDetail">
|
||||
<div class="feedback-score-grid">
|
||||
<div class="feedback-score-item">
|
||||
<div class="feedback-score-item-inner">
|
||||
<div class="feedback-score-label">综合评分</div>
|
||||
<div class="feedback-score-value">{{formatFeedbackScore(feedbackDetail.compositeScore)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feedback-score-item">
|
||||
<div class="feedback-score-item-inner">
|
||||
<div class="feedback-score-label">旅行社评分</div>
|
||||
<div class="feedback-score-value">{{formatFeedbackScore(feedbackDetail.evaluationForTravelAgency)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feedback-score-item" v-if="feedbackDetail.typeName === '线路'">
|
||||
<div class="feedback-score-item-inner">
|
||||
<div class="feedback-score-label">行程评分</div>
|
||||
<div class="feedback-score-value">{{formatFeedbackScore(feedbackDetail.evaluationForJourney)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feedback-score-item">
|
||||
<div class="feedback-score-item-inner">
|
||||
<div class="feedback-score-label">{{feedbackDetail.typeName === '线路' ? '住宿评分' : '酒店评分'}}</div>
|
||||
<div class="feedback-score-value">{{formatFeedbackScore(feedbackDetail.evaluationForAccommodation)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feedback-score-item" v-if="feedbackDetail.typeName === '线路'">
|
||||
<div class="feedback-score-item-inner">
|
||||
<div class="feedback-score-label">餐饮评分</div>
|
||||
<div class="feedback-score-value">{{formatFeedbackScore(feedbackDetail.evaluationForDining)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feedback-score-item" v-if="feedbackDetail.typeName === '线路'">
|
||||
<div class="feedback-score-item-inner">
|
||||
<div class="feedback-score-label">交通评分</div>
|
||||
<div class="feedback-score-value">{{formatFeedbackScore(feedbackDetail.evaluationForTransportation)}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="feedback-content">{{feedbackDetail.feedbackContent || '暂无评价建议'}}</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog title="评价建议" :visible="schemeFeedbackVisible" width="720px" @close="closeSchemeFeedbackDialog">
|
||||
<div class="scheme-feedback-list" v-if="getSelectedSchemeFeedbackDetails().length">
|
||||
<div class="scheme-feedback-row" v-for="item in getSelectedSchemeFeedbackDetails()" :key="item.id">
|
||||
<div class="scheme-feedback-user">
|
||||
{{item.userName || '匿名评价人'}}
|
||||
<span class="scheme-feedback-union">{{item.unitName || '暂无所属单位'}}</span>
|
||||
</div>
|
||||
<div class="scheme-feedback-content">{{item.feedbackContent}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scheme-empty" v-else>当前方案暂无评价建议</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
new Vue({el:'#app',mixins:[initTableMixins],data(){return{activeTab:'summary',pageForm:{pageNumber:1,pageSize:10,totalCount:0,year:new Date().getFullYear().toString(),lineId:'',searchKeyword:'',unionId:'',unitId:'',evaluateScore:''},unionList:[],unitList:[],lineList:[],summaryLoading:false,feedbackLoading:false,agencyRatings:[],schemeRatings:[],feedbackDetails:[],feedbackType:'全部',feedbackVisible:false,feedbackDetail:{}}},methods:{
|
||||
score(value){return value===null||value===undefined||value===''?'—':Number(value).toFixed(1)},yearChange(){this.$set(this.pageForm,'lineId','');this.loadLines();this.loadSummary();if(this.activeTab==='feedback')this.loadFeedback();if(this.activeTab==='users')this.doSearch()},tabChange(){if(this.activeTab==='summary')this.loadSummary();if(this.activeTab==='feedback')this.loadFeedback();if(this.activeTab==='users')this.pageData()},
|
||||
loadSummary(){this.$set(this,'summaryLoading',true);this.$axios.post(loc()+'/getSatisfactionRatingStatistics',{year:this.pageForm.year}).then((res)=>{if(res.code===0){this.$set(this,'agencyRatings',(res.data&&res.data.travelAgencyCompositeRatings)||[]);this.$set(this,'schemeRatings',(res.data&&res.data.schemeServiceRatings)||[])}}).finally(()=>{this.$set(this,'summaryLoading',false)})},
|
||||
loadFeedback(){this.$set(this,'feedbackLoading',true);this.$axios.post(loc()+'/getSatisfactionFeedbackDetails',{year:this.pageForm.year,typeName:this.feedbackType}).then((res)=>{if(res.code===0)this.$set(this,'feedbackDetails',res.data||[])}).finally(()=>{this.$set(this,'feedbackLoading',false)})},exportFeedback(){this.$downLoad(loc()+'/exportSatisfactionFeedbackDetails',{year:this.pageForm.year,typeName:this.feedbackType})},viewFeedback(row){this.$set(this,'feedbackDetail',row);this.$set(this,'feedbackVisible',true)},
|
||||
loadLines(){this.$axios.post(loc()+'/lineList',{year:this.pageForm.year}).then((res)=>{if(res.code===0)this.$set(this,'lineList',res.data||[])})},pageData(){this.$set(this,'tableLoading',true);this.$axios.post(loc()+'/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)}}).finally(()=>{this.$set(this,'tableLoading',false)})},exportEvaluate(){this.$downLoad(loc()+'/exportEvaluate',this.pageForm)}
|
||||
},created(){this.$businessTool.listUnion().then((res)=>this.$set(this,'unionList',res||[]));this.$businessTool.listUnit().then((res)=>this.$set(this,'unitList',res||[]));this.loadLines();this.loadSummary()}})
|
||||
new Vue({
|
||||
el: '#app',
|
||||
mixins: [initTableMixins],
|
||||
data() {
|
||||
return {
|
||||
year: new Date().getFullYear().toString(),
|
||||
summaryLoading: false,
|
||||
feedbackLoading: false,
|
||||
travelAgencyCompositeRatings: [],
|
||||
schemeServiceRatings: [],
|
||||
schemeType: '线路',
|
||||
selectedSchemeId: '',
|
||||
feedbackDetails: [],
|
||||
feedbackType: '全部',
|
||||
feedbackPage: 1,
|
||||
feedbackPageSize: 10,
|
||||
feedbackDetail: {},
|
||||
feedbackDetailVisible: false,
|
||||
schemeFeedbackVisible: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
doSearch() {
|
||||
this.getSatisfactionRatingStatistics()
|
||||
this.getSatisfactionFeedbackDetails()
|
||||
},
|
||||
getSatisfactionRatingStatistics() {
|
||||
this.$set(this, 'summaryLoading', true)
|
||||
this.$axios.post(loc() + '/getSatisfactionRatingStatistics', {year: this.year}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
const statisticData = res.data || {}
|
||||
this.$set(this, 'travelAgencyCompositeRatings', statisticData.travelAgencyCompositeRatings || [])
|
||||
this.$set(this, 'schemeServiceRatings', statisticData.schemeServiceRatings || [])
|
||||
this.resetSelectedScheme()
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.$set(this, 'summaryLoading', false)
|
||||
})
|
||||
},
|
||||
getSatisfactionFeedbackDetails() {
|
||||
this.$set(this, 'feedbackLoading', true)
|
||||
this.$axios.post(loc() + '/getSatisfactionFeedbackDetails', {year: this.year}).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.$set(this, 'feedbackDetails', res.data || [])
|
||||
this.$set(this, 'feedbackPage', 1)
|
||||
} else {
|
||||
this.$message.warning(res.msg)
|
||||
}
|
||||
}).finally(() => {
|
||||
this.$set(this, 'feedbackLoading', false)
|
||||
})
|
||||
},
|
||||
formatRatingScore(score) {
|
||||
if (score === null || score === undefined || score === '') return '-'
|
||||
return Number(score).toFixed(1)
|
||||
},
|
||||
hasRatingScore(score) {
|
||||
return score !== null && score !== undefined && score !== ''
|
||||
},
|
||||
formatFeedbackScore(score) {
|
||||
if (score === null || score === undefined || score === '') return '-'
|
||||
return Number(score).toFixed(1) + ' 分'
|
||||
},
|
||||
getFeedbackContentSummary(content) {
|
||||
const feedbackContent = String(content || '').trim()
|
||||
if (!feedbackContent) return '暂无评价建议'
|
||||
return feedbackContent.length > 36 ? feedbackContent.substring(0, 36) + '…' : feedbackContent
|
||||
},
|
||||
changeSchemeType(value) {
|
||||
this.$set(this, 'schemeType', value)
|
||||
this.resetSelectedScheme()
|
||||
},
|
||||
selectScheme(schemeRating) {
|
||||
this.$set(this, 'selectedSchemeId', schemeRating.schemeId)
|
||||
},
|
||||
isSelectedScheme(schemeRating) {
|
||||
return String(this.selectedSchemeId) === String(schemeRating.schemeId)
|
||||
},
|
||||
getSchemeRatingsByType() {
|
||||
return this.schemeServiceRatings.filter((item) => item.typeName === this.schemeType)
|
||||
},
|
||||
getSelectedSchemeRating() {
|
||||
return this.getSchemeRatingsByType().find((item) => this.isSelectedScheme(item))
|
||||
},
|
||||
resetSelectedScheme() {
|
||||
const schemeRatings = this.getSchemeRatingsByType()
|
||||
this.$set(this, 'selectedSchemeId', schemeRatings.length ? schemeRatings[0].schemeId : '')
|
||||
},
|
||||
getSelectedSchemeMetrics() {
|
||||
const schemeRating = this.getSelectedSchemeRating() || {}
|
||||
const metrics = [
|
||||
{key: 'travelAgency', label: '旅行社', icon: 'el-icon-guide', avg: schemeRating.travelAgencyAvg, count: schemeRating.travelAgencyCount},
|
||||
{key: 'journey', label: '行程', icon: 'el-icon-map-location', avg: schemeRating.journeyAvg, count: schemeRating.journeyCount},
|
||||
{key: 'accommodation', label: '住宿', icon: 'el-icon-house', avg: schemeRating.accommodationAvg, count: schemeRating.accommodationCount},
|
||||
{key: 'dining', label: '餐饮', icon: 'el-icon-food', avg: schemeRating.diningAvg, count: schemeRating.diningCount},
|
||||
{key: 'transportation', label: '交通', icon: 'el-icon-truck', avg: schemeRating.transportationAvg, count: schemeRating.transportationCount}
|
||||
]
|
||||
if (schemeRating.typeName === '线路') return metrics
|
||||
return [
|
||||
metrics[0],
|
||||
{key: 'accommodation', label: '酒店', icon: 'el-icon-house', avg: schemeRating.accommodationAvg, count: schemeRating.accommodationCount}
|
||||
]
|
||||
},
|
||||
getSelectedSchemeFeedbackDetails() {
|
||||
const schemeRating = this.getSelectedSchemeRating()
|
||||
if (!schemeRating) return []
|
||||
return this.feedbackDetails.filter((item) => item.typeName === schemeRating.typeName
|
||||
&& String(item.schemeId) === String(schemeRating.schemeId)
|
||||
&& String(item.feedbackContent || '').trim())
|
||||
},
|
||||
openSchemeFeedbackDialog() {
|
||||
this.$set(this, 'schemeFeedbackVisible', true)
|
||||
},
|
||||
closeSchemeFeedbackDialog() {
|
||||
this.$set(this, 'schemeFeedbackVisible', false)
|
||||
},
|
||||
changeFeedbackType(value) {
|
||||
this.$set(this, 'feedbackType', value)
|
||||
this.$set(this, 'feedbackPage', 1)
|
||||
},
|
||||
exportFeedbackDetails() {
|
||||
this.$downLoad(loc() + '/exportSatisfactionFeedbackDetails', {
|
||||
year: this.year,
|
||||
typeName: this.feedbackType
|
||||
})
|
||||
},
|
||||
getFilteredFeedbackDetails() {
|
||||
if (this.feedbackType === '全部') return this.feedbackDetails
|
||||
return this.feedbackDetails.filter((item) => item.typeName === this.feedbackType)
|
||||
},
|
||||
getPagedFeedbackDetails() {
|
||||
const start = (this.feedbackPage - 1) * this.feedbackPageSize
|
||||
return this.getFilteredFeedbackDetails().slice(start, start + this.feedbackPageSize)
|
||||
},
|
||||
feedbackIndexMethod(index) {
|
||||
return (this.feedbackPage - 1) * this.feedbackPageSize + index + 1
|
||||
},
|
||||
changeFeedbackPage(page) {
|
||||
this.$set(this, 'feedbackPage', page)
|
||||
},
|
||||
changeFeedbackPageSize(pageSize) {
|
||||
this.$set(this, 'feedbackPageSize', pageSize)
|
||||
this.$set(this, 'feedbackPage', 1)
|
||||
},
|
||||
openFeedbackDetail(feedbackDetail) {
|
||||
this.$set(this, 'feedbackDetail', feedbackDetail)
|
||||
this.$set(this, 'feedbackDetailVisible', true)
|
||||
},
|
||||
closeFeedbackDetail() {
|
||||
this.$set(this, 'feedbackDetailVisible', false)
|
||||
this.$set(this, 'feedbackDetail', {})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.doSearch()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!--# } #-->
|
||||
|
||||
|
||||
<!--#
|
||||
}
|
||||
#-->
|
||||
|
||||
Reference in New Issue
Block a user