1159 lines
30 KiB
Plaintext
1159 lines
30 KiB
Plaintext
<!-- pages/mall/consumer/messages.uvue -->
|
||
<template>
|
||
<view class="messages-page">
|
||
<!-- 顶部标题栏 -->
|
||
<view class="messages-header">
|
||
<text class="header-title">消息中心</text>
|
||
<view class="header-actions">
|
||
<text class="action-icon" @click="clearAllUnread">📝</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 消息分类标签 - 客服消息放在第一位 -->
|
||
<view class="message-tabs">
|
||
<view
|
||
v-for="tab in messageTabs"
|
||
:key="tab.id"
|
||
:class="['tab-item', { active: activeTab === tab.id }]"
|
||
@click="switchTab(tab.id)"
|
||
>
|
||
<text class="tab-name">{{ tab.name }}</text>
|
||
<text v-if="tab.unread > 0" class="tab-badge">{{ tab.unread }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 消息列表 -->
|
||
<scroll-view
|
||
scroll-y
|
||
class="messages-content"
|
||
refresher-enabled
|
||
:refresher-triggered="refreshing"
|
||
@refresherrefresh="onRefresh"
|
||
>
|
||
<!-- 客服消息 - 放在第一位 -->
|
||
<view v-if="activeTab === 'service'" class="message-section">
|
||
<!-- 在线客服 -->
|
||
<view class="customer-service-info">
|
||
<view class="service-header">
|
||
<text class="service-title">康乐医药在线客服</text>
|
||
<text class="service-status online">在线</text>
|
||
</view>
|
||
<text class="service-desc">专业医药顾问在线解答,服务时间 9:00-22:00</text>
|
||
|
||
<view class="service-categories">
|
||
<view class="category-item" @click="startQuickService('用药咨询')">
|
||
<text class="category-icon">💊</text>
|
||
<text class="category-name">用药咨询</text>
|
||
</view>
|
||
<view class="category-item" @click="startQuickService('处方咨询')">
|
||
<text class="category-icon">📋</text>
|
||
<text class="category-name">处方咨询</text>
|
||
</view>
|
||
<view class="category-item" @click="startQuickService('副作用咨询')">
|
||
<text class="category-icon">⚠️</text>
|
||
<text class="category-name">副作用咨询</text>
|
||
</view>
|
||
<view class="category-item" @click="startQuickService('药品配送')">
|
||
<text class="category-icon">🚚</text>
|
||
<text class="category-name">药品配送</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 客服消息列表 -->
|
||
<view
|
||
v-for="message in serviceMessages"
|
||
:key="message.id"
|
||
:class="['message-item', { unread: !message.read, active: message.active }]"
|
||
@click="startChatWithService(message)"
|
||
>
|
||
<view class="message-icon-wrapper">
|
||
<image
|
||
v-if="message.avatar"
|
||
class="message-avatar"
|
||
:src="message.avatar"
|
||
mode="aspectFill"
|
||
/>
|
||
<view v-else class="message-icon-default" :style="{ backgroundColor: message.color }">
|
||
<text>{{ message.icon }}</text>
|
||
</view>
|
||
<view v-if="message.online" class="online-dot"></view>
|
||
</view>
|
||
<view class="message-content">
|
||
<view class="message-header">
|
||
<view class="message-title-wrapper">
|
||
<text class="message-title">{{ message.title }}</text>
|
||
<text v-if="message.role" class="message-role">{{ message.role }}</text>
|
||
</view>
|
||
<view class="message-header-right">
|
||
<text class="message-time">{{ message.time }}</text>
|
||
<text v-if="message.unreadCount > 0" class="message-unread-count">{{ message.unreadCount }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="message-preview-wrapper">
|
||
<text class="message-preview">{{ message.content }}</text>
|
||
<text v-if="message.lastMessage" class="last-message">{{ message.lastMessage }}</text>
|
||
</view>
|
||
<view v-if="message.tags" class="message-tags">
|
||
<text v-for="tag in message.tags" :key="tag" class="message-tag">{{ tag }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 客服系统提示 -->
|
||
<view class="service-tips">
|
||
<text class="tip-icon">💡</text>
|
||
<text class="tip-text">温馨提示:请勿相信任何要求转账、付款的信息,谨防诈骗</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 系统通知 -->
|
||
<view v-if="activeTab === 'system'" class="message-section">
|
||
<view
|
||
v-for="message in systemMessages"
|
||
:key="message.id"
|
||
:class="['message-item', { unread: !message.read }]"
|
||
@click="viewSystemMessage(message)"
|
||
>
|
||
<view class="message-icon-wrapper">
|
||
<text class="message-icon">📢</text>
|
||
</view>
|
||
<view class="message-content">
|
||
<view class="message-header">
|
||
<text class="message-title">{{ message.title }}</text>
|
||
<text class="message-time">{{ message.time }}</text>
|
||
</view>
|
||
<text class="message-preview">{{ message.content }}</text>
|
||
<view v-if="message.important" class="important-tag">重要</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 订单消息 -->
|
||
<view v-if="activeTab === 'order'" class="message-section">
|
||
<view
|
||
v-for="message in orderMessages"
|
||
:key="message.id"
|
||
:class="['message-item', { unread: !message.read }]"
|
||
@click="viewOrderMessage(message)"
|
||
>
|
||
<view class="message-icon-wrapper">
|
||
<text class="message-icon">📦</text>
|
||
</view>
|
||
<view class="message-content">
|
||
<view class="message-header">
|
||
<text class="message-title">{{ message.title }}</text>
|
||
<text class="message-time">{{ message.time }}</text>
|
||
</view>
|
||
<text class="message-preview">{{ message.content }}</text>
|
||
<text class="order-info" v-if="message.order_no">订单号: {{ message.order_no }}</text>
|
||
<view v-if="message.status" class="order-status" :class="message.status">
|
||
{{ message.statusText }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 优惠活动 -->
|
||
<view v-if="activeTab === 'promo'" class="message-section">
|
||
<view
|
||
v-for="message in promoMessages"
|
||
:key="message.id"
|
||
:class="['message-item', { unread: !message.read }]"
|
||
@click="viewPromoMessage(message)"
|
||
>
|
||
<view class="message-icon-wrapper">
|
||
<text class="message-icon">🎁</text>
|
||
</view>
|
||
<view class="message-content">
|
||
<view class="message-header">
|
||
<text class="message-title">{{ message.title }}</text>
|
||
<text class="message-time">{{ message.time }}</text>
|
||
</view>
|
||
<text class="message-preview">{{ message.content }}</text>
|
||
<view v-if="message.coupon" class="coupon-info">
|
||
<text class="coupon-text">{{ message.coupon }}优惠券</text>
|
||
<text class="coupon-expiry">有效期至 {{ message.expiry }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 空状态 -->
|
||
<view v-if="!loading && currentMessages.length === 0 && activeTab !== 'service'" class="empty-messages">
|
||
<text class="empty-icon">💬</text>
|
||
<text class="empty-title">暂无消息</text>
|
||
<text class="empty-desc">暂时没有新消息</text>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<!-- 底部固定按钮 -->
|
||
<view class="floating-action">
|
||
<button class="action-button" @click="startNewChat">
|
||
<text class="button-icon">✏️</text>
|
||
<text class="button-text">新建聊天</text>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="uts">
|
||
import { ref, reactive, computed, onMounted } from 'vue'
|
||
|
||
// 响应式数据 - 默认显示客服消息
|
||
const activeTab = ref<string>('service')
|
||
const refreshing = ref<boolean>(false)
|
||
const loading = ref<boolean>(false)
|
||
const unreadCount = ref<number>(12)
|
||
|
||
// 消息分类标签 - 客服消息放在第一位
|
||
const messageTabs = reactive([
|
||
{ id: 'service', name: '客服消息', unread: 5 },
|
||
{ id: 'system', name: '系统通知', unread: 3 },
|
||
{ id: 'order', name: '订单消息', unread: 2 },
|
||
{ id: 'promo', name: '优惠活动', unread: 2 }
|
||
])
|
||
|
||
// Mock 客服消息数据 - 增强版
|
||
const serviceMessages = reactive([
|
||
{
|
||
id: 'service001',
|
||
title: '康乐医药在线客服',
|
||
role: '官方客服',
|
||
content: '您好,我是康乐医药在线客服,有什么可以帮助您的吗?',
|
||
lastMessage: '请问有什么药品需要咨询?',
|
||
time: '刚刚',
|
||
read: false,
|
||
type: 'service',
|
||
avatar: 'https://picsum.photos/50/50?random=service1',
|
||
online: true,
|
||
unreadCount: 3,
|
||
tags: ['在线', '专业药师'],
|
||
icon: '👨⚕️',
|
||
color: '#4CAF50'
|
||
},
|
||
{
|
||
id: 'service002',
|
||
title: '处方药咨询',
|
||
role: '药师',
|
||
content: '关于您的处方药咨询,我们已经收到,请提供处方照片。',
|
||
lastMessage: '已收到您的处方,正在审核中...',
|
||
time: '10:30',
|
||
read: true,
|
||
type: 'service',
|
||
avatar: 'https://picsum.photos/50/50?random=service2',
|
||
online: true,
|
||
unreadCount: 0,
|
||
tags: ['处方药', '审核'],
|
||
icon: '💊',
|
||
color: '#2196F3'
|
||
},
|
||
{
|
||
id: 'service003',
|
||
title: '药品配送服务',
|
||
role: '配送客服',
|
||
content: '您的订单预计今天下午送达,请保持电话畅通。',
|
||
lastMessage: '配送员正在路上,预计30分钟内送达',
|
||
time: '09:45',
|
||
read: false,
|
||
type: 'service',
|
||
avatar: 'https://picsum.photos/50/50?random=service3',
|
||
online: true,
|
||
unreadCount: 1,
|
||
tags: ['配送中', '今日达'],
|
||
icon: '🚚',
|
||
color: '#FF9800'
|
||
},
|
||
{
|
||
id: 'service004',
|
||
title: '用药指导',
|
||
role: '临床药师',
|
||
content: '关于您咨询的药品服用方法,建议饭后半小时服用。',
|
||
lastMessage: '记得按时服药,如有不适及时联系',
|
||
time: '昨天',
|
||
read: true,
|
||
type: 'service',
|
||
avatar: 'https://picsum.photos/50/50?random=service4',
|
||
online: false,
|
||
unreadCount: 0,
|
||
tags: ['用药指导', '专业'],
|
||
icon: '📋',
|
||
color: '#9C27B0'
|
||
},
|
||
{
|
||
id: 'service005',
|
||
title: '售后服务中心',
|
||
role: '售后专员',
|
||
content: '您申请的药品退换货已受理,我们会尽快处理。',
|
||
lastMessage: '退款将在3-5个工作日内退回原账户',
|
||
time: '前天',
|
||
read: false,
|
||
type: 'service',
|
||
avatar: 'https://picsum.photos/50/50?random=service5',
|
||
online: true,
|
||
unreadCount: 2,
|
||
tags: ['售后', '退换货'],
|
||
icon: '🔄',
|
||
color: '#F44336'
|
||
}
|
||
])
|
||
|
||
// Mock 系统通知数据
|
||
const systemMessages = reactive([
|
||
{
|
||
id: 'sys001',
|
||
title: '系统维护通知',
|
||
content: '平台将于今晚23:00-01:00进行系统维护,届时部分功能可能无法使用。',
|
||
time: '2023-11-23 15:30',
|
||
read: false,
|
||
type: 'system',
|
||
important: true
|
||
},
|
||
{
|
||
id: 'sys002',
|
||
title: '隐私政策更新',
|
||
content: '我们已更新隐私政策,请查阅相关条款。',
|
||
time: '2023-11-22 10:15',
|
||
read: true,
|
||
type: 'system',
|
||
important: false
|
||
},
|
||
{
|
||
id: 'sys003',
|
||
title: '账户安全提醒',
|
||
content: '检测到您的账户在异地登录,如果不是您本人操作,请及时修改密码。',
|
||
time: '2023-11-21 18:45',
|
||
read: false,
|
||
type: 'system',
|
||
important: true
|
||
}
|
||
])
|
||
|
||
// Mock 订单消息数据
|
||
const orderMessages = reactive([
|
||
{
|
||
id: 'order001',
|
||
title: '订单发货通知',
|
||
content: '您的订单202311230001已发货,点击查看物流信息。',
|
||
time: '2023-11-23 14:20',
|
||
read: false,
|
||
type: 'order',
|
||
order_no: '202311230001',
|
||
status: 'shipping',
|
||
statusText: '配送中'
|
||
},
|
||
{
|
||
id: 'order002',
|
||
title: '订单支付成功',
|
||
content: '您的订单202311220001支付成功,商家正在备货中。',
|
||
time: '2023-11-22 09:30',
|
||
read: false,
|
||
type: 'order',
|
||
order_no: '202311220001',
|
||
status: 'processing',
|
||
statusText: '处理中'
|
||
},
|
||
{
|
||
id: 'order003',
|
||
title: '订单确认收货',
|
||
content: '您的订单202311210001已完成,期待您的评价。',
|
||
time: '2023-11-21 16:15',
|
||
read: true,
|
||
type: 'order',
|
||
order_no: '202311210001',
|
||
status: 'completed',
|
||
statusText: '已完成'
|
||
}
|
||
])
|
||
|
||
// Mock 优惠活动数据
|
||
const promoMessages = reactive([
|
||
{
|
||
id: 'promo001',
|
||
title: '新人专享券',
|
||
content: '您有一张新人专享优惠券已到账,有效期3天。',
|
||
time: '2023-11-23 08:00',
|
||
read: false,
|
||
type: 'promo',
|
||
coupon: '50元',
|
||
expiry: '2023-11-26'
|
||
},
|
||
{
|
||
id: 'promo002',
|
||
title: '双11大促',
|
||
content: '双11狂欢购物节,全场满300减50。',
|
||
time: '2023-11-22 12:30',
|
||
read: true,
|
||
type: 'promo',
|
||
coupon: '满300减50',
|
||
expiry: '2023-11-30'
|
||
}
|
||
])
|
||
|
||
// 计算当前显示的消息
|
||
const currentMessages = computed(() => {
|
||
switch (activeTab.value) {
|
||
case 'system': return systemMessages
|
||
case 'order': return orderMessages
|
||
case 'service': return serviceMessages
|
||
case 'promo': return promoMessages
|
||
default: return []
|
||
}
|
||
})
|
||
|
||
// 生命周期
|
||
onMounted(() => {
|
||
loadMessages()
|
||
})
|
||
|
||
// 加载消息
|
||
const loadMessages = () => {
|
||
loading.value = true
|
||
setTimeout(() => {
|
||
// 模拟加载消息数据
|
||
updateUnreadCount()
|
||
loading.value = false
|
||
}, 800)
|
||
}
|
||
|
||
// 更新未读数量
|
||
const updateUnreadCount = () => {
|
||
let totalUnread = 0
|
||
|
||
// 计算客服消息未读
|
||
const serviceUnread = serviceMessages.filter(msg => !msg.read).length
|
||
messageTabs[0].unread = serviceUnread
|
||
totalUnread += serviceUnread
|
||
|
||
// 计算系统消息未读
|
||
const systemUnread = systemMessages.filter(msg => !msg.read).length
|
||
messageTabs[1].unread = systemUnread
|
||
totalUnread += systemUnread
|
||
|
||
// 计算订单消息未读
|
||
const orderUnread = orderMessages.filter(msg => !msg.read).length
|
||
messageTabs[2].unread = orderUnread
|
||
totalUnread += orderUnread
|
||
|
||
// 计算优惠活动未读
|
||
const promoUnread = promoMessages.filter(msg => !msg.read).length
|
||
messageTabs[3].unread = promoUnread
|
||
totalUnread += promoUnread
|
||
|
||
unreadCount.value = totalUnread
|
||
}
|
||
|
||
// 切换标签
|
||
const switchTab = (tabId: string) => {
|
||
activeTab.value = tabId
|
||
}
|
||
|
||
// 开始与客服聊天
|
||
const startChatWithService = (message: any) => {
|
||
// 标记为已读
|
||
message.read = true
|
||
message.unreadCount = 0
|
||
|
||
// 更新未读计数
|
||
updateUnreadCount()
|
||
|
||
// 跳转到聊天页面,传递客服信息
|
||
uni.navigateTo({
|
||
url: `/pages/mall/consumer/chat?id=${message.id}&name=${encodeURIComponent(message.title)}&role=${encodeURIComponent(message.role)}`
|
||
})
|
||
}
|
||
|
||
// 快速开始服务
|
||
const startQuickService = (category: string) => {
|
||
uni.navigateTo({
|
||
url: `/pages/mall/consumer/chat?category=${encodeURIComponent(category)}`
|
||
})
|
||
}
|
||
|
||
// 新建聊天
|
||
const startNewChat = () => {
|
||
uni.showActionSheet({
|
||
itemList: ['用药咨询', '处方咨询', '副作用咨询', '药品配送', '其他问题'],
|
||
success: (res) => {
|
||
const categories = ['用药咨询', '处方咨询', '副作用咨询', '药品配送', '其他问题']
|
||
const category = categories[res.tapIndex]
|
||
startQuickService(category)
|
||
}
|
||
})
|
||
}
|
||
|
||
// 查看系统消息
|
||
const viewSystemMessage = (message: any) => {
|
||
message.read = true
|
||
updateUnreadCount()
|
||
uni.navigateTo({
|
||
url: `/pages/mall/consumer/message-detail?id=${message.id}&type=system`
|
||
})
|
||
}
|
||
|
||
// 查看订单消息
|
||
const viewOrderMessage = (message: any) => {
|
||
message.read = true
|
||
updateUnreadCount()
|
||
uni.navigateTo({
|
||
url: `/pages/mall/consumer/order-detail?id=${message.order_no}`
|
||
})
|
||
}
|
||
|
||
// 查看优惠活动
|
||
const viewPromoMessage = (message: any) => {
|
||
message.read = true
|
||
updateUnreadCount()
|
||
uni.navigateTo({
|
||
url: `/pages/mall/consumer/coupons`
|
||
})
|
||
}
|
||
|
||
// 清除所有未读
|
||
const clearAllUnread = () => {
|
||
uni.showModal({
|
||
title: '确认操作',
|
||
content: '确定要标记所有消息为已读吗?',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
// 标记所有消息为已读
|
||
serviceMessages.forEach(msg => {
|
||
msg.read = true
|
||
msg.unreadCount = 0
|
||
})
|
||
systemMessages.forEach(msg => msg.read = true)
|
||
orderMessages.forEach(msg => msg.read = true)
|
||
promoMessages.forEach(msg => msg.read = true)
|
||
|
||
// 更新标签未读数
|
||
messageTabs.forEach(tab => tab.unread = 0)
|
||
unreadCount.value = 0
|
||
|
||
uni.showToast({
|
||
title: '已标记所有消息为已读',
|
||
icon: 'success'
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
// 下拉刷新
|
||
const onRefresh = () => {
|
||
refreshing.value = true
|
||
setTimeout(() => {
|
||
loadMessages()
|
||
refreshing.value = false
|
||
uni.showToast({
|
||
title: '刷新成功',
|
||
icon: 'success'
|
||
})
|
||
}, 1000)
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
.messages-page {
|
||
width: 100%;
|
||
height: 100vh;
|
||
background-color: #f8fafc;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* 头部 */
|
||
.messages-header {
|
||
background: linear-gradient(135deg, #4CAF50 0%, #2E7D32 100%);
|
||
padding: 15px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
color: white;
|
||
}
|
||
|
||
.header-title {
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
color: white;
|
||
}
|
||
|
||
.header-actions .action-icon {
|
||
font-size: 20px;
|
||
color: white;
|
||
padding: 8px;
|
||
}
|
||
|
||
/* 消息分类标签 */
|
||
.message-tabs {
|
||
background-color: white;
|
||
display: flex;
|
||
padding: 0 15px;
|
||
border-bottom: 1px solid #e0e0e0;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
||
}
|
||
|
||
.tab-item {
|
||
flex: 1;
|
||
padding: 15px 5px;
|
||
text-align: center;
|
||
position: relative;
|
||
border-bottom: 3px solid transparent;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.tab-item.active {
|
||
color: #4CAF50;
|
||
border-bottom-color: #4CAF50;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.tab-name {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.tab-badge {
|
||
position: absolute;
|
||
top: 8px;
|
||
right: 8px;
|
||
background-color: #FF5722;
|
||
color: white;
|
||
font-size: 10px;
|
||
padding: 2px 6px;
|
||
border-radius: 10px;
|
||
min-width: 16px;
|
||
text-align: center;
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* 消息内容区 */
|
||
.messages-content {
|
||
flex: 1;
|
||
padding-bottom: 80px;
|
||
}
|
||
|
||
/* 客服信息区域 */
|
||
.customer-service-info {
|
||
background: white;
|
||
border-radius: 12px;
|
||
padding: 20px;
|
||
margin: 15px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||
}
|
||
|
||
.service-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.service-title {
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.service-status {
|
||
font-size: 12px;
|
||
padding: 4px 10px;
|
||
border-radius: 12px;
|
||
font-weight: 500;
|
||
}
|
||
|
||
.service-status.online {
|
||
background: #E8F5E9;
|
||
color: #4CAF50;
|
||
}
|
||
|
||
.service-desc {
|
||
font-size: 14px;
|
||
color: #666;
|
||
line-height: 1.5;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.service-categories {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, 1fr);
|
||
gap: 12px;
|
||
}
|
||
|
||
.category-item {
|
||
background: #f8f9fa;
|
||
border-radius: 10px;
|
||
padding: 15px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
.category-item:hover {
|
||
background: #e8f5e9;
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 8px rgba(76, 175, 80, 0.2);
|
||
}
|
||
|
||
.category-icon {
|
||
font-size: 24px;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.category-name {
|
||
font-size: 13px;
|
||
color: #333;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* 消息项 */
|
||
.message-section {
|
||
padding: 10px;
|
||
}
|
||
|
||
.message-item {
|
||
background-color: white;
|
||
border-radius: 12px;
|
||
padding: 15px;
|
||
margin-bottom: 10px;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||
transition: all 0.3s ease;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.message-item:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
|
||
}
|
||
|
||
.message-item.unread {
|
||
background-color: #f0f9f0;
|
||
border-left: 3px solid #4CAF50;
|
||
}
|
||
|
||
.message-item.active {
|
||
border: 1px solid #4CAF50;
|
||
}
|
||
|
||
.message-icon-wrapper {
|
||
width: 50px;
|
||
height: 50px;
|
||
border-radius: 25px;
|
||
background-color: #f5f5f5;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 15px;
|
||
flex-shrink: 0;
|
||
position: relative;
|
||
}
|
||
|
||
.message-icon-default {
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: 25px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.message-icon-default text {
|
||
font-size: 24px;
|
||
color: white;
|
||
}
|
||
|
||
.message-avatar {
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: 25px;
|
||
}
|
||
|
||
.online-dot {
|
||
position: absolute;
|
||
bottom: 2px;
|
||
right: 2px;
|
||
width: 12px;
|
||
height: 12px;
|
||
background-color: #4CAF50;
|
||
border-radius: 6px;
|
||
border: 2px solid white;
|
||
}
|
||
|
||
.message-content {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.message-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: flex-start;
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.message-title-wrapper {
|
||
flex: 1;
|
||
min-width: 0;
|
||
margin-right: 10px;
|
||
}
|
||
|
||
.message-title {
|
||
font-size: 16px;
|
||
color: #333;
|
||
font-weight: bold;
|
||
display: block;
|
||
margin-bottom: 4px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.message-role {
|
||
font-size: 12px;
|
||
color: #4CAF50;
|
||
background: #E8F5E9;
|
||
padding: 2px 8px;
|
||
border-radius: 10px;
|
||
display: inline-block;
|
||
}
|
||
|
||
.message-header-right {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-end;
|
||
gap: 4px;
|
||
}
|
||
|
||
.message-time {
|
||
font-size: 12px;
|
||
color: #999;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.message-unread-count {
|
||
font-size: 11px;
|
||
color: white;
|
||
background: #FF5722;
|
||
padding: 2px 6px;
|
||
border-radius: 10px;
|
||
min-width: 18px;
|
||
text-align: center;
|
||
font-weight: bold;
|
||
}
|
||
|
||
.message-preview-wrapper {
|
||
margin-bottom: 8px;
|
||
}
|
||
|
||
.message-preview {
|
||
font-size: 14px;
|
||
color: #666;
|
||
line-height: 1.4;
|
||
margin-bottom: 4px;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
-webkit-box-orient: vertical;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.last-message {
|
||
font-size: 13px;
|
||
color: #999;
|
||
display: block;
|
||
}
|
||
|
||
.message-tags {
|
||
display: flex;
|
||
gap: 6px;
|
||
flex-wrap: wrap;
|
||
}
|
||
|
||
.message-tag {
|
||
font-size: 11px;
|
||
color: #666;
|
||
background: #f0f0f0;
|
||
padding: 3px 8px;
|
||
border-radius: 10px;
|
||
}
|
||
|
||
.order-info {
|
||
font-size: 12px;
|
||
color: #4CAF50;
|
||
background-color: #E8F5E9;
|
||
padding: 4px 10px;
|
||
border-radius: 4px;
|
||
display: inline-block;
|
||
margin-top: 8px;
|
||
}
|
||
|
||
.order-status {
|
||
display: inline-block;
|
||
font-size: 12px;
|
||
padding: 4px 10px;
|
||
border-radius: 12px;
|
||
margin-top: 8px;
|
||
margin-left: 8px;
|
||
}
|
||
|
||
.order-status.shipping {
|
||
background: #E3F2FD;
|
||
color: #2196F3;
|
||
}
|
||
|
||
.order-status.processing {
|
||
background: #FFF3E0;
|
||
color: #FF9800;
|
||
}
|
||
|
||
.order-status.completed {
|
||
background: #E8F5E9;
|
||
color: #4CAF50;
|
||
}
|
||
|
||
.important-tag {
|
||
display: inline-block;
|
||
background-color: #FF5722;
|
||
color: white;
|
||
font-size: 11px;
|
||
padding: 3px 8px;
|
||
border-radius: 10px;
|
||
margin-top: 8px;
|
||
}
|
||
|
||
.coupon-info {
|
||
background: linear-gradient(135deg, #FF9800, #FF5722);
|
||
border-radius: 8px;
|
||
padding: 10px;
|
||
margin-top: 8px;
|
||
color: white;
|
||
}
|
||
|
||
.coupon-text {
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
display: block;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.coupon-expiry {
|
||
font-size: 12px;
|
||
opacity: 0.9;
|
||
}
|
||
|
||
/* 客服系统提示 */
|
||
.service-tips {
|
||
background: #FFF3E0;
|
||
border-radius: 10px;
|
||
padding: 15px;
|
||
margin: 15px;
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 10px;
|
||
}
|
||
|
||
.tip-icon {
|
||
font-size: 18px;
|
||
color: #FF9800;
|
||
flex-shrink: 0;
|
||
margin-top: 2px;
|
||
}
|
||
|
||
.tip-text {
|
||
font-size: 13px;
|
||
color: #666;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
/* 空状态 */
|
||
.empty-messages {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 80px 20px;
|
||
text-align: center;
|
||
}
|
||
|
||
.empty-icon {
|
||
font-size: 80px;
|
||
color: #ddd;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.empty-title {
|
||
font-size: 18px;
|
||
color: #666;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.empty-desc {
|
||
font-size: 14px;
|
||
color: #999;
|
||
}
|
||
|
||
/* 底部浮动按钮 */
|
||
.floating-action {
|
||
position: fixed;
|
||
bottom: 20px;
|
||
right: 20px;
|
||
z-index: 100;
|
||
}
|
||
|
||
.action-button {
|
||
background: linear-gradient(135deg, #4CAF50, #2E7D32);
|
||
color: white;
|
||
border: none;
|
||
border-radius: 25px;
|
||
padding: 12px 20px;
|
||
display: flex;
|
||
align-items: center;
|
||
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
|
||
font-weight: 500;
|
||
}
|
||
|
||
.button-icon {
|
||
font-size: 18px;
|
||
margin-right: 8px;
|
||
}
|
||
|
||
.button-text {
|
||
font-size: 14px;
|
||
font-weight: bold;
|
||
}
|
||
|
||
/* 响应式适配 */
|
||
@media screen and (max-width: 320px) {
|
||
.tab-name {
|
||
font-size: 12px;
|
||
}
|
||
|
||
.message-title {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.message-preview {
|
||
font-size: 13px;
|
||
}
|
||
|
||
.service-categories {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
}
|
||
|
||
@media screen and (min-width: 415px) {
|
||
.message-item {
|
||
padding: 20px;
|
||
}
|
||
|
||
.message-icon-wrapper {
|
||
width: 60px;
|
||
height: 60px;
|
||
border-radius: 30px;
|
||
}
|
||
|
||
.message-icon-default text {
|
||
font-size: 28px;
|
||
}
|
||
|
||
.customer-service-info {
|
||
padding: 25px;
|
||
}
|
||
|
||
.service-categories {
|
||
grid-template-columns: repeat(4, 1fr);
|
||
}
|
||
}
|
||
|
||
/* 平板设备 */
|
||
@media screen and (min-width: 768px) {
|
||
.messages-header {
|
||
padding: 20px 30px;
|
||
}
|
||
|
||
.message-tabs {
|
||
padding: 0 30px;
|
||
}
|
||
|
||
.message-section {
|
||
padding: 20px 30px;
|
||
}
|
||
|
||
.customer-service-info {
|
||
margin: 20px 30px;
|
||
}
|
||
|
||
.service-tips {
|
||
margin: 20px 30px;
|
||
}
|
||
}
|
||
|
||
/* 暗黑模式适配 */
|
||
@media (prefers-color-scheme: dark) {
|
||
.messages-page {
|
||
background-color: #121212;
|
||
}
|
||
|
||
.messages-header {
|
||
background: linear-gradient(135deg, #2E7D32 0%, #1B5E20 100%);
|
||
}
|
||
|
||
.message-tabs {
|
||
background-color: #1e1e1e;
|
||
border-bottom-color: #333;
|
||
}
|
||
|
||
.tab-item.active {
|
||
color: #4CAF50;
|
||
}
|
||
|
||
.customer-service-info,
|
||
.message-item,
|
||
.service-tips {
|
||
background-color: #1e1e1e;
|
||
}
|
||
|
||
.message-item.unread {
|
||
background-color: #2d2d2d;
|
||
}
|
||
|
||
.category-item {
|
||
background: #2d2d2d;
|
||
}
|
||
|
||
.category-name {
|
||
color: #fff;
|
||
}
|
||
|
||
.service-title,
|
||
.message-title {
|
||
color: #fff;
|
||
}
|
||
|
||
.service-desc,
|
||
.message-preview,
|
||
.last-message,
|
||
.tip-text {
|
||
color: #aaa;
|
||
}
|
||
|
||
.message-icon-wrapper {
|
||
background-color: #2d2d2d;
|
||
}
|
||
|
||
.order-info {
|
||
background-color: #1b5e20;
|
||
color: #a5d6a7;
|
||
}
|
||
|
||
.coupon-info {
|
||
background: linear-gradient(135deg, #ff8f00, #ef6c00);
|
||
}
|
||
|
||
.message-tag {
|
||
background: #333;
|
||
color: #ccc;
|
||
}
|
||
}
|
||
</style> |