148 lines
4.9 KiB
Vue
148 lines
4.9 KiB
Vue
<template>
|
|
<view class="picker-wrap">
|
|
<view class="promoter-picker" @click="onOpen">
|
|
<view v-if="selected" class="promoter-selected">
|
|
<image v-if="selected.avatar" :src="selected.avatar" class="avatar" mode="aspectFill" />
|
|
<view v-else class="avatar placeholder">{{ (selected.nick_name || '?').charAt(0) }}</view>
|
|
<view class="meta">
|
|
<text class="name">{{ selected.nick_name || '-' }}</text>
|
|
<text class="sub">{{ selectedSubText }}</text>
|
|
</view>
|
|
</view>
|
|
<text v-else class="placeholder-text">{{ placeholder }}</text>
|
|
<u-icon v-if="!disabled" name="arrow-right" color="#c0c4cc" size="28"></u-icon>
|
|
</view>
|
|
|
|
<drawer-page-container v-model="showPopup" title="选择业务员">
|
|
<view class="search-wrap">
|
|
<u-input
|
|
v-model="searchKeyword"
|
|
placeholder="搜索姓名、业务码、手机号"
|
|
:clearable="true"
|
|
border="surround"
|
|
/>
|
|
</view>
|
|
<scroll-view scroll-y class="sheet-scroll">
|
|
<view v-if="loading" class="empty">加载中...</view>
|
|
<view v-else-if="!filteredOptions.length" class="empty">无匹配业务员</view>
|
|
<view
|
|
v-for="item in filteredOptions"
|
|
:key="item.id"
|
|
class="option-item"
|
|
@click="onPick(item)"
|
|
>
|
|
<image v-if="item.avatar" :src="item.avatar" class="avatar" mode="aspectFill" />
|
|
<view v-else class="avatar placeholder">{{ (item.nick_name || '?').charAt(0) }}</view>
|
|
<view class="meta">
|
|
<text class="name">{{ item.nick_name || '-' }}</text>
|
|
<text class="sub">{{ item.code }} · {{ item.role_name || '业务员' }}</text>
|
|
<text v-if="item.phone" class="phone">{{ item.phone }}</text>
|
|
</view>
|
|
<u-icon v-if="value === item.code" name="checkmark" color="#6acdbb" size="32"></u-icon>
|
|
</view>
|
|
</scroll-view>
|
|
</drawer-page-container>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import DrawerPageContainer from '@/subPackages/sub_salesperson/components/DrawerPageContainer.vue'
|
|
|
|
function filterPromoterOptions(keyword, list) {
|
|
const q = String(keyword || '').trim().toLowerCase()
|
|
if (!q) return list
|
|
return list.filter((item) => {
|
|
const name = (item.nick_name || '').toLowerCase()
|
|
const code = (item.code || '').toLowerCase()
|
|
const phone = (item.phone || '').toLowerCase()
|
|
const role = (item.role_name || '').toLowerCase()
|
|
return name.includes(q) || code.includes(q) || phone.includes(q) || role.includes(q)
|
|
})
|
|
}
|
|
|
|
export default {
|
|
name: 'PromoterPicker',
|
|
components: { DrawerPageContainer },
|
|
props: {
|
|
value: { type: String, default: '' },
|
|
disabled: { type: Boolean, default: false },
|
|
placeholder: { type: String, default: '请选择业务员' },
|
|
options: { type: Array, default: () => [] },
|
|
loading: { type: Boolean, default: false },
|
|
},
|
|
data() {
|
|
return {
|
|
showPopup: false,
|
|
searchKeyword: '',
|
|
}
|
|
},
|
|
computed: {
|
|
selected() {
|
|
return this.options.find((o) => o.code === this.value) || null
|
|
},
|
|
filteredOptions() {
|
|
return filterPromoterOptions(this.searchKeyword, this.options)
|
|
},
|
|
selectedSubText() {
|
|
if (!this.selected) return ''
|
|
const parts = []
|
|
if (this.selected.code) parts.push(this.selected.code)
|
|
if (this.selected.phone) parts.push(this.selected.phone)
|
|
else if (this.selected.role_name) parts.push(this.selected.role_name)
|
|
return parts.join(' · ')
|
|
},
|
|
},
|
|
methods: {
|
|
onOpen() {
|
|
if (this.disabled) return
|
|
this.searchKeyword = ''
|
|
this.showPopup = true
|
|
},
|
|
onPick(item) {
|
|
this.$emit('input', item.code)
|
|
this.$emit('change', item)
|
|
this.showPopup = false
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.picker-wrap { width: 100%; }
|
|
.promoter-picker {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
width: 100%;
|
|
min-height: 88rpx;
|
|
padding: 8rpx 0;
|
|
box-sizing: border-box;
|
|
}
|
|
.promoter-selected { display: flex; align-items: center; gap: 16rpx; flex: 1; min-width: 0; }
|
|
.avatar { width: 72rpx; height: 72rpx; border-radius: 50%; flex-shrink: 0; }
|
|
.avatar.placeholder {
|
|
background: #e8f7f4;
|
|
color: #6acdbb;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 30rpx;
|
|
font-weight: 600;
|
|
}
|
|
.meta { flex: 1; min-width: 0; }
|
|
.name { display: block; font-size: 28rpx; color: #1d2129; }
|
|
.sub { display: block; font-size: 24rpx; color: #86909c; margin-top: 6rpx; }
|
|
.phone { display: block; font-size: 22rpx; color: #86909c; margin-top: 4rpx; }
|
|
.placeholder-text { font-size: 28rpx; color: #c0c4cc; flex: 1; }
|
|
.search-wrap { padding: 0 32rpx 16rpx; }
|
|
.sheet-scroll { max-height: 55vh; padding-bottom: 24rpx; }
|
|
.option-item {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 16rpx;
|
|
padding: 24rpx 32rpx;
|
|
border-bottom: 1rpx solid #f5f5f5;
|
|
}
|
|
.empty { text-align: center; color: #86909c; padding: 80rpx 0; font-size: 28rpx; }
|
|
</style>
|