144 lines
4.7 KiB
Plaintext
144 lines
4.7 KiB
Plaintext
<view class="chat-page">
|
||
<!-- 深色渐变背景 -->
|
||
<view class="hero-bg">
|
||
<view class="hero-blob blob-1"></view>
|
||
<view class="hero-blob blob-2"></view>
|
||
<view class="hero-blob blob-3"></view>
|
||
<view class="hero-noise"></view>
|
||
</view>
|
||
|
||
<!-- 顶部栏 -->
|
||
<view class="topbar">
|
||
<!-- <view class="topbar-back" bindtap="goBack">
|
||
<text class="back-arrow">‹</text>
|
||
</view> -->
|
||
<!-- <view class="brand-mini">财务智能问答</view> -->
|
||
<view class="topbar-more" bindtap="openDrawer" aria-label="更多">
|
||
<view class="dot"></view>
|
||
<view class="dot"></view>
|
||
<view class="dot"></view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 消息列表 -->
|
||
<scroll-view
|
||
class="messages"
|
||
scroll-y="{{true}}"
|
||
scroll-into-view="{{scrollAnchor}}"
|
||
scroll-with-animation="{{true}}"
|
||
enhanced="{{true}}"
|
||
show-scrollbar="{{false}}"
|
||
>
|
||
<block wx:for="{{messages}}" wx:key="key">
|
||
<view id="msg-{{index}}" class="msg-row {{item.role}}">
|
||
<view class="bubble {{item.role}}">
|
||
<block wx:if="{{item.role === 'user'}}">
|
||
<block wx:if="{{item.attachments && item.attachments.length}}">
|
||
<view class="atts">
|
||
<image
|
||
wx:for="{{item.attachments}}"
|
||
wx:for-item="att"
|
||
wx:key="id"
|
||
class="att-img"
|
||
src="{{att.data_url}}"
|
||
mode="aspectFill"
|
||
bindtap="previewImage"
|
||
data-src="{{att.data_url}}"
|
||
/>
|
||
</view>
|
||
</block>
|
||
<text wx:if="{{item.text}}" class="txt">{{item.text}}</text>
|
||
</block>
|
||
<block wx:else>
|
||
<text class="txt">{{item.text || (item.streaming ? '思考中...' : '')}}</text>
|
||
<block wx:if="{{item.references && item.references.length}}">
|
||
<view class="refs">
|
||
<view class="refs-title">参考来源</view>
|
||
<view class="ref-item" wx:for="{{item.references}}" wx:for-item="ref" wx:key="idx" wx:for-index="idx">
|
||
<text class="ref-title">[{{idx + 1}}] {{ref.source_title}}</text>
|
||
<text wx:if="{{ref.snippet}}" class="ref-snippet">{{ref.snippet}}</text>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
</block>
|
||
</view>
|
||
</view>
|
||
</block>
|
||
<view id="anchor-end" class="anchor-end"></view>
|
||
</scroll-view>
|
||
|
||
<!-- 底部吸底容器 -->
|
||
<view class="bottom-dock">
|
||
<!-- 待发送图片预览 -->
|
||
<view wx:if="{{pendingImages.length}}" class="pending-bar">
|
||
<view class="pending-item" wx:for="{{pendingImages}}" wx:key="id">
|
||
<image class="pending-img" src="{{item.data_url}}" mode="aspectFill" />
|
||
<view class="pending-remove" bindtap="removePending" data-index="{{index}}">×</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 语音识别中提示 -->
|
||
<view wx:if="{{recording}}" class="recording-tip">
|
||
<view class="recording-dot"></view>
|
||
<text>正在录音,松开发送...</text>
|
||
</view>
|
||
|
||
<!-- 输入行 -->
|
||
<view class="input-bar">
|
||
<view class="btn-icon" bindtap="chooseImage">
|
||
<text class="icon">+</text>
|
||
</view>
|
||
|
||
<block wx:if="{{voiceMode}}">
|
||
<button
|
||
class="voice-hold {{recording ? 'active' : ''}}"
|
||
bindtouchstart="startRecord"
|
||
bindtouchend="stopRecord"
|
||
bindtouchcancel="cancelRecord"
|
||
>
|
||
{{recording ? '松开发送' : '按住说话'}}
|
||
</button>
|
||
</block>
|
||
<block wx:else>
|
||
<input
|
||
class="input-text"
|
||
placeholder="输入问题..."
|
||
placeholder-class="input-ph"
|
||
value="{{question}}"
|
||
bindinput="onQuestionInput"
|
||
confirm-type="send"
|
||
bindconfirm="submit"
|
||
adjust-position="{{true}}"
|
||
disabled="{{streaming}}"
|
||
/>
|
||
</block>
|
||
|
||
<view class="btn-icon" bindtap="toggleVoiceMode">
|
||
<text class="icon">{{voiceMode ? '⌨' : '🎤'}}</text>
|
||
</view>
|
||
|
||
<button class="btn-send {{(streaming || (!question && pendingImages.length === 0)) ? 'disabled' : ''}}"
|
||
bindtap="submit"
|
||
disabled="{{streaming || (!question && pendingImages.length === 0)}}"
|
||
wx:if="{{!voiceMode}}"
|
||
>
|
||
{{streaming ? '···' : '发送'}}
|
||
</button>
|
||
</view>
|
||
</view>
|
||
|
||
<side-drawer
|
||
open="{{drawerOpen}}"
|
||
sessions="{{sessions}}"
|
||
sessions-loading="{{sessionsLoading}}"
|
||
user-name="{{userName}}"
|
||
user-sub="{{userSub}}"
|
||
avatar-char="{{avatarChar}}"
|
||
current-sid="{{conversationId}}"
|
||
bind:close="closeDrawer"
|
||
bind:newchat="newConversation"
|
||
bind:selectsession="onSelectSession"
|
||
bind:logout="logout"
|
||
/>
|
||
</view>
|