ykt-team-wxapp/pages/home/select-consultant-popup.vue

317 lines
6.4 KiB
Vue
Raw Permalink Normal View History

2026-01-28 13:38:05 +08:00
<template>
<uni-popup ref="popup" type="bottom" :safe-area="false" @change="handleChange">
<view class="popup-container">
<view class="popup-header">
<view class="popup-title">选择咨询人</view>
</view>
<scroll-view scroll-x class="consultant-scroll">
<view class="consultant-list">
<!-- 咨询人卡片 -->
<view
v-for="customer in customers"
:key="customer._id"
class="consultant-card"
:class="{ 'selected': selectedId === customer._id }"
@click="selectCustomer(customer)"
>
<!-- 关系标签 -->
<view v-if="customer.relationship" class="relationship-badge">
{{ customer.relationship }}
</view>
<view class="card-content">
<!-- 头像 -->
<view class="avatar-wrapper">
<image
v-if="customer.avatar"
:src="customer.avatar"
class="avatar-img"
mode="aspectFill"
/>
<view v-else class="avatar-placeholder">
<uni-icons type="person-filled" size="40" color="#1989fa" />
</view>
</view>
<!-- 用户信息 -->
<view class="user-info">
<view class="user-name">{{ customer.name || '未命名' }}</view>
<view class="user-detail">
{{ customer.sex === 1 ? '男' : customer.sex === 2 ? '女' : '' }}
{{ customer.age ? customer.age + '岁' : '' }}
</view>
</view>
</view>
<!-- 选中标记 -->
<view v-if="selectedId === customer._id" class="selected-mark">
<uni-icons type="checkmarkempty" size="18" color="#fff" />
</view>
</view>
<!-- 新建档案卡片 -->
<view class="consultant-card add-card" @click="addNewArchive">
<view class="add-content">
<uni-icons type="plusempty" size="32" color="#1989fa" />
<view class="add-text">新建档案</view>
</view>
</view>
</view>
</scroll-view>
<view class="popup-footer">
<button class="confirm-btn" @click="confirm">确定</button>
</view>
</view>
</uni-popup>
</template>
<script setup>
import { ref } from 'vue';
import { toast } from '@/utils/widget';
const props = defineProps({
customers: {
type: Array,
default: () => []
},
corpId: {
type: String,
default: ''
},
teamId: {
type: String,
default: ''
}
});
const emit = defineEmits(['confirm', 'addNew']);
const popup = ref(null);
const selectedId = ref('');
function open(defaultId) {
if (defaultId) {
selectedId.value = defaultId;
} else if (props.customers.length > 0) {
selectedId.value = props.customers[0]._id;
}
popup.value?.open();
}
function close() {
popup.value?.close();
}
function handleChange(e) {
if (!e.show) {
selectedId.value = '';
}
}
function selectCustomer(customer) {
selectedId.value = customer._id;
}
function confirm() {
if (!selectedId.value) {
toast('请选择咨询人');
return;
}
const selected = props.customers.find(c => c._id === selectedId.value);
if (selected) {
emit('confirm', selected);
close();
}
}
function addNewArchive() {
close();
emit('addNew');
}
defineExpose({
open,
close
});
</script>
<style lang="scss" scoped>
.popup-container {
background: #fff;
border-radius: 24rpx 24rpx 0 0;
max-height: 70vh;
display: flex;
flex-direction: column;
}
.popup-header {
padding: 24rpx 32rpx 20rpx;
}
.popup-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
text-align: center;
}
.consultant-scroll {
flex: 1;
white-space: nowrap;
padding: 0 32rpx 24rpx;
}
.consultant-list {
display: inline-flex;
gap: 20rpx;
}
.consultant-card {
position: relative;
display: inline-block;
width: 280rpx;
background: #f0f7ff;
border: 2rpx solid #1989fa;
border-radius: 12rpx;
padding: 16rpx;
transition: all 0.3s;
vertical-align: top;
height: 80rpx;
&.selected {
background: #e6f7ff;
border-color: #1989fa;
box-shadow: 0 4rpx 12rpx rgba(25, 137, 250, 0.2);
}
&.add-card {
border: 2rpx dashed #1989fa;
background: #fff;
display: inline-flex;
align-items: center;
justify-content: center;
}
}
.relationship-badge {
position: absolute;
top: 0;
right: 0;
padding: 8rpx 16rpx;
background: linear-gradient(135deg, #ffa726 0%, #ff9800 100%);
color: #fff;
font-size: 22rpx;
border-radius: 0 12rpx 0 12rpx;
font-weight: 600;
z-index: 2;
}
.card-content {
display: flex;
align-items: center;
gap: 16rpx;
}
.avatar-wrapper {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
overflow: hidden;
flex-shrink: 0;
}
.avatar-img {
width: 100%;
height: 100%;
}
.avatar-placeholder {
width: 100%;
height: 100%;
background: linear-gradient(135deg, #e3f2fd 0%, #bbdefb 100%);
display: flex;
align-items: center;
justify-content: center;
}
.user-info {
flex: 1;
min-width: 0;
}
.user-name {
font-size: 30rpx;
font-weight: 700;
color: #333;
margin-bottom: 6rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.user-detail {
font-size: 26rpx;
color: #666;
font-weight: 500;
}
.selected-mark {
position: absolute;
bottom: 0;
right: 0;
width: 48rpx;
height: 48rpx;
background: linear-gradient(135deg, #1989fa 0%, #0d6efd 100%);
border-radius: 12rpx 0 12rpx 0;
display: inline-flex;
align-items: center;
justify-content: center;
}
.add-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 12rpx;
}
.add-text {
font-size: 26rpx;
color: #1989fa;
font-weight: 600;
}
.popup-footer {
padding: 20rpx 32rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
border-top: 1rpx solid #f0f0f0;
}
.confirm-btn {
width: 100%;
height: 80rpx;
background: linear-gradient(135deg, #1989fa 0%, #0d6efd 100%);
color: #fff;
font-size: 32rpx;
font-weight: 700;
border-radius: 12rpx;
border: none;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx rgba(25, 137, 250, 0.3);
&::after {
border: none;
}
&:active {
opacity: 0.9;
transform: translateY(2rpx);
}
}
</style>