Files
dvcp_v2_webapp/ui/packages/common/AiPersonSelect.vue
2022-12-01 09:35:20 +08:00

561 lines
12 KiB
Vue

<template>
<section class="AiPersonSelect">
<el-button
v-if="!customClicker"
size="mini"
type="primary"
@click="isDialog = true"
:disabled="disabled">
{{ dialogTitle || '选择人员' }}
</el-button>
<div v-if="customClicker" class="list-wrapper">
<div class="userlist">
<div class="user" v-for="(item, index) in userList" :key="index" v-if="item">
<img :src="item.avatarUrl1" v-if="item.avatarUrl1" alt="">
<h2 v-else>{{ formatName(item.userName || item.name) }}</h2>
<span>{{ item.userName || item.name }}</span>
<i class="iconfont iconOverrule remove-icon" v-if="!disabled" @click="removeUser(item, index)"></i>
</div>
</div>
<div class="userlist-add" @click="showDialog" v-if="!disabled" :title="dialogTitle">
<div class="userlist-add__icon">
<i class="el-icon-plus"></i>
</div>
<span>{{ dialogTitle || '选择人员' }}</span>
</div>
</div>
<ai-dialog
title="选择人员"
:visible.sync="isDialog"
width="880px"
append-to-body
:modal-append-to-body="false"
:close-on-click-modal="false"
@onConfirm="saveSelect">
<el-row type="flex" justify="space-between" class="ai-personselect">
<el-col class="selectCont">
<el-row type="flex" justify="space-between">
<el-col>
<span style="font-weight: bold;">{{ headerTitle }}</span>
</el-col>
<el-col>
<el-input
size="mini"
placeholder="请输入..."
v-model="searchObj.con"
v-throttle="reSearchInfo"
@clear="reSearchInfo"
clearable>
<i slot="suffix" class="iconfont iconSearch" @click="reSearchInfo"/>
</el-input>
</el-col>
</el-row>
<ul class="seleceUl">
<li
v-for="(item, index) in meta || tableData"
:key="index"
@click="chooseItem(item, index)"
:class="{ selectedLi: getIsActive(item.id)}">
<slot v-if="customRightText" name="option" :item="item"></slot>
<template v-else>
<span class="iconfont iconProlife">{{ item.name }}</span>
<ai-id v-if="item.idNumber == 'undefined'" mode="show" :show-eyes="false" :value="item.idNumber"/>
</template>
</li>
</ul>
<div v-if="!meta" class="pagination">
<el-pagination
background
:current-page.sync="searchObj.current"
:total="total"
:small="true"
layout="prev, pager, next,total"
@current-change="handleChange"
:pager-count="5"
></el-pagination>
</div>
</el-col>
<div class="selected-people add-item">
<p class="add_top">
<span>已选择</span>
<el-button
icon="iconfont iconDelete"
size="mini"
@click="clearAll">
清空
</el-button>
</p>
<div class="add_tag" v-if="selectPeople.length" style="width:100%;">
<el-tag
v-for="(item, i) in selectPeople"
:disable-transitions="true"
:key="i"
closable
@close="cancelSelect(item, i)">{{ item.name || item.userName }}
</el-tag>
</div>
<div class="add_tag" v-else style="display:flex;align-items:center;justify-content:center;width:100%;">
<span>暂无数据</span>
</div>
</div>
</el-row>
</ai-dialog>
</section>
</template>
<script>
export default {
name: 'AiPersonSelect',
props: {
instance: Function,
appendToBody: Boolean,
url: String,
meta: Array,
chooseUserList: {
type: Array,
default: () => {
return []
}
},
dialogTitle: String,
headerTitle: {
type: String,
default: '居民列表',
},
isMultiple: {
type: Boolean,
default: false
},
customClicker: {
type: Boolean,
default: false
},
customRightText: {
type: Boolean
},
disabled: {type: Boolean, default: false},
},
data() {
return {
searchObj: {
con: '',
current: 1,
size: 10,
status: '',
},
tableData: [],
total: 0,
isDialog: false,
whichOne: -1,
userList: [],
selectPeople: []
}
},
computed: {
isHasOptionSlot() {
return this.$slots.option
}
},
watch: {
chooseUserList: {
handler(val) {
this.userList = val.length ? [...val] : []
this.selectPeople = val.length ? [...val] : []
},
immediate: true,
deep: true
}
},
created() {
this.searchInfo()
},
methods: {
showDialog() {
if (this.disabled) return
this.isDialog = true
},
reSearchInfo() {
this.searchObj.current = 1
this.searchInfo()
},
removeUser(user, index) {
if (!this.isMultiple) {
this.$confirm(`确认删除此人员?`).then(() => {
this.userList = []
this.selectPeople = []
this.$emit('selectPerson', null)
this.$emit('update:chooseUserList', null)
}).catch(() => {
})
return false
}
this.$confirm(`确认删除此人员?`).then(() => {
this.userList.splice(index, 1)
this.chooseItem(user)
this.$emit('selectPerson', this.isMultiple ? this.selectPeople : this.selectPeople[0])
this.$emit('update:chooseUserList', this.isMultiple ? this.selectPeople : this.selectPeople[0])
}).catch(() => {
})
},
formatName(name) {
if (name == undefined) {
return
}
return name.substr(name.length - 2, name.length > 2 ? (name.length - 1) : name.length)
},
chooseItem(user) {
if (!this.isMultiple) {
this.selectPeople = []
}
let index = this.selectPeople.findIndex(item => item.id === user.id)
if (index > -1) {
this.selectPeople.splice(index, 1)
} else {
this.selectPeople.push(user)
}
},
onClear() {
this.searchObj.con = ''
this.$nextTick(() => {
this.reSearchInfo()
})
},
cancelSelect(item) {
if (!this.isMultiple) {
this.selectPeople = []
} else {
this.chooseItem(item)
}
},
getIsActive(id) {
return this.selectPeople.findIndex(item => item.id === id) > -1
},
clearAll() {
this.selectPeople = []
},
searchInfo() {
let url = ''
if (!this.url) {
//非居民
url = '/app/appresident/list'
} else {
url = this.url
}
if (url == '/app/appvillagecadres/list') {
this.searchObj.status = '1'
}
this.instance.post(url, null, {
params: {
...this.searchObj,
fileStatus: 0,
auditType: 1,
phone: this.searchObj.con,
userName: this.searchObj.con
},
}).then((res) => {
this.tableData = res.data.records
this.total = res.data.total
})
},
handleChange(val) {
this.searchObj.current = val
this.searchInfo()
},
saveSelect() {
this.userList = this.isMultiple ? [...this.selectPeople] : [this.selectPeople[0]]
this.$emit('selectPerson', this.isMultiple ? this.selectPeople : this.selectPeople[0])
this.$emit('update:chooseUserList', this.isMultiple ? this.selectPeople : this.selectPeople[0])
this.isDialog = false
},
}
}
</script>
<style lang="scss" scoped>
.ai-personselect {
padding: 0 20px;
}
:deep( .el-pager li.active + li ){
border-left: solid 1px #d0d4dc !important;
}
:deep( .el-pager .number:last-child ){
border-color: #d0d4dc;
}
:deep( .el-pager .number.active ){
border-color: $primaryColor;
}
:deep(.pagination .el-pager li ){
line-height: 22px !important;
}
.selectCont {
position: relative;
}
.selectCont .pagination {
width: 100%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
position: absolute;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
bottom: 0 !important;
height: 32px;
line-height: 1;
background: #f5f6f7;
border-bottom: none !important;
}
.list-wrapper {
display: block;
font-size: 0;
.userlist {
display: inline-block;
}
.userlist, .user {
display: inline-block;
}
.user {
position: relative;
width: 70px;
text-align: center;
.remove-icon {
position: absolute;
right: 7px;
top: -4px;
line-height: 1;
padding: 6px 0;
font-size: 16px;
cursor: pointer;
&:hover {
color: crimson;
}
}
img, h2 {
display: block;
width: 40px;
height: 40px;
line-height: 40px;
text-align: center;
margin: 0 auto 4px;
font-size: 14px;
color: #fff;
border-radius: 50%;
}
h2 {
background-color: $primaryColor;
}
span {
color: #666;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
word-break: break-all;
text-overflow: ellipsis;
}
}
}
.userlist-add {
display: inline-block;
width: 70px;
text-align: center;
cursor: pointer;
&:hover {
color: crimson;
}
.userlist-add__icon {
width: 40px;
height: 40px;
line-height: 40px;
margin: 0 auto 4px;
text-align: center;
font-size: 20px;
color: $primaryColor;
border: 1px dashed $primaryColor;
border-radius: 50%;
box-sizing: border-box;
}
span {
color: #666;
font-size: 14px;
}
}
.selectCont {
border: 1px solid #d0d4dc;
background: #fcfcfc;
width: 416px;
height: 336px;
.el-row {
background: #f5f5f5;
border-bottom: 1px solid #d0d4dc;
height: 40px;
line-height: 40px;
padding: 0 8px;
}
.seleceUl {
margin: 8px;
padding: 0;
height: 248px;
overflow-y: auto;
.AiID {
line-height: inherit;
}
li {
display: flex;
justify-content: space-between;
height: 24px;
line-height: 24px;
font-size: 12px;
cursor: pointer;
.iconfont {
font-size: 12px;
}
p {
padding: 0;
margin: 0;
}
}
li:hover {
background: #eff6ff;
color: #5088ff;
}
.selectedLi {
background: #eff6ff;
color: #5088ff;
}
}
.pagination {
padding: 0;
background: #f5f5f5;
border-top: 1px solid #d0d4dc;
border-bottom: 1px solid #d0d4dc;
}
}
.ai-personselect .add-item {
position: relative;
width: 260px;
background: rgba(252, 252, 252, 1);
border-radius: 2px;
border: 1px solid rgba(208, 212, 220, 1);
overflow: auto;
box-sizing: border-box;
&:nth-of-type(2) {
width: 360px;
overflow: hidden;
}
.pagination {
position: absolute;
bottom: 20px;
padding: 0;
}
.add_top {
width: 100%;
height: 40px;
background: rgba(245, 245, 245, 1);
border-bottom: 1px solid rgba(208, 212, 220, 1);
margin: 0;
padding: 0 8px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
}
.tree_list {
width: 100%;
overflow: auto;
height: calc(100% - 40px);
.el-tree {
height: 100%;
}
}
.add_buttom {
position: absolute;
left: 0;
bottom: 0;
font-size: 12px;
width: 310px;
height: 32px;
line-height: 32px;
z-index: 10000;
background: rgba(245, 246, 247, 1);
color: rgba(51, 51, 51, 1);
box-shadow: 0 1px 0 0 rgba(216, 220, 227, 1);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.add_tag {
width: 310px;
height: calc(100% - 40px);
overflow-y: auto;
.el-tag {
margin: 8px;
}
}
}
.el-dialog__wrapper {
z-index: 3000 !important;
}
</style>