You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
337 lines
12 KiB
337 lines
12 KiB
<view class="consult-page">
|
|
<!-- 头部专家信息 -->
|
|
<view class="consult-header">
|
|
<view class="header-content">
|
|
<view class="header-center">
|
|
<view class="expert-info">
|
|
<text class="expert-name">{{expertInfo.name}}</text>
|
|
<view class="expert-status">
|
|
<view class="status-dot {{expertInfo.online ? 'online' : 'offline'}}"></view>
|
|
<text class="status-text">{{expertInfo.online ? '在线' : '离线'}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 聊天内容区域 -->
|
|
<scroll-view
|
|
id="chatScroll"
|
|
class="chat-container"
|
|
scroll-y
|
|
scroll-top="{{scrollTop}}"
|
|
scroll-with-animation="{{scrollAnimate}}"
|
|
enable-back-to-top="true"
|
|
show-scrollbar="{{false}}"
|
|
bindscroll="onScroll"
|
|
>
|
|
<!-- 日期分隔线 -->
|
|
<view class="date-divider" wx:if="{{showDateDivider}}">
|
|
<text class="date-text">{{todayDate}}</text>
|
|
</view>
|
|
|
|
<!-- 消息列表 -->
|
|
<block wx:for="{{messageList}}" wx:key="id">
|
|
|
|
<!-- 对方消息 -->
|
|
<view class="message-item message-left" wx:if="{{item.sender === 'expert'}}">
|
|
<view class="message-avatar">
|
|
<image src="/pagesA/images/1.png" class="avatar-img"></image>
|
|
</view>
|
|
|
|
<view class="message-content-wrapper">
|
|
<!-- 气泡箭头 -->
|
|
<view class="message-arrow arrow-left"></view>
|
|
|
|
<!-- 文本消息 -->
|
|
<view class="message-bubble bubble-left" wx:if="{{item.type === 'text'}}">
|
|
<text class="message-text">{{item.content}}</text>
|
|
</view>
|
|
|
|
<!-- 图片消息 -->
|
|
<view class="media-bubble" wx:elif="{{item.type === 'image'}}">
|
|
<image
|
|
src="{{item.content}}"
|
|
class="message-image"
|
|
mode="aspectFill"
|
|
bindtap="previewImage"
|
|
data-url="{{item.content}}"
|
|
></image>
|
|
</view>
|
|
|
|
<!-- 视频消息 -->
|
|
<view class="media-bubble" wx:elif="{{item.type === 'video'}}">
|
|
<video
|
|
src="{{item.content}}"
|
|
class="message-video"
|
|
controls
|
|
show-center-play-btn
|
|
poster="{{item.thumb}}"
|
|
></video>
|
|
<view class="video-play-overlay">
|
|
<image src="/images/icons/play.png" class="play-icon"></image>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 语音消息 -->
|
|
<view class="message-bubble bubble-left message-audio" wx:elif="{{item.type === 'audio'}}">
|
|
<image src="/images/icons/voice_left.png" class="audio-icon-left"></image>
|
|
<view class="audio-content">
|
|
<view class="audio-wave">
|
|
<view class="wave-bar" style="animation-delay: 0s;"></view>
|
|
<view class="wave-bar" style="animation-delay: 0.2s;"></view>
|
|
<view class="wave-bar" style="animation-delay: 0.4s;"></view>
|
|
</view>
|
|
<text class="audio-duration">{{item.duration || 0}}''</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 文件消息 -->
|
|
<view class="message-bubble bubble-left message-file" wx:elif="{{item.type === 'file'}}">
|
|
<view class="file-icon-box">
|
|
<image src="/images/icons/file_icon.png" class="file-icon"></image>
|
|
</view>
|
|
<view class="file-info">
|
|
<text class="file-name">{{item.fileName}}</text>
|
|
<text class="file-size">{{formatFileSize(item.fileSize)}}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 我的消息 -->
|
|
<view class="message-item message-right" wx:else>
|
|
<view class="message-content-wrapper">
|
|
<!-- 气泡箭头 -->
|
|
<view class="message-arrow arrow-right"></view>
|
|
|
|
<!-- 文本消息 -->
|
|
<view class="message-bubble bubble-right" wx:if="{{item.type === 'text'}}">
|
|
<text class="message-text">{{item.content}}</text>
|
|
</view>
|
|
|
|
<!-- 图片消息 -->
|
|
<view class="media-bubble" wx:elif="{{item.type === 'image'}}">
|
|
<image
|
|
src="{{item.content}}"
|
|
class="message-image"
|
|
mode="aspectFill"
|
|
bindtap="previewImage"
|
|
data-url="{{item.content}}"
|
|
></image>
|
|
<view class="upload-progress" wx:if="{{item.status === 'uploading'}}">
|
|
<view class="progress-circle">
|
|
<text class="progress-text">{{item.progress}}%</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 视频消息 -->
|
|
<view class="media-bubble" wx:elif="{{item.type === 'video'}}">
|
|
<video
|
|
src="{{item.content}}"
|
|
class="message-video"
|
|
controls
|
|
show-center-play-btn
|
|
poster="{{item.thumb}}"
|
|
></video>
|
|
<view class="video-play-overlay">
|
|
<image src="/images/icons/play.png" class="play-icon"></image>
|
|
</view>
|
|
<view class="upload-progress" wx:if="{{item.status === 'uploading'}}">
|
|
<view class="progress-circle">
|
|
<text class="progress-text">{{item.progress}}%</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 语音消息 -->
|
|
<view class="message-bubble bubble-right message-audio" wx:elif="{{item.type === 'audio'}}">
|
|
<view class="audio-content">
|
|
<view class="audio-wave">
|
|
<view class="wave-bar" style="animation-delay: 0s;"></view>
|
|
<view class="wave-bar" style="animation-delay: 0.2s;"></view>
|
|
<view class="wave-bar" style="animation-delay: 0.4s;"></view>
|
|
</view>
|
|
<text class="audio-duration">{{item.duration || 0}}''</text>
|
|
</view>
|
|
<image src="/images/icons/voice_right.png" class="audio-icon-right"></image>
|
|
</view>
|
|
|
|
<!-- 文件消息 -->
|
|
<view class="message-bubble bubble-right message-file" wx:elif="{{item.type === 'file'}}">
|
|
<view class="file-icon-box">
|
|
<image src="/images/icons/file_icon.png" class="file-icon"></image>
|
|
</view>
|
|
<view class="file-info">
|
|
<text class="file-name">{{item.fileName}}</text>
|
|
<text class="file-size">{{formatFileSize(item.fileSize)}}</text>
|
|
</view>
|
|
<view class="upload-progress" wx:if="{{item.status === 'uploading'}}">
|
|
<view class="progress-circle">
|
|
<text class="progress-text">{{item.progress}}%</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="message-avatar">
|
|
<image src="/pagesA/images/2.png" class="avatar-img"></image>
|
|
</view>
|
|
</view>
|
|
</block>
|
|
|
|
<!-- 底部留白区域 -->
|
|
<view class="chat-bottom-space"></view>
|
|
|
|
<!-- 加载更多提示 -->
|
|
<view class="load-more-tip" wx:if="{{loadingMore}}">
|
|
<text>加载中...</text>
|
|
</view>
|
|
|
|
<!-- 没有消息提示 -->
|
|
<view class="empty-tip" wx:if="{{messageList.length === 0 && !loading}}">
|
|
<image src="/images/icons/empty_chat.png" class="empty-icon"></image>
|
|
<text class="empty-text">暂无聊天记录,开始咨询吧</text>
|
|
</view>
|
|
</scroll-view>
|
|
|
|
<!-- 输入区域 -->
|
|
<view class="input-section">
|
|
<!-- 语音输入模式 -->
|
|
<view class="voice-input-panel" wx:if="{{inputMode === 'voice'}}">
|
|
<!-- 切换到文字输入按钮 -->
|
|
<view class="voice-input-btn" bindtap="switchInputMode">
|
|
<image src="/pagesA/images/xjp.png" class="voice-btn-icon"></image>
|
|
</view>
|
|
|
|
<!-- 语音输入按钮 -->
|
|
<view class="input-wrapper">
|
|
<view
|
|
class="voice-record-btn"
|
|
bindtouchstart="startVoiceRecord"
|
|
bindtouchmove="onVoiceTouchMove"
|
|
bindtouchend="endVoiceRecord"
|
|
bindtouchcancel="cancelVoiceRecord"
|
|
>
|
|
<text class="voice-tip">{{voiceTip}}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="more-btn" bindtap="showMediaActionSheet" >
|
|
<image src="/pagesA/images/add.png" class="more-icon"></image>
|
|
</view>
|
|
|
|
</view>
|
|
|
|
<!-- 文字输入模式 -->
|
|
<view class="text-input-panel" wx:else>
|
|
<!-- 切换到语音输入按钮 -->
|
|
<view class="voice-input-btn" bindtap="switchInputMode">
|
|
<image src="/pagesA/images/yy.png" class="voice-btn-icon"></image>
|
|
</view>
|
|
|
|
<!-- 文字输入框 -->
|
|
<view class="input-wrapper">
|
|
<input
|
|
type="text"
|
|
class="chat-input"
|
|
placeholder="{{inputPlaceholder}}"
|
|
placeholder-class="input-placeholder"
|
|
value="{{inputValue}}"
|
|
bindinput="onInput"
|
|
bindconfirm="sendTextMessage"
|
|
confirm-type="send"
|
|
focus="{{inputFocus}}"
|
|
adjust-position="{{false}}"
|
|
cursor-spacing="20"
|
|
bindfocus="onInputFocus"
|
|
bindblur="onInputBlur"
|
|
/>
|
|
|
|
<!-- 输入框操作按钮 -->
|
|
<view class="input-actions" wx:if="{{inputValue.trim()}}">
|
|
<button class="clear-btn" bindtap="clearInput">
|
|
<image src="/images/icons/clear.png" class="clear-icon"></image>
|
|
</button>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 发送/更多按钮 -->
|
|
<!-- <button
|
|
class="send-btn"
|
|
bindtap="sendTextMessage"
|
|
wx:if="{{inputValue.trim()}}"
|
|
>
|
|
<text class="send-text">发送</text>
|
|
</button> -->
|
|
|
|
<view class="more-btn" bindtap="showMediaActionSheet" >
|
|
<image src="/pagesA/images/add.png" class="more-icon"></image>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 多媒体选择面板 -->
|
|
<view class="media-action-sheet" wx:if="{{showMediaSheet}}" catchtap="hideMediaActionSheet">
|
|
<view class="media-sheet-content" catchtap="stopPropagation">
|
|
<view class="media-sheet-header">
|
|
<text class="sheet-title">发送内容</text>
|
|
<view class="close-sheet-btn" bindtap="hideMediaActionSheet">
|
|
<image src="/pagesA/images/cuo.png"></image>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="media-options-grid">
|
|
<view class="media-option" bindtap="chooseImage">
|
|
<view class="option-icon-box">
|
|
<image src="/pagesA/images/zp.png"></image>
|
|
</view>
|
|
<text class="option-text">照片</text>
|
|
</view>
|
|
|
|
<view class="media-option" bindtap="chooseVideo">
|
|
<view class="option-icon-box">
|
|
<image src="/pagesA/images/ps.png"></image>
|
|
</view>
|
|
<text class="option-text">视频</text>
|
|
</view>
|
|
|
|
<view class="media-option" bindtap="chooseFile">
|
|
<view class="option-icon-box">
|
|
<image src="/pagesA/images/wj.png"></image>
|
|
</view>
|
|
<text class="option-text">文件</text>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="sheet-bottom">
|
|
<text class="bottom-tip">最多可选择9张照片</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 录音提示 -->
|
|
<view class="recording-modal" wx:if="{{isRecording}}">
|
|
<view class="recording-box {{isCanceling ? 'is-canceling' : ''}}">
|
|
<view class="recording-icon">
|
|
<image
|
|
src="{{isCanceling ? '/images/icons/cancel_recording.png' : '/images/icons/recording.png'}}"
|
|
class="recording-mic-icon"
|
|
></image>
|
|
</view>
|
|
<text class="recording-tip">{{recordingTip}}</text>
|
|
<view class="recording-meter">
|
|
<view class="recording-waves">
|
|
<view
|
|
class="recording-wave"
|
|
wx:for="{{[1,2,3,4,5]}}"
|
|
wx:key="index"
|
|
style="animation-delay: {{index * 0.1}}s;"
|
|
></view>
|
|
</view>
|
|
<text class="recording-time">{{recordingTime}}s</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|