diff --git a/app.json b/app.json index d9d1bba..215bdd4 100644 --- a/app.json +++ b/app.json @@ -15,7 +15,9 @@ "pages/advisory/advisory", "pages/releaseSuffer/releaseSuffer", "pages/precept/precept", - "pages/attestation/attestation" + "pages/attestation/attestation", + "pages/serviceEvaluation/serviceEvaluation", + "pages/expertChat/expertChat" ] }, { diff --git a/pages/images/kzt.png b/pages/images/kzt.png new file mode 100644 index 0000000..39886b6 Binary files /dev/null and b/pages/images/kzt.png differ diff --git a/pages/personal/personal.js b/pages/personal/personal.js index 9ee7228..a0ac7d0 100644 --- a/pages/personal/personal.js +++ b/pages/personal/personal.js @@ -48,6 +48,13 @@ Page({ }, + // 服务评价 + showFeedback(){ + wx.navigateTo({ + url: '/pagesA/pages/serviceEvaluation/serviceEvaluation', + }) + }, + onShow() { console.log('个人中心页面显示,重新获取用户信息') // 每次显示页面都从服务器获取最新数据 @@ -144,13 +151,6 @@ Page({ avatarUrl: uploadedFilePath, }) - // 更新缓存中的用户信息 - const cachedUserInfo = wx.getStorageSync('userInfo') || {} - if (!cachedUserInfo.user) { - cachedUserInfo.user = {} - } - cachedUserInfo.user.avatar = uploadedFilePath - wx.setStorageSync('userInfo', cachedUserInfo) // 更新头像的API http.revise({ data: { @@ -302,8 +302,6 @@ Page({ }, - - // 退出登录相关 showLogoutConfirm() { this.setData({ diff --git a/pagesA/images/add.png b/pagesA/images/add.png new file mode 100644 index 0000000..5f1f5ab Binary files /dev/null and b/pagesA/images/add.png differ diff --git a/pagesA/images/cuo.png b/pagesA/images/cuo.png new file mode 100644 index 0000000..560f3d5 Binary files /dev/null and b/pagesA/images/cuo.png differ diff --git a/pagesA/images/duig.png b/pagesA/images/duig.png new file mode 100644 index 0000000..41de07f Binary files /dev/null and b/pagesA/images/duig.png differ diff --git a/pagesA/images/ps.png b/pagesA/images/ps.png new file mode 100644 index 0000000..c0f3103 Binary files /dev/null and b/pagesA/images/ps.png differ diff --git a/pagesA/images/zp.png b/pagesA/images/zp.png new file mode 100644 index 0000000..7309fb4 Binary files /dev/null and b/pagesA/images/zp.png differ diff --git a/pagesA/pages/advisory/advisory.js b/pagesA/pages/advisory/advisory.js index 2858aba..1bdf7a6 100644 --- a/pagesA/pages/advisory/advisory.js +++ b/pagesA/pages/advisory/advisory.js @@ -118,28 +118,11 @@ Page({ // 处理点击申请项 handleApply(e) { - const { id, user } = e.currentTarget.dataset; - wx.showActionSheet({ - itemList: ['接受并回复', '标记为已读', '稍后处理'], - success: (res) => { - if (res.tapIndex === 0) { - wx.showToast({ title: '已接受申请', icon: 'success' }); - // 模拟更新状态 - const newList = this.data.applyList.map(item => - item.id === id ? {...item, status: 'accepted'} : item - ); - this.setData({ applyList: newList }); - } else if (res.tapIndex === 1) { - const newList = this.data.applyList.map(item => - item.id === id ? {...item, unreadCount: 0} : item - ); - this.setData({ applyList: newList }); - wx.showToast({ title: '已标记已读', icon: 'none' }); - } else { - wx.showToast({ title: '已稍后处理', icon: 'none' }); - } - } - }); + console.log(111,e); + const id = e.currentTarget.dataset.id + wx.navigateTo({ + url: `/pagesA/pages/expertChat/expertChat?id=${id}`, + }) }, diff --git a/pagesA/pages/askingSyDetails/askingSyDetails.js b/pagesA/pages/askingSyDetails/askingSyDetails.js index 2594584..ad874a9 100644 --- a/pagesA/pages/askingSyDetails/askingSyDetails.js +++ b/pagesA/pages/askingSyDetails/askingSyDetails.js @@ -1,4 +1,3 @@ -// 第一个页面的完整JS代码 - pages/diagnosisDetail/diagnosisDetail.js import http from '../../../utils/api' const baseUrl = require('../../../utils/baseUrl') diff --git a/pagesA/pages/expertChat/expertChat.js b/pagesA/pages/expertChat/expertChat.js new file mode 100644 index 0000000..742ccab --- /dev/null +++ b/pagesA/pages/expertChat/expertChat.js @@ -0,0 +1,534 @@ +// 专家端聊天页面 - 纯模拟数据,无真实接口 +Page({ + data: { + // 专家信息 + expertInfo: { + id: 'expert_001', + name: '张医生', + avatar: '/pages/images/tx.png' + }, + expertAvatar: '/pages/images/tx.png', + + // 对话信息 + conversation: { + userId: 'user_001', + userName: '李华', + userAvatar: '/pages/images/tx.png' + }, + + // 在线状态 + onlineStatus: true, + + // 消息列表 + messageList: [], + scrollTop: 0, + scrollAnimate: true, + + // 输入相关 + inputValue: '', + inputFocus: false, + + // 多媒体面板 + showMediaSheet: false, + + + // 页面状态 + loadingMore: false, + hasMore: true, + page: 1, + + // 模拟数据 + mockMessages: [ + { + id: 'msg_1', + isMe: false, + type: 'text', + content: '医生您好,我想咨询一下皮肤问题', + timestamp: Date.now() - 3600000, + status: 'success', + avatar: '/pages/images/tx.png' + }, + { + id: 'msg_2', + isMe: true, + type: 'text', + content: '您好,请描述一下您的具体症状', + timestamp: Date.now() - 3500000, + status: 'success', + avatar: '/pages/images/tx.png' + }, + { + id: 'msg_3', + isMe: false, + type: 'text', + content: '脸上起了很多小红点,有点痒', + timestamp: Date.now() - 3400000, + status: 'success', + avatar: '/pages/images/tx.png' + }, + { + id: 'msg_4', + isMe: false, + type: 'image', + content: 'https://picsum.photos/200/200?random=1', + timestamp: Date.now() - 3300000, + status: 'success', + avatar: '/pages/images/tx.png' + }, + { + id: 'msg_5', + isMe: true, + type: 'text', + content: '看起来像是过敏反应,最近有接触什么新的东西吗?', + timestamp: Date.now() - 3200000, + status: 'success', + avatar: '/pages/images/tx.png' + } + ], + + // 定时器 + typingTimer: null, + mockUserTimer: null + }, + + onLoad: function(options) { + console.log('专家端聊天页面加载', options); + + // 获取传递的参数 + if (options.userId) { + this.setData({ + 'conversation.userId': options.userId, + 'conversation.userName': options.userName || '用户' + }); + } + + // 加载模拟消息 + this.loadMockMessages(); + + // 模拟用户在线状态变化 + this.simulateOnlineStatus(); + + // 模拟用户发送消息 + this.startMockUserTyping(); + }, + + onShow: function() { + // 滚动到底部 + setTimeout(() => { + this.scrollToBottom(false); + }, 200); + }, + + onUnload: function() { + // 清理定时器 + if (this.data.mockUserTimer) { + clearInterval(this.data.mockUserTimer); + } + if (this.data.typingTimer) { + clearTimeout(this.data.typingTimer); + } + }, + + // 返回上一页 + goBack: function() { + wx.navigateBack({ + delta: 1 + }); + }, + + + + // 加载模拟消息 + loadMockMessages: function() { + // 处理消息时间显示 + const messages = this.processMessageTimes(this.data.mockMessages); + + this.setData({ + messageList: messages, + hasMore: false + }); + }, + + // 加载更多消息(模拟) + loadMoreMessages: function() { + if (this.data.loadingMore || !this.data.hasMore) return; + + this.setData({ loadingMore: true }); + + // 模拟网络延迟 + setTimeout(() => { + // 模拟更早的消息 + const olderMessages = [ + { + id: 'old_' + Date.now(), + isMe: false, + type: 'text', + content: '之前也出现过类似情况', + timestamp: Date.now() - 86400000, + status: 'success', + avatar: '/pages/images/tx.png' + }, + { + id: 'old_' + (Date.now() + 1), + isMe: true, + type: 'text', + content: '那当时是怎么处理的呢?', + timestamp: Date.now() - 86000000, + status: 'success', + avatar: '/pages/images/tx.png' + } + ]; + + const processedOld = this.processMessageTimes(olderMessages); + const newList = [...processedOld, ...this.data.messageList]; + + this.setData({ + messageList: newList, + loadingMore: false, + hasMore: false // 模拟没有更多了 + }); + + // 调整滚动位置 + setTimeout(() => { + this.setData({ + scrollAnimate: false, + scrollTop: 300 + }, () => { + setTimeout(() => { + this.setData({ scrollAnimate: true }); + }, 100); + }); + }, 50); + }, 800); + }, + + // 模拟用户在线状态变化 + simulateOnlineStatus: function() { + setInterval(() => { + // 随机改变在线状态(模拟) + const random = Math.random(); + this.setData({ + onlineStatus: random > 0.3 // 70%时间在线 + }); + }, 30000); + }, + + // 模拟用户正在输入并发送消息 + startMockUserTyping: function() { + // 每45-90秒模拟用户发送一条消息 + const timer = setInterval(() => { + // 只有在线时才发送 + if (this.data.onlineStatus) { + this.simulateUserMessage(); + } + }, Math.random() * 45000 + 45000); // 45-90秒 + + this.setData({ mockUserTimer: timer }); + }, + + // 模拟用户发送消息 + simulateUserMessage: function() { + const messages = [ + '好的,我明白了', + '谢谢医生!', + '需要用什么药吗?', + '大概多久能好?', + '有没有什么需要注意的?', + '好的,我试试看', + '明白了,非常感谢!' + ]; + + const randomMsg = messages[Math.floor(Math.random() * messages.length)]; + + const newMsg = { + id: 'user_' + Date.now() + Math.random(), + isMe: false, + type: 'text', + content: randomMsg, + timestamp: Date.now(), + status: 'success', + avatar: this.data.conversation.userAvatar || '/pages/images/tx.png' + }; + + this.addMessageToList(newMsg); + + // 震动提示(可选) + wx.vibrateShort({ type: 'light' }); + }, + + // 发送文本消息 + sendTextMessage: function() { + const content = this.data.inputValue.trim(); + if (!content) return; + + const messageId = 'msg_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9); + + // 创建本地消息 + const newMessage = { + id: messageId, + isMe: true, + type: 'text', + content: content, + timestamp: Date.now(), + status: 'sending', + avatar: this.data.expertAvatar + }; + + // 添加到列表 + this.addMessageToList(newMessage); + + // 清空输入框 + this.setData({ inputValue: '' }); + + // 模拟发送延迟 + setTimeout(() => { + this.updateMessageStatus(messageId, 'success'); + }, 500); + }, + + // 添加消息到列表 + addMessageToList: function(message) { + const { messageList } = this.data; + + // 新消息添加到末尾 + messageList.push(message); + + // 重新处理时间显示 + const processedMessages = this.processMessageTimes(messageList); + + this.setData({ + messageList: processedMessages + }, () => { + this.scrollToBottom(true); + }); + }, + + // 更新消息状态 + updateMessageStatus: function(messageId, status) { + const { messageList } = this.data; + const index = messageList.findIndex(msg => msg.id === messageId); + + if (index !== -1) { + messageList[index].status = status; + this.setData({ messageList }); + } + }, + + // 重试发送 + retrySend: function(e) { + const messageId = e.currentTarget.dataset.id; + const { messageList } = this.data; + const msg = messageList.find(m => m.id === messageId); + + if (msg) { + msg.status = 'sending'; + this.setData({ messageList }); + + setTimeout(() => { + msg.status = 'success'; + this.setData({ messageList }); + }, 500); + } + }, + + // 处理消息时间显示 + processMessageTimes: function(messages) { + if (!messages || messages.length === 0) return []; + + const timeInterval = 5; // 5分钟间隔显示时间 + + return messages.map((msg, index) => { + const showTime = index === 0 || + (msg.timestamp - messages[index - 1].timestamp) > timeInterval * 60 * 1000; + + return { + ...msg, + showTime + }; + }); + }, + + // 格式化时间 + formatTime: function(timestamp) { + if (!timestamp) return ''; + + const date = new Date(Number(timestamp)); + const hours = date.getHours().toString().padStart(2, '0'); + const minutes = date.getMinutes().toString().padStart(2, '0'); + return `${hours}:${minutes}`; + }, + + // 格式化文件大小 + formatFileSize: function(bytes) { + if (!bytes || bytes === 0) return '0B'; + + const units = ['B', 'KB', 'MB', 'GB']; + let size = bytes; + let unitIndex = 0; + + while (size >= 1024 && unitIndex < units.length - 1) { + size /= 1024; + unitIndex++; + } + + return size.toFixed(1) + units[unitIndex]; + }, + + // 输入处理 + onInput: function(e) { + this.setData({ inputValue: e.detail.value }); + }, + + // 输入框获得焦点 + onInputFocus: function() { + this.setData({ inputFocus: true }, () => { + setTimeout(() => { + this.scrollToBottom(true); + }, 200); + }); + }, + + // 输入框失去焦点 + onInputBlur: function() { + this.setData({ inputFocus: false }); + }, + + // 清除输入 + clearInput: function() { + this.setData({ + inputValue: '', + inputFocus: true + }); + }, + + // 滚动事件 + onScroll: function(e) { + const scrollTop = e.detail.scrollTop; + this.setData({ lastScrollTop: scrollTop }); + + // 滚动到顶部加载更多 + if (scrollTop <= 30 && !this.data.loadingMore && this.data.hasMore) { + this.loadMoreMessages(); + } + }, + + // 滚动到底部 + scrollToBottom: function(animate = true) { + this.setData({ + scrollAnimate: animate + }, () => { + setTimeout(() => { + this.setData({ scrollTop: 999999 }); + }, 50); + }); + }, + + // 显示多媒体选择面板 + showMediaActionSheet: function() { + this.setData({ + showMediaSheet: true, + inputFocus: false + }); + }, + + // 隐藏多媒体选择面板 + hideMediaActionSheet: function() { + this.setData({ showMediaSheet: false }); + }, + + // 选择图片(模拟) + chooseImage: function() { + this.hideMediaActionSheet(); + + // 模拟选择图片 + const mockImages = [ + 'https://picsum.photos/200/200?random=2', + 'https://picsum.photos/200/200?random=3', + 'https://picsum.photos/200/200?random=4' + ]; + + const randomImage = mockImages[Math.floor(Math.random() * mockImages.length)]; + + const messageId = 'img_' + Date.now(); + + const newMessage = { + id: messageId, + isMe: true, + type: 'image', + content: randomImage, + timestamp: Date.now(), + status: 'uploading', + progress: 0, + avatar: this.data.expertAvatar + }; + + this.addMessageToList(newMessage); + + // 模拟上传进度 + let progress = 0; + const interval = setInterval(() => { + progress += 20; + + if (progress >= 100) { + clearInterval(interval); + this.updateMessageStatus(messageId, 'success'); + } else { + const msgIndex = this.data.messageList.findIndex(m => m.id === messageId); + if (msgIndex !== -1) { + this.data.messageList[msgIndex].progress = progress; + this.setData({ messageList: this.data.messageList }); + } + } + }, 200); + }, + + // 选择视频(模拟) + chooseVideo: function() { + this.hideMediaActionSheet(); + + const messageId = 'video_' + Date.now(); + + const newMessage = { + id: messageId, + isMe: true, + type: 'video', + content: 'https://example.com/video.mp4', + thumb: 'https://picsum.photos/200/200?random=5', + timestamp: Date.now(), + status: 'uploading', + progress: 0, + avatar: this.data.expertAvatar + }; + + this.addMessageToList(newMessage); + + // 模拟上传进度 + let progress = 0; + const interval = setInterval(() => { + progress += 25; + + if (progress >= 100) { + clearInterval(interval); + this.updateMessageStatus(messageId, 'success'); + } else { + const msgIndex = this.data.messageList.findIndex(m => m.id === messageId); + if (msgIndex !== -1) { + this.data.messageList[msgIndex].progress = progress; + this.setData({ messageList: this.data.messageList }); + } + } + }, 300); + }, + + // 预览图片 + previewImage: function(e) { + const url = e.currentTarget.dataset.url; + wx.previewImage({ + current: url, + urls: [url] + }); + }, + + // 阻止事件冒泡 + stopPropagation: function() {} +}); \ No newline at end of file diff --git a/pagesA/pages/expertChat/expertChat.json b/pagesA/pages/expertChat/expertChat.json new file mode 100644 index 0000000..73f6293 --- /dev/null +++ b/pagesA/pages/expertChat/expertChat.json @@ -0,0 +1,4 @@ +{ + "navigationBarTitleText":"咨询", + "usingComponents": {} +} \ No newline at end of file diff --git a/pagesA/pages/expertChat/expertChat.wxml b/pagesA/pages/expertChat/expertChat.wxml new file mode 100644 index 0000000..11c7c54 --- /dev/null +++ b/pagesA/pages/expertChat/expertChat.wxml @@ -0,0 +1,280 @@ + + + + + + + + + + + {{conversation.userName || '用户'}} + + + {{onlineStatus ? '在线' : '离线'}} + + + + + + + + + + + 加载中... + + + + + + + + + + + + + + + + {{item.content}} + + + + + + + + + + + + + + + + + + + + + + {{item.fileName}} + {{formatFileSize(item.fileSize)}} + + + + + {{formatTime(item.timestamp)}} + + + + + + + + + + + {{item.content}} + + + + + + + + + {{item.progress}}% + + + + + + + + + + + + + {{item.progress}}% + + + + + + + + + + + {{item.fileName}} + {{formatFileSize(item.fileSize)}} + + + + {{item.progress}}% + + + + + + + 发送中 + + + 发送失败 + 重试 + + + + {{formatTime(item.timestamp)}} + + + + + + + + + + + + + + 暂无聊天记录,开始咨询吧 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 发送内容 + + + + + + + + + + + 照片 + + + + + + + 视频 + + + + + 最多可选择9张照片 + + + + + + + + + 清空聊天记录 + + + 举报用户 + + + 拉黑用户 + + + + \ No newline at end of file diff --git a/pagesA/pages/expertChat/expertChat.wxss b/pagesA/pages/expertChat/expertChat.wxss new file mode 100644 index 0000000..392581c --- /dev/null +++ b/pagesA/pages/expertChat/expertChat.wxss @@ -0,0 +1,685 @@ +/* 专家端聊天样式 */ +.consult-page { + width: 100vw; + height: 100vh; + background: #f5f5f5; + display: flex; + flex-direction: column; + overflow: hidden; + } + + /* 头部样式 */ + .consult-header { + background: #ffffff; + border-bottom: 1rpx solid #e5e5e5; + position: relative; + z-index: 1000; + box-shadow: 0 1rpx 6rpx rgba(0, 0, 0, 0.05); + flex-shrink: 0; + } + + .header-content { + display: flex; + align-items: center; + padding: 12rpx 24rpx; + height: 96rpx; + } + + .back-btn, .header-right { + width: 48rpx; + height: 48rpx; + display: flex; + align-items: center; + justify-content: center; + } + + .back-icon, .more-icon { + width: 40rpx; + height: 40rpx; + } + + .header-center { + flex: 1; + display: flex; + justify-content: center; + } + + .expert-info { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } + + .expert-name { + font-size: 32rpx; + font-weight: 600; + color: #000000; + line-height: 44rpx; + margin-bottom: 4rpx; + } + + .expert-status { + display: flex; + align-items: center; + justify-content: center; + } + + .status-dot { + width: 16rpx; + height: 16rpx; + border-radius: 50%; + margin-right: 8rpx; + } + + .status-dot.online { + background: #07c160; + animation: pulse 2s infinite; + } + + .status-dot.offline { + background: #cccccc; + } + + @keyframes pulse { + 0% { box-shadow: 0 0 0 0 rgba(7, 193, 96, 0.4); } + 70% { box-shadow: 0 0 0 8rpx rgba(7, 193, 96, 0); } + 100% { box-shadow: 0 0 0 0 rgba(7, 193, 96, 0); } + } + + .status-text { + font-size: 24rpx; + color: #666666; + } + + /* 聊天容器 */ + .chat-container { + flex: 1; + padding: 20rpx 0; + background: #f5f5f5; + overflow-y: auto; + position: relative; + height: 0; + } + + /* 消息项 */ + .message-item { + display: flex; + margin-bottom: 24rpx; + padding: 0 30rpx; + opacity: 0; + animation: fadeIn 0.3s ease forwards; + align-items: flex-start; + position: relative; + } + + @keyframes fadeIn { + from { opacity: 0; transform: translateY(10rpx); } + to { opacity: 1; transform: translateY(0); } + } + + .message-left { justify-content: flex-start; } + .message-right { justify-content: flex-end; } + + /* 头像 */ + .message-avatar { + width: 80rpx; + height: 80rpx; + border-radius: 8rpx; + overflow: hidden; + flex-shrink: 0; + background: #ffffff; + border: 1rpx solid #f0f0f0; + position: relative; + z-index: 1; + } + + .message-left .message-avatar { margin-right: 16rpx; } + .message-right .message-avatar { margin-left: 16rpx; } + + .avatar-img { + width: 100%; + height: 100%; + object-fit: cover; + } + + /* 消息内容包装器 */ + .message-content-wrapper { + max-width: 480rpx; + position: relative; + display: flex; + flex-direction: column; + z-index: 2; + } + + .message-left .message-content-wrapper { align-items: flex-start; } + .message-right .message-content-wrapper { align-items: flex-end; } + + /* 气泡箭头 */ + .message-arrow { + position: absolute; + width: 0; + height: 0; + border-style: solid; + border-width: 12rpx; + top: 30rpx; + z-index: 1; + } + + .arrow-left { + left: -24rpx; + border-color: transparent #ffffff transparent transparent; + } + + .arrow-right { + right: -24rpx; + border-color: transparent transparent transparent #95ec69; + } + + /* 消息气泡 */ + .message-bubble { + position: relative; + padding: 16rpx 20rpx; + word-break: break-word; + box-sizing: border-box; + min-height: 60rpx; + display: flex; + align-items: center; + } + + .bubble-left { + background: #ffffff; + border-radius: 10rpx; + border-top-left-radius: 4rpx; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); + } + + .bubble-right { + background: #95ec69; + border-radius: 10rpx; + border-top-right-radius: 4rpx; + box-shadow: 0 2rpx 8rpx rgba(149, 236, 105, 0.2); + } + + /* 文本消息 */ + .message-text { + font-size: 32rpx; + color: #000000; + line-height: 1.4; + } + + .bubble-right .message-text { color: #000000; } + + /* 媒体消息 */ + .media-bubble { + position: relative; + border-radius: 10rpx; + overflow: hidden; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05); + background: #ffffff; + min-height: 60rpx; + display: flex; + align-items: center; + justify-content: center; + } + + .message-left .media-bubble { border-top-left-radius: 4rpx; } + .message-right .media-bubble { border-top-right-radius: 4rpx; } + + .message-image { + width: 280rpx; + height: 280rpx; + display: block; + } + + .message-video { + width: 280rpx; + height: 280rpx; + background: #000000; + } + + .video-play-overlay { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 80rpx; + height: 80rpx; + border-radius: 50%; + background: rgba(0, 0, 0, 0.6); + display: flex; + align-items: center; + justify-content: center; + } + + .play-icon { + width: 40rpx; + height: 40rpx; + margin-left: 4rpx; + } + + /* 文件消息 */ + .message-file { + min-width: 280rpx; + padding: 20rpx; + display: flex; + align-items: center; + min-height: 60rpx; + } + + .file-icon-box { + width: 56rpx; + height: 72rpx; + margin-right: 16rpx; + position: relative; + flex-shrink: 0; + } + + .file-icon { + width: 100%; + height: 100%; + } + + .file-info { + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + overflow: hidden; + } + + .file-name { + font-size: 28rpx; + font-weight: 500; + color: #000000; + margin-bottom: 6rpx; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .file-size { + font-size: 24rpx; + color: #666666; + } + + /* 消息时间 */ + .message-time { + font-size: 22rpx; + color: #999999; + margin-top: 8rpx; + align-self: flex-start; + } + + .message-right .message-time { + align-self: flex-end; + } + + /* 消息状态 */ + .message-status { + font-size: 22rpx; + color: #999999; + margin-top: 4rpx; + display: flex; + align-items: center; + gap: 8rpx; + } + + .message-status .fail { + color: #ff4d4f; + } + + .retry-text { + color: #1890ff; + text-decoration: underline; + margin-left: 8rpx; + } + + /* 上传进度 */ + .upload-progress { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + border-radius: inherit; + } + + .progress-circle { + width: 80rpx; + height: 80rpx; + border-radius: 50%; + border: 6rpx solid rgba(255, 255, 255, 0.3); + border-top-color: #ffffff; + animation: spin 1s linear infinite; + display: flex; + align-items: center; + justify-content: center; + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } + + .progress-text { + font-size: 20rpx; + color: #ffffff; + font-weight: 600; + } + + /* 底部留白 */ + .chat-bottom-space { height: 40rpx; } + + /* 加载更多 */ + .load-more-tip { + display: flex; + justify-content: center; + align-items: center; + padding: 30rpx 0; + color: #999999; + font-size: 24rpx; + } + + /* 空状态 */ + .empty-tip { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 100rpx 0; + color: #999999; + } + + .empty-text { + font-size: 28rpx; + color: #999999; + } + + /* 输入区域 */ + .input-section { + background: #ffffff; + border-top: 1rpx solid #e5e5e5; + padding: 16rpx 30rpx; + position: relative; + z-index: 100; + box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05); + flex-shrink: 0; + width: 100%; + box-sizing: border-box; + } + + .text-input-panel { + display: flex; + align-items: center; + gap: 16rpx; + min-height: 72rpx; + } + + .add-btn { + width: 72rpx; + height: 72rpx; + display: flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + } + + .add-icon { + width: 60rpx; + height: 60rpx; + } + + .input-wrapper { + flex: 1; + position: relative; + background: #f5f5f5; + border-radius: 10rpx; + min-height: 72rpx; + display: flex; + align-items: center; + padding: 0 24rpx; + transition: all 0.2s; + box-sizing: border-box; + } + + .input-wrapper:active { + background: #e8e8e8; + } + + .chat-textarea { + flex: 1; + width: 100%; + font-size: 30rpx; + color: #333333; + line-height: 1.4; + min-height: 48rpx; + max-height: 160rpx; + padding: 12rpx 0; + margin: 0; + background: transparent; + border: none; + box-sizing: border-box; + overflow-y: auto; + } + + .input-placeholder { + color: #999999; + font-size: 28rpx; + line-height: 1.4; + } + + .input-actions { + position: absolute; + right: 16rpx; + top: 50%; + transform: translateY(-50%); + z-index: 2; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; + } + + .clear-btn { + width: 36rpx; + height: 36rpx; + border: none; + background: transparent; + padding: 0; + margin: 0; + line-height: 1; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + } + + .clear-btn::after { + border: none; + } + + .clear-btn:active { + background: rgba(0, 0, 0, 0.1); + } + + .clear-icon { + width: 28rpx; + height: 28rpx; + } + + .send-btn { + background: linear-gradient(135deg, #07c160 0%, #06ae56 100%); + width: 112rpx; + height: 66rpx; + border-radius: 10rpx; + border: none; + display: flex; + align-items: center; + justify-content: center; + transition: all 0.3s ease; + padding: 0; + margin: 0; + line-height: 1; + flex-shrink: 0; + box-shadow: 0 4rpx 8rpx rgba(7, 193, 96, 0.2); + position: relative; + overflow: hidden; + } + + .send-btn:active { + background: linear-gradient(135deg, #06ae56 0%, #059c4c 100%); + transform: scale(0.96); + box-shadow: 0 2rpx 4rpx rgba(7, 193, 96, 0.3); + } + + .send-text { + font-size: 28rpx; + color: #ffffff; + font-weight: 600; + letter-spacing: 2rpx; + } + + .send-placeholder { + width: 112rpx; + height: 72rpx; + flex-shrink: 0; + } + + /* 多媒体选择面板 */ + .media-action-sheet { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.5); + display: flex; + align-items: flex-end; + justify-content: center; + z-index: 2000; + animation: fadeIn 0.3s ease; + } + + .media-sheet-content { + width: 100%; + background: #F7F7F7; + border-radius: 40rpx 40rpx 0 0; + padding: 40rpx 30rpx calc(10rpx + env(safe-area-inset-bottom)); + animation: slideUp 0.3s ease; + box-sizing: border-box; + } + + @keyframes slideUp { + from { transform: translateY(100%); } + to { transform: translateY(0); } + } + + .media-sheet-header { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 40rpx; + padding: 0 10rpx 20rpx; + border-bottom: 1px solid #E4E4E4; + } + + .sheet-title { + font-size: 32rpx; + font-weight: 600; + color: #000000; + } + + .close-sheet-btn image { + width: 60rpx; + height: 60rpx; + } + + .media-options-grid { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 40rpx 30rpx; + margin-bottom: 40rpx; + } + + .media-option { + display: flex; + flex-direction: column; + align-items: center; + } + + .option-icon-box { + width: 120rpx; + height: 120rpx; + border-radius: 30rpx; + display: flex; + align-items: center; + justify-content: center; + margin-bottom: 16rpx; + transition: transform 0.2s; + background-color: #fff; + } + + .media-option:active .option-icon-box { + transform: scale(0.95); + } + + .option-icon-box image { + width: 60rpx; + height: 60rpx; + } + + .option-text { + font-size: 26rpx; + color: #666666; + } + + .sheet-bottom { + text-align: center; + } + + .bottom-tip { + font-size: 24rpx; + color: #999999; + } + + /* 更多菜单 */ + .more-menu { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(0, 0, 0, 0.3); + z-index: 2000; + } + + .menu-content { + position: absolute; + top: 96rpx; + right: 24rpx; + background: #ffffff; + border-radius: 12rpx; + padding: 16rpx 0; + min-width: 200rpx; + box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.15); + } + + .menu-item { + padding: 24rpx 32rpx; + font-size: 28rpx; + color: #333333; + border-bottom: 1rpx solid #f0f0f0; + } + + .menu-item:last-child { + border-bottom: none; + } + + .menu-item:active { + background: #f5f5f5; + } \ No newline at end of file diff --git a/pagesA/pages/serviceEvaluation/serviceEvaluation.js b/pagesA/pages/serviceEvaluation/serviceEvaluation.js new file mode 100644 index 0000000..0cd8d15 --- /dev/null +++ b/pagesA/pages/serviceEvaluation/serviceEvaluation.js @@ -0,0 +1,127 @@ +import http from '../../../utils/api' +const baseUrl = require('../../../utils/baseUrl') + +Page({ + data: { + baseUrl: baseUrl, + loadMoreText: '上拉加载更多', + evaluations: [], + pageNo: 1, + pageSize: 10, + total: 0, + isLoading: false, + hasMore: true + }, + + onLoad() { + this.getfeedback(true) + }, + + // 服务评价列表 + getfeedback(isRefresh = false) { + // 防止重复请求 + if (this.data.isLoading) return + + // 如果没有更多数据且不是刷新,直接返回 + if (!this.data.hasMore && !isRefresh) { + this.setData({ + loadMoreText: '—— 没有更多了 ——' + }) + return + } + + this.setData({ isLoading: true }) + + // 如果是刷新,重置为第一页 + if (isRefresh) { + this.setData({ + pageNo: 1, + hasMore: true + }) + } + + // 显示加载提示 + if (this.data.pageNo > 1) { + this.setData({ loadMoreText: '加载中...' }) + } + + http.feedback({ + data: { + type: '服务评价', + pageNo: this.data.pageNo, + pageSize: this.data.pageSize + }, + success: res => { + console.log('评价列表响应:', res) + + if (res && res.rows) { + const list = res.rows || [] + const total = res.total || 0 + + // 判断是否还有更多数据 + const hasMore = this.data.pageNo * this.data.pageSize < total + + this.setData({ + evaluations: isRefresh ? list : this.data.evaluations.concat(list), + total: total, + hasMore: hasMore, + loadMoreText: hasMore ? '上拉加载更多' : '—— 没有更多了 ——', + pageNo: this.data.pageNo + 1 + }) + } else { + // 处理异常情况 + if (isRefresh) { + this.setData({ + evaluations: [], + hasMore: false, + loadMoreText: '—— 没有更多了 ——' + }) + } + } + }, + fail: err => { + console.error('获取评价列表失败:', err) + wx.showToast({ + title: '加载失败', + icon: 'none' + }) + + // 加载失败时,恢复加载提示 + this.setData({ + loadMoreText: this.data.hasMore ? '点击重试' : '—— 没有更多了 ——' + }) + }, + complete: () => { + this.setData({ isLoading: false }) + wx.hideNavigationBarLoading() + wx.stopPullDownRefresh() + } + }) + }, + + // 下拉刷新 + onPullDownRefresh() { + wx.showNavigationBarLoading() + this.getfeedback(true) + }, + + // 上拉加载更多 + onReachBottom() { + if (this.data.hasMore && !this.data.isLoading) { + this.getfeedback() + } else if (!this.data.hasMore) { + this.setData({ + loadMoreText: '—— 没有更多了 ——' + }) + } + }, + + // 重新加载(可用于点击重试) + retryLoad() { + if (this.data.evaluations.length === 0) { + this.getfeedback(true) + } else if (this.data.hasMore) { + this.getfeedback() + } + } +}) \ No newline at end of file diff --git a/pagesA/pages/serviceEvaluation/serviceEvaluation.json b/pagesA/pages/serviceEvaluation/serviceEvaluation.json new file mode 100644 index 0000000..1e22034 --- /dev/null +++ b/pagesA/pages/serviceEvaluation/serviceEvaluation.json @@ -0,0 +1,4 @@ +{ + "navigationBarTitleText":"服务评价", + "usingComponents": {} +} \ No newline at end of file diff --git a/pagesA/pages/serviceEvaluation/serviceEvaluation.wxml b/pagesA/pages/serviceEvaluation/serviceEvaluation.wxml new file mode 100644 index 0000000..6b307b1 --- /dev/null +++ b/pagesA/pages/serviceEvaluation/serviceEvaluation.wxml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 暂无评价 + + + + + {{loadMoreText}} + + + \ No newline at end of file diff --git a/pagesA/pages/serviceEvaluation/serviceEvaluation.wxss b/pagesA/pages/serviceEvaluation/serviceEvaluation.wxss new file mode 100644 index 0000000..76f94f4 --- /dev/null +++ b/pagesA/pages/serviceEvaluation/serviceEvaluation.wxss @@ -0,0 +1,146 @@ +.page { + min-height: 100vh; + background-color: #ffffff; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif; + } + + /* 列表容器 - 直接贴边 */ + .list-container { + padding: 0 16px; + } + + /* 评价卡片 - 极简风格 */ + .evaluation-card { + background-color: #ffffff; + padding: 20px 0; + position: relative; + transition: background-color 0.2s ease; + } + + .evaluation-card:active { + background-color: #f8f9fc; + } + + /* 用户信息行 */ + .user-row { + display: flex; + align-items: center; + margin-bottom: 12px; + } + + /* 头像区域 */ + .avatar-wrapper { + margin-right: 12px; + } + + .avatar { + width: 48px; + height: 48px; + border-radius: 50%; + background-color: #f0f2f6; + overflow: hidden; + flex-shrink: 0; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03); + } + + .avatar-placeholder { + display: flex; + align-items: center; + justify-content: center; + } + + .avatar-text { + font-size: 20px; + font-weight: 500; + color: #ffffff; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); + } + + /* 用户信息区 */ + .user-info { + flex: 1; + } + + .name-row { + display: flex; + align-items: baseline; + justify-content: space-between; + margin-bottom: 4px; + } + + .user-name { + font-size: 16px; + font-weight: 600; + color: #1e2a3a; + letter-spacing: -0.2px; + } + + .time { + font-size: 12px; + color: #98a2b3; + font-weight: 400; + } + + + + /* 评价内容 */ + .content-section { + margin-bottom: 12px; + padding-right: 8px; + } + + .content-text { + font-size: 15px; + line-height: 1.5; + color: #1e2a3a; + word-break: break-word; + font-weight: 400; + } + + + + /* 卡片底部分隔线 */ + .card-footer { + margin-top: 8px; + } + + .divider { + height: 1px; + background-color: #eef1f4; + width: 100%; + } + + /* 空状态 */ + .empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + padding: 80px 20px; + background-color: #ffffff; + } + + .empty-icon { + width: 140px; + height: 140px; + margin-bottom: 20px; + opacity: 0.6; + } + + .empty-text { + font-size: 15px; + color: #9aa6b8; + font-weight: 400; + } + + /* 加载更多 */ + .load-more { + text-align: center; + padding: 24px 0 30px; + } + + .load-more-text { + font-size: 12px; + color: #b8c0cc; + font-weight: 400; + } \ No newline at end of file diff --git a/pagesB/pages/publishAdd/publishAdd.js b/pagesB/pages/publishAdd/publishAdd.js index 2639ad4..5e7b811 100644 --- a/pagesB/pages/publishAdd/publishAdd.js +++ b/pagesB/pages/publishAdd/publishAdd.js @@ -216,6 +216,8 @@ Page({ articleCoverTemp: tempPath, 'articleForm.coverImage': serverPath, isUploading: false + }, () => { + this.validateArticleForm(); }); } else { // 视频封面 @@ -277,9 +279,11 @@ Page({ maxDuration: 300, success: (res) => { if (res.tempFiles && res.tempFiles.length > 0) { + const tempFilePath = res.tempFiles[0].tempFilePath; + this.setData({ isUploading: true, - videoUrlTemp: res.tempFiles[0].tempFilePath // 先显示本地路径 + videoUrlTemp: tempFilePath // 先显示本地路径 }); // 显示加载提示 @@ -288,9 +292,18 @@ Page({ mask: true }); + console.log(111,tempFilePath); + // 上传视频 - this.uploadVideo(res.tempFiles[0].tempFilePath); + this.uploadVideo(tempFilePath); } + }, + fail: (error) => { + console.error('选择视频失败:', error); + wx.showToast({ + title: '选择视频失败', + icon: 'none' + }); } }); }, @@ -307,8 +320,9 @@ Page({ success: (uploadRes) => { try { const result = JSON.parse(uploadRes.data); + console.log(333,result) if (result.code === 200 || result.fileName) { - const serverPath = result.fileName || result.url; + const serverPath = result.fileName this.setData({ 'videoForm.videoUrl': serverPath, diff --git a/pagesB/pages/wzDetails/wzDetails.wxml b/pagesB/pages/wzDetails/wzDetails.wxml index d5c07b0..80c85a9 100644 --- a/pagesB/pages/wzDetails/wzDetails.wxml +++ b/pagesB/pages/wzDetails/wzDetails.wxml @@ -34,7 +34,7 @@ {{article.viewCount}} 阅读 - + diff --git a/project.private.config.json b/project.private.config.json index d4bd5d0..bcfa452 100644 --- a/project.private.config.json +++ b/project.private.config.json @@ -4,7 +4,7 @@ "setting": { "compileHotReLoad": true, "skylineRenderEnable": true, - "urlCheck": true, + "urlCheck": false, "coverView": true, "lazyloadPlaceholderEnable": false, "preloadBackgroundData": false, diff --git a/utils/api.js b/utils/api.js index 6a1fda2..7145fa1 100644 --- a/utils/api.js +++ b/utils/api.js @@ -139,13 +139,15 @@ function shareAdd(params) { http('/vet/article', 'post', params) } - // 制定方案新增 function fazdAdd(params) { http('/vet/plan', 'post', params) } - +// 个人中心服务评价 +function feedback(params) { + http('/muhu/feedback/list', 'get', params) +} @@ -162,12 +164,6 @@ function revise(params) { http('/muhu/user', 'put', params) } -// 个人中心反馈建议 -function feedback(params) { - http('/muhu/feedback', 'post', params) -} - - // 个人中心今日问诊 function today(params) { http('/muhu/consultation/today', 'get', params)