aiBook.wxml 4.34 KB
<view class="page">
	<nav backgroundColor="#FFFFFF" color="#1A1B1C">
		<view class="nav-title">
			<text class="nav-title-main">AI 经营助手</text>
			<text class="nav-title-sub">{{storeName}}</text>
		</view>
	</nav>

	<scroll-view class="msg-list" scroll-y scroll-with-animation scroll-into-view="{{scrollIntoView}}" enhanced show-scrollbar="{{false}}">
		<view class="msg-list-inner">
			<block wx:for="{{messages}}" wx:key="id">
				<view id="msg-{{item.id}}" class="msg {{item.role}}">
					<view class="bubble">
						<view wx:if="{{item.typing}}" class="typing">
							<view class="dot"></view>
							<view class="dot"></view>
							<view class="dot"></view>
						</view>
						<block wx:else>
							<view class="bubble-body">
								<text class="bubble-text" user-select>{{item.text}}</text><text wx:if="{{item.showCaret}}" class="caret">|</text><text wx:if="{{item.stopped}}" class="stopped-tag"> (已停止)</text>
							</view>
						</block>

						<!-- KPI 卡片 -->
						<view wx:if="{{item.card && item.card.type === 'kpi'}}" class="card">
							<view class="c-title">{{item.card.title}}</view>
							<view class="kpis">
								<view class="kpi" wx:for="{{item.card.items}}" wx:for-item="kpi" wx:key="label">
									<view class="k-label">{{kpi.label}}</view>
									<view class="k-val">{{kpi.value}}</view>
									<view class="k-delta {{kpi.trend}}">{{kpi.delta}}</view>
								</view>
							</view>
						</view>

						<!-- 行列表卡片(桌位 / 预订 / 订单) -->
						<view wx:if="{{item.card && item.card.type === 'rows'}}" class="card">
							<view class="c-title">{{item.card.title}}</view>
							<view class="row" wx:for="{{item.card.rows}}" wx:for-item="row" wx:key="label">
								<text class="row-label">{{row.label}}</text>
								<text class="row-status {{row.status}}">{{row.statusText}}</text>
							</view>
						</view>

						<!-- 排行卡片 -->
						<view wx:if="{{item.card && item.card.type === 'rank'}}" class="card">
							<view class="c-title">{{item.card.title}}</view>
							<view class="rank" wx:for="{{item.card.items}}" wx:for-item="rank" wx:key="name">
								<view class="no">{{rank.no}}</view>
								<text class="rank-name">{{rank.name}}</text>
								<view class="bar">
									<view class="bar-fill" style="width: {{rank.percent}};"></view>
								</view>
								<text class="rank-val">{{rank.value}}</text>
							</view>
						</view>
					</view>
					<view class="meta">{{item.meta}}</view>
				</view>
			</block>
			<view id="msg-bottom" class="msg-bottom"></view>
		</view>
	</scroll-view>

	<!-- 快捷提问 -->
	<scroll-view wx:if="{{showHints}}" class="hints" scroll-x enable-flex show-scrollbar="{{false}}">
		<view class="hint-btn" wx:for="{{hints}}" wx:key="*this" data-text="{{item}}" bindtap="onHintTap">{{item}}</view>
	</scroll-view>

	<!-- 语音转写确认 -->
	<view wx:if="{{confirmVisible}}" class="confirm-box">
		<textarea class="confirm-text" value="{{confirmText}}" maxlength="-1" auto-height placeholder="{{recognizing ? '正在识别…' : '转写结果可在这里修改…'}}" disabled="{{recognizing}}" bindinput="onConfirmInput" />
		<view class="confirm-bar">
			<view class="cbtn cancel" bindtap="onCancelConfirm">取消</view>
			<view class="cbtn ok" bindtap="onOkConfirm">确认发送</view>
		</view>
	</view>

	<!-- 输入区 -->
	<view class="inputbar">
		<input class="text-input" value="{{inputText}}" placeholder="问点什么…" confirm-type="send" bindinput="onInput" bindconfirm="onSend" disabled="{{recording}}" />
		<view class="ibtn voice {{recording ? 'recording' : ''}}" catchtouchstart="onVoiceStart" catchtouchend="onVoiceEnd" catchtouchcancel="onVoiceCancel" catchtouchmove="onVoiceMove">🎤</view>
		<view wx:if="{{streaming}}" class="stop-btn" bindtap="onStop">停止</view>
		<view wx:else class="ibtn send" bindtap="onSend">➤</view>
	</view>

	<!-- 录音浮层 -->
	<view class="record-overlay {{recording ? 'show' : ''}} {{cancelHint ? 'cancel' : ''}}">
		<view class="rec-time">{{recTime}}</view>
		<view class="wave">
			<view class="wave-bar"></view>
			<view class="wave-bar"></view>
			<view class="wave-bar"></view>
			<view class="wave-bar"></view>
			<view class="wave-bar"></view>
			<view class="wave-bar"></view>
			<view class="wave-bar"></view>
		</view>
		<view class="rec-hint">{{cancelHint ? '松开取消' : '松开发送 · 上滑取消'}}</view>
	</view>
</view>