优化聊天:配对群组、稳定连接、消息列表与订单详情跳转
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
const app = getApp();
|
||||
import { formatDate } from '../../static/lib/utils';
|
||||
import { sendGroupMessage } from '../../utils/message-sender';
|
||||
import { showConfirmByScene } from '../../utils/scriptService.js';
|
||||
import { normalizeGroupMessage } from '../../utils/group-chat.js';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -89,33 +91,45 @@ Page({
|
||||
},*/
|
||||
|
||||
onShow() {
|
||||
this.autoConnect();
|
||||
this.ensureChatConnection();
|
||||
},
|
||||
|
||||
onHide() {
|
||||
this.clearAllListeners();
|
||||
this.clearPageListeners();
|
||||
},
|
||||
|
||||
autoConnect() {
|
||||
ensureChatConnection() {
|
||||
const role = app.globalData.currentRole || 'normal';
|
||||
const uid = wx.getStorageSync('uid');
|
||||
const prefixMap = { normal:'Boss', dashou:'Ds', shangjia:'Sj', guanshi:'Gs', zuzhang:'Zz' };
|
||||
const prefix = prefixMap[role] || 'Boss';
|
||||
const targetUserId = prefix + uid;
|
||||
const targetUserId = (prefixMap[role] || 'Boss') + uid;
|
||||
|
||||
const status = wx.goEasy.getConnectionStatus ? wx.goEasy.getConnectionStatus() : 'disconnected';
|
||||
if (status === 'connected' || status === 'reconnected') {
|
||||
const currentUserId = wx.goEasy.im ? wx.goEasy.im.userId : null;
|
||||
if (currentUserId === targetUserId) {
|
||||
this.subscribeGroupIfNeeded();
|
||||
this.setupAllListeners();
|
||||
this.loadHistory(true);
|
||||
return;
|
||||
} else {
|
||||
wx.goEasy.disconnect();
|
||||
}
|
||||
const onReady = () => {
|
||||
this.subscribeGroupIfNeeded();
|
||||
this.setupAllListeners();
|
||||
this.loadHistory(true).then(() => this.markGroupMessageAsRead());
|
||||
};
|
||||
|
||||
const status = wx.goEasy?.getConnectionStatus?.() || 'disconnected';
|
||||
const currentUserId = wx.goEasy?.im?.userId;
|
||||
|
||||
if ((status === 'connected' || status === 'reconnected') && currentUserId === targetUserId) {
|
||||
onReady();
|
||||
return;
|
||||
}
|
||||
this.connectGoEasy(targetUserId);
|
||||
|
||||
if (app.connectWithIdentity) {
|
||||
app.connectWithIdentity(role, targetUserId, true).then(onReady).catch(() => {
|
||||
const s = wx.goEasy?.getConnectionStatus?.();
|
||||
if (s === 'connected' || s === 'reconnected') onReady();
|
||||
});
|
||||
} else {
|
||||
this.connectGoEasy(targetUserId);
|
||||
}
|
||||
},
|
||||
|
||||
clearPageListeners() {
|
||||
this.clearAllListeners();
|
||||
},
|
||||
|
||||
connectGoEasy(userId) {
|
||||
@@ -130,10 +144,7 @@ Page({
|
||||
onSuccess: () => {
|
||||
this.subscribeGroupIfNeeded();
|
||||
this.setupAllListeners();
|
||||
this.loadHistory(true).then(()=>{
|
||||
this.markGroupMessageAsRead
|
||||
|
||||
});
|
||||
this.loadHistory(true).then(() => this.markGroupMessageAsRead());
|
||||
},
|
||||
onFailed: (error) => {
|
||||
if (error.code === 408) {
|
||||
@@ -213,6 +224,7 @@ Page({
|
||||
let list = res.content || [];
|
||||
list.sort((a, b) => a.timestamp - b.timestamp);
|
||||
list.forEach((m, idx) => {
|
||||
normalizeGroupMessage(m);
|
||||
m.formattedTime = formatDate(m.timestamp);
|
||||
if (idx === 0) m.showTime = true;
|
||||
else m.showTime = (m.timestamp - list[idx-1].timestamp) / 60000 > 5;
|
||||
@@ -248,6 +260,7 @@ Page({
|
||||
this._msgHandler = (msg) => {
|
||||
if (msg.groupId !== this.data.groupId) return;
|
||||
if (msg.senderId === this.data.currentUser.id) return;
|
||||
normalizeGroupMessage(msg);
|
||||
msg.formattedTime = formatDate(msg.timestamp);
|
||||
const msgs = this.data.messages;
|
||||
const last = msgs.length ? msgs[msgs.length-1] : null;
|
||||
@@ -301,8 +314,11 @@ Page({
|
||||
|
||||
sendMessage() {
|
||||
if (this.data.pendingImage) {
|
||||
this.sendImageMsg(this.data.pendingImage);
|
||||
this.setData({ pendingImage: '' });
|
||||
const file = this.data.pendingImage;
|
||||
showConfirmByScene('chat_image_confirm', () => {
|
||||
this.sendImageMsg(file);
|
||||
this.setData({ pendingImage: '' });
|
||||
});
|
||||
return;
|
||||
}
|
||||
const text = this.data.inputText.trim();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// pages/sjddxq/sjddxq.js - 商家订单详情(完整版,已添加罚款/退款操作及教程按钮)
|
||||
const app = getApp()
|
||||
import request from '../../utils/request.js'
|
||||
import connectionManager from '../../utils/xiaoxilj.js'
|
||||
import PopupService from '../../services/popupService.js' // 新增:导入弹窗服务
|
||||
|
||||
Page({
|
||||
@@ -94,55 +95,17 @@ Page({
|
||||
ensureIMConnection() {
|
||||
const uid = wx.getStorageSync('uid')
|
||||
if (!uid) return
|
||||
app.globalData.currentRole = 'shangjia'
|
||||
wx.setStorageSync('currentRole', 'shangjia')
|
||||
const targetUserId = 'Sj' + uid
|
||||
if (wx.goEasy && wx.goEasy.getConnectionStatus) {
|
||||
const status = wx.goEasy.getConnectionStatus()
|
||||
if (status === 'connected' || status === 'reconnected') {
|
||||
const currentUserId = wx.goEasy.im ? wx.goEasy.im.userId : null
|
||||
if (currentUserId === targetUserId) {
|
||||
this.setData({ currentIMUserId: targetUserId })
|
||||
return
|
||||
} else {
|
||||
wx.goEasy.disconnect()
|
||||
}
|
||||
}
|
||||
const status = wx.goEasy?.getConnectionStatus?.() || 'disconnected'
|
||||
const currentUserId = wx.goEasy?.im?.userId
|
||||
if ((status === 'connected' || status === 'reconnected') && currentUserId === targetUserId) {
|
||||
this.setData({ currentIMUserId: targetUserId })
|
||||
return
|
||||
}
|
||||
this.connectGoEasy(targetUserId)
|
||||
},
|
||||
|
||||
connectGoEasy(userId) {
|
||||
let currentUser = app.globalData.currentUser
|
||||
if (!currentUser) {
|
||||
const uid = wx.getStorageSync('uid')
|
||||
currentUser = {
|
||||
id: uid,
|
||||
name: '用户' + (uid ? uid.substring(0, 6) : ''),
|
||||
avatar: app.globalData.ossImageUrl + app.globalData.morentouxiang
|
||||
}
|
||||
}
|
||||
wx.goEasy.connect({
|
||||
id: userId,
|
||||
data: {
|
||||
name: currentUser.name,
|
||||
avatar: currentUser.avatar || (app.globalData.ossImageUrl + app.globalData.morentouxiang)
|
||||
},
|
||||
onSuccess: () => {
|
||||
this.setData({ currentIMUserId: userId })
|
||||
try {
|
||||
wx.setStorageSync('savedGoEasyConnection', JSON.stringify({
|
||||
userId, identityType: 'shangjia', lastConnectTime: Date.now()
|
||||
}))
|
||||
wx.setStorageSync('goEasyUserId', userId)
|
||||
} catch (e) {}
|
||||
},
|
||||
onFailed: (error) => {
|
||||
if (error.code === 408) {
|
||||
this.setData({ currentIMUserId: userId })
|
||||
} else {
|
||||
console.error('IM连接失败', error)
|
||||
}
|
||||
}
|
||||
})
|
||||
if (app.ensureConnection) app.ensureConnection()
|
||||
this.setData({ currentIMUserId: targetUserId })
|
||||
},
|
||||
|
||||
jiexiTiaozhuanCanshu(options) {
|
||||
@@ -265,7 +228,7 @@ Page({
|
||||
})
|
||||
},
|
||||
|
||||
// ===== 联系打手(替打手订阅 + 发机器人消息 + 跳转) =====
|
||||
// ===== 联系打手(后端准备配对群 + 稳定跳转) =====
|
||||
goToChatWithDashou() {
|
||||
const uid = wx.getStorageSync('uid')
|
||||
if (!uid) return
|
||||
@@ -276,110 +239,14 @@ Page({
|
||||
return
|
||||
}
|
||||
|
||||
const targetUserId = 'Sj' + uid
|
||||
if (this.data.currentIMUserId !== targetUserId) {
|
||||
this.ensureIMConnection()
|
||||
wx.showToast({ title: '连接中,请稍后再试', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
const that = this
|
||||
const groupName = this.data.jibenShuju.nicheng + '的订单群'
|
||||
const isCross = this.data.jibenShuju.fadanpingtai || 0
|
||||
const dashouUid = this.data.dashouInfo.yonghuid
|
||||
|
||||
// 第一步:商家自己订阅群组
|
||||
wx.goEasy.im.subscribeGroup({
|
||||
groupIds: [orderId],
|
||||
onSuccess: () => {
|
||||
// 如果有打手,则需要帮打手订阅并发送消息
|
||||
if (dashouUid) {
|
||||
that.bangDashouDingyue(orderId, dashouUid)
|
||||
.then(() => {
|
||||
that.tiaozhuanQunLiao(orderId, groupName, isCross)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('替打手订阅失败,仍可跳转群聊', err)
|
||||
wx.showToast({ title: '通知打手可能失败', icon: 'none' })
|
||||
that.tiaozhuanQunLiao(orderId, groupName, isCross)
|
||||
})
|
||||
} else {
|
||||
// 无打手,直接跳转
|
||||
that.tiaozhuanQunLiao(orderId, groupName, isCross)
|
||||
}
|
||||
},
|
||||
onFailed: (error) => {
|
||||
console.error('订阅群组失败', error)
|
||||
wx.showToast({ title: '连接群聊失败', icon: 'none' })
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 帮打手订阅群组 + 发送机器人消息
|
||||
bangDashouDingyue(orderId, dashouUid) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const dashouImId = 'Ds' + dashouUid
|
||||
const appkey = 'BC-32e2991c69bc47e1b538e73aaed37fc1' // 你的GoEasy AppKey
|
||||
const restHost = 'https://rest-hz.goeasy.io'
|
||||
|
||||
// 1. 通过 REST API 为打手订阅群组
|
||||
wx.request({
|
||||
url: restHost + '/v2/im/subscribe-groups',
|
||||
method: 'POST',
|
||||
header: { 'content-type': 'application/json' },
|
||||
data: {
|
||||
appkey: appkey,
|
||||
userIds: [dashouImId],
|
||||
groupIds: [orderId]
|
||||
},
|
||||
success: (res) => {
|
||||
if (res.data.code === 200) {
|
||||
// 2. 订阅成功后,以打手身份发送一条系统消息
|
||||
wx.request({
|
||||
url: restHost + '/v2/im/message',
|
||||
method: 'POST',
|
||||
header: { 'content-type': 'application/json' },
|
||||
data: {
|
||||
appkey: appkey,
|
||||
senderId: dashouImId,
|
||||
senderData: { name: '系统通知', avatar: '' },
|
||||
to: {
|
||||
type: 'group',
|
||||
id: orderId,
|
||||
data: { name: '订单群', avatar: '' }
|
||||
},
|
||||
type: 'text',
|
||||
payload: '此消息为系统自动发送,打手看到后会尽快回复您。'
|
||||
},
|
||||
success: (msgRes) => {
|
||||
if (msgRes.data.code === 200) {
|
||||
resolve()
|
||||
} else {
|
||||
reject(new Error('发送消息失败'))
|
||||
}
|
||||
},
|
||||
fail: reject
|
||||
})
|
||||
} else {
|
||||
reject(new Error('订阅打手失败'))
|
||||
}
|
||||
},
|
||||
fail: reject
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
// 跳转群聊页面
|
||||
tiaozhuanQunLiao(orderId, groupName, isCross) {
|
||||
const param = {
|
||||
groupId: orderId,
|
||||
orderId: orderId,
|
||||
groupName: groupName,
|
||||
groupAvatar: '',
|
||||
isCross: isCross
|
||||
}
|
||||
wx.navigateTo({
|
||||
url: '/pages/qunliaotian/qunliaotian?data=' + encodeURIComponent(JSON.stringify(param))
|
||||
connectionManager.connectToGroupChat({
|
||||
identityType: 'shangjia',
|
||||
userId: 'Sj' + uid,
|
||||
orderId,
|
||||
groupName: (this.data.dashouInfo.nicheng || this.data.jibenShuju.nicheng) + '的订单群',
|
||||
isCross: this.data.jibenShuju.fadanpingtai || 0
|
||||
}).catch(err => {
|
||||
console.error('跳转群聊失败', err)
|
||||
})
|
||||
},
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
const app = getApp();
|
||||
import { formatDate } from '../../static/lib/utils';
|
||||
const { jianquanxian } = require('../../utils/imAuth/jianquanxian');
|
||||
import { enrichGroupConversation, isOrderGroupConversation } from '../../utils/group-chat.js';
|
||||
|
||||
Page({
|
||||
data: {
|
||||
@@ -9,7 +10,7 @@ Page({
|
||||
filteredConversations: [],
|
||||
activeTab: 0,
|
||||
tabUnread: [0, 0, 0],
|
||||
displayCount: 10,
|
||||
displayCount: 4,
|
||||
searchKeyword: '',
|
||||
actionPopup: { visible: false, conversation: null },
|
||||
currentUser: null,
|
||||
@@ -81,26 +82,42 @@ Page({
|
||||
return true;
|
||||
},
|
||||
|
||||
// ========== 自动连接 ==========
|
||||
// ========== 自动连接(复用全局连接,避免反复 disconnect) ==========
|
||||
autoConnect() {
|
||||
const role = app.globalData.currentRole || 'normal';
|
||||
const uid = wx.getStorageSync('uid');
|
||||
const prefixMap = { normal: 'Boss', dashou: 'Ds', shangjia: 'Sj', guanshi: 'Gs', zuzhang: 'Zz' };
|
||||
const prefix = prefixMap[role] || 'Boss';
|
||||
const targetUserId = prefix + uid;
|
||||
const targetUserId = (prefixMap[role] || 'Boss') + uid;
|
||||
|
||||
const status = wx.goEasy.getConnectionStatus ? wx.goEasy.getConnectionStatus() : 'disconnected';
|
||||
if (status === 'connected' || status === 'reconnected') {
|
||||
const currentUserId = wx.goEasy.im ? wx.goEasy.im.userId : null;
|
||||
if (currentUserId === targetUserId) {
|
||||
this.setupConversationListener();
|
||||
this.loadConversations();
|
||||
return;
|
||||
} else {
|
||||
wx.goEasy.disconnect();
|
||||
}
|
||||
const onReady = () => {
|
||||
this.setupConversationListener();
|
||||
this.loadConversations();
|
||||
};
|
||||
|
||||
const status = wx.goEasy?.getConnectionStatus?.() || 'disconnected';
|
||||
const currentUserId = wx.goEasy?.im?.userId;
|
||||
|
||||
if ((status === 'connected' || status === 'reconnected') && currentUserId === targetUserId) {
|
||||
onReady();
|
||||
return;
|
||||
}
|
||||
this.connectGoEasy(targetUserId);
|
||||
|
||||
if (currentUserId && currentUserId !== targetUserId && app.disconnectGoEasy) {
|
||||
app.disconnectGoEasy().then(() => {
|
||||
app.connectWithIdentity(role, targetUserId, true).then(onReady).catch(() => {});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!app.connectWithIdentity) {
|
||||
this.connectGoEasy(targetUserId);
|
||||
return;
|
||||
}
|
||||
|
||||
app.connectWithIdentity(role, targetUserId, true).then(onReady).catch(() => {
|
||||
const s = wx.goEasy?.getConnectionStatus?.();
|
||||
if (s === 'connected' || s === 'reconnected') onReady();
|
||||
});
|
||||
},
|
||||
|
||||
connectGoEasy(userId) {
|
||||
@@ -168,12 +185,27 @@ Page({
|
||||
}
|
||||
let list = content.conversations;
|
||||
const defaultAvatar = app.globalData.ossImageUrl + app.globalData.morentouxiang;
|
||||
const myGoEasyId = wx.goEasy?.im?.userId || '';
|
||||
const ossBase = app.globalData.ossImageUrl || '';
|
||||
const groupMeta = app.globalData.groupInfoMap || {};
|
||||
|
||||
list.forEach(item => {
|
||||
if (item.data && item.data.avatar) {
|
||||
if (!item.data.avatar.startsWith('http')) {
|
||||
item.data.avatar = app.globalData.ossImageUrl + item.data.avatar;
|
||||
if (item.type === 'group') {
|
||||
const meta = groupMeta[item.groupId];
|
||||
if (meta) {
|
||||
if (!item.data) item.data = {};
|
||||
if (meta.name) item.data.name = meta.name;
|
||||
if (meta.avatar) item.data.avatar = meta.avatar;
|
||||
if (meta.orderDesc) item.data.orderDesc = meta.orderDesc;
|
||||
if (meta.orderId) item.data.orderId = meta.orderId;
|
||||
if (meta.orderZhuangtai != null) item.data.orderZhuangtai = meta.orderZhuangtai;
|
||||
}
|
||||
} else {
|
||||
enrichGroupConversation(item, myGoEasyId, defaultAvatar, ossBase);
|
||||
} else if (item.data && item.data.avatar) {
|
||||
if (!item.data.avatar.startsWith('http')) {
|
||||
item.data.avatar = ossBase + item.data.avatar;
|
||||
}
|
||||
} else if (item.data) {
|
||||
item.data.avatar = defaultAvatar;
|
||||
}
|
||||
if (item.lastMessage && item.lastMessage.timestamp) {
|
||||
@@ -189,7 +221,7 @@ Page({
|
||||
return (b.lastMessage.timestamp || 0) - (a.lastMessage.timestamp || 0);
|
||||
});
|
||||
|
||||
this.setData({ allConversations: list, displayCount: 10 }, () => {
|
||||
this.setData({ allConversations: list, displayCount: 4 }, () => {
|
||||
this.applyFilter();
|
||||
});
|
||||
|
||||
@@ -234,7 +266,7 @@ Page({
|
||||
const { allConversations, activeTab, searchKeyword } = this.data;
|
||||
let filtered = [];
|
||||
if (activeTab === 0) {
|
||||
filtered = allConversations.filter(c => c.type === 'group' && c.data && c.data.orderId);
|
||||
filtered = allConversations.filter(c => isOrderGroupConversation(c));
|
||||
} else if (activeTab === 1) {
|
||||
filtered = allConversations.filter(c => c.type === 'private');
|
||||
} else if (activeTab === 2) {
|
||||
@@ -253,7 +285,7 @@ Page({
|
||||
|
||||
const tabUnread = [0, 0, 0];
|
||||
allConversations.forEach(c => {
|
||||
if (c.type === 'group' && c.data && c.data.orderId) tabUnread[0] += c.unread || 0;
|
||||
if (isOrderGroupConversation(c)) tabUnread[0] += c.unread || 0;
|
||||
else if (c.type === 'private') tabUnread[1] += c.unread || 0;
|
||||
else if (c.type === 'cs') tabUnread[2] += c.unread || 0;
|
||||
});
|
||||
@@ -263,17 +295,17 @@ Page({
|
||||
|
||||
switchTab(e) {
|
||||
const index = parseInt(e.currentTarget.dataset.index);
|
||||
this.setData({ activeTab: index, displayCount: 10, searchKeyword: '' }, () => this.applyFilter());
|
||||
this.setData({ activeTab: index, displayCount: 4, searchKeyword: '' }, () => this.applyFilter());
|
||||
},
|
||||
|
||||
onSearchInput(e) {
|
||||
this.setData({ searchKeyword: e.detail.value, displayCount: 10 }, () => this.applyFilter());
|
||||
this.setData({ searchKeyword: e.detail.value, displayCount: 4 }, () => this.applyFilter());
|
||||
},
|
||||
|
||||
onScrollToLower() {
|
||||
const { displayCount, filteredConversations } = this.data;
|
||||
if (displayCount < filteredConversations.length) {
|
||||
this.setData({ displayCount: Math.min(displayCount + 10, filteredConversations.length) });
|
||||
this.setData({ displayCount: Math.min(displayCount + 4, filteredConversations.length) });
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -29,14 +29,25 @@
|
||||
<!-- 会话列表 (上拉加载更多) -->
|
||||
<scroll-view class="conversation-list" scroll-y="true" bindscrolltolower="onScrollToLower" style="height: {{scrollHeight}}px">
|
||||
<block wx:for="{{filteredConversations}}" wx:key="key" wx:for-index="i" wx:if="{{i < displayCount}}">
|
||||
<view class="conversation-item {{item.unread > 0 ? 'has-unread' : ''}}" data-conversation="{{item}}" bindtap="chat" bindlongpress="showAction">
|
||||
<image class="avatar" src="{{item.data.avatar}}" mode="aspectFill" />
|
||||
<view class="conversation-item {{item.unread > 0 ? 'has-unread' : ''}} {{item.type === 'group' ? 'order-group-item' : ''}}" data-conversation="{{item}}" bindtap="chat" bindlongpress="showAction">
|
||||
<image class="avatar {{item.type === 'group' ? 'avatar-round' : ''}}" src="{{item.data.avatar}}" mode="aspectFill" />
|
||||
<view class="info">
|
||||
<view class="top-line">
|
||||
<text class="name">{{item.data.name}}</text>
|
||||
<text class="time">{{item.lastMessage.date}}</text>
|
||||
</view>
|
||||
<view class="bottom-line">
|
||||
<block wx:if="{{item.type === 'group'}}">
|
||||
<view class="order-block" wx:if="{{item.data.orderId || item.data.orderDesc}}">
|
||||
<text class="order-id" wx:if="{{item.data.orderId}}">单号 {{item.data.orderId}}</text>
|
||||
<text class="order-desc" wx:if="{{item.data.orderDesc}}">{{item.data.orderDesc}}</text>
|
||||
<text class="order-status" wx:if="{{item.data.orderZhuangtaiText}}">{{item.data.orderZhuangtaiText}}</text>
|
||||
</view>
|
||||
<view class="bottom-line">
|
||||
<text class="last-msg">{{item.displayLastMsg || item.lastMessage.payload.text}}</text>
|
||||
<view class="unread-dot" wx:if="{{item.unread > 0}}">{{item.unread > 99 ? '99+' : item.unread}}</view>
|
||||
</view>
|
||||
</block>
|
||||
<view class="bottom-line" wx:else>
|
||||
<text class="last-msg">{{item.lastMessage.type === 'text' ? item.lastMessage.payload.text : '[其他消息]'}}</text>
|
||||
<view class="unread-dot" wx:if="{{item.unread > 0}}">{{item.unread > 99 ? '99+' : item.unread}}</view>
|
||||
</view>
|
||||
|
||||
@@ -14,13 +14,19 @@
|
||||
.tab-badge { background: #fa5151; color: #fff; font-size: 20rpx; border-radius: 20rpx; padding: 2rpx 12rpx; margin-left: 8rpx; min-width: 32rpx; text-align: center; }
|
||||
|
||||
.conversation-list { background: #fff; }
|
||||
.conversation-item { display: flex; align-items: center; padding: 20rpx 24rpx; border-bottom: 1rpx solid #f0f0f0; }
|
||||
.conversation-item { display: flex; align-items: flex-start; padding: 24rpx 24rpx; border-bottom: 1rpx solid #f0f0f0; }
|
||||
.order-group-item { min-height: 160rpx; padding: 28rpx 24rpx; }
|
||||
.has-unread { background: #fafafa; }
|
||||
.avatar { width: 96rpx; height: 96rpx; border-radius: 12rpx; margin-right: 20rpx; background: #eee; }
|
||||
.info { flex: 1; }
|
||||
.avatar { width: 96rpx; height: 96rpx; border-radius: 12rpx; margin-right: 20rpx; background: #eee; flex-shrink: 0; }
|
||||
.avatar-round { border-radius: 50%; }
|
||||
.info { flex: 1; min-width: 0; }
|
||||
.top-line { display: flex; justify-content: space-between; margin-bottom: 8rpx; }
|
||||
.name { font-size: 30rpx; color: #1a1a1a; font-weight: 500; }
|
||||
.time { font-size: 22rpx; color: #999; }
|
||||
.time { font-size: 22rpx; color: #999; flex-shrink: 0; margin-left: 12rpx; }
|
||||
.order-block { background: #f7f8fa; border-radius: 12rpx; padding: 16rpx 18rpx; margin-bottom: 10rpx; }
|
||||
.order-id { display: block; font-size: 24rpx; color: #576b95; margin-bottom: 6rpx; }
|
||||
.order-desc { display: block; font-size: 26rpx; color: #333; line-height: 1.5; word-break: break-all; }
|
||||
.order-status { display: inline-block; font-size: 22rpx; color: #07c160; margin-top: 8rpx; padding: 2rpx 12rpx; background: #e8f8ef; border-radius: 8rpx; }
|
||||
.bottom-line { display: flex; justify-content: space-between; align-items: center; }
|
||||
.last-msg { font-size: 26rpx; color: #888; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
.unread-dot { background: #fa5151; color: #fff; font-size: 20rpx; border-radius: 50%; min-width: 36rpx; height: 36rpx; line-height: 36rpx; text-align: center; margin-left: 12rpx; }
|
||||
|
||||
Reference in New Issue
Block a user