501 lines
15 KiB
Vue
501 lines
15 KiB
Vue
<template>
|
|
<van-popup class="history-list-popup" v-model="isShow" v-if="isShow" position="right" :style="{ width: '100%', height: '100%' }">
|
|
<!-- 增加一个标题-->
|
|
<custom-header :title="$t('selectUser')" :leftArrow="true" :handle-left="handleLeft"></custom-header>
|
|
<div class="list-container">
|
|
<van-search
|
|
v-model="realnameOrUsername"
|
|
show-action
|
|
input-align="center"
|
|
placeholder="请输入姓名/工号"
|
|
@search="onSearch"
|
|
@clear="onSearch">
|
|
<template #action>
|
|
<div @click="onSearch">搜索</div>
|
|
</template>
|
|
</van-search>
|
|
|
|
<van-dropdown-menu :close-on-click-overlay="true" :close-on-click-outside="true">
|
|
<!-- 内部工作组 -->
|
|
<van-dropdown-item :title="selectedWorkGroup" ref="workGroupDropdownItem">
|
|
<van-cascader
|
|
v-model="workingGroupId"
|
|
title="请选择内部工作组"
|
|
:options="workGroupList"
|
|
:closeable="false"
|
|
:show-header="false"
|
|
:field-names="{text: 'name', value: 'id', children: 'subset'}"
|
|
@change="handleWorkGroupChange" />
|
|
<div class="dropdown-operate-box">
|
|
<van-button @click="handleClearDepart" class="dropdown-confirm-btn" type="primary" round plain size="small">清空</van-button>
|
|
<van-button @click="handleConfirmDepart" class="dropdown-confirm-btn" type="primary" round size="small">确定</van-button>
|
|
</div>
|
|
</van-dropdown-item>
|
|
<!--角色-->
|
|
<van-dropdown-item :title="selectedRole" ref="roleDropdownItem">
|
|
<van-picker
|
|
ref="rolePicker"
|
|
show-toolbar
|
|
toolbar-position="bottom"
|
|
:columns="rolesList"
|
|
@confirm="handleConfirmRole"
|
|
@cancel="handleCancelRole">
|
|
<template v-slot:default>
|
|
<div class="dropdown-operate-box">
|
|
<van-button @click="handleClearRole" class="dropdown-confirm-btn" type="primary" round plain size="small">清空
|
|
</van-button>
|
|
<van-button @click="confirmRole" class="dropdown-confirm-btn" type="primary" round size="small">确定</van-button>
|
|
</div>
|
|
</template>
|
|
</van-picker>
|
|
</van-dropdown-item>
|
|
</van-dropdown-menu>
|
|
|
|
<van-list
|
|
v-model="loading"
|
|
:finished="listFinished"
|
|
:finished-text="listData.length > 0 ? '没有更多了' : '暂无数据'"
|
|
@load="onLoadMore"
|
|
:immediate-check="false">
|
|
<van-checkbox-group v-if="type === 'checkbox'" v-model="checkedArr" ref="checkboxGroup">
|
|
<van-swipe-cell
|
|
v-for="(item, index) in listData"
|
|
:key="index"
|
|
:name="index"
|
|
stop-propagation
|
|
:before-close="handleBeforeClose">
|
|
<div class="item-box">
|
|
<van-checkbox :name="item.userId" @click="checkboxClick(item)" shape="square" :disabled="readonly"></van-checkbox>
|
|
<div class="item-container">
|
|
<div class="item-title">
|
|
{{ item.realname }}({{ item.username }})
|
|
</div>
|
|
<div class="item-content">
|
|
<div class="item-content-item">
|
|
<span class="label">角色:</span>
|
|
<span class="text">{{ item.userRoleName }}</span>
|
|
</div>
|
|
<div class="item-content-item">
|
|
<span class="label">岗位:</span>
|
|
<span class="text">{{ item.userPostName }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</van-swipe-cell>
|
|
</van-checkbox-group>
|
|
<van-radio-group v-else v-model="checkedArr" ref="checkboxGroup">
|
|
<van-swipe-cell
|
|
v-for="(item, index) in listData"
|
|
:key="index"
|
|
:name="index"
|
|
stop-propagation
|
|
:before-close="handleBeforeClose">
|
|
<div class="item-box">
|
|
<van-radio :name="item.userId" @click="checkboxClick(item)" :disabled="readonly"></van-radio>
|
|
<div class="item-container">
|
|
<div class="item-title">
|
|
{{ item.realname }}({{ item.username }})
|
|
</div>
|
|
<div class="item-content">
|
|
<div class="item-content-item">
|
|
<span class="label">角色:</span>
|
|
<span class="text">{{ item.userRoleName }}</span>
|
|
</div>
|
|
<div class="item-content-item">
|
|
<span class="label">岗位:</span>
|
|
<span class="text">{{ item.userPostName }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</van-swipe-cell>
|
|
</van-radio-group>
|
|
</van-list>
|
|
|
|
<!-- 底部的按钮 -->
|
|
<div class="bottom-button-container">
|
|
<div class="bottom-btn bottom-justify-div">
|
|
<van-button size="small" color="#C6C7CA" native-type="button" plain :disabled="disabled" @click="resetFunc">重置
|
|
</van-button>
|
|
<van-button v-if="type === 'checkbox'" size="small" color="#E63636" native-type="button" :disabled="disabled" @click="checkAll">
|
|
全选
|
|
</van-button>
|
|
<van-button size="small" color="#E63636" native-type="button" :disabled="disabled" @click="confirmFunc()">确定
|
|
</van-button>
|
|
<van-button size="small" color="#C6C7CA" native-type="button" plain :disabled="disabled" @click="hide()">取消
|
|
</van-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</van-popup>
|
|
</template>
|
|
|
|
<script>
|
|
import CustomHeader from '@/components/CustomHeader'
|
|
import ListMixin from '@/mixins/ListMixin'
|
|
import { getWorkGroupTreeList, queryAllRole } from '@/api/api'
|
|
import { getAction } from '@/api/manage'
|
|
|
|
export default {
|
|
name: 'SelectUserByWorkGroup',
|
|
components: { CustomHeader },
|
|
mixins: [ListMixin],
|
|
props: {
|
|
selectedData: {
|
|
type: String,
|
|
required: false,
|
|
default: () => {
|
|
return ''
|
|
}
|
|
},
|
|
// 一些其他的查询参数
|
|
filterData: {
|
|
type: Object,
|
|
required: false,
|
|
default: () => {
|
|
return {}
|
|
}
|
|
},
|
|
readonly: {
|
|
type: Boolean,
|
|
required: false,
|
|
default: false
|
|
},
|
|
type: {
|
|
type: String,
|
|
required: false,
|
|
default: 'radio'
|
|
}
|
|
},
|
|
watch: {
|
|
selectedData: {
|
|
immediate: true,
|
|
handler (val) {
|
|
if (val) {
|
|
this.getUserListByIds(val)
|
|
}
|
|
}
|
|
}
|
|
},
|
|
data () {
|
|
return {
|
|
realname: '', // 搜索框数据
|
|
realnameOrUsername: null, // 搜索框数据(姓名和工号一起搜索改的)
|
|
isShow: false,
|
|
loading: false, // 加载数据的标识,
|
|
listFinished: false, // 完成加载的标识
|
|
refreshing: false, // 下拉刷新的标志
|
|
listData: [], // 列表页的数据
|
|
listCount: 0, // 所有数据的数量
|
|
/* 分页的配置 */
|
|
ipagination: {
|
|
pageNo: 1,
|
|
pageSize: 10
|
|
},
|
|
url: {
|
|
list: '/act/user/workGroupPage',
|
|
userListByIds: '/sys/user/queryByIds'
|
|
},
|
|
checkedArr: [],
|
|
selectedDataArr: [],
|
|
selectedWorkGroup: '内部工作组', // 回显在页面上的选中部门的名字
|
|
selectedRole: '角色', // 回显在页面上的选中角色的名字
|
|
workGroupList: [], // 内部工作组数据
|
|
workingGroupId: null, // 查询时候传给后端的参数
|
|
tempSelectedWorkGroup: {}, // change的时候记录一下选中的内部工作组
|
|
rolesList: [], // 角色下拉框
|
|
roleName: null // 查询时候传给后端的参数
|
|
}
|
|
},
|
|
computed: {
|
|
disabled () {
|
|
return this.listData.length === 0 || this.readonly
|
|
}
|
|
},
|
|
methods: {
|
|
open () {
|
|
this.isShow = true
|
|
this.initData()
|
|
this.getListData()
|
|
this.getWorkGroup()
|
|
this.initRoleList()
|
|
},
|
|
checkboxClick (item) {
|
|
console.log(item)
|
|
if (this.type === 'checkbox') {
|
|
if (this.checkedArr.includes(item.userId)) {
|
|
console.log('------------增加了数据------------')
|
|
// 说明是增加了数据,为了顺序和列表顺序保持一致,用循环设置
|
|
const arr = []
|
|
for (const i of this.listData) {
|
|
if (this.checkedArr.includes(i.userId)) {
|
|
arr.push(i)
|
|
}
|
|
}
|
|
for (const i of this.selectedDataArr) {
|
|
if (!arr.find(item => item.userId === i.userId)) {
|
|
// 已加载完的列表里还没有的选中数据,按顺序推入
|
|
arr.push(i)
|
|
}
|
|
}
|
|
this.selectedDataArr = arr
|
|
} else {
|
|
console.log('------------删除了数据------------')
|
|
// 说明是删除了数据
|
|
this.selectedDataArr = this.selectedDataArr.filter(i => i.userId !== item.userId)
|
|
}
|
|
} else {
|
|
this.selectedDataArr = [item]
|
|
}
|
|
console.log(this.selectedDataArr)
|
|
},
|
|
// 根据id获取用户信息,初始化选中数据,不查选中数据的话如果没有划到那一页,名字带不出来
|
|
getUserListByIds (ids) {
|
|
const params = {}
|
|
params.userIds = ids
|
|
getAction(this.url.userListByIds, params).then((res) => {
|
|
if (res.success) {
|
|
this.selectedDataArr = res.result.map(item => {
|
|
return {
|
|
...item,
|
|
userId: item.id
|
|
}
|
|
}) || []
|
|
} else {
|
|
this.$message(res.message)
|
|
}
|
|
})
|
|
},
|
|
handleCheckedArr () {
|
|
// 清空选中的数据
|
|
if (this.type === 'checkbox') {
|
|
if (this.selectedData) {
|
|
this.checkedArr = this.selectedData.split(',')
|
|
} else {
|
|
this.checkedArr = []
|
|
}
|
|
} else {
|
|
if (this.selectedData) {
|
|
this.checkedArr = this.selectedData
|
|
} else {
|
|
this.checkedArr = ''
|
|
}
|
|
}
|
|
},
|
|
// 初始化数据
|
|
initData () {
|
|
this.ipagination.pageNo = 1
|
|
this.listData = []
|
|
this.listFinished = false
|
|
this.refreshing = false
|
|
this.loading = true
|
|
this.handleCheckedArr()
|
|
},
|
|
// 重置按钮点击的方法
|
|
resetFunc () {
|
|
this.checkedArr = []
|
|
},
|
|
checkAll () {
|
|
this.$refs.checkboxGroup.toggleAll(true)
|
|
this.selectedDataArr = [...this.listData]
|
|
},
|
|
// 确定 按钮触发的方法
|
|
confirmFunc () {
|
|
console.log(this.checkedArr)
|
|
// 先判断是否选择数据,没有提示
|
|
if ((this.type === 'checkbox' && this.checkedArr.length === 0) || (this.type === 'radio' && (!this.checkedArr || this.checkedArr.length === 0))) {
|
|
this.$message('请至少选择一条数据')
|
|
return
|
|
}
|
|
if (this.type === 'checkbox') {
|
|
this.$emit('selected-change', this.checkedArr.join(','))
|
|
} else {
|
|
this.$emit('selected-change', this.checkedArr)
|
|
}
|
|
this.$emit('selected-change-name', this.selectedDataArr.map(item => item.realname + '(' + item.username + ')').join(','))
|
|
this.hide()
|
|
},
|
|
onSearch () {
|
|
if (this.realname) {
|
|
this.filters.realname = this.realname
|
|
} else {
|
|
this.filters.realname = null
|
|
}
|
|
this.filters.realnameOrUsername = this.realnameOrUsername || null
|
|
this.filters.workingGroupId = this.workingGroupId
|
|
this.filters.userRoleName = this.roleName
|
|
this.ipagination.pageNo = 1
|
|
this.getListData()
|
|
},
|
|
handleLeft () {
|
|
this.hide()
|
|
},
|
|
hide () {
|
|
this.isShow = false
|
|
Object.assign(this.$data, this.$options.data())
|
|
},
|
|
// 获取内部工作组
|
|
getWorkGroup () {
|
|
getWorkGroupTreeList().then((res) => {
|
|
if (res.success) {
|
|
this.workGroupList = res.result
|
|
} else {
|
|
this.workGroupList = []
|
|
}
|
|
})
|
|
},
|
|
handleWorkGroupChange ({ value, selectedOptions }) {
|
|
this.tempSelectedWorkGroup = selectedOptions.find(tt => tt.id === value) || {}
|
|
console.log(this.tempSelectedWorkGroup)
|
|
},
|
|
handleConfirmDepart () {
|
|
this.$refs.workGroupDropdownItem.toggle()
|
|
this.selectedWorkGroup = this.tempSelectedWorkGroup.name
|
|
this.onSearch()
|
|
},
|
|
handleClearDepart () {
|
|
this.$refs.workGroupDropdownItem.toggle()
|
|
this.selectedWorkGroup = '组织机构'
|
|
this.tempSelectedWorkGroup = {}
|
|
this.workingGroupId = null
|
|
this.onSearch()
|
|
},
|
|
// 初始化角色字典
|
|
initRoleList () {
|
|
queryAllRole().then((res) => {
|
|
if (res.success) {
|
|
this.rolesList = res.result.map((item) => {
|
|
return { text: item.roleName, value: item.id }
|
|
})
|
|
}
|
|
})
|
|
},
|
|
confirmRole () {
|
|
this.$refs.rolePicker.confirm()
|
|
},
|
|
handleClearRole () {
|
|
this.$refs.roleDropdownItem.toggle()
|
|
this.selectedRole = '角色'
|
|
this.roleName = null
|
|
this.onSearch()
|
|
},
|
|
handleConfirmRole (value) {
|
|
this.$refs.roleDropdownItem.toggle()
|
|
this.roleName = value.text
|
|
this.selectedRole = value.text
|
|
this.onSearch()
|
|
},
|
|
handleCancelRole () {
|
|
this.$refs.roleDropdownItem.toggle()
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
@import '~@assets/less/list.less';
|
|
@import '~@assets/less/common.less';
|
|
|
|
.history-list-popup {
|
|
background: @global-bg;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.list-container {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 0;
|
|
}
|
|
|
|
.van-list {
|
|
padding: @pad-base;
|
|
flex: 1;
|
|
overflow: auto;
|
|
}
|
|
|
|
// 中间内容
|
|
.item-box {
|
|
background: #FFFFFF;
|
|
padding: 0.24rem;
|
|
display: flex;
|
|
align-items: center;
|
|
border-bottom: 1px solid #C9CDD4;
|
|
border-radius: 0;
|
|
|
|
.van-checkbox {
|
|
display: block;
|
|
margin: 0 20px 0 0;
|
|
}
|
|
|
|
.van-radio {
|
|
display: block;
|
|
margin: 0 20px 0 0;
|
|
}
|
|
|
|
/deep/ .van-checkbox__icon--checked {
|
|
.van-icon {
|
|
background: @primary-color;
|
|
border-color: @primary-color;
|
|
}
|
|
}
|
|
|
|
/deep/ .van-radio__icon--checked {
|
|
.van-icon {
|
|
background: @primary-color;
|
|
border-color: @primary-color;
|
|
}
|
|
}
|
|
}
|
|
|
|
.item-container {
|
|
flex: 1;
|
|
}
|
|
|
|
// 底部按钮
|
|
.bottom-button-container {
|
|
height: 1.28rem;
|
|
line-height: 1.28rem;
|
|
padding: 0 0.2rem;
|
|
background: #FFFFFF;
|
|
}
|
|
|
|
.bottom-justify-div {
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-around;
|
|
gap: 0.2rem;
|
|
|
|
.van-button {
|
|
height: 0.8rem;
|
|
flex: 1;
|
|
}
|
|
|
|
/deep/ .van-button--plain {
|
|
color: #898989 !important;
|
|
}
|
|
}
|
|
|
|
.dropdown-operate-box {
|
|
width: 100%;
|
|
display: flex;
|
|
padding: 0.24rem;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.dropdown-confirm-btn {
|
|
width: calc(50% - 0.12rem);
|
|
}
|
|
|
|
/deep/ .van-picker__toolbar {
|
|
height: auto;
|
|
}
|
|
|
|
/deep/ .van-cascader__options {
|
|
max-height: 40vh;
|
|
}
|
|
</style>
|