You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

172 lines
4.2 KiB

<template>
<van-popup :show="show" position="bottom" :style="{ width: '100%', height: '80%' }" class="bureau-popup"
@update:show="onUpdateShow">
<div class="popup-page">
<van-nav-bar title="单位查询" left-arrow @click-left="onCancel">
<template #right>
<van-icon name="cross" size="20" @click="onCancel" />
</template>
</van-nav-bar>
<div class="search-bar">
<div class="search-input-wrap">
<van-field v-model="searchKey" placeholder="请输入单位名称" clearable class="search-field" />
<van-icon name="search" class="search-icon" />
</div>
<van-button type="primary" size="small" class="confirm-btn" @click="onConfirm">确定</van-button>
</div>
<div class="bureau-list">
<div v-if="loading" class="loading-wrap">
<van-loading type="spinner" size="24" color="#2b7de9">加载中...</van-loading>
</div>
<template v-else>
<van-radio-group v-model="selected">
<div v-for="item in filteredList" :key="item.virId || item.id || item.virName"
class="bureau-row" @click="selected = item">
<van-radio :name="item" class="bureau-radio" @click.stop />
<span class="bureau-name">{{ item.virName }}</span>
</div>
</van-radio-group>
<van-empty v-if="filteredList.length === 0" description="暂无数据" />
</template>
</div>
</div>
</van-popup>
</template>
<script setup name="BureauPicker">
import { computed } from 'vue';
const props = defineProps({
show: { type: Boolean, default: false },
list: { type: Array, default: () => [] },
loading: { type: Boolean, default: false }
});
const emit = defineEmits(['update:show', 'confirm']);
const searchKey = ref('');
const selected = ref(null);
const filteredList = computed(() => {
if (!searchKey.value) return props.list;
return props.list.filter(item => (item.virName || '').includes(searchKey.value));
});
const onUpdateShow = (val) => {
emit('update:show', val);
};
const onConfirm = () => {
emit('confirm', selected.value);
emit('update:show', false);
};
const onCancel = () => {
emit('update:show', false);
};
watch(() => props.show, (val) => {
if (val) {
searchKey.value = '';
selected.value = null;
}
});
</script>
<style lang="less" scoped>
.popup-page {
display: flex;
flex-direction: column;
height: 100%;
background: #fbfdff;
}
.search-bar {
display: flex;
align-items: center;
padding: 0.2rem 0.3rem;
background: #fff;
gap: 0.2rem;
.search-input-wrap {
flex: 1;
display: flex;
align-items: center;
background: #f5f5f5;
border-radius: 0.1rem;
padding: 0 0.2rem;
height: 0.9rem;
}
.search-field {
flex: 1;
padding: 0;
background: transparent;
:deep(.van-field__control) {
font-size: 0.32rem;
color: #333;
}
}
.search-icon {
font-size: 0.4rem;
color: #999;
padding: 0 0.15rem;
}
.confirm-btn {
height: 0.9rem;
padding: 0 0.35rem;
border-radius: 0.1rem;
font-size: 0.32rem;
}
}
.bureau-list {
flex: 1;
overflow-y: auto;
padding: 0.2rem 0;
:deep(.van-cell__title) {
font-size: 0.32rem;
color: #333;
}
}
.bureau-row {
display: flex;
align-items: center;
padding: 0.25rem 0.3rem;
background: #fff;
border-bottom: 1px solid #f5f5f5;
cursor: pointer;
.bureau-radio {
margin-right: 0.2rem;
flex-shrink: 0;
}
.bureau-name {
flex: 1;
font-size: 0.32rem;
color: #333;
word-break: break-all;
}
}
.loading-wrap {
display: flex;
align-items: center;
justify-content: center;
padding: 1rem 0;
:deep(.van-loading__text) {
font-size: 0.3rem;
color: #999;
}
}
</style>