diff --git a/App.vue b/App.vue
index 19fd7d9..db0586e 100644
--- a/App.vue
+++ b/App.vue
@@ -3,6 +3,7 @@
getVersion
} from './request/api/api'
import { webSocketManager } from '@/utils/ws/websocket.js';
+ import { ChatManager } from '@/store/chat/chat.js';
import {checkDev} from "@/utils/utils";
import {bindUserApi} from "@/request/api/salesperson";
export default {
@@ -151,7 +152,76 @@
methods: {
initWebSocket() {
webSocketManager.connect();
+
+ // 注册全局消息处理器
+ webSocketManager.addMessageHandler((data) => {
+ // 只处理聊天消息(包含 room_id 的消息)
+ if (data.room_id) {
+ // 获取当前页面路径
+ const pages = getCurrentPages();
+ const currentPage = pages[pages.length - 1];
+ const currentPath = currentPage ? currentPage.route : '';
+
+ // 如果用户在聊天页面,不调用 ChatManager(chat.vue 会自己处理)
+ // 避免消息重复推送
+ if (currentPath && currentPath.includes('chat/chat')) {
+ return;
+ }
+
+ ChatManager.handleIncomingMessage(data);
+ }
+ });
+
+ // 监听全局通知事件
+ uni.$on('show-global-notification', this.handleShowNotification);
+ },
+
+ /**
+ * 处理显示通知
+ * @param {Object} message 消息对象
+ */
+ handleShowNotification(message) {
+ // 获取当前页面路径
+ const pages = getCurrentPages();
+ const currentPage = pages[pages.length - 1];
+ const currentPath = currentPage ? currentPage.route : '';
+
+ // 如果在聊天页面,不显示顶部通知
+ if (currentPath && currentPath.includes('chat/chat')) {
+ return;
+ }
+
+ // 获取消息预览文本
+ const messagePreview = ChatManager.getMessagePreview(message);
+
+ // 从消息中提取发送者信息
+ let senderName = '新消息';
+ let senderAvatar = '/static/xx/ysxx.png';
+
+ // 尝试解析发送者ID获取更多信息
+ const senderId = message.sender_user_id || '';
+ if (senderId.startsWith('doctor-')) {
+ senderName = '医生消息';
+ }
+
+ // 触发通知组件显示
+ uni.$emit('show-message-notification', {
+ avatar: senderAvatar,
+ title: senderName,
+ message: messagePreview,
+ roomId: message.room_id,
+ roomData: {
+ nick_name: senderName,
+ user_id: senderId,
+ avatar: senderAvatar
+ }
+ });
}
+ },
+
+ onUnload() {
+ // 移除全局通知事件监听
+ uni.$off('show-global-notification', this.handleShowNotification);
}
}
diff --git a/components/MessageNotification/MessageNotification.vue b/components/MessageNotification/MessageNotification.vue
new file mode 100644
index 0000000..6850026
--- /dev/null
+++ b/components/MessageNotification/MessageNotification.vue
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+
+
+ {{ title || '新消息' }}
+ {{ displayMessage }}
+
+
+
+
+ ×
+
+
+
+
+
+
+
+
+
diff --git a/pages.json b/pages.json
index a211a95..52fa7b5 100644
--- a/pages.json
+++ b/pages.json
@@ -3,7 +3,9 @@
// 下载安装方式
// "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
// npm安装方式
- "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
+ "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue",
+ // 消息通知组件
+ "^MessageNotification": "@/components/MessageNotification/MessageNotification.vue"
},
"pages": [
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
diff --git a/pages/Inquiries/Inquiries.vue b/pages/Inquiries/Inquiries.vue
index 1ff888b..2846338 100644
--- a/pages/Inquiries/Inquiries.vue
+++ b/pages/Inquiries/Inquiries.vue
@@ -1,5 +1,6 @@
+
+
+
diff --git a/pages/home/home.vue b/pages/home/home.vue
index 2368205..5c890fe 100644
--- a/pages/home/home.vue
+++ b/pages/home/home.vue
@@ -1,5 +1,8 @@
+
+
+
-
+
在线复诊
在线选药 极速达
@@ -208,8 +211,12 @@ import {
import { getPlatformQualificationsApi } from '../../request/api/platform'
import { getStoreDrugListBySalespersonApi, getHomeTopProductsApi, getHomeZonesApi, checkOnlineConsultationConfigApi } from "@/request/api/product";
import request from "@/request/api/request";
+import MessageNotification from "@/components/MessageNotification/MessageNotification.vue";
export default {
+ components: {
+ MessageNotification
+ },
data() {
return {
storeId: 0,
@@ -293,27 +300,10 @@ export default {
},
async golist(type) {
if (type === 3) {
- try {
- const storeId = uni.getStorageSync('store_id');
- const res = await checkOnlineConsultationConfigApi({ store_id: storeId });
- if (!res.data?.result?.can_use) {
- uni.showToast({
- title: res.data?.result?.message || '该药店暂不支持在线复诊功能',
- icon: 'none',
- duration: 2000
- });
- return;
- }
- const doctorId = res.data.result.doctor_id || this.defaultDoctorId;
- const delegateStoreId = res.data.result.delegate_store_id || storeId;
- return uni.navigateTo({
- url: '/subPackages/product/product?doctor_id=' + doctorId + '®ister_type=3&delegate_store_id=' + delegateStoreId
- });
- } catch (error) {
- console.error('检查在线复诊配置失败:', error);
- uni.showToast({ title: '网络异常,请稍后重试', icon: 'none' });
- return;
- }
+ // 药店模式直接进入商品页,不检查配置
+ return uni.navigateTo({
+ url: '/subPackages/product/product?register_type=3'
+ });
}
uni.navigateTo({
url: '/pages/Inquiries/Inquiries?type=' + type
@@ -365,6 +355,7 @@ export default {
}).then((res) => {
if (res.data.errcode == 0) {
this.storeType = res.data.data.store['type']
+ uni.setStorageSync('store_type', res.data.data.store['type']) // 存储门店类型
this.infoList = res.data.data
this.headerTitle = res.data.data.store['name']
this.getBannered();
@@ -669,19 +660,18 @@ $card-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.04);
/* --- 5. 药品卡片 (双列瀑布流) --- */
.product-list-container {
- padding: 0 20rpx; /* 减小左右边距 */
+ padding: 0 24rpx; /* 左右边距 */
display: flex;
flex-wrap: wrap;
- justify-content: space-between;
+ gap: 16rpx; /* 卡片间隙 */
}
.product-card {
background: #fff;
- /* 动态计算宽度,保留中间20rpx间隙 (750 - 20*2 - 20) / 2 = 345rpx */
- width: calc((100% - 20rpx) / 2);
- margin-bottom: 24rpx;
+ /* 动态计算宽度,保留中间16rpx间隙 */
+ width: calc((100% - 16rpx) / 2);
padding: 0;
- border-radius: $card-radius;
+ border-radius: 16rpx;
display: flex;
flex-direction: column;
box-shadow: $card-shadow;
@@ -690,7 +680,7 @@ $card-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.04);
.prod-img-box {
width: 100%;
- height: 345rpx; /* 保持正方形 */
+ height: 280rpx; /* 缩小图片高度:原345rpx,减小约19% */
background: #f8f8f8;
border-radius: 0;
margin: 0;
@@ -698,21 +688,21 @@ $card-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.04);
align-items: center;
justify-content: center;
- .prod-img { width: 100%; height: 100%; border-radius: 0; &.prescription-blur { filter: blur(4px); } }
+ .prod-img { width: 100%; height: 100%; border-radius: 0; /* &.prescription-blur { filter: blur(4px); } 暂时禁用模糊 */ }
}
.prod-info {
flex: 1;
display: flex; flex-direction: column; justify-content: space-between;
- padding: 16rpx;
+ padding: 12rpx; /* 减小内边距:原16rpx */
.prod-title {
- font-size: 28rpx;
+ font-size: 26rpx; /* 减小字号:原28rpx */
font-weight: 600;
color: #333;
line-height: 1.4;
- margin-bottom: 12rpx;
- height: 80rpx; /* 限制两行高度 */
+ margin-bottom: 8rpx;
+ height: 72rpx; /* 减小高度:原80rpx */
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
@@ -720,19 +710,19 @@ $card-shadow: 0 8rpx 20rpx rgba(0, 0, 0, 0.04);
-webkit-box-orient: vertical;
}
- .tag-row { display: flex; margin-bottom: 12rpx; .otc-tag { font-size: 18rpx; padding: 0rpx 6rpx; border-radius: 4rpx; font-weight: 700; border: 1rpx solid transparent; &.otc-green { color: $secondary-color; background: #E6F7F0; border-color: #A3E6CD; } &.otc-red { color: #FF4D4F; background: #FFF0F0; border-color: #FFCDCD; } } }
- .prod-spec { font-size: 20rpx; color: #999; margin-bottom: 16rpx;}
+ .tag-row { display: flex; margin-bottom: 8rpx; .otc-tag { font-size: 18rpx; padding: 0rpx 6rpx; border-radius: 4rpx; font-weight: 700; border: 1rpx solid transparent; &.otc-green { color: $secondary-color; background: #E6F7F0; border-color: #A3E6CD; } &.otc-red { color: #FF4D4F; background: #FFF0F0; border-color: #FFCDCD; } } }
+ .prod-spec { font-size: 18rpx; color: #999; margin-bottom: 12rpx;} /* 减小字号:原20rpx */
.prod-bottom {
display: flex; justify-content: space-between; align-items: flex-end;
- .price-box { color: #FF4D4F; font-weight: 800; font-size: 34rpx; .price-symbol { font-size: 22rpx; margin-right: 2rpx; } }
- .buy-btn { background: linear-gradient(135deg, #4175EE 0%, #298DFF 100%); color: #fff; width: 56rpx; height: 56rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 4rpx 12rpx rgba(65, 117, 238, 0.3); }
+ .price-box { color: #FF4D4F; font-weight: 800; font-size: 30rpx; .price-symbol { font-size: 20rpx; margin-right: 2rpx; } } /* 减小字号:原34rpx/22rpx */
+ .buy-btn { background: linear-gradient(135deg, #4175EE 0%, #298DFF 100%); color: #fff; width: 52rpx; height: 52rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: 0 4rpx 12rpx rgba(65, 117, 238, 0.3); } /* 减小尺寸:原56rpx */
}
}
}
.qualifications-section {
- padding: 0 32rpx 40rpx;
+ padding: 40rpx 32rpx 40rpx;
.qualifications-row {
display: flex;
flex-wrap: wrap;
diff --git a/pages/home/index-list.vue b/pages/home/index-list.vue
index 8f171b8..5c7d5df 100644
--- a/pages/home/index-list.vue
+++ b/pages/home/index-list.vue
@@ -1,5 +1,6 @@
+
+
diff --git a/pages/index/doctor-info.vue b/pages/index/doctor-info.vue
index 501f6d4..d6959e2 100644
--- a/pages/index/doctor-info.vue
+++ b/pages/index/doctor-info.vue
@@ -1,5 +1,6 @@
+
diff --git a/pages/index/index.vue b/pages/index/index.vue
index 2efa551..2f80f77 100644
--- a/pages/index/index.vue
+++ b/pages/index/index.vue
@@ -1,5 +1,8 @@
+
+
+
全部消息
@@ -155,8 +158,12 @@ import {
import {getSystemNoticeIndexApi} from '../../request/api/systemNotice'
import {getChatFriendsListApi} from "@/request/api/im";
import {checkDev} from "@/utils/utils";
+import MessageNotification from "@/components/MessageNotification/MessageNotification.vue";
export default {
+ components: {
+ MessageNotification
+ },
data() {
return {
order: [],
@@ -169,10 +176,25 @@ export default {
}
},
onLoad() {
-
+ // 监听聊天列表更新事件
+ uni.$on('chat-list-update', this.handleChatListUpdate);
+ },
+
+ onUnload() {
+ // 移除事件监听
+ uni.$off('chat-list-update', this.handleChatListUpdate);
},
methods: {
checkDev,
+
+ /**
+ * 处理聊天列表更新事件
+ * 收到新消息时自动刷新列表
+ */
+ handleChatListUpdate() {
+ this.getMyChatFriendsList();
+ },
+
// 清除未读信息
getClearInfo() {
getseesionRead({
@@ -237,11 +259,8 @@ export default {
})
},
goChat(item, index) {
- console.log(this.imChat, 'ssssssssss')
- console.log(item, 'ssssssssss')
- console.log(index, 'ssssssssss')
uni.navigateTo({
- url: `/subPackages/chat/chat?room_id=${item.room_id}&nick_name=${item.nick_name}&user_id=${item.id}&avatar=${item.avatar}`
+ url: `/subPackages/chat/chat?room_id=${item.room_id}&nick_name=${item.nick_name}&user_id=${item.id}&avatar=${encodeURIComponent(item.avatar || '')}&room_status=${item.room_status || 0}`
})
// getseesionRead({
// method: "post",
diff --git a/pages/index/order-info.vue b/pages/index/order-info.vue
index 06af653..b1babc8 100644
--- a/pages/index/order-info.vue
+++ b/pages/index/order-info.vue
@@ -1,5 +1,6 @@
+
diff --git a/pages/index/platform-info.vue b/pages/index/platform-info.vue
index f4d898e..a554f9d 100644
--- a/pages/index/platform-info.vue
+++ b/pages/index/platform-info.vue
@@ -1,5 +1,6 @@
+
{{ storeName || (isPlatform ? '萧康云医' : '店铺') }} - 资质证明
diff --git a/pages/index/system.vue b/pages/index/system.vue
index d8e1c1f..004efbf 100644
--- a/pages/index/system.vue
+++ b/pages/index/system.vue
@@ -1,5 +1,6 @@
+
diff --git a/pages/login/login.vue b/pages/login/login.vue
index d2c967c..836dc2e 100644
--- a/pages/login/login.vue
+++ b/pages/login/login.vue
@@ -1,5 +1,6 @@
+
diff --git a/pages/login/logon.vue b/pages/login/logon.vue
index a97b13a..f4598b3 100644
--- a/pages/login/logon.vue
+++ b/pages/login/logon.vue
@@ -1,5 +1,6 @@
+
欢迎注册新账号
diff --git a/pages/mine/mine.vue b/pages/mine/mine.vue
index 4c96440..2036821 100644
--- a/pages/mine/mine.vue
+++ b/pages/mine/mine.vue
@@ -1,5 +1,6 @@
+
diff --git a/request/api/im.js b/request/api/im.js
index 628d282..83cdad4 100644
--- a/request/api/im.js
+++ b/request/api/im.js
@@ -69,4 +69,13 @@ export function upLoadChatFileApi(params) {
*/
export async function getDoctorInfoApi(params) {
return await get('/chat-friends/get-doctor-info', params, 3)
+}
+
+/**
+ * 获取房间状态
+ * @param params { room_id: string }
+ * @returns {Promise<*>}
+ */
+export async function getRoomStatusApi(params) {
+ return await get('/chat-friends/get-room-status', params, 3)
}
\ No newline at end of file
diff --git a/request/api/product.js b/request/api/product.js
index bb65726..bf2a934 100644
--- a/request/api/product.js
+++ b/request/api/product.js
@@ -56,4 +56,13 @@ export async function updateIntroductionImagesApi(params) {
*/
export async function checkOnlineConsultationConfigApi(params) {
return await get('/store/check-online-consultation-config', params, 3)
+}
+
+/**
+ * 获取药品分类列表
+ * @param params { zone_type: string }
+ * @returns {Promise<*>}
+ */
+export async function getDrugCategoriesApi(params) {
+ return await get('/product/drug-categories', params, 3)
}
\ No newline at end of file
diff --git a/store/chat/chat.js b/store/chat/chat.js
index a3fcbe2..14beae7 100644
--- a/store/chat/chat.js
+++ b/store/chat/chat.js
@@ -23,7 +23,6 @@ const ChatManager = {
enterRoom(roomId) {
this.currentRoomId = roomId;
uni.setStorageSync('currentRoomId', roomId);
- console.log(`进入房间`);
// 重置当前房间的未读消息
this.resetUnreadCount(roomId);
},
@@ -32,7 +31,6 @@ const ChatManager = {
leaveRoom() {
this.currentRoomId = null;
uni.removeStorageSync('currentRoomId');
- console.log('离开当前房间');
},
// 获取当前房间ID
@@ -46,7 +44,6 @@ const ChatManager = {
if (this.getCurrentRoomId() !== roomId) {
this.unreadCounts[roomId] = (this.unreadCounts[roomId] || 0) + 1;
this.notifyUnreadChange();
- console.log(`房间 ${roomId} 未读消息 +1, 当前: ${this.unreadCounts[roomId]}`);
}
},
@@ -55,7 +52,6 @@ const ChatManager = {
if (this.unreadCounts[roomId]) {
this.unreadCounts[roomId] = 0;
this.notifyUnreadChange();
- console.log(`重置房间 ${roomId} 未读消息数`);
}
},
@@ -83,7 +79,6 @@ const ChatManager = {
this.roomMessages[roomId] = [];
}
this.roomMessages[roomId].push(message);
- console.log('addMessageToRoom', this.roomMessages[roomId])
},
// 获取房间消息
@@ -96,7 +91,6 @@ const ChatManager = {
}).then((res) => {
that.roomMessages[roomId] = that.checkMessage(res.data.result.list);
that.lastMessageId = res.data.result.last_message_id;
- console.log(that.roomMessages[roomId], 'roomMessages')
uni.$emit('load-room-message', 1);
return this.roomMessages[roomId] || [];
@@ -190,13 +184,7 @@ const ChatManager = {
getChatRegisterInfoApi({
id: item.id
}).then((res) => {
- console.log(that.roomMessages, 'ssssssssssss1')
- console.log(that.currentRoomId, 'ssssssssssss2')
- console.log(index, 'ssssssssssss3')
- console.log(that.roomMessages[that.currentRoomId][index], 'ssssssssssss4')
that.roomMessages[that.currentRoomId][index].content = res.data.result;
- console.log('getChatRegisterInfo', that.roomMessages[that.currentRoomId][index].content)
- // return res.data.result
})
},
@@ -297,6 +285,61 @@ const ChatManager = {
} else {
// 不在当前房间,缓存消息并增加未读消息数
this.increaseUnreadCount(roomId);
+
+ // 触发顶部通知(传递原始消息,由 App.vue 处理通知显示)
+ uni.$emit('show-global-notification', message);
+ }
+
+ // 通知聊天列表页刷新
+ uni.$emit('chat-list-update');
+ },
+
+ /**
+ * 获取消息预览文本
+ * @param {Object} message 消息对象
+ * @returns {string} 预览文本
+ */
+ getMessagePreview(message) {
+ const messageType = message.message_type;
+ const content = message.message_content;
+
+ switch (messageType) {
+ case 0: // 文本
+ return content;
+ case 1: // 图片
+ return '[图片]';
+ case 2: // 音频
+ return '[语音消息]';
+ case 3: // 视频
+ return '[视频]';
+ case 4: // 处方
+ return '[处方单]';
+ case 5: // 文件
+ return '[文件]';
+ case 6: // 视频通话
+ return '[视频通话]';
+ case 7: // 音频通话
+ return '[语音通话]';
+ case 9: // 系统消息
+ try {
+ const parsed = JSON.parse(content);
+ if (parsed.type === 'price_update') {
+ return parsed.message || '[价格更新]';
+ }
+ return '[系统消息]';
+ } catch (e) {
+ return '[系统消息]';
+ }
+ case 10: // 挂号
+ return '[挂号信息]';
+ case 11: // 患者就诊经历
+ return '[就诊信息]';
+ case 12: // 产品卡片
+ return '[商品推荐]';
+ case 13: // 结束问诊
+ return '[问诊已结束]';
+ default:
+ return '您有一条新消息';
}
}
};
diff --git a/subPackages/chat/chat.vue b/subPackages/chat/chat.vue
index a2b83d5..f72a792 100644
--- a/subPackages/chat/chat.vue
+++ b/subPackages/chat/chat.vue
@@ -108,7 +108,7 @@
-
+
@@ -117,9 +117,6 @@
预约挂号
-
- {{ getRegisterStatusText(getParsedContent(msg.message_type, msg.message_content).status) }}
-
@@ -225,6 +222,23 @@
+
+
+
+
+
+ {{ getParsedContent(msg.message_type, msg.message_content).message }}
+
+
+ 订单号:{{ getParsedContent(msg.message_type, msg.message_content).order_no }}
+ 应付金额:¥{{ getParsedContent(msg.message_type, msg.message_content).total_pay_price }}
+
+
+
+ {{ msg.message_content }}
+
+
+
-
+
@@ -285,9 +299,6 @@
预约挂号
-
- {{ getRegisterStatusText(getParsedContent(msg.message_type, msg.message_content).status) }}
-
@@ -434,71 +445,80 @@