HomeLease/components/customer-service-modal/customer-service-modal.vue
2025-08-30 10:08:23 +08:00

396 lines
8.2 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>
<view v-if="visible" class="modal-overlay" @click="handleOverlayClick">
<view class="modal-container" @click.stop>
<!-- 头部 -->
<view class="modal-header">
<view class="header-content">
<view class="header-text">
<text class="title">联系客服</text>
<text class="subtitle">为您解决难题</text>
</view>
</view>
<view class="close-btn" @click="handleClose">
<text class="close-icon">×</text>
</view>
</view>
<!-- 客服信息 -->
<view class="service-section">
<text class="section-title">订单要售后:</text>
<!-- 客服列表 -->
<view class="service-list">
<view v-for="(service, index) in serviceList" :key="index" class="service-item">
<view class="service-info">
<view class="service-name">
<text class="name">{{ service.name }}</text>
<text class="phone">{{ service.contact }}</text>
</view>
<view class="work-time">
<text class="time-label">工作时间:</text>
<text class="time-value">{{ service.startTime }}~{{ service.entTime }}</text>
</view>
</view>
<view class="call-btn" @click="handleCall(service)">
<text class="call-icon">📞</text>
<text class="call-text">拨打</text>
</view>
</view>
</view>
</view>
<!-- 底部提示 -->
<view class="modal-footer">
<text class="footer-tip">客服电话高峰期可能遇忙,请耐心等待</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref, defineProps, defineEmits, onMounted } from 'vue'
import { getCustomerList } from '../../api/customer/customer'
// 定义props
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
})
// 定义emits
const emit = defineEmits(['close'])
// 响应式数据
const serviceList = ref([])
// 关闭弹窗
const handleClose = () => {
emit('close')
}
// 点击遮罩层关闭
const handleOverlayClick = () => {
handleClose()
}
// 拨打电话
const handleCall = service => {
uni.showModal({
title: '确认拨打电话',
content: `是否拨打 ${service.name} 的电话 ${service.contact}`,
success: res => {
if (res.confirm) {
// 检查当前时间是否在工作时间内
const now = new Date()
const currentTime = now.getHours() * 10000 + now.getMinutes() * 100 + now.getSeconds()
// 解析工作时间
const [startTime, endTime] = service.workTime.split('~')
const start = parseInt(startTime.replace(/:/g, ''))
const end = parseInt(endTime.replace(/:/g, ''))
if (currentTime >= start && currentTime <= end) {
// 在工作时间内,直接拨打电话
uni.makePhoneCall({
phoneNumber: service.contact,
success: () => {
console.log('拨打电话成功')
},
fail: err => {
console.error('拨打电话失败:', err)
uni.showToast({
title: '拨打电话失败',
icon: 'none',
})
},
})
} else {
// 不在工作时间内,提示用户
uni.showModal({
title: '温馨提示',
content: `${service.name} 当前不在工作时间内,是否仍要拨打?`,
success: res => {
if (res.confirm) {
uni.makePhoneCall({
phoneNumber: service.contact,
success: () => {
console.log('拨打电话成功')
},
fail: err => {
console.error('拨打电话失败:', err)
uni.showToast({
title: '拨打电话失败',
icon: 'none',
})
},
})
}
},
})
}
}
},
})
}
// 获取客服列表
const fetchCustomerList = async () => {
try {
console.log('开始获取客服列表...')
console.log('当前弹窗状态:', props.visible)
const response = await getCustomerList()
console.log('API响应:', response)
if (response && response.data) {
serviceList.value = response.data
console.log('客服列表获取成功:', serviceList.value)
} else {
console.warn('API响应中没有data字段:', response)
}
} catch (error) {
console.error('获取客服列表失败:', error)
// 隐藏加载状态
uni.hideLoading()
uni.showToast({
title: '获取客服信息失败',
icon: 'none',
})
}
}
// 组件挂载时也尝试获取一次数据
onMounted(() => {
console.log('组件挂载visible状态:', props.visible)
fetchCustomerList()
})
</script>
<style scoped>
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 9999;
animation: fadeIn 0.3s ease-out;
}
.modal-container {
width: 90%;
max-width: 600rpx;
background: linear-gradient(135deg, #f8f9ff 0%, #ffffff 100%);
border-radius: 24rpx;
box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.15);
overflow: hidden;
animation: slideUp 0.3s ease-out;
}
.modal-header {
position: relative;
padding: 40rpx 40rpx 20rpx;
background: linear-gradient(135deg, #f15a04 0%, #f15a04 100%);
}
.header-content {
display: flex;
align-items: center;
justify-content: space-between;
}
.header-text {
flex: 1;
}
.title {
display: block;
font-size: 36rpx;
font-weight: bold;
color: #ffffff;
margin-bottom: 8rpx;
}
.subtitle {
display: block;
font-size: 24rpx;
color: rgba(255, 255, 255, 0.8);
}
.robot-icon {
font-size: 40rpx;
}
.close-btn {
position: absolute;
top: 20rpx;
right: 20rpx;
width: 60rpx;
height: 60rpx;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
}
.close-icon {
font-size: 32rpx;
color: #ffffff;
font-weight: bold;
}
.service-section {
padding: 40rpx;
}
.section-title {
display: block;
font-size: 28rpx;
font-weight: bold;
color: #333333;
margin-bottom: 30rpx;
}
.service-list {
display: flex;
flex-direction: column;
gap: 24rpx;
}
.service-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 24rpx;
background: #f8f9fa;
border-radius: 16rpx;
border: 2rpx solid #e9ecef;
}
.service-info {
flex: 1;
}
.service-name {
display: flex;
align-items: center;
margin-bottom: 12rpx;
}
.name {
font-size: 28rpx;
font-weight: bold;
color: #333333;
margin-right: 16rpx;
}
.phone {
font-size: 26rpx;
color: #666666;
}
.work-time {
display: flex;
align-items: center;
}
.time-label {
font-size: 24rpx;
color: #999999;
margin-right: 8rpx;
}
.time-value {
font-size: 24rpx;
color: #666666;
}
.call-btn {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100rpx;
height: 100rpx;
background: linear-gradient(135deg, #f15a04 0%, #f15a04 100%);
border-radius: 16rpx;
box-shadow: 0 8rpx 20rpx rgba(102, 126, 234, 0.3);
}
.call-icon {
font-size: 24rpx;
margin-bottom: 4rpx;
}
.call-text {
font-size: 20rpx;
color: #ffffff;
font-weight: bold;
}
.modal-footer {
padding: 20rpx 40rpx 40rpx;
text-align: center;
}
.footer-tip {
font-size: 22rpx;
color: #999999;
line-height: 1.5;
}
/* 动画效果 */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideUp {
from {
transform: translateY(100rpx);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
/* 响应式设计 */
@media (max-width: 750rpx) {
.modal-container {
width: 95%;
margin: 0 20rpx;
}
.modal-header {
padding: 30rpx 30rpx 15rpx;
}
.service-section {
padding: 30rpx;
}
.service-item {
padding: 20rpx;
}
.call-btn {
width: 80rpx;
height: 80rpx;
}
}
</style>