517 lines
22 KiB
HTML
517 lines
22 KiB
HTML
<!--#
|
||
layout("/layouts/platform.html"){
|
||
#-->
|
||
|
||
<style>
|
||
.item {
|
||
padding: 6px 12px;
|
||
margin: 0px 10px 0px 10px;
|
||
border: solid 1px #eee;
|
||
background-color: #f1f1f1;
|
||
}
|
||
|
||
.item:hover {
|
||
background-color: #fdfdfd;
|
||
cursor: move;
|
||
}
|
||
|
||
.item + .item {
|
||
border-top: none;
|
||
margin-top: 6px;
|
||
}
|
||
|
||
.clusterMembersSubmitBtn {
|
||
/* position: absolute;
|
||
bottom: 0px;
|
||
right: 0px;*/
|
||
padding-bottom: 10px;
|
||
}
|
||
|
||
.cluster-card {
|
||
margin: 10px 0;
|
||
}
|
||
|
||
.cluster-card .el-card__header {
|
||
height: 50px;
|
||
display: flex;
|
||
align-items: center;
|
||
position: relative;
|
||
}
|
||
|
||
.cluster-card .el-card__body {
|
||
height: 660px;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
</style>
|
||
|
||
<div id="app" v-cloak>
|
||
<guava ref="guava">
|
||
<el-card shadow="never">
|
||
<div class="search">
|
||
<div class="search-item">
|
||
<div class="search-item-label">年度:</div>
|
||
<div class="search-item-option">
|
||
<el-date-picker
|
||
@change="doSearch"
|
||
placeholder="选择年度"
|
||
style="width: 100%"
|
||
type="year"
|
||
v-model="pageForm.year"
|
||
value-format="yyyy">
|
||
</el-date-picker>
|
||
</div>
|
||
</div>
|
||
<div class="search-item">
|
||
<div class="search-item-label">线路名称:</div>
|
||
<div class="search-item-option">
|
||
<el-input @keyup.enter.native="doSearch" clearable
|
||
placeholder="请输入内容"
|
||
style="width: 100%"
|
||
v-model="pageForm.keywords">
|
||
</el-input>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="search-item" v-if="${@shiro.hasRole('sysadmin')||@shiro.hasRole('A06')}">
|
||
<div class="search-item-label">分工会:</div>
|
||
<div class="search-item-option">
|
||
<el-select @change="doSearch" clearable filterable style="width: 100%"
|
||
v-model="pageForm.unionId">
|
||
<el-option :key="item.id"
|
||
:label="item.unionname"
|
||
:value="item.id"
|
||
v-for="item in unionOptions"></el-option>
|
||
</el-select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="search-query">
|
||
<el-button @click="doSearch" icon="el-icon-search" type="primary">搜索</el-button>
|
||
</div>
|
||
</div>
|
||
</el-card>
|
||
|
||
<el-card class="mt10" shadow="never">
|
||
<table-tool :app="this" label="线路列表">
|
||
<template #func>
|
||
|
||
</template>
|
||
</table-tool>
|
||
<el-table :data="tableData" :size="tableSize" @sort-change="pageOrder"
|
||
align="center"
|
||
header-align="center">
|
||
<el-table-column :index="indexMethod" align="center" header-align="center" label="序号" type="index"
|
||
width="80px"></el-table-column>
|
||
<el-table-column
|
||
:label="column.label"
|
||
:prop="column.prop"
|
||
:sortable="column.sortable"
|
||
align="center"
|
||
header-align="center"
|
||
show-overflow-tooltip
|
||
v-for="column in tableColumns"
|
||
>
|
||
<template scope="{row:{signUpMode}}" v-if="column.prop==='signUpMode'">
|
||
{{signUpModeName(signUpMode)}}
|
||
</template>
|
||
<template scope="{row:{createMode}}" v-else-if="column.prop==='createMode'">
|
||
{{createModeName(createMode)}}
|
||
</template>
|
||
<template scope="{row}" v-if="column.prop==='times'">
|
||
{{row.playStartTime.substr(0,10)}}至{{row.playEndTime.substr(0,10)}}
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="200px">
|
||
<template scope="{row}">
|
||
<el-button @click="openViewClusterInfo(row.id)" size="mini" type="primary">查看</el-button>
|
||
<el-button @click="openCluster(row.id,row.ascriptionUnionId)" size="mini" type="primary">组团
|
||
</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-card>
|
||
|
||
|
||
<template #edit_func>
|
||
<el-button @click="addCluster" type="primary">添加团</el-button>
|
||
</template>
|
||
<template #edit>
|
||
<el-row :gutter="20">
|
||
<el-col :span="6" v-for="item,itemKey in clusterData">
|
||
<el-card class="cluster-card" shadow="never">
|
||
<div class="text-primary" slot="header">
|
||
<template v-if="!item.editClusterName">
|
||
{{getClusterName(item)}}
|
||
<i @click="item.editClusterName=true"
|
||
class="el-icon-edit"
|
||
v-if="itemKey!=='unSelectedUsers'"></i>
|
||
</template>
|
||
|
||
<el-input @blur="item.editClusterName=false"
|
||
autofocus
|
||
maxlength="10"
|
||
size="mini"
|
||
v-if="item.editClusterName"
|
||
v-model="item.clusterName"></el-input>
|
||
|
||
<i @click="removeCluster(itemKey)"
|
||
class="el-icon-close"
|
||
style="position: absolute;right: 5px;top: 5px;cursor: pointer"
|
||
v-if="itemKey!=='unSelectedUsers'"></i>
|
||
|
||
<el-button @click="openBatchMove"
|
||
size="mini"
|
||
style="position:absolute;right: 10px"
|
||
type="primary"
|
||
v-if="itemKey==='unSelectedUsers'">批量调整
|
||
</el-button>
|
||
</div>
|
||
<draggable @end="drag=false" @start="drag=true" group="cluster" style="height: 100%"
|
||
v-model="item.members">
|
||
<transition-group :style="tgGroup">
|
||
<div :key="ele.loginName" class="item" v-for="ele in item.members">
|
||
<el-popover :content="ele.userName+'-'+ele.loginName+'-'+ele.sex+'-'+ele.unionName"
|
||
placement="right-end"
|
||
trigger="hover">
|
||
<el-row :gutter="4" slot="reference" style="white-space: nowrap" type="flex">
|
||
<el-col :span="3">
|
||
<el-tag :type="ele.isLeader?null:'info'" effect="dark" size="mini">
|
||
{{ele.isLeader ? '团长' : '成员' }}
|
||
</el-tag>
|
||
</el-col>
|
||
|
||
<el-col :span="16" style="overflow: hidden">
|
||
{{ele.userName+'-'+ele.loginName+'-'+ele.sex+'-'+ele.unionName}}
|
||
</el-col>
|
||
|
||
<el-col :span="3" style="overflow: hidden">
|
||
{{'(' + ele.companionCount + ')'}}
|
||
</el-col>
|
||
|
||
<el-col :span="2" class="text-center">
|
||
<el-dropdown
|
||
@command="(isLeader)=>{setMemberRole(itemKey,ele.loginName,isLeader)}"
|
||
v-if="itemKey!=='unSelectedUsers'">
|
||
<i class="el-icon-user-solid"></i>
|
||
<el-dropdown-menu slot="dropdown">
|
||
<el-dropdown-item command="true">设为团长</el-dropdown-item>
|
||
<el-dropdown-item command="false">设为成员</el-dropdown-item>
|
||
</el-dropdown-menu>
|
||
</el-dropdown>
|
||
</el-col>
|
||
</el-row>
|
||
</el-popover>
|
||
</div>
|
||
</transition-group>
|
||
</draggable>
|
||
</el-card>
|
||
</el-col>
|
||
</el-row>
|
||
<el-row class="clusterMembersSubmitBtn" justify="end" type="flex">
|
||
<!-- <el-button @click="addCluster">添加团</el-button>-->
|
||
<el-button @click="$refs.guava.index()">取消</el-button>
|
||
<el-button @click="setClusterMembers" type="primary">提交</el-button>
|
||
</el-row>
|
||
</template>
|
||
|
||
<template #view>
|
||
<div>
|
||
<vi-title title="团列表"></vi-title>
|
||
<el-card shadow="never">
|
||
<el-tag :effect="item.id === selectClusterTagId ? 'dark':'light'"
|
||
:key="item.id"
|
||
@click="selectClusterTagId = item.id"
|
||
class="mr10"
|
||
style="cursor: pointer"
|
||
v-for="item in clusterViewList"
|
||
v-if="clusterViewList && clusterViewList.length>0">
|
||
{{ item.clusterName }}
|
||
</el-tag>
|
||
</el-card>
|
||
<vi-title class="mt10" title="人员列表"></vi-title>
|
||
<el-card shadow="never">
|
||
<el-table :data="clusterTableData">
|
||
<el-table-column label="序号" type="index"></el-table-column>
|
||
<el-table-column label="工号" prop="loginName"></el-table-column>
|
||
<el-table-column label="姓名" prop="userName"></el-table-column>
|
||
<el-table-column label="性别" prop="sex"></el-table-column>
|
||
<el-table-column label="工会" prop="unionName"></el-table-column>
|
||
<el-table-column label="身份" prop="isLeader">
|
||
<template scope="{row}">
|
||
<span class="text-primary" v-if="row.isLeader">团长</span>
|
||
<span v-else>成员</span>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</el-card>
|
||
</div>
|
||
</template>
|
||
</guava>
|
||
|
||
<el-dialog :close-on-click-modal="false" :visible.sync="batchMoveDialogVisible" title="批量调整" width="60%">
|
||
<div class="mb10">
|
||
<vi-title2 title="原分组"></vi-title2>
|
||
<el-radio-group size="small" v-model="batchMoveData.originalGroup">
|
||
<el-radio :label="item"
|
||
border
|
||
v-for="(item,key) in clusterData">{{item.clusterName}}
|
||
</el-radio>
|
||
</el-radio-group>
|
||
|
||
<el-table :data="batchMoveData.originalGroup.members"
|
||
class="mt10 mb10"
|
||
max-height="250px"
|
||
ref="originalGroupMembersTable"
|
||
v-show="batchMoveData.originalGroup && batchMoveData.originalGroup.members">
|
||
<el-table-column type="selection"></el-table-column>
|
||
<el-table-column label="工号" prop="loginName"></el-table-column>
|
||
<el-table-column label="姓名" prop="userName"></el-table-column>
|
||
<el-table-column label="性别" prop="sex"></el-table-column>
|
||
<el-table-column label="工会" prop="unionName"></el-table-column>
|
||
</el-table>
|
||
</div>
|
||
|
||
<div v-if="batchMoveData.originalGroup.members.length>0">
|
||
<vi-title2 title="筛选条件"></vi-title2>
|
||
|
||
<el-form label-width="80px">
|
||
<el-form-item label="分工会">
|
||
<el-select multiple size="small" style="width: 100%" v-model="batchMoveData.cnd.unionNames">
|
||
<el-option
|
||
:key="item.id"
|
||
:label="item.unionname"
|
||
:value="item.unionname"
|
||
v-for="item in unionOptions">
|
||
</el-option>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
|
||
<div class="mb10" v-if="batchMoveData.originalGroup.members.length>0">
|
||
<vi-title2 title="移动后分组"></vi-title2>
|
||
<el-radio-group size="small" v-model="batchMoveData.currentGroup">
|
||
<el-radio :disabled="item.clusterName == batchMoveData.originalGroup.clusterName"
|
||
:label="item"
|
||
border
|
||
v-for="(item,key) in clusterData">{{item.clusterName}}
|
||
</el-radio>
|
||
</el-radio-group>
|
||
</div>
|
||
|
||
<el-row justify="end" type="flex">
|
||
<el-button @click="batchMoveDialogVisible=false">取消</el-button>
|
||
<el-button @click="doBatchMove" type="primary">确定</el-button>
|
||
</el-row>
|
||
|
||
</el-dialog>
|
||
|
||
</div>
|
||
|
||
<script src="/assets/platform/plugins/vuedrag/Sortable.js"></script>
|
||
<script src="/assets/platform/plugins/vuedrag/vuedraggable.js"></script>
|
||
|
||
<script>
|
||
var vue = new Vue({
|
||
el: '#app',
|
||
mixins: [initTableMixins],
|
||
components: {
|
||
'line-info': httpVueLoader('/components/theRapyRecuperation/LineInfo.vue')
|
||
},
|
||
data() {
|
||
return {
|
||
tableColumns: [
|
||
{label: '年度', prop: 'year', sortable: true},
|
||
{label: '线路名称', prop: 'lineName', sortable: true},
|
||
{label: '线路编号', prop: 'serialNumber', sortable: true},
|
||
{label: '旅行社名称', prop: 'travelAgencyName', sortable: true},
|
||
{label: '线路类型', prop: 'regionalNature', sortable: true},
|
||
{label: '出行时间', prop: 'times', sortable: true},
|
||
{label: '最少成团人数', prop: 'minimumGroupSize', sortable: true},
|
||
// {label: '创建工会', prop: 'createUnionName'},
|
||
// {label: '创建人', prop: 'createUserName', sortable: true},
|
||
// {label: '创建模式', prop: 'createMode'},
|
||
{label: '线路归属', prop: 'ascriptionUnionName', sortable: true},
|
||
// {label: '组织形式', prop: 'signUpMode', sortable: true},
|
||
],
|
||
pageForm: {
|
||
keywords: null,
|
||
year: new Date().getFullYear().toString(),
|
||
selectStatus: 0
|
||
},
|
||
drag: false,
|
||
clusterData: {},
|
||
tgGroup: 'min-height:100%;display: block',
|
||
lineId: null,
|
||
clusterViewList: [],
|
||
selectClusterTagId: null,
|
||
batchMoveDialogVisible: false,
|
||
batchMoveData: {
|
||
originalGroup: {
|
||
members: []
|
||
},
|
||
currentGroup: null,
|
||
cnd: {}
|
||
},
|
||
unionOptions: []
|
||
}
|
||
},
|
||
computed: {
|
||
clusterTableData() {
|
||
if (this.selectClusterTagId) {
|
||
return this.clusterViewList.find(v => v.id === this.selectClusterTagId).members
|
||
}
|
||
return []
|
||
}
|
||
},
|
||
watch: {
|
||
'batchMoveData.cnd': {
|
||
handler(v) {
|
||
const unionNames = v['unionNames']
|
||
console.log(unionNames)
|
||
},
|
||
deep: true
|
||
}
|
||
},
|
||
methods: {
|
||
getClusterName(item) {
|
||
let count = 0
|
||
item.members.forEach(item => {
|
||
count += item.companionCount
|
||
})
|
||
return item.clusterName + '(' + (item.members.length + count) + ')'
|
||
},
|
||
async openViewClusterInfo(id) {
|
||
this.$refs.guava.view()
|
||
const resp = await $.post(loc() + '/selectClusterInfo/' + id)
|
||
if (resp.code === 0) {
|
||
this.clusterViewList = resp.data
|
||
if (this.clusterViewList && this.clusterViewList.length > 0) {
|
||
this.selectClusterTagId = this.clusterViewList[0].id
|
||
} else {
|
||
this.selectClusterTagId = null
|
||
}
|
||
} else {
|
||
this.notifyWarning(resp.msg)
|
||
}
|
||
},
|
||
async openCluster(id, ascriptionUnionId) {
|
||
this.lineId = id
|
||
this.$refs.guava.edit()
|
||
const resp = await $.post(loc() + '/findClusterInfo/', {
|
||
lineId: id,
|
||
usUnionId: ascriptionUnionId
|
||
})
|
||
if (resp.code === 0) {
|
||
this.clusterData = resp.data
|
||
}
|
||
},
|
||
addCluster() {
|
||
const l = Object.keys(this.clusterData).length
|
||
const key = "cluster" + l
|
||
this.$set(this.clusterData, key, {
|
||
members: [],
|
||
clusterName: '团' + l,
|
||
editClusterName: false,
|
||
lineId: this.lineId
|
||
})
|
||
},
|
||
removeCluster(key) {
|
||
const h = this.clusterData[key]
|
||
const m = h.members
|
||
this.clusterData['unSelectedUsers'].members.push(...m)
|
||
delete this.clusterData[key]
|
||
},
|
||
|
||
async setClusterMembers() {
|
||
const emptyCluster = Object.values(vue.clusterData).filter(v => v.clusterName !== '线路未分配人员').find(v => v.members.length === 0)
|
||
if (emptyCluster) {
|
||
this.notifyWarning(emptyCluster.clusterName + '未分配成员,请分配后再提交!')
|
||
return
|
||
}
|
||
|
||
const resp = await $.post(loc() + '/setClusterMembers', {
|
||
clusters: JSON.stringify(this.clusterData),
|
||
lineId: this.lineId
|
||
})
|
||
if (resp.code === 0) {
|
||
this.notifySuccess(resp.msg)
|
||
this.$refs.guava.index()
|
||
this.lineId = null
|
||
this.clusterData = {}
|
||
} else {
|
||
this.notifyWarning(resp.msg)
|
||
}
|
||
},
|
||
setMemberRole(key, loginName, isLeader) {
|
||
const i = this.clusterData[key].members.findIndex(v => v.loginName === loginName)
|
||
this.$set(this.clusterData[key].members[i], 'isLeader', isLeader)
|
||
},
|
||
openBatchMove() {
|
||
this.batchMoveDialogVisible = true
|
||
this.batchMoveData = {
|
||
originalGroup: {
|
||
members: []
|
||
},
|
||
currentGroup: null,
|
||
cnd: {}
|
||
}
|
||
},
|
||
doBatchMove() {
|
||
const unionNames = this.batchMoveData.cnd.unionNames
|
||
|
||
|
||
//需要移动的数据(工会筛选)
|
||
let filterData = []
|
||
const unionSelectData = this.batchMoveData.originalGroup.members.filter(v => unionNames.includes(v['unionName']))
|
||
const selectionData = this.$refs.originalGroupMembersTable.selection
|
||
filterData = filterData.concat(unionSelectData).concat(selectionData)
|
||
|
||
const filterLoginNames = filterData.map(v => v.loginName)
|
||
|
||
//原分组移动之后剩下的数据
|
||
const deleteData = this.batchMoveData.originalGroup.members.filter(v => !filterLoginNames.includes(v.loginName))
|
||
|
||
//现分组Name
|
||
const cName = this.batchMoveData.currentGroup.clusterName
|
||
|
||
//原分组Name
|
||
const oName = this.batchMoveData.originalGroup.clusterName
|
||
|
||
|
||
for (let k in this.clusterData) {
|
||
if (this.clusterData[k]['clusterName'] === cName) {
|
||
this.clusterData[k].members = this.clusterData[k].members.concat(filterData)
|
||
}
|
||
if (this.clusterData[k]['clusterName'] === oName) {
|
||
this.clusterData[k].members = deleteData
|
||
}
|
||
}
|
||
|
||
this.batchMoveDialogVisible = false
|
||
},
|
||
|
||
createModeName(val) {
|
||
const d = this.createModeList.find(v => v.value === val)
|
||
return d ? d.label : null
|
||
},
|
||
signUpModeName(val) {
|
||
const d = this.signUpModeList.find(v => v.value === val)
|
||
return d ? d.label : null
|
||
},
|
||
|
||
},
|
||
async created() {
|
||
this.createModeList = await getEnumOptions('TheRapyRecuperationLineCreateMode')
|
||
this.signUpModeList = await getEnumOptions('TheRapyRecuperationSignUpMode')
|
||
this.unionOptions = await getUnions(null)
|
||
this.pageData()
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<!--#
|
||
}
|
||
#-->
|