diff --git a/.local.config.js b/.local.config.js
index 973319c..f81a81b 100644
--- a/.local.config.js
+++ b/.local.config.js
@@ -257,7 +257,11 @@ const localDevConfig = ({
// })['2811']; // 本地
// })['5g-317']; // 电磁兼容
// })['5g-351']; //
+<<<<<<< HEAD
})['5g-97']; // 本地
+=======
+ })['2881']; // 本地
+>>>>>>> temp221
// })['local-2']; // 本地
// })['local-11']; // 本地
// })['1-test']; // test
diff --git a/pages_tool/ai-chat/ai-chat-message.vue b/pages_tool/ai-chat/ai-chat-message.vue
index 38e75f3..fe0ee3b 100644
--- a/pages_tool/ai-chat/ai-chat-message.vue
+++ b/pages_tool/ai-chat/ai-chat-message.vue
@@ -234,10 +234,10 @@
-
+
-
+
@@ -250,10 +250,10 @@
-
+
-
+
@@ -529,17 +529,30 @@
① 默认(未输入/未聚焦): 单行胶囊 —— 语音图标 + 输入框 + 加号
② 语音模式(点语音图标进入): 「按住说话」按钮 + 底部工具栏(表情/模型/加号)
③ 文字输入(聚焦或有文字): 输入框独占一行 + 底部工具栏(语音/模型/加号/发送) -->
-
+
- {{ voiceHoldText }}
+ class="voice-mode-row"
+ :class="{ 'is-holding': voiceHolding, 'is-cancelling': voiceHoldCancelling }">
+
+
+
+
+
+
+ {{ voiceHoldText }}
+
+
+
{{ voiceHoldCancelling ? $lang('ai-chat.index.slideUpToCancelHint') : $lang('ai-chat.index.slideUpToCancel') }}
@@ -587,14 +600,10 @@
-
-
-
-
-
-
+
+
-
+
@@ -3928,17 +3937,24 @@ _handleStreamError(msg) {
},
// AI 消息渲染(含关键词高亮)
- getAIDisplayContent(content) {
+ // isWelcome: 欢迎语消息 — 小程序端 mp-html 组件有样式隔离, 页面样式(::v-deep)进不去,
+ // 图片间距只能在内容层面改内联样式(机器人图片与下方标题的间距, 对齐 WorkBuddy 参考稿)
+ getAIDisplayContent(content, isWelcome) {
+ let html
if (!this.searchKeyword || !content) {
- return this.parseMarkdown(content)
+ html = this.parseMarkdown(content)
+ } else if (content.toLowerCase().indexOf(this.searchKeyword.toLowerCase()) === -1) {
+ html = this.parseMarkdown(content)
+ } else {
+ // 先做 markdown 渲染,再做关键词高亮
+ const mdHtml = this.parseMarkdown(content)
+ html = this._wrapHighlightInHtml(mdHtml, this.searchKeyword)
}
- // 仅当内容包含关键词时才执行高亮,避免非匹配消息的额外处理
- if (content.toLowerCase().indexOf(this.searchKeyword.toLowerCase()) === -1) {
- return this.parseMarkdown(content)
+ if (isWelcome && html) {
+ // 仅替换 img 的 margin(机器人图片), 不影响列表等其他元素的 margin:8rpx 0
+ html = html.replace(/(
]*style="[^"]*?)margin:\s*8rpx 0;/, '$1margin:0 0 48rpx 0;')
}
- // 先做 markdown 渲染,再做关键词高亮
- const mdHtml = this.parseMarkdown(content)
- return this._wrapHighlightInHtml(mdHtml, this.searchKeyword)
+ return html
},
// 在纯文本中高亮关键词(用于用户消息)
@@ -4780,11 +4796,24 @@ _handleStreamError(msg) {
background: #ffffff !important;
}
+ // 欢迎语消息: 图片(机器人)与下方标题的间距加大, 对齐 WorkBuddy 参考稿
+ // 图片是 v-html 插入的
, 不带 scoped 的 data-v 属性,
+ // 普通 img 选择器编译后会匹配不到, 必须用 ::v-deep 穿透
+ &.is-welcome .ai-message .message-bubble ::v-deep img {
+ margin-bottom: 48rpx !important;
+ }
+
// 欢迎语消息: 隐藏上方时间戳
&.is-welcome .ai-message .message-nickname.ai-nickname {
display: none;
}
+ // 欢迎语消息: 标题与快捷问题的间距, 与"图片→标题"保持一致 (48rpx)
+ // 下方 5326 行的 .quick-questions-row 嵌套链更长、特异性更高, 必须 !important 覆盖
+ &.is-welcome .quick-questions-row {
+ margin-top: 48rpx !important;
+ }
+
// 搜索定位 - 当前结果: 用柔和的浅绿底色提示 (WorkBuddy 风格, 无气泡 box-shadow)
&.search-current {
position: relative;
@@ -5323,7 +5352,7 @@ _handleStreamError(msg) {
margin-bottom: 16rpx;
padding: 12rpx 28rpx;
background: #ffffff;
- border: 1rpx solid #e4e6eb;
+ border: 1rpx solid #eef0f3;
border-radius: 999rpx;
font-size: 26rpx;
color: #1a1a1a;
@@ -5331,7 +5360,7 @@ _handleStreamError(msg) {
transition: all 0.2s ease;
max-width: 100%;
line-height: 1.4;
- box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
+ box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.14);
&:last-child {
margin-bottom: 0;
@@ -5753,6 +5782,7 @@ _handleStreamError(msg) {
height: 56rpx;
padding: 0 20rpx;
gap: 8rpx;
+ margin-top: 20rpx;
.refresh-icon {
width: 28rpx;
@@ -5810,9 +5840,12 @@ _handleStreamError(msg) {
justify-content: space-between;
background: #ffffff;
border-radius: 999rpx;
- padding: 18rpx 14rpx 18rpx 32rpx;
- min-height: 108rpx;
- box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
+ /* 高度与语音模式胶囊(.voice-mode-row: height 96rpx)保持一致:
+ 内部图标容器 76rpx + 上下 padding 10rpx*2 = 96rpx */
+ padding: 10rpx 14rpx 10rpx 32rpx;
+ min-height: 96rpx;
+ /* 与快捷问题按钮(.quick-question-chip)同款阴影, 白底更突出 */
+ box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.14);
/* 无文字时左侧语音图标,点击打开语音面板
PR-INPUT-LAYOUT-SYMMETRY (2026-09-28): 容器从 52rpx 扩大到 76rpx,
@@ -5944,17 +5977,24 @@ _handleStreamError(msg) {
background-size: contain;
}
- /* 展开态: 卡片变白底圆角容器, 内部输入行不再单独成胶囊 */
+ /* 展开态: 文字输入时卡片变白底圆角容器;
+ 语音模式卡片保持透明, 白色胶囊由 .voice-mode-row 自身呈现 (避免双层白底) */
.input-card {
- &.is-voice-mode,
&.is-text-mode {
background: #ffffff;
border-radius: 28rpx;
padding: 14rpx 16rpx 6rpx;
- box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
+ /* 与快捷问题按钮(.quick-question-chip)同款阴影 */
+ box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.14);
+ }
+
+ &.is-voice-mode {
+ background: transparent;
+ border-radius: 0;
+ padding: 0;
+ box-shadow: none;
}
- &.is-voice-mode .input-row-top,
&.is-text-mode .input-row-top {
background: transparent;
border-radius: 0;
@@ -5964,30 +6004,54 @@ _handleStreamError(msg) {
}
}
- /* 语音模式: 按住说话 */
- .voice-hold-btn {
+ /* 语音模式单行 (PR-VOICE-MODE-ONE-ROW-V2): 整行即白色胶囊(flex布局,不依赖绝对定位)
+ 键盘图标在左 / 按住说话占中间 / + 在右, 与参考稿一致 */
+ .voice-mode-row {
+ position: relative; /* 「上滑取消」提示 .voice-cancel-hint 锚定到这里 */
display: flex;
align-items: center;
- justify-content: center;
height: 96rpx;
margin: 4rpx 0 8rpx;
- border-radius: 16rpx;
- background: #f2f2f3;
- position: relative; // PR-FRONTEND-VOICE-INPUT: 让 .voice-cancel-hint 锚定到这里
+ padding: 0 10rpx 0 24rpx;
+ border-radius: 999rpx;
+ background: #ffffff;
+ box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.14);
transition: background-color 0.15s ease-out;
&.is-holding {
- background: #e2e2e4;
+ background: #f2f2f3;
}
// PR-FRONTEND-VOICE-INPUT (2026-09-24): 上滑到 80px+ 视为取消手势
&.is-cancelling {
background: #fdecec;
+
.voice-hold-text {
color: #d23f3f;
}
}
+ .voice-side-btn {
+ flex-shrink: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ .voice-side-right {
+ margin-left: 8rpx;
+ }
+
+ /* 按住说话区域: 透明, 占据中间剩余全部空间 */
+ .voice-hold-btn {
+ flex: 1;
+ height: 100%;
+ min-width: 0;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
.voice-hold-text {
font-size: 30rpx;
color: #1f1f1f;