consumerm模块完成度90%,完善消费者和商家端数据库表,商品、聊天、订单数据对接好了supabase,和商家端对接了聊天功能,安卓端编译通过了css样式,剩余几个页面在处理函数规范问题
This commit is contained in:
@@ -86,7 +86,7 @@
|
||||
mode="aspectFill"
|
||||
/>
|
||||
<view v-else class="message-icon-default" :style="{ backgroundColor: message.color }">
|
||||
<text>{{ message.icon }}</text>
|
||||
<text class="message-icon-text">{{ message.icon }}</text>
|
||||
</view>
|
||||
<view v-if="message.online" class="online-dot"></view>
|
||||
</view>
|
||||
@@ -202,20 +202,53 @@
|
||||
<view class="safe-area"></view>
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部固定按钮 -->
|
||||
<view class="floating-action">
|
||||
<!-- 底部固定按钮 (Hidden) -->
|
||||
<!-- <view class="floating-action">
|
||||
<button class="action-button" @click="startNewChat">
|
||||
<text class="button-icon">✏️</text>
|
||||
<text class="button-text">新建聊天</text>
|
||||
</button>
|
||||
</view>
|
||||
</view> -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { onShow } from '@dcloudio/uni-app'
|
||||
import { supabaseService, type Notification, type ChatMessage } from '@/utils/supabaseService.uts'
|
||||
import { supabaseService, type Notification, type ChatMessage, type ChatRoom } from '@/utils/supabaseService.uts'
|
||||
|
||||
// 定义消息项类型
|
||||
type MessageItem = {
|
||||
id: string,
|
||||
title: string,
|
||||
content: string,
|
||||
time: string,
|
||||
read: boolean,
|
||||
type: string,
|
||||
avatar: string | null,
|
||||
important: boolean,
|
||||
coupon: string,
|
||||
expiry: string,
|
||||
claimed: boolean,
|
||||
order_no: string,
|
||||
status: string,
|
||||
statusText: string,
|
||||
role: string,
|
||||
lastMessage: string,
|
||||
online: boolean,
|
||||
unreadCount: number,
|
||||
tags: string[],
|
||||
icon: string,
|
||||
color: string,
|
||||
active: boolean
|
||||
}
|
||||
|
||||
// 定义标签类型
|
||||
type MessageTab = {
|
||||
id: string,
|
||||
name: string,
|
||||
unread: number
|
||||
}
|
||||
|
||||
// 响应式数据
|
||||
const activeTab = ref<string>('service')
|
||||
@@ -226,33 +259,22 @@ const statusBarHeight = ref(0)
|
||||
const scrollTop = ref(0)
|
||||
const scrollHeight = ref(0)
|
||||
|
||||
// 初始化页面布局数据
|
||||
const initPage = () => {
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
statusBarHeight.value = systemInfo.statusBarHeight || 0
|
||||
|
||||
// 计算滚动区域高度:屏幕高度 - 状态栏 - 导航栏(44) - 标签栏(42)
|
||||
const windowHeight = systemInfo.windowHeight
|
||||
scrollHeight.value = windowHeight - statusBarHeight.value - 44 - 42
|
||||
}
|
||||
|
||||
// 消息分类标签
|
||||
const messageTabs = reactive([
|
||||
const messageTabs = reactive<MessageTab[]>([
|
||||
{ id: 'service', name: '客服消息', unread: 5 },
|
||||
{ id: 'system', name: '系统通知', unread: 3 },
|
||||
{ id: 'order', name: '订单消息', unread: 2 },
|
||||
{ id: 'promo', name: '优惠活动', unread: 2 }
|
||||
])
|
||||
|
||||
// Mock 客服消息数据
|
||||
const serviceMessages = reactive<any[]>([])
|
||||
const systemMessages = reactive<any[]>([])
|
||||
const orderMessages = reactive<any[]>([])
|
||||
// Mock 优惠活动数据
|
||||
const promoMessages = reactive<any[]>([])
|
||||
// 消息数据
|
||||
const serviceMessages = reactive<MessageItem[]>([])
|
||||
const systemMessages = reactive<MessageItem[]>([])
|
||||
const orderMessages = reactive<MessageItem[]>([])
|
||||
const promoMessages = reactive<MessageItem[]>([])
|
||||
|
||||
// 计算当前显示的消息
|
||||
const currentMessages = computed(() => {
|
||||
const currentMessages = computed<MessageItem[]>(() => {
|
||||
switch (activeTab.value) {
|
||||
case 'system': return systemMessages
|
||||
case 'order': return orderMessages
|
||||
@@ -262,21 +284,9 @@ const currentMessages = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
console.log('Messages Page Mounted')
|
||||
initPage()
|
||||
// loadMessages() // 移至 onShow 调用
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
console.log('Messages Page Show')
|
||||
loadMessages()
|
||||
})
|
||||
|
||||
// 简单的日期格式化
|
||||
const formatTime = (isoString: string): string => {
|
||||
if (!isoString) return ''
|
||||
if (isoString == '') return ''
|
||||
try {
|
||||
return isoString.split('T')[0]
|
||||
} catch(e) {
|
||||
@@ -284,12 +294,56 @@ const formatTime = (isoString: string): string => {
|
||||
}
|
||||
}
|
||||
|
||||
// 加载消息
|
||||
// 更新未读数量 - 必须在 loadMessages 之前定义
|
||||
const updateUnreadCount = () => {
|
||||
let totalUnread = 0
|
||||
|
||||
let serviceUnread = 0
|
||||
serviceMessages.forEach((msg: MessageItem) => {
|
||||
if (!msg.read) serviceUnread++
|
||||
})
|
||||
messageTabs[0].unread = serviceUnread
|
||||
totalUnread += serviceUnread
|
||||
|
||||
let systemUnread = 0
|
||||
systemMessages.forEach((msg: MessageItem) => {
|
||||
if (!msg.read) systemUnread++
|
||||
})
|
||||
messageTabs[1].unread = systemUnread
|
||||
totalUnread += systemUnread
|
||||
|
||||
let orderUnread = 0
|
||||
orderMessages.forEach((msg: MessageItem) => {
|
||||
if (!msg.read) orderUnread++
|
||||
})
|
||||
messageTabs[2].unread = orderUnread
|
||||
totalUnread += orderUnread
|
||||
|
||||
let promoUnread = 0
|
||||
promoMessages.forEach((msg: MessageItem) => {
|
||||
if (!msg.read) promoUnread++
|
||||
})
|
||||
messageTabs[3].unread = promoUnread
|
||||
totalUnread += promoUnread
|
||||
|
||||
unreadCount.value = totalUnread
|
||||
}
|
||||
|
||||
// 初始化页面布局数据
|
||||
const initPage = () => {
|
||||
const systemInfo = uni.getSystemInfoSync()
|
||||
statusBarHeight.value = systemInfo.statusBarHeight
|
||||
|
||||
const windowHeight = systemInfo.windowHeight
|
||||
scrollHeight.value = windowHeight - statusBarHeight.value - 44 - 42
|
||||
}
|
||||
|
||||
// 加载消息函数 - 必须在 updateUnreadCount 之后定义
|
||||
const loadMessages = async () => {
|
||||
loading.value = true
|
||||
|
||||
try {
|
||||
// 清空现有Mock数据
|
||||
// 清空现有数据
|
||||
serviceMessages.length = 0
|
||||
systemMessages.length = 0
|
||||
orderMessages.length = 0
|
||||
@@ -299,17 +353,15 @@ const loadMessages = async () => {
|
||||
const notes = await supabaseService.getUserNotifications()
|
||||
|
||||
notes.forEach((note: Notification) => {
|
||||
// 这里使用 any 类型构建对象,以匹配 reactive 数组的结构
|
||||
const item = {
|
||||
const item: MessageItem = {
|
||||
id: note.id,
|
||||
title: note.title,
|
||||
content: note.content,
|
||||
time: formatTime(note.created_at || ''),
|
||||
time: formatTime(note.created_at ?? ''),
|
||||
read: note.is_read,
|
||||
type: note.type, // 'system', 'order', 'promotion' => 'promo'
|
||||
// 默认填充字段以避免渲染报错
|
||||
type: note.type,
|
||||
avatar: note.icon_url,
|
||||
important: note.type === 'system', // 简单逻辑
|
||||
important: note.type === 'system',
|
||||
coupon: '点击查看',
|
||||
expiry: '',
|
||||
claimed: false,
|
||||
@@ -320,9 +372,10 @@ const loadMessages = async () => {
|
||||
lastMessage: '',
|
||||
online: false,
|
||||
unreadCount: 0,
|
||||
tags: [],
|
||||
tags: [] as string[],
|
||||
icon: '',
|
||||
color: ''
|
||||
color: '',
|
||||
active: false
|
||||
}
|
||||
|
||||
if (note.type === 'system') {
|
||||
@@ -330,85 +383,44 @@ const loadMessages = async () => {
|
||||
} else if (note.type === 'order') {
|
||||
orderMessages.push(item)
|
||||
} else if (note.type === 'promotion') {
|
||||
// map type 'promotion' to 'promo' for tab
|
||||
item.type = 'promo'
|
||||
promoMessages.push(item)
|
||||
}
|
||||
})
|
||||
|
||||
// 2. 获取客服消息 (Chat)
|
||||
const chats = await supabaseService.getUserChatMessages()
|
||||
// console.log('Raw chats:', chats)
|
||||
|
||||
if (chats.length > 0) {
|
||||
const currentUserId = supabaseService.getCurrentUserId()
|
||||
const conversations = new Map<string, any>()
|
||||
|
||||
// 1. Group by conversation partner
|
||||
for (const msg of chats) {
|
||||
const partnerId = (msg.sender_id == currentUserId) ? msg.receiver_id : msg.sender_id
|
||||
|
||||
// Skip if partner is null/invalid
|
||||
if (!partnerId) continue;
|
||||
|
||||
if (!conversations.has(partnerId)) {
|
||||
conversations.set(partnerId, {
|
||||
partnerId: partnerId,
|
||||
lastMessage: msg,
|
||||
unreadCount: 0
|
||||
})
|
||||
}
|
||||
|
||||
const conv = conversations.get(partnerId)
|
||||
// Since chats are likely sorted desc, the first one seen is the latest.
|
||||
// Just count unread: if I am the receiver and it's not read
|
||||
if (msg.receiver_id == currentUserId && !msg.is_read) {
|
||||
conv.unreadCount++
|
||||
}
|
||||
}
|
||||
|
||||
console.log('Conversations found:', conversations.size)
|
||||
|
||||
// 2. Fetch shop details for each conversation
|
||||
const convList = Array.from(conversations.values())
|
||||
const promises = convList.map(async (conv) => {
|
||||
const shop = await supabaseService.getShopByMerchantId(conv.partnerId)
|
||||
const shopName = shop ? shop.shop_name : '未知商家'
|
||||
const shopAvatar = (shop && shop.logo_url) ? shop.logo_url : '/static/icons/shop-default.png'
|
||||
|
||||
return {
|
||||
id: conv.partnerId, // Use partnerId as the ID for navigation
|
||||
title: shopName,
|
||||
role: '商家客服',
|
||||
content: conv.lastMessage.content,
|
||||
lastMessage: conv.lastMessage.content,
|
||||
time: formatTime(conv.lastMessage.created_at || ''),
|
||||
read: conv.unreadCount === 0,
|
||||
type: 'service',
|
||||
avatar: shopAvatar,
|
||||
online: true,
|
||||
unreadCount: conv.unreadCount,
|
||||
tags: shop ? ['官方认证'] : [],
|
||||
icon: '🏪',
|
||||
color: '#FF9800',
|
||||
important: false,
|
||||
coupon: '',
|
||||
expiry: '',
|
||||
claimed: false,
|
||||
order_no: '',
|
||||
status: '',
|
||||
statusText: ''
|
||||
}
|
||||
})
|
||||
|
||||
const renderedMessages = await Promise.all(promises)
|
||||
serviceMessages.push(...renderedMessages)
|
||||
|
||||
}
|
||||
const rooms = await supabaseService.getChatRooms()
|
||||
rooms.forEach((room: ChatRoom) => {
|
||||
const msgItem: MessageItem = {
|
||||
id: room.merchant_id,
|
||||
title: room.shop_name,
|
||||
role: '商家客服',
|
||||
content: room.last_message ?? '暂无消息',
|
||||
lastMessage: room.last_message ?? '暂无消息',
|
||||
time: formatTime(room.last_message_at ?? ''),
|
||||
read: room.unread_count === 0,
|
||||
type: 'service',
|
||||
avatar: room.shop_logo ?? '/static/icons/shop-default.png',
|
||||
online: true,
|
||||
unreadCount: room.unread_count,
|
||||
tags: [] as string[],
|
||||
icon: '🏪',
|
||||
color: '#FF9800',
|
||||
important: false,
|
||||
coupon: '',
|
||||
expiry: '',
|
||||
claimed: false,
|
||||
order_no: '',
|
||||
status: '',
|
||||
statusText: '',
|
||||
active: false
|
||||
}
|
||||
serviceMessages.push(msgItem)
|
||||
})
|
||||
|
||||
// 如果没有消息,为了演示效果(或者真的需要),可以保留一个默认的系统客服
|
||||
// 如果没有消息,添加默认客服
|
||||
if (serviceMessages.length === 0) {
|
||||
serviceMessages.push({
|
||||
const defaultService: MessageItem = {
|
||||
id: 'default_service',
|
||||
title: '平台客服',
|
||||
role: '智能助手',
|
||||
@@ -429,8 +441,10 @@ const loadMessages = async () => {
|
||||
claimed: false,
|
||||
order_no: '',
|
||||
status: '',
|
||||
statusText: ''
|
||||
})
|
||||
statusText: '',
|
||||
active: false
|
||||
}
|
||||
serviceMessages.push(defaultService)
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
@@ -441,28 +455,16 @@ const loadMessages = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 更新未读数量
|
||||
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
|
||||
}
|
||||
// 生命周期钩子
|
||||
onMounted(() => {
|
||||
console.log('Messages Page Mounted')
|
||||
initPage()
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
console.log('Messages Page Show')
|
||||
loadMessages()
|
||||
})
|
||||
|
||||
// 切换标签
|
||||
const switchTab = (tabId: string) => {
|
||||
@@ -472,7 +474,7 @@ const switchTab = (tabId: string) => {
|
||||
}
|
||||
|
||||
// 开始与客服聊天
|
||||
const startChatWithService = (message: any) => {
|
||||
const startChatWithService = (message: MessageItem) => {
|
||||
message.read = true
|
||||
message.unreadCount = 0
|
||||
updateUnreadCount()
|
||||
@@ -506,7 +508,7 @@ const startNewChat = () => {
|
||||
}
|
||||
|
||||
// 查看系统消息
|
||||
const viewSystemMessage = (message: any) => {
|
||||
const viewSystemMessage = (message: MessageItem) => {
|
||||
message.read = true
|
||||
updateUnreadCount()
|
||||
uni.navigateTo({
|
||||
@@ -515,7 +517,7 @@ const viewSystemMessage = (message: any) => {
|
||||
}
|
||||
|
||||
// 查看订单消息
|
||||
const viewOrderMessage = (message: any) => {
|
||||
const viewOrderMessage = (message: MessageItem) => {
|
||||
message.read = true
|
||||
updateUnreadCount()
|
||||
uni.navigateTo({
|
||||
@@ -524,7 +526,7 @@ const viewOrderMessage = (message: any) => {
|
||||
}
|
||||
|
||||
// 查看优惠活动
|
||||
const viewPromoMessage = (message: any) => {
|
||||
const viewPromoMessage = (message: MessageItem) => {
|
||||
message.read = true
|
||||
updateUnreadCount()
|
||||
uni.navigateTo({
|
||||
@@ -533,7 +535,7 @@ const viewPromoMessage = (message: any) => {
|
||||
}
|
||||
|
||||
// 领取优惠券
|
||||
const claimCoupon = (message: any) => {
|
||||
const claimCoupon = (message: MessageItem) => {
|
||||
if (message.claimed) {
|
||||
uni.showToast({
|
||||
title: '您已领取该优惠券',
|
||||
@@ -544,13 +546,14 @@ const claimCoupon = (message: any) => {
|
||||
|
||||
message.claimed = true
|
||||
// 保存领取状态到本地存储,供个人页读取
|
||||
const claimedCouponsCount = uni.getStorageSync('claimedCoupons') || 0
|
||||
uni.setStorageSync('claimedCoupons', (claimedCouponsCount as number) + 1)
|
||||
const claimedCouponsCount = uni.getStorageSync('claimedCoupons')
|
||||
const count = (claimedCouponsCount != null) ? (claimedCouponsCount as number) : 0
|
||||
uni.setStorageSync('claimedCoupons', count + 1)
|
||||
|
||||
// 保存详细的优惠券信息到 myCoupons 列表
|
||||
const myCoupons = uni.getStorageSync('myCoupons')
|
||||
let couponsList: any[] = []
|
||||
if (myCoupons) {
|
||||
if (myCoupons != null) {
|
||||
try {
|
||||
couponsList = JSON.parse(myCoupons as string) as any[]
|
||||
} catch (e) {
|
||||
@@ -579,15 +582,23 @@ const clearAllUnread = () => {
|
||||
content: '确定要标记所有消息为已读吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
serviceMessages.forEach(msg => {
|
||||
serviceMessages.forEach((msg: MessageItem) => {
|
||||
msg.read = true
|
||||
msg.unreadCount = 0
|
||||
})
|
||||
systemMessages.forEach(msg => msg.read = true)
|
||||
orderMessages.forEach(msg => msg.read = true)
|
||||
promoMessages.forEach(msg => msg.read = true)
|
||||
systemMessages.forEach((msg: MessageItem) => {
|
||||
msg.read = true
|
||||
})
|
||||
orderMessages.forEach((msg: MessageItem) => {
|
||||
msg.read = true
|
||||
})
|
||||
promoMessages.forEach((msg: MessageItem) => {
|
||||
msg.read = true
|
||||
})
|
||||
|
||||
messageTabs.forEach(tab => tab.unread = 0)
|
||||
messageTabs.forEach((tab: MessageTab) => {
|
||||
tab.unread = 0
|
||||
})
|
||||
unreadCount.value = 0
|
||||
|
||||
uni.showToast({
|
||||
@@ -617,7 +628,7 @@ const onRefresh = () => {
|
||||
/* 页面结构优化 - 避免双滚动条 */
|
||||
.messages-page {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
height: 100%;
|
||||
background-color: #f8fafc;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -673,7 +684,7 @@ const onRefresh = () => {
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
padding: 4px 12px;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
/* cursor: pointer; removed for uniapp-x support */
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
@@ -689,7 +700,7 @@ const onRefresh = () => {
|
||||
.action-text {
|
||||
font-size: 12px;
|
||||
color: white;
|
||||
font-weight: 500;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 导航栏占位符 */
|
||||
@@ -716,7 +727,7 @@ const onRefresh = () => {
|
||||
/* overflow-x: auto; 移除自动滚动,改为自适应宽度 */
|
||||
max-width: 1400px;
|
||||
margin: 0 auto;
|
||||
gap: 4px; /* 减小间距 */
|
||||
/* gap: 4px; removed for uniapp-x support */
|
||||
justify-content: space-between; /* 均匀分布 */
|
||||
}
|
||||
|
||||
@@ -726,6 +737,7 @@ const onRefresh = () => {
|
||||
|
||||
.tab-item {
|
||||
padding: 0 4px;
|
||||
margin: 0 2px; /* replaced gap */
|
||||
display: flex; /* 改为 flex 布局 */
|
||||
flex-direction: row; /* 关键:横向排列 文字和数字 */
|
||||
align-items: center; /* 垂直居中 */
|
||||
@@ -804,7 +816,7 @@ const onRefresh = () => {
|
||||
font-size: 12px;
|
||||
padding: 4px 10px;
|
||||
border-radius: 12px;
|
||||
font-weight: 500;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.service-status.online {
|
||||
@@ -820,9 +832,12 @@ const onRefresh = () => {
|
||||
}
|
||||
|
||||
.service-categories {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 12px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap; /* allow wrapping to simulate grid */
|
||||
/* grid-template-columns: repeat(2, 1fr); REMOVED */
|
||||
/* gap: 12px; removed for uniapp-x support */
|
||||
padding: 6px; /* compensated padding */
|
||||
}
|
||||
|
||||
.category-item {
|
||||
@@ -832,8 +847,10 @@ const onRefresh = () => {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
/* cursor: pointer; removed for uniapp-x support */
|
||||
transition: all 0.3s ease;
|
||||
margin: 1%; /* replaced gap */
|
||||
width: 48%; /* 2 columns */
|
||||
}
|
||||
|
||||
.category-item:hover {
|
||||
@@ -850,7 +867,7 @@ const onRefresh = () => {
|
||||
.category-name {
|
||||
font-size: 13px;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* 消息项 */
|
||||
@@ -867,7 +884,7 @@ const onRefresh = () => {
|
||||
align-items: flex-start;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
/* cursor: pointer; removed for uniapp-x support */
|
||||
}
|
||||
|
||||
.message-item:hover {
|
||||
@@ -906,7 +923,7 @@ const onRefresh = () => {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.message-icon-default text {
|
||||
.message-icon-text {
|
||||
font-size: 24px;
|
||||
color: white;
|
||||
}
|
||||
@@ -950,7 +967,7 @@ const onRefresh = () => {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
/* display: block; REMOVED for uniapp-x support */
|
||||
margin-bottom: 4px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
@@ -963,20 +980,21 @@ const onRefresh = () => {
|
||||
background: #E8F5E9;
|
||||
padding: 2px 8px;
|
||||
border-radius: 10px;
|
||||
display: inline-block;
|
||||
/* display: inline-block; REMOVED for uniapp-x support */
|
||||
}
|
||||
|
||||
.message-header-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
gap: 4px;
|
||||
/* gap: 4px; removed for uniapp-x support */
|
||||
}
|
||||
|
||||
.message-time {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 4px; /* replaced gap */
|
||||
}
|
||||
|
||||
.message-unread-count {
|
||||
@@ -999,21 +1017,23 @@ const onRefresh = () => {
|
||||
color: #666;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 4px;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
/* display: -webkit-box; REMOVED for uniapp-x support */
|
||||
/* -webkit-line-clamp: 2; REMOVED for uniapp-x support */
|
||||
/* -webkit-box-orient: vertical; REMOVED for uniapp-x support */
|
||||
lines: 2; /* UTS text truncation */
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis; /* Ensure standard CSS property is present */
|
||||
}
|
||||
|
||||
.last-message {
|
||||
font-size: 13px;
|
||||
color: #999;
|
||||
display: block;
|
||||
/* display: block; REMOVED for uniapp-x support */
|
||||
}
|
||||
|
||||
.message-tags {
|
||||
display: flex;
|
||||
gap: 6px;
|
||||
/* gap: 6px; removed for uniapp-x support */
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
@@ -1023,6 +1043,8 @@ const onRefresh = () => {
|
||||
background: #f0f0f0;
|
||||
padding: 3px 8px;
|
||||
border-radius: 10px;
|
||||
margin-right: 6px; /* replaced gap */
|
||||
margin-bottom: 4px; /* for wrapping */
|
||||
}
|
||||
|
||||
.order-info {
|
||||
@@ -1031,17 +1053,19 @@ const onRefresh = () => {
|
||||
background-color: #E8F5E9;
|
||||
padding: 4px 10px;
|
||||
border-radius: 4px;
|
||||
display: inline-block;
|
||||
/* display: inline-block; REMOVED for uniapp-x support */
|
||||
margin-top: 8px;
|
||||
align-self: flex-start; /* Ensure it doesn't stretch */
|
||||
}
|
||||
|
||||
.order-status {
|
||||
display: inline-block;
|
||||
/* display: inline-block; REMOVED for uniapp-x support */
|
||||
font-size: 12px;
|
||||
padding: 4px 10px;
|
||||
border-radius: 12px;
|
||||
margin-top: 8px;
|
||||
margin-left: 8px;
|
||||
align-self: flex-start; /* Ensure it doesn't stretch */
|
||||
}
|
||||
|
||||
.order-status.shipping {
|
||||
@@ -1060,13 +1084,14 @@ const onRefresh = () => {
|
||||
}
|
||||
|
||||
.important-tag {
|
||||
display: inline-block;
|
||||
/* display: inline-block; REMOVED for uniapp-x support */
|
||||
background-color: #FF5722;
|
||||
color: white;
|
||||
font-size: 11px;
|
||||
padding: 3px 8px;
|
||||
border-radius: 10px;
|
||||
margin-top: 8px;
|
||||
align-self: flex-start; /* Ensure it doesn't stretch */
|
||||
}
|
||||
|
||||
.coupon-info {
|
||||
@@ -1080,7 +1105,7 @@ const onRefresh = () => {
|
||||
.coupon-text {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
/* display: block; REMOVED for uniapp-x support */
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
@@ -1107,7 +1132,7 @@ const onRefresh = () => {
|
||||
margin: 15px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
/* gap: 10px; removed for uniapp-x support */
|
||||
}
|
||||
|
||||
.tip-icon {
|
||||
@@ -1115,6 +1140,7 @@ const onRefresh = () => {
|
||||
color: #FF9800;
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px;
|
||||
margin-right: 10px; /* replaced gap */
|
||||
}
|
||||
|
||||
.tip-text {
|
||||
@@ -1167,7 +1193,7 @@ const onRefresh = () => {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-shadow: 0 4px 12px rgba(76, 175, 80, 0.3);
|
||||
font-weight: 500;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.button-icon {
|
||||
@@ -1191,8 +1217,12 @@ const onRefresh = () => {
|
||||
}
|
||||
|
||||
.service-categories {
|
||||
grid-template-columns: 1fr;
|
||||
/* grid-template-columns: 1fr; REMOVED */
|
||||
}
|
||||
|
||||
.category-item {
|
||||
width: 100%; /* 1 column */
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 415px) {
|
||||
@@ -1206,7 +1236,7 @@ const onRefresh = () => {
|
||||
border-radius: 30px;
|
||||
}
|
||||
|
||||
.message-icon-default text {
|
||||
.message-icon-text {
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
@@ -1215,9 +1245,16 @@ const onRefresh = () => {
|
||||
}
|
||||
|
||||
.service-categories {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
/* grid-template-columns: repeat(4, 1fr); REMOVED */
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.service-categories .category-item {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
/* 平板和桌面端优化标签栏显示 */
|
||||
.message-tabs {
|
||||
justify-content: flex-start; /* 左对齐 */
|
||||
|
||||
Reference in New Issue
Block a user