Files
jnpf_app/components/Jnpf/RoleSelect/SelectPopup.vue
2026-01-04 11:09:06 +08:00

160 lines
4.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<u-popup class="jnpf-tree-select-popup" mode="right" v-model="showPopup" @close="close" :z-index="uZIndex"
width="100%">
<view class="jnpf-tree-select-body">
<view class="jnpf-tree-select-title">
<text class="icon-ym icon-ym-report-icon-preview-pagePre backIcon" @tap="close()"></text>
<view class="title">角色选择</view>
</view>
<view class="jnpf-tree-select-search">
<u-search :placeholder="$t('app.apply.pleaseKeyword')" v-model="keyword" height="72"
:show-action="false" @change="handleSearch" bg-color="#f0f2f6" shape="square">
</u-search>
</view>
<view class="jnpf-tree-selected">
<view class="jnpf-tree-selected-head">
<view>{{$t('component.jnpf.common.selected')}}({{selectedList.length||0}})</view>
<view v-if="multiple" class="clear-btn" @click="removeAll">
{{$t('component.jnpf.common.clearAll')}}
</view>
</view>
<view class="jnpf-tree-selected-box">
<scroll-view scroll-y="true" class="select-list">
<u-tag closeable @close="handleRemove(index)" v-for="(item,index) in selectedList" :key="index"
:text="item.fullName" class="u-selectTag" />
</scroll-view>
</view>
</view>
<view class="jnpf-tree-selected-line"></view>
<view class="jnpf-tree-selected-tabs">
<view class="tab-item tab-item-active">用户角色</view>
</view>
<view class="jnpf-tree-select-tree">
<scroll-view :scroll-y="true" style="height: 100%">
<view class="jnpf-selcet-list" v-if="options.length">
<view class="jnpf-selcet-cell" v-for="item in options" :key="item.id"
@click.stop="handleNodeClick(item)">
<view class="jnpf-selcet-cell-action">
<lyCheckbox :type="multiple ? 'checkbox' : 'radio'"
:checked="selectedIds.includes(item.id)" />
</view>
<view class="jnpf-selcet-cell-name">
{{item.fullName}}
</view>
</view>
</view>
<Empty class="h-full" v-else />
</scroll-view>
</view>
<!-- 底部按钮 -->
<view class="jnpf-tree-select-actions">
<u-button class="buttom-btn" @click="close()">{{$t('common.cancelText')}}</u-button>
<u-button class="buttom-btn" type="primary"
@click.stop="handleConfirm()">{{$t('common.okText')}}</u-button>
</view>
</view>
</u-popup>
</template>
<script>
import lyCheckbox from '@/components/ly-tree/components/ly-checkbox.vue';
import Empty from '../Empty/index.vue'
export default {
components: {
lyCheckbox,
Empty
},
props: {
getOptions: {
type: Function,
},
selectedData: {
type: Array,
default: () => []
},
// 通过双向绑定控制组件的弹出与收起
modelValue: {
type: Boolean,
default: false
},
// 弹出的z-index值
zIndex: {
type: [String, Number],
default: 99999
},
multiple: {
type: Boolean,
default: false
}
},
data() {
return {
moving: false,
selectedList: [],
selectedIds: [],
keyword: '',
showPopup: false,
options: [],
cacheData: [],
};
},
watch: {
modelValue: {
handler(val) {
this.showPopup = val
if (val) setTimeout(() => this.init(), 10);
},
immediate: true
},
selectedList: {
handler(val) {
this.selectedIds = val.map((o) => o.id);
},
deep: true
},
},
computed: {
uZIndex() {
// 如果用户有传递z-index值优先使用
return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
},
},
methods: {
init() {
this.keyword = ''
this.selectedList = JSON.parse(JSON.stringify(this.selectedData))
if (this.getOptions) {
this.getOptions().then(res => {
this.options = res || []
this.cacheData = res || []
})
} else {
this.options = []
this.cacheData = []
}
},
handleNodeClick(data) {
const index = this.selectedList.findIndex((o) => o.id === data.id);
if (index !== -1) return this.selectedList.splice(index, 1);
this.multiple ? this.selectedList.push(data) : (this.selectedList = [data]);
},
handleRemove(index) {
this.selectedList.splice(index, 1);
},
removeAll() {
this.selectedList = [];
},
handleConfirm() {
this.$emit('confirm', this.selectedList, this.selectedIds);
this.close();
},
close() {
this.$emit('close');
},
handleSearch(val) {
this.options = this.cacheData.filter((o) => o.fullName.includes(val));
},
}
};
</script>