Files
xk-doctor-wx/subPackages/sub_business_shared/order/components/ExpressCompanyPicker.vue

187 lines
4.7 KiB
Vue
Raw Normal View History

2026-06-18 10:20:24 +08:00
<template>
<view class="picker-wrap">
<view class="picker-trigger" @click="openDrawer">
<text :class="selected ? 'summary-text' : 'placeholder-text'">{{ summaryText }}</text>
<text class="arrow"></text>
</view>
<drawer-page-container
v-model="showPopup"
title="选择快递公司"
:use-page-guard="false"
:show-close="true"
>
<view class="drawer-body">
<view class="search-bar">
<input
class="search-input"
v-model="keyword"
placeholder="搜索公司名称或编码"
placeholder-style="color:#BDBDBD"
confirm-type="search"
/>
</view>
<scroll-view scroll-y class="list-scroll">
<view v-if="!filteredOptions.length" class="empty">无匹配快递公司</view>
<view
v-for="item in filteredOptions"
:key="item._wxKey"
class="option-item"
@click="onPick(item)"
>
<view class="option-main">
<text class="option-name">{{ item.name || '-' }}</text>
<text class="option-code">{{ item.code || '' }}</text>
</view>
<text v-if="value === item.code" class="check"></text>
</view>
</scroll-view>
</view>
</drawer-page-container>
</view>
</template>
<script>
import DrawerPageContainer from '@/subPackages/sub_business_shared/components/DrawerPageContainer.vue'
export default {
name: 'ExpressCompanyPicker',
components: { DrawerPageContainer },
props: {
value: { type: String, default: '' },
options: { type: Array, default: () => [] },
disabled: { type: Boolean, default: false },
placeholder: { type: String, default: '请选择快递公司' },
},
data() {
return {
showPopup: false,
keyword: '',
}
},
computed: {
selected() {
const code = this.value
if (!code) return null
return this.options.find(o => o.code === code) || null
},
summaryText() {
if (!this.selected) return this.placeholder
const name = this.selected.name || '-'
const code = this.selected.code || ''
return code ? `${name}${code}` : name
},
filteredOptions() {
const kw = (this.keyword || '').trim().toLowerCase()
if (!kw) return this.options
return this.options.filter(o => {
const name = String(o.name || '').toLowerCase()
const code = String(o.code || '').toLowerCase()
return name.includes(kw) || code.includes(kw)
})
},
},
methods: {
openDrawer() {
if (this.disabled) return
this.keyword = ''
this.showPopup = true
},
onPick(item) {
this.$emit('input', item.code || '')
this.$emit('change', item)
this.showPopup = false
},
},
}
</script>
<style lang="scss" scoped>
.picker-wrap { width: 100%; }
.picker-trigger {
display: flex;
align-items: center;
justify-content: space-between;
min-height: 88rpx;
padding: 0 24rpx;
background: #F7F8FA;
border-radius: 12rpx;
box-sizing: border-box;
}
.summary-text {
flex: 1;
font-size: 28rpx;
color: #1D2129;
word-break: break-all;
}
.placeholder-text {
flex: 1;
font-size: 28rpx;
color: #BDBDBD;
}
.arrow {
font-size: 36rpx;
color: #C0C4CC;
margin-left: 12rpx;
flex-shrink: 0;
}
.drawer-body {
display: flex;
flex-direction: column;
max-height: 65vh;
}
.search-bar {
padding: 16rpx 32rpx;
flex-shrink: 0;
}
.search-input {
width: 100%;
box-sizing: border-box;
min-height: 72rpx;
height: 72rpx;
line-height: 72rpx;
padding: 0 24rpx;
background: #F7F8FA;
border-radius: 12rpx;
font-size: 28rpx;
}
.list-scroll {
flex: 1;
max-height: 52vh;
padding-bottom: 24rpx;
}
.option-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx 32rpx;
border-bottom: 1rpx solid #F2F3F5;
}
.option-main { flex: 1; min-width: 0; }
.option-name {
display: block;
font-size: 28rpx;
color: #1D2129;
font-weight: 500;
}
.option-code {
display: block;
font-size: 24rpx;
color: #86909C;
margin-top: 6rpx;
}
.check {
font-size: 32rpx;
color: #6acdbb;
font-weight: 700;
margin-left: 16rpx;
flex-shrink: 0;
}
.empty {
text-align: center;
color: #86909C;
padding: 80rpx 0;
font-size: 28rpx;
}
</style>