diff --git a/pages_tool/ai-chat/ai-chat-message.vue b/pages_tool/ai-chat/ai-chat-message.vue
index e99d343..d683396 100644
--- a/pages_tool/ai-chat/ai-chat-message.vue
+++ b/pages_tool/ai-chat/ai-chat-message.vue
@@ -34,19 +34,9 @@
class="message-item"
:class="[message.role, { 'first-message': index === 0, 'search-current': showSearchBar && searchResultFilteredIndex === index, 'search-flash': showSearchBar && searchFlashAnimatingIndex === index }]">
-
+
-
-
-
-
- {{ formatTime(message.timestamp) }}
- {{ localUserNickname }}
-
-
- {{ formatTime(message.timestamp) }}
-
{{ message.content }}
+
+
+
-
🤖
@@ -199,8 +192,8 @@
-
-
+
+
+
+
+ ⎘
+
+
+ 👍
+
+
+ 👎
+
+
+ ···
+
+
+
@@ -217,49 +226,75 @@
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+ @
+ 引用对话文件
+
+ /
+
+ 调用技能与指令
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -443,7 +478,10 @@ export default {
searchKeyword: '',
searchResultFilteredIndex: -1,
searchFlashAnimatingIndex: -1, // 当前正在播放 flash 动画的消息索引
- searchFlashTimer: null // flash 动画定时器
+ searchFlashTimer: null, // flash 动画定时器
+
+ // 用户发出消息时记录的开始时间戳, AI 回复完成时算 elapsed (已完成 XmXXs)
+ _aiRequestStart: 0
}
},
computed: {
@@ -839,8 +877,11 @@ async loadChatHistoryIfExist() {
// 确保有内容或表情
const hasContent = this.inputText && this.inputText.trim() !== ''
const hasEmoji = this.containsEmoji(this.inputText)
-
+
if (!hasContent && !hasEmoji) return
+
+ // 记录用户发出消息的时间戳, AI 回复完成时算 elapsed
+ this._aiRequestStart = Date.now()
const userMessage = {
id: ++this.messageId,
@@ -934,6 +975,9 @@ async loadChatHistoryIfExist() {
timestamp: Date.now(),
conversationId: response.conversationId,
messageId: response.messageId,
+ // 耗时(秒): 用户发消息到 AI 回复完成的耗时
+ elapsed: this._aiRequestStart > 0 ? (Date.now() - this._aiRequestStart) / 1000 : 0,
+ _finished: true,
actions: []
}
this.shouldScrollToBottom = true
@@ -1075,6 +1119,12 @@ _finishStream(msg, result) {
msg.actions = []
+ // 计算并写入耗时 (秒), 用于状态行 "已完成 XmXXs"
+ if (this._aiRequestStart > 0) {
+ msg.elapsed = (Date.now() - this._aiRequestStart) / 1000
+ msg._finished = true
+ }
+
this.$nextTick(() => this.scrollToBottom())
this.$emit('ai-response', msg)
return true
@@ -1147,6 +1197,18 @@ _handleStreamError(msg) {
parseMarkdown(content) {
if (!content) return ''
+ // 兜底: 后端流式响应有时会把每个字用 \n 拼接 ("你\n好\n!"), 导致最终渲染一字一行.
+ // 检测"每行 1 个字符"的比例, 若超过 70% 则认为是退化格式, 先合并成连续字符串再走 markdown.
+ try {
+ const rawLines = String(content).split('\n')
+ if (rawLines.length >= 5) {
+ const singleCharLines = rawLines.filter(l => l.trim().length === 1).length
+ if (singleCharLines / rawLines.length > 0.7) {
+ content = rawLines.join('').replace(/\s+/g, '')
+ }
+ }
+ } catch (e) { /* 忽略, 走原始 content */ }
+
// 辅助:内联格式处理
const parseInline = (text) => {
return text
@@ -1402,6 +1464,17 @@ _handleStreamError(msg) {
const secs = Math.floor(seconds % 60)
return mins.toString().padStart(2, '0') + ':' + secs.toString().padStart(2, '0')
},
+
+ // 格式化 AI 处理耗时 (秒 -> "XmXXs" 风格, 0 时显示 "<1s")
+ formatElapsed(seconds) {
+ if (seconds === undefined || seconds === null || isNaN(seconds)) return '1s'
+ seconds = Math.max(0, Math.floor(seconds))
+ if (seconds < 1) return '1s'
+ const m = Math.floor(seconds / 60)
+ const s = seconds % 60
+ if (m === 0) return s + 's'
+ return m + 'm' + (s < 10 ? '0' + s : s) + 's'
+ },
// 滚动到底部 - 统一使用 scroll-into-view
scrollToBottom() {
@@ -1622,10 +1695,113 @@ _handleStreamError(msg) {
this.retryMessage(message)
return
}
-
+
this.$emit('action-click', { action, message })
},
+ // ====== AI 消息下方操作栏 (复制 / 点赞 / 不喜欢 / 朗读 / 更多) ======
+
+ // 复制 AI 回复
+ onAiActionCopy(message) {
+ this.copyMessage(message)
+ },
+
+ // 点赞 (toggle, 与不喜欢互斥)
+ onAiActionLike(message) {
+ try {
+ this.$set(message, '_liked', !message._liked)
+ if (message._liked) this.$set(message, '_disliked', false)
+ uni.showToast({ title: message._liked ? '已点赞' : '已取消点赞', icon: 'none', duration: 1200 })
+ } catch (e) { /* noop */ }
+ },
+
+ // 不喜欢 (toggle, 与点赞互斥)
+ onAiActionDislike(message) {
+ try {
+ this.$set(message, '_disliked', !message._disliked)
+ if (message._disliked) this.$set(message, '_liked', false)
+ uni.showToast({ title: message._disliked ? '已反馈' : '已取消反馈', icon: 'none', duration: 1200 })
+ } catch (e) { /* noop */ }
+ },
+
+ // 朗读 / 停止朗读 (用 uni.createInnerAudioContext 简单播放, 占位实现)
+ onAiActionSpeak(message) {
+ try {
+ const text = this._stripMarkdown(message && (message.content || ''))
+ if (!text) {
+ uni.showToast({ title: '暂无可朗读内容', icon: 'none' })
+ return
+ }
+ if (this._ttsPlaying && this._ttsCtx) {
+ // 暂停/停止
+ try { this._ttsCtx.stop() } catch (e) {}
+ this._ttsPlaying = false
+ if (this._ttsMsg === message) this.$set(message, '_playing', false)
+ return
+ }
+ // #ifdef MP-WEIXIN
+ // 微信小程序优先用 wx.createInnerAudioContext + 走 TTS, 这里给个最小占位
+ try {
+ this._ttsCtx = uni.createInnerAudioContext()
+ this._ttsCtx.onError(() => {
+ this._ttsPlaying = false
+ this.$set(message, '_playing', false)
+ uni.showToast({ title: '朗读失败', icon: 'none' })
+ })
+ // 真实项目应接入 TTS 服务 (微信同声传译插件 / 第三方 API)
+ // 此处仅占位, 让 _playing 状态可切换
+ this._ttsPlaying = true
+ this._ttsMsg = message
+ this.$set(message, '_playing', true)
+ setTimeout(() => {
+ this._ttsPlaying = false
+ this.$set(message, '_playing', false)
+ }, 1500)
+ } catch (e) { /* noop */ }
+ // #endif
+
+ // 非微信环境: 仅切换状态, 不实际朗读
+ // #ifndef MP-WEIXIN
+ this._ttsPlaying = true
+ this._ttsMsg = message
+ this.$set(message, '_playing', true)
+ setTimeout(() => {
+ this._ttsPlaying = false
+ this.$set(message, '_playing', false)
+ }, 1500)
+ // #endif
+ } catch (e) { /* noop */ }
+ },
+
+ // 更多菜单: 只保留"复制" (uni.showActionSheet 自带底部"取消"按钮, 无需额外添加)
+ onAiActionMore(message) {
+ try {
+ uni.showActionSheet({
+ itemList: ['复制'],
+ success: (res) => {
+ if (res.tapIndex === 0) {
+ this.copyMessage(message)
+ }
+ },
+ fail: () => { /* 用户取消 */ }
+ })
+ } catch (e) { /* noop */ }
+ },
+
+ // 去掉 markdown 标记, 用于 TTS 朗读
+ _stripMarkdown(text) {
+ if (!text) return ''
+ return String(text)
+ .replace(/```[\s\S]*?```/g, '')
+ .replace(/`([^`]+)`/g, '$1')
+ .replace(/\*\*(.+?)\*\*/g, '$1')
+ .replace(/~~(.+?)~~/g, '$1')
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
+ .replace(/<[^>]+>/g, '')
+ .replace(/[ \t]+/g, ' ')
+ .trim()
+ },
+
// 长按消息→直接复制
onMessageLongPress(message) {
// loading 消息不允许操作
@@ -1827,6 +2003,9 @@ _handleStreamError(msg) {
// 使用指定内容发送消息
async sendMessageWithContent(content) {
+ // 记录用户发出消息的时间戳, AI 回复完成时算 elapsed
+ this._aiRequestStart = Date.now()
+
const userMessage = {
id: ++this.messageId,
role: 'user',
@@ -1906,6 +2085,33 @@ _handleStreamError(msg) {
this.showToolsPanel = false
},
+ // 快捷指令占位提示点击: 在输入框插入 @ 或 / 触发后续指令面板 (此处仅展示交互, 后续按需扩展)
+ onQuickTipClick(type) {
+ try {
+ if (type === 'quote') {
+ this.inputText = (this.inputText || '') + '@'
+ } else if (type === 'skill') {
+ this.inputText = (this.inputText || '') + '/'
+ }
+ } catch (e) { /* noop */ }
+ },
+
+ // 默认权限下拉点击: 占位交互, 后续接入权限弹窗
+ onTogglePermission() {
+ try {
+ uni.showToast({ title: '权限设置待接入', icon: 'none' })
+ } catch (e) { /* noop */ }
+ },
+
+ // 语音按钮点击: 复用 showVoicePanel 流程 (若需要触发工具面板里的语音入口)
+ onVoiceClick() {
+ try {
+ this.showVoicePanel && this.showVoicePanel()
+ } catch (e) {
+ try { this.showToolsPanel = true } catch (e2) { /* noop */ }
+ }
+ },
+
// 打开扩大编辑器
openExpandEditor() {
this.expandInputText = this.inputText
@@ -2164,7 +2370,9 @@ _handleStreamError(msg) {
display: flex;
flex-direction: column;
box-sizing: border-box;
- background: #f8f8f8; /* 微信聊天页面背景色 */
+ /* WorkBuddy IDE 风格: 纯白底, 无气泡, 文字直接渲染其上 */
+ background: #ffffff;
+ color: #1f1f1f;
overflow: hidden;
box-sizing: border-box;
@@ -2174,10 +2382,11 @@ _handleStreamError(msg) {
overflow-y: auto;
box-sizing: border-box;
min-height: 0; /* 重要:防止flex元素溢出 */
-
+ background: transparent;
+
/* 微信小程序专属:聊天消息区域增加底部内边距,确保键盘弹出时最后一条消息可见 */
/* 由 chatMessagesStyle 动态控制 */
-
+
.load-more {
text-align: center;
padding: 16rpx 0;
@@ -2185,28 +2394,29 @@ _handleStreamError(msg) {
}
.message-item {
- margin-bottom: 20rpx;
+ margin-bottom: 28rpx;
scroll-margin-top: 300rpx;
scroll-margin-bottom: 200rpx;
-
- // 搜索定位 - 当前结果:持续绿色发光效果
+
+ // 搜索定位 - 当前结果: 用柔和的浅绿底色提示 (WorkBuddy 风格, 无气泡 box-shadow)
&.search-current {
position: relative;
z-index: 1;
- border-radius: 18rpx;
-
+ border-radius: 12rpx;
+ background: rgba(7, 193, 96, 0.08);
+
.user-message .message-bubble,
.ai-message .message-bubble {
- box-shadow: 0 0 0 4rpx rgba(7, 193, 96, 0.7), 0 4rpx 24rpx rgba(7, 193, 96, 0.35) !important;
- transition: box-shadow 0.3s ease;
+ background: transparent !important;
+ transition: background 0.3s ease;
}
}
-
+
// 搜索定位 - Flash 脉冲动画(导航到新结果时触发)
&.search-flash {
animation: searchPulse 1.2s ease-out;
}
-
+
&.first-message {
margin-top: 16rpx;
}
@@ -2216,35 +2426,36 @@ _handleStreamError(msg) {
align-items: flex-start;
.avatar {
- width: 88rpx;
- height: 88rpx;
+ width: 40rpx;
+ height: 40rpx;
border-radius: 50%;
overflow: hidden;
flex-shrink: 0;
- box-shadow: $shadow-sm;
- background-color: $bg-card;
- border: 2rpx solid #f0f4f8;
+ /* 白底风格: 取消外圈与阴影 */
+ box-shadow: none;
+ background-color: transparent;
+ border: none;
transition: transform 0.2s ease;
display: flex;
align-items: center;
justify-content: center;
position: relative;
-
+
&:hover {
transform: scale(1.03);
}
-
+
image {
width: 100%;
height: 100%;
object-fit: cover;
}
-
+
text {
- font-size: 56rpx;
+ font-size: 32rpx;
line-height: 1;
}
-
+
.avatar-fallback {
position: absolute;
top: 0;
@@ -2254,40 +2465,49 @@ _handleStreamError(msg) {
display: flex;
align-items: center;
justify-content: center;
- font-size: 56rpx;
- background-color: $bg-card;
+ font-size: 32rpx;
+ background-color: transparent;
}
}
.message-content {
flex: 1;
- margin-left: 24rpx;
- max-width: calc(100% - 96rpx);
+ margin-left: 16rpx;
+ max-width: calc(100% - 56rpx);
min-width: 0;
width: 0; /* 添加这个属性防止flex元素溢出 */
.message-bubble {
- padding: 24rpx 32rpx;
+ /* 去掉所有气泡视觉: 背景透明, 无边框, 无阴影, 无内边距, 无小三角 */
+ padding: 0 !important;
max-width: 100%;
word-break: break-word;
- box-shadow: $shadow-md;
+ box-shadow: none !important;
position: relative;
- border: 1rpx solid #f0f4f8;
+ border: none !important;
+ background: transparent !important;
+
+ &::before {
+ display: none !important;
+ content: none !important;
+ }
.message-text {
- font-size: 28rpx;
- line-height: 1.7;
+ font-size: 30rpx;
+ line-height: 1.6;
position: relative;
z-index: 1;
- letter-spacing: 0.8rpx;
+ letter-spacing: 0.3rpx;
+ color: #1f1f1f;
}
}
.message-time {
font-size: 22rpx;
- color: $color-text-light;
- margin-top: 12rpx;
- opacity: 0.9;
+ /* 白底风格: 浅灰色时间戳 */
+ color: #999;
+ margin-top: 8rpx;
+ opacity: 1;
letter-spacing: 0.5rpx;
}
@@ -2759,95 +2979,180 @@ _handleStreamError(msg) {
padding-left: 0;
align-self: flex-start;
margin-bottom: 4rpx;
- justify-content: space-between;
+ justify-content: flex-start;
display: flex;
- align-items: baseline;
+ align-items: center;
width: 100%;
position: relative;
-
+ gap: 12rpx;
+
.ai-nickname-text {
position: relative;
z-index: 1;
}
-
+
.message-time {
- position: absolute;
- left: 50%;
- transform: translateX(-50%);
- margin-top: -2rpx;
+ /* 时间显示在 AI 智能昵称的右面 */
+ position: static;
+ margin-top: 0;
+ margin-left: 0;
}
}
- /* 用户消息特有样式 */
+ /* 用户消息特有样式 (WorkBuddy 风格: 右对齐 + 浅灰气泡 + 头像在右)
+ 整体不再贴左, 头像显示且位于气泡右侧 */
.user-message {
- flex-direction: row-reverse;
-
+ flex-direction: row;
+ justify-content: flex-end;
+
+ .avatar {
+ /* 隐藏用户头像: 消息保持右对齐气泡, 但不再显示头像 */
+ display: none !important;
+ }
+
.message-content {
margin-left: 0;
- margin-right: 24rpx;
+ margin-right: 0;
text-align: right;
-
+ max-width: calc(100% - 64rpx);
+ display: flex;
+ flex-direction: column;
+ align-items: flex-end;
+
+ /* 昵称 + 时间戳行, 右对齐 */
+ .message-nickname {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ margin-bottom: 6rpx;
+ font-size: 22rpx;
+ color: #999;
+
+ .message-time {
+ margin-right: 8rpx;
+ margin-top: 0;
+ }
+
+ .nickname-text {
+ color: #666;
+ }
+ }
+
+ /* 气泡: 浅灰背景 + 圆角, 内容在气泡内左对齐(中文阅读体验更好) */
.message-bubble {
- background: #07c160 !important; /* 微信绿色 */
- color: white !important;
- border-radius: 18rpx 4rpx 18rpx 18rpx; /* 微信风格:右上角直角 */
- box-shadow: 0 2rpx 8rpx rgba(7, 193, 96, 0.2) !important;
+ background: #f5f5f5 !important;
+ color: #1f1f1f !important;
border: none !important;
- min-height: auto;
- height: auto;
- padding: 16rpx 20rpx; /* 微信风格内边距 */
+ border-radius: 16rpx !important;
+ box-shadow: none !important;
+ padding: 14rpx 18rpx !important;
display: inline-block;
word-break: break-word;
white-space: pre-wrap;
- line-height: 1.5;
+ line-height: 1.6;
text-align: left;
+ max-width: 100%;
+
&::before {
- content: '';
- position: absolute;
- top: 12rpx;
- right: -8rpx;
- width: 16rpx;
- height: 16rpx;
- background: #07c160 !important; /* 与气泡同色 */
- transform: rotate(45deg);
+ display: none !important;
+ content: none !important;
}
}
}
}
- /* AI消息特有样式 */
+ /* AI消息特有样式 (微信风格: 头像 + 名称 + 时间同行, 下方内容)
+ 与你截图样式一致 */
.ai-message {
.message-content {
- /* 确保昵称在气泡上方的布局 */
+ /* 确保昵称在内容上方的布局 */
display: flex;
flex-direction: column;
align-items: flex-start;
-
+
+ .message-nickname.ai-nickname {
+ display: flex;
+ align-items: center;
+ gap: 12rpx;
+ margin-bottom: 4rpx;
+
+ .ai-nickname-text {
+ font-size: 24rpx;
+ font-weight: 500;
+ color: #666;
+ line-height: 1;
+ }
+
+ .message-time {
+ margin-top: 0;
+ font-size: 22rpx;
+ color: #999;
+ line-height: 1;
+ }
+ }
+
.message-bubble {
- background: white !important; /* 微信风格白色 */
- color: black !important;
- border-radius: 4rpx 18rpx 18rpx 18rpx; /* 微信风格:左上角直角 */
- box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1) !important;
- border: 1rpx solid #e0e0e0 !important;
- min-height: auto;
- height: auto;
- padding: 16rpx 20rpx; /* 微信风格内边距 */
- display: inline-block;
- word-break: break-word;
- white-space: pre-wrap;
- line-height: 1.5;
+ background: transparent !important;
+ color: #1f1f1f !important;
+ border: none !important;
+ border-radius: 0 !important;
+ box-shadow: none !important;
+ padding: 0 !important;
+ display: block;
+ /* 容器不够宽时正常换行, 不主动按字断开 */
+ overflow-wrap: break-word;
+ word-wrap: break-word;
+ /* pre-line: 保留后端 \n 的段落分隔, 但合并多个连续空白, 配合 parseMarkdown normalize 避免每字一行 */
+ white-space: pre-line;
+ line-height: 1.6;
+
&::before {
- content: '';
- position: absolute;
- top: 12rpx;
- left: -8rpx;
- width: 16rpx;
- height: 16rpx;
- background: white !important; /* 与气泡同色 */
- transform: rotate(45deg);
- border: 1rpx solid #e0e0e0;
- border-right: none;
- border-top: none;
+ display: none !important;
+ content: none !important;
+ }
+ }
+
+ /* AI 消息下方操作栏: 复制 / 点赞 / 不喜欢 / 朗读 / 更多 */
+ .ai-actions {
+ margin-top: 12rpx;
+ display: flex;
+ align-items: center;
+ gap: 8rpx;
+ flex-wrap: nowrap;
+
+ .ai-action-btn {
+ min-width: 56rpx;
+ height: 56rpx;
+ padding: 0 14rpx;
+ border-radius: 28rpx;
+ background: #f5f5f5;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background-color 0.2s ease, color 0.2s ease;
+
+ .iconfont {
+ font-size: 30rpx;
+ color: #666;
+ line-height: 1;
+ }
+
+ &.more-btn .iconfont {
+ font-size: 32rpx;
+ letter-spacing: -2rpx;
+ }
+
+ &.active {
+ background: #e6f0ff;
+
+ .iconfont {
+ color: #1f6cff;
+ }
+ }
+
+ &:active {
+ background: #ebebeb;
+ }
}
}
}
@@ -2861,141 +3166,245 @@ _handleStreamError(msg) {
transition: height 0.25s ease;
}
- /* 输入区域 */
+ /* 输入区域 (WorkBuddy IDE 风格: 圆角白底容器 + 顶部输入 + 底部工具栏) */
.input-area {
- background: white; /* 白色 */
- border-top: 1rpx solid #e5e5e5;
- padding: 16rpx 24rpx;
+ background: transparent;
+ padding: 12rpx 20rpx 16rpx;
flex-shrink: 0;
box-sizing: border-box;
- .input-tools {
+ /* 圆角白底容器: 把输入框、占位提示、底部工具栏都包在一个带边框的卡片里 */
+ .input-card {
+ background: #ffffff;
+ border: 1rpx solid #e5e7eb;
+ border-radius: 20rpx;
+ padding: 14rpx 16rpx 12rpx;
+ box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
+ box-sizing: border-box;
+ }
+
+ /* 顶部输入区: textarea + 占位模式下的 @ / / 快捷提示 */
+ .input-row-top {
+ position: relative;
display: flex;
- margin-bottom: 16rpx;
align-items: flex-start;
-
- /* 微信小程序专属样式:减少工具条下边距 */
- /* #ifdef MP-WEIXIN */
- margin-bottom: 0rpx;
- /* #endif */
-
- .tool-btn {
+ min-height: 72rpx;
+
+ .message-input {
+ flex: 1;
+ min-height: 56rpx;
+ max-height: 240rpx;
+ background: transparent !important;
+ border: none !important;
+ padding: 12rpx 8rpx 12rpx 4rpx;
+ font-size: 30rpx;
+ line-height: 1.5;
+ color: #1f1f1f;
+ box-sizing: border-box;
+ }
+
+ /* placeholder 样式: 浅灰色 */
+ .message-input-placeholder {
+ color: #999 !important;
+ font-size: 30rpx !important;
+ }
+
+ /* 占位模式下显示在输入框右侧的快捷指令链接 */
+ .quick-tips {
+ position: absolute;
+ top: 50%;
+ left: 8rpx;
+ transform: translateY(-50%);
+ display: flex;
+ align-items: center;
+ pointer-events: none; /* 让 textarea 能接收点击 */
+
+ .quick-tip,
+ .quick-tip-sep {
+ font-size: 24rpx;
+ color: #1f6cff;
+ margin-right: 12rpx;
+ pointer-events: auto;
+
+ .quick-tip-icon {
+ margin-right: 4rpx;
+ }
+ }
+
+ .quick-tip-sep {
+ color: #999;
+ margin-right: 12rpx;
+ }
+ }
+
+ /* textarea 有内容时, 占位链接隐藏 (CSS 简易判断) */
+ .quick-tips {
+ opacity: 1;
+ }
+
+ /* 扩大按钮 */
+ .expand-btn {
+ flex-shrink: 0;
width: 56rpx;
height: 56rpx;
border-radius: 50%;
- background-color: #f2f2f2;
- margin-right: 12rpx;
+ background-color: #f5f5f5;
+ border: none;
display: flex;
align-items: center;
justify-content: center;
-
+ margin-left: 8rpx;
+
.iconfont {
- font-size: 32rpx;
+ font-size: 28rpx;
color: #666;
}
}
}
- .input-container {
+ /* 底部工具栏 */
+ .input-toolbar {
display: flex;
align-items: center;
-
- /* 微信小程序专属样式:让输入容器更紧凑 */
- /* #ifdef MP-WEIXIN */
- padding-top: 0rpx;
- padding-bottom: 0rpx;
- /* #endif */
-
- .message-input {
- flex: 1;
- min-height: 72rpx;
- max-height: 200rpx;
- background-color: white;
- border-radius: 36rpx;
- padding: 16rpx 24rpx;
- font-size: 28rpx;
- line-height: 1.5;
- border: 1rpx solid #e5e5e5;
- color: #333;
- margin-right: -50rpx;
- &::placeholder {
- color: #999;
- opacity: 1;
- }
+ justify-content: space-between;
+ margin-top: 6rpx;
+ min-height: 64rpx;
+
+ .toolbar-left,
+ .toolbar-right {
+ display: flex;
+ align-items: center;
}
-
- /* Emoji按钮 */
- .emoji-btn {
- width: 89rpx;
- height: 89rpx;
- border-radius: 12rpx;
-
- margin-left: 2rpx;
+
+ /* 左侧: + 圆形按钮 */
+ .tool-btn-plus {
+ width: 56rpx;
+ height: 56rpx;
+ border-radius: 50%;
+ background-color: #f5f5f5;
+ border: none;
display: flex;
align-items: center;
justify-content: center;
- border: none;
- padding: 0;
- left:43rpx;
-
- .iconfont {
- font-size: 36rpx;
+ margin-right: 12rpx;
+
+ .plus-icon {
+ font-size: 32rpx;
+ color: #666;
line-height: 1;
}
}
-
- /* 发送按钮 - 微信聊天样式 */
- .send-btn {
- width: 120rpx;
- height: 72rpx;
- border-radius: 12rpx;
- background-color: #07c160;
- margin-left: 12rpx;
+
+ /* 左侧: 默认权限下拉 */
+ .tool-btn-with-text {
+ height: 56rpx;
+ padding: 0 18rpx;
+ border-radius: 28rpx;
+ background-color: #f5f5f5;
+ border: none;
+ display: flex;
+ align-items: center;
+ margin-right: 12rpx;
+
+ .perm-icon {
+ font-size: 28rpx;
+ color: #1f6cff;
+ margin-right: 6rpx;
+ line-height: 1;
+ }
+
+ .perm-text {
+ font-size: 26rpx;
+ color: #333;
+ line-height: 1;
+ }
+
+ .arrow-icon {
+ font-size: 22rpx;
+ color: #999;
+ margin-left: 6rpx;
+ line-height: 1;
+ }
+ }
+
+ /* 右侧: emoji 按钮 */
+ .emoji-btn {
+ width: 56rpx;
+ height: 56rpx;
+ border-radius: 50%;
+ background-color: #f5f5f5;
+ border: none;
display: flex;
align-items: center;
justify-content: center;
- color: white;
- font-size: 28rpx;
- font-weight: 500;
+ margin-right: 12rpx;
+ padding: 0;
+
+ .iconfont {
+ font-size: 30rpx;
+ color: #666;
+ line-height: 1;
+ }
+ }
+
+ /* 右侧: 语音按钮 */
+ .voice-btn {
+ width: 56rpx;
+ height: 56rpx;
+ border-radius: 50%;
+ background-color: #f5f5f5;
border: none;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-right: 12rpx;
+ padding: 0;
+
+ .iconfont {
+ font-size: 30rpx;
+ color: #666;
+ line-height: 1;
+ }
+ }
+
+ /* 发送按钮: 圆形灰色, 内含向上箭头图标 (WorkBuddy 风格) */
+ .send-btn {
+ flex-shrink: 0;
+ width: 60rpx;
+ height: 60rpx;
+ border-radius: 50%;
+ background-color: #d1d5db;
+ border: none;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0;
+ margin-left: 0;
+ color: #ffffff;
text-align: center;
white-space: nowrap;
line-height: 1;
-
+ transition: background-color 0.2s ease;
+
+ .send-icon {
+ font-size: 28rpx;
+ line-height: 1;
+ color: #ffffff;
+ }
+
&.disabled {
- background-color: #ccc;
- opacity: 0.7;
+ background-color: #d1d5db;
+ opacity: 0.65;
+ }
+
+ &:not(.disabled) {
+ background-color: #1f1f1f;
+
+ .send-icon {
+ color: #ffffff;
+ }
}
}
-
- /* 微信小程序专属样式:调整输入框和发送按钮高度 */
- /* #ifdef MP-WEIXIN */
- .message-input {
- min-height: 64rpx;
- padding: 12rpx 16rpx;
- margin-top: 0rpx;
- margin-bottom: 0rpx;
- }
-
- .send-btn {
- width: 120rpx;
- height: 72rpx;
- border-radius: 12rpx;
- font-size: 33rpx;
- margin-top: 0rpx;
- margin-bottom: 0rpx;
- }
- /* #endif */
-
- /* H5专属样式:发送按钮为微信聊天样式 */
- /* #ifdef H5 */
- .send-btn {
- width: 120rpx;
- height: 72rpx;
- border-radius: 12rpx;
- font-size: 28rpx;
- }
- /* #endif */
}
}
@@ -3232,25 +3641,26 @@ _handleStreamError(msg) {
.ai-chat-container {
.chat-messages {
padding: 16rpx 24rpx;
-
+
.message-item {
margin-bottom: 24rpx;
-
+
.user-message, .ai-message {
.avatar {
- width: 72rpx;
- height: 72rpx;
+ width: 40rpx;
+ height: 40rpx;
}
-
+
.message-content {
margin-left: 16rpx;
- max-width: calc(100% - 72rpx);
-
+ max-width: calc(100% - 56rpx);
+
.message-bubble {
- padding: 16rpx 24rpx;
-
+ /* 移动端也保持无气泡样式, 文字直接渲染在深色背景上 */
+ padding: 0 !important;
+
.message-text {
- font-size: 26rpx;
+ font-size: 28rpx;
}
}
}
@@ -3259,20 +3669,36 @@ _handleStreamError(msg) {
}
.input-area {
- padding: 16rpx 24rpx;
-
- .input-container {
+ padding: 10rpx 16rpx 12rpx;
+
+ .input-card {
+ padding: 12rpx 14rpx 10rpx;
+ border-radius: 18rpx;
+ }
+
+ .input-row-top {
+ min-height: 64rpx;
+
.message-input {
- min-height: 72rpx;
- padding: 16rpx 24rpx;
- font-size: 26rpx;
+ min-height: 52rpx;
+ font-size: 28rpx;
}
-
+
+ .message-input-placeholder {
+ font-size: 28rpx !important;
+ }
+ }
+
+ .input-toolbar {
+ min-height: 56rpx;
+
.send-btn {
- width: 120rpx;
- height: 72rpx;
- border-radius: 12rpx;
- font-size: 33rpx;
+ width: 56rpx;
+ height: 56rpx;
+
+ .send-icon {
+ font-size: 26rpx;
+ }
}
}
}