Files
foton-laws-system-front/src/components/OrgTable/index.vue
T
2021-05-25 18:06:45 +08:00

721 lines
20 KiB
Vue

<!-- 分页从全公司选择人员 -->
<template>
<div>
<!-- 弹窗,dialogModel则作为单独组件使用 -->
<el-dialog
append-to-body
:title="showTitle"
:visible.sync="isVisible"
:close-on-click-modal="false"
class="org-table"
@close="handleClose">
<div class="search-area">
<el-form
:model="searchForm"
inline
class="label-input-form"
@keyup.enter.native="handleSearch">
<el-form-item label="部门" class="search-item">
<el-input v-model="searchForm.orgId" v-show="false"/>
<el-popover
placement="bottom"
popper-class="user-dept-popper"
trigger="click"
:value="false"
>
<el-input
@mouseenter.native="handleMouseEnter"
@mouseleave.native="handleMouseLeave"
slot="reference"
v-model="searchForm.orgName"
placeholder="根据部门查询"
readonly
clearable
id="orgInput">
<i slot="suffix"
class="org el-icon-circle-close"
@click.stop="handleOrgDel"
v-show="visibleOrgClearBtn"></i>
</el-input>
<div class="api">
<laws-tree
:zNodes="orgZNodes"
ref="orgTree"
:editable="false"
treeDivId="orgTree"
deptSelect
@treeDblClick="handleSearchOrgChecked"
style="width: 200px;height: 400px;overflow: auto;">
</laws-tree>
</div>
</el-popover>
</el-form-item>
<el-form-item label="姓名" class="search-item">
<el-input
v-model="searchForm.userName"
placeholder="根据姓名查询"
clearable></el-input>
</el-form-item>
<el-form-item class="search-item btn-box">
<el-button
:loading="loading.searching"
icon="el-icon-search"
type="primary"
class="common-button-primary"
round
@click="handleSearch">
</el-button>
<el-button
class="common-button-default"
icon="el-icon-refresh-left"
round
@click="handleReset"></el-button>
</el-form-item>
</el-form>
</div>
<div class="org-user">
<el-table
ref="orgTable"
:data="tableData"
tooltip-effect="dark"
style="width: 100%"
border
stripe
:header-cell-style="{ background: '#f8f8f9', color: '#515a6e' }"
height="350"
v-loading="loading.loadData"
:cell-class-name="cellClassName"
@select="selectionRow">
<el-table-column
type="selection"
width="55"
align="center"
:selectable="isSelectable">
</el-table-column>
<el-table-column
label="姓名"
width="120"
prop="userName"
align="center">
</el-table-column>
<el-table-column
prop="email"
label="邮箱"
align="center"
show-overflow-tooltip>
</el-table-column>
<el-table-column
prop="roleName"
label="角色"
align="center">
<template slot-scope="scope">
<div class="tag-wrap">
<el-tag
size="small"
v-for="(tag, index) in scope.row.roleName.split(',')"
:key="index">{{ tag }}</el-tag>
</div>
</template>
</el-table-column>
<el-table-column
label="部门"
align="center">
<template #default="{ row }">{{ row.departName || row.orgName }}</template>
</el-table-column>
</el-table>
</div>
<pagination
:page="pageNo"
:pageSize="pageSize"
:total="total"
@pageChange="handlePageChange"
@pageSizeChange="handlePageSizeChange"
></pagination>
<!-- 已选择的用户 -->
<el-divider content-position="left">已选择</el-divider>
<div class="checked-user-list">
<el-tag
size="medium"
closable
v-for="item in checkedList"
:key="item.userId || item.id"
@close="handleRemove(item)">{{ item.userName || item.name }}</el-tag>
<el-button
type="danger"
size="mini"
@click="handleCleanChecked"
v-show="checkedIdList.length > 1">全部删除</el-button>
</div>
<div slot="footer" class="dialog-footer">
<el-button
type="primary"
class="common-button-primary"
icon="el-icon-check"
round
@click="handleConfirm"> </el-button>
<el-button
round
class="common-button-default"
icon="el-icon-close"
@click="handleCancel"> </el-button>
</div>
</el-dialog>
<!-- 非弹窗模式使用 -->
<el-col :span="span" v-if="!dialogModel">
<el-form-item
:label="config.attrName"
:prop="config.attrField"
:label-width="labelWidth"
class="add-form-item expand-form-item"
:class="{'form-item-disabled': disabled}"
>
<el-input
v-model="checkedName"
:placeholder="'请选择' + config.attrName"
readonly
:disabled="disabled"
:id="config.attrField"
@click.native="handleChooseByDialog"
/>
</el-form-item>
</el-col>
</div>
</template>
<script>
import { getRoleAndUserByOrgIdPage } from 'api'
import { mapGetters } from 'vuex'
export default {
name: 'OrgTable',
mixins: [],
components: {},
props: {
title: {
type: String,
default: '组织机构'
},
visible: {
type: Boolean,
default: false
},
// 弹窗模式选取
dialogModel: {
type: Boolean,
default: false
},
config: {
type: Object
},
value: {
required: false
},
disabled: {
type: Boolean,
default: false
},
// 栅格比例
span: {
type: Number,
default: 24
},
// 原数据对象
dataModel: {
type: Object,
default: () => {
return {}
}
},
labelWidth: {
type: String,
default: '150px'
},
maxSelected: {
type: Number
},
maxSelectedTips: {
type: String
},
// 不可选人员
excludeUser: {
type: [Array, String]
},
defaultCheck: {
type: Object
},
deptZNodes: {
type: Array
},
orgId: {
type: String
},
roleName: {
type: String
}
},
data() {
return {
isVisible: false,
visibleOrgClearBtn: false,
searchForm: {
orgId: '',
orgName: '',
userName: ''
},
tableData: [],
tableDataSelectedList: [],
pageNo: 1,
pageSize: this.configContent,
total: 0,
checkedList: [],
loading: {
searching: false,
loadData: false
},
orgZNodes: [],
// 选中节点id集合
checkedIdList: [],
// 非弹窗模式
treeCheckNode: [],
checkedName: '',
zNodesRole: [],
roleList: [],
repeatFlag: false
}
},
methods: {
handleClose() {
this.searchForm = {
orgId: '',
orgName: '',
userName: ''
}
this.pageNo = 1
this.checkedList = []
this.checkedIdList = []
this.$refs['orgTable'].clearSelection()
},
handleCancel() {
this.isVisible = false
},
handleConfirm() {
if (this.dialogModel) {
if (this.maxSelected && this.maxSelected > -1 && this.checkedList.length > this.maxSelected) {
this.$message.warning(this.maxSelectedTips || `${this.title} 只能选择一个用户`)
} else {
const checkedIdList = []
this.checkedList.map(chkItem => {
checkedIdList.push(chkItem.userId || chkItem.id)
})
this.$emit('confirm', this.checkedList, checkedIdList)
this.isVisible = false
}
} else {
switch (this.config.attrType) {
// 多选
case 'SEL_OPTS':
break
// 单选
default:
if (this.checkedList.length > 1) {
this.$message.warning(`${this.config.attrName} 只能选择一个用户`)
} else {
const dataItem = this.checkedList[0]
this.checkedName = dataItem.userName || dataItem.orgName
const id = dataItem.id || dataItem.userId
this.$emit('input', id)
this.$emit('on-checked', this.checkedName)
this.$emit('on-dept', dataItem.pOrgId, dataItem.pOrgName)
setTimeout(() => {
this.isVisible = false
}, 100)
}
}
}
},
handlePageChange(pageNo) {
this.pageNo = pageNo
this.getRoleAndUserByOrgIdPage()
},
handlePageSizeChange(pageSize) {
this.getRoleAndUserByOrgIdPage()
},
handleSearch() {
this.pageNo = 1
this.loading.searching = true
this.getRoleAndUserByOrgIdPage()
},
handleReset() {
this.pageNo = 1
this.searchForm = {
orgId: '',
orgName: '',
userName: ''
}
this.getRoleAndUserByOrgIdPage()
},
handleSearchOrgChecked(treeId, treeNode) {
this.searchForm.orgId = treeNode.id
this.searchForm.orgName = treeNode.oldname || treeNode.name
$('#orgInput').click()
},
/**
* @description: 获取组织机构
* @author: chenxiaoxi
* @time: 2021-03-21 14:40:59
*/
getOrg() {
this.$http.get('sys/org/getTree', {}, {_this: this},
res => {
if (res.ok) {
res.data.map(item => {
item.name = item.orgName
item.icon = 'static/images/dept.png'
})
this.orgZNodes = res.data
}
}, e => {})
},
/**
* @description: 分页查询用户
* @author: chenxiaoxi
* @time: 2021-03-21 17:08:06
*/
getRoleAndUserByOrgIdPage() {
this.loading.loadData = true
if (this.orgId) {
if (this.searchForm.orgId === '') {
this.searchForm.orgId = this.orgId
}
}
getRoleAndUserByOrgIdPage({
pageNo: this.pageNo,
pageSize: this.userInfo.configContent,
...this.searchForm,
roleName: this.roleName
}).then(res => {
this.loading.loadData = false
this.loading.searching = false
if (res.ok) {
this.total = res.data.count
this.tableData = res.data.list
const checkedRow = []
this.tableData.map(dataItem => {
const id = dataItem.userId || dataItem.orgId || dataItem.id
if (this.checkedIdList.includes(id)) {
checkedRow.push(dataItem)
}
})
this.checkedRow(checkedRow)
}
}).catch(e => {
this.loading.loadData = false
this.loading.searching = false
})
},
// handleRowSelect(selection, row) {
// const id = row.userId || row.id
// // 当前行选中/取消选中,其他相同用户(角色不同)被选中/取消选中
// this.tableData.map(dataItem => {
// if (dataItem.userId === id || dataItem.id === id) {
// this.$refs['orgTable'].toggleRowSelection(dataItem, selection.includes(row))
// }
// })
// console.log(this.checkedList)
// },
selectionRow(selection,row){
let selected = selection.length && selection.indexOf(row) !== -1; //为true时选中,为 0 时(false)未选中
if(selected){
selection.map(selItem => {
const id = selItem.roleId || selItem.orgId
if (!this.checkedIdList.includes(id) && !this.excludeIdList.includes(id)) {
this.checkedIdList.push(id)
this.checkedList.push(row);
}
})
} else {
this.handleRemove(row)
}
},
handleSelectionChange(selection) {
if (selection.length) {
selection.map(selItem => {
const id = selItem.userId || selItem.orgId || selItem.id
// 如果exclude不含当前行
if (!this.excludeIdList.includes(id)) {
// 如果下面列表没有,就填到下面列表里
if (!this.checkedIdList.includes(id)) {
this.checkedList.push(selItem)
this.checkedIdList.push(id)
}
} else {
// 如果exclude含当前行,当前行置为未选中状态
// this.$message.warning('主起草人/其他起草人不能为同一个人')
// this.$nextTick(() => {
// this.$refs['orgTable'].toggleRowSelection(selItem, false)
// })
}
})
}
},
handleRemove(user) {
let delIndex = -1
this.checkedList.map((checkedItem, chkIndex) => {
if (user.userId === checkedItem.userId) {
delIndex = chkIndex
return false
}
})
this.checkedList.splice(delIndex, 1)
this.checkedIdList.splice(delIndex, 1)
},
handleOrgDel() {
this.searchForm.orgId = ''
this.searchForm.orgName = ''
},
/**
* @description: 设置选中状态
* @author: chenxiaoxi
* @time: 2021-03-22 10:06:03
*/
checkedRow(rows) {
this.$nextTick(() => {
if (rows.length) {
rows.forEach(row => {
this.$refs['orgTable'] && this.$refs['orgTable'].toggleRowSelection(row)
});
} else {
this.$refs['orgTable'] && this.$refs['orgTable'].clearSelection()
}
})
},
cellClassName({row, column, rowIndex, columnIndex}) {
if (columnIndex === 3) {
return 'tag-column'
}
},
isSelectable(row, index) {
return !this.excludeIdList.includes(row.userId)
},
handleChooseByDialog() {
if (!this.dialogModel) {
this.checkedName = this.config.valueName || ''
if (this.config.value) {
this.checkedList = [{
userId: this.config.value,
userName: this.config.valueName
}]
}
const idList = this.config.value === '' || !this.config.value ? [] : this.config.value.split(',')
this.checkedIdList = [...idList]
}
this.isVisible = true
this.getRoleAndUserByOrgIdPage()
},
handleMouseEnter() {
if (this.searchForm.orgName !== '') {
this.visibleOrgClearBtn = true
}
},
handleMouseLeave() {
this.visibleOrgClearBtn = false
},
handleCleanChecked() {
this.$confirm('您是否确定移除全部已选中', '确定移除', {
confirmButtonText: '确定',
cancelButtonText: '取消',
confirmButtonClass: 'common-button-primary',
roundButton: true,
type: 'warning'
}).then(() => {
this.checkedList = []
this.checkedIdList = []
this.$refs['orgTable'].clearSelection()
}).catch(e => {})
}
},
computed: {
configContent() {
return this.userInfo.configContent
},
placeholder () {
return !this.dialogModel && `请选择${this.config.attrName}`
},
showMessage () {
return !this.dialogModel && `${this.config.attrName}不能为空`
},
isRequired () {
return !this.dialogModel && !!this.config.isMust
},
isString (str) {
return (typeof str === 'string') && str.constructor === String
},
isFO () {
return !this.dialogModel && this.config.attrField === 'FO'
},
ZRBM () {
return this.dataModel['ZRBM'] || ''
},
showTitle() {
return this.dialogModel ? this.title : this.config.attrName
},
excludeIdList() {
return this.excludeUser && this.excludeUser !== '' ? (this.excludeUser instanceof Array ? this.excludeUser : this.excludeUser.split(',')) : []
},
...mapGetters(['userInfo'])
},
watch: {
visible (val) {
this.isVisible = val
if (val) {
if (this.config.value !== '') {
const idList = this.config.value instanceof Array ? this.config.value : (this.config.value === '' ? [] : this.config.value.split(','))
const nameList = this.config.valueName instanceof Array ? this.config.valueName.split(',') : (this.config.valueName === '' ? [] : this.config.valueName.split(','))
this.checkedIdList = idList
const checkedList = []
idList.map((id, index) => {
checkedList.push({
userId: id,
userName: nameList[index]
})
})
this.checkedList = checkedList
}
this.getRoleAndUserByOrgIdPage()
}
},
isVisible (val) {
this.$emit('update:visible', val)
},
value (newVal, oldVal) {
this.checkedName = newVal !== '' ? this.checkedName : ''
},
deptZNodes: {
handler (val) {
this.orgZNodes = val
}
}
},
mounted() {
this.isVisible = this.visible
if (!this.dialogModel) {
this.checkedName = this.config.valueName || ''
if (this.config.value !== '') {
this.checkedList = [{
userId: this.config.value,
userName: this.config.valueName
}]
const idList = this.config.value === '' ? [] : this.config.value.split(',')
this.checkedIdList = [...idList]
}
} else {
const idList = this.config.value instanceof Array ? this.config.value : (this.config.value === '' ? [] : this.config.value.split(','))
const nameList = this.config.valueName instanceof Array ? this.config.valueName.split(',') : (this.config.valueName === '' ? [] : this.config.valueName.split(','))
this.checkedIdList = idList
const checkedList = []
idList.map((id, index) => {
checkedList.push({
userId: id,
userName: nameList[index]
})
})
this.checkedList = checkedList
}
this.getOrg()
this.getRoleAndUserByOrgIdPage()
}
}
</script>
<style lang="less" scoped>
.org-table {
/deep/ .el-dialog__header {
padding: 0 20px;
height: 50px;
display: flex;
align-items: center;
border-bottom: 1px solid #ddd;
}
/deep/ .el-dialog__body {
padding: 15px 20px 20px 20px;
}
.search-area {
padding: 0;
/deep/ .el-form-item__label {
line-height: 35px;
}
/deep/ .el-form-item__content {
line-height: 35px;
.el-input__inner {
height: 35px;
line-height: 35px;
}
}
}
.pagination {
position: static;
}
.checked-user-list {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
.el-tag {
margin: 0 10px 10px 0;
}
.el-button--mini {
padding: 0 15px;
height: 28px;
line-height: 28px;
}
}
}
/deep/ .el-popover__reference-wrapper {
.el-input__suffix {
padding-right: 5px;
&:hover {
cursor: pointer;
}
}
}
/deep/ .tag-column {
.cell {
padding: 5px 10px;
overflow: visible;
text-overflow: clip;
.tag-wrap {
.el-tag {
height: auto;
white-space: normal;
text-align: left;
}
}
}
}
</style>