支持markdown格式显示,效果
This commit is contained in:
@@ -74,7 +74,21 @@
|
||||
<text class="qa-copy-btn-icon">⧉</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="qa-msg-text" selectable="true">{{ m.text }}</text>
|
||||
<!-- 用户消息仍按纯文本展示 -->
|
||||
<text
|
||||
v-if="m.role === 'user'"
|
||||
class="qa-msg-text"
|
||||
selectable="true"
|
||||
>{{ m.text }}</text>
|
||||
<!-- AI 消息支持 Markdown 渲染,保留纯文本兜底 -->
|
||||
<view
|
||||
v-else
|
||||
class="qa-msg-text qa-msg-text-markdown"
|
||||
>
|
||||
<rich-text
|
||||
:nodes="renderMarkdownNodes(m.text)"
|
||||
></rich-text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
@@ -601,7 +615,16 @@ export default {
|
||||
parsed.content ??
|
||||
parsed.answer ??
|
||||
parsed.text ??
|
||||
parsed.data ??
|
||||
parsed.result ??
|
||||
parsed.message ??
|
||||
parsed.output ??
|
||||
parsed.token ??
|
||||
'';
|
||||
// 若对象结构未知,至少回退到原始行,避免“有返回但前端无内容”
|
||||
if ((textToAppend === undefined || textToAppend === null || String(textToAppend) === '') && raw) {
|
||||
textToAppend = raw;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// 非 JSON 分片按纯文本处理
|
||||
@@ -850,6 +873,151 @@ export default {
|
||||
return String(value);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 非常轻量的 Markdown 转换,仅支持:
|
||||
* - 换行 => <br/>
|
||||
* - **加粗** => <strong>
|
||||
* - *斜体* => <em>
|
||||
* - 无序列表行 "- " => <ul><li>
|
||||
* - 代码块 ``` => <pre><code>
|
||||
* 复杂 Markdown 语法暂不完全覆盖,但足够保证结构清晰。
|
||||
*/
|
||||
parseInlineMarkdownToNodes(line) {
|
||||
const text = String(line || '');
|
||||
const nodes = [];
|
||||
const tokenRe = /(\*\*[^*]+\*\*|`[^`\n]+`|\*[^*\n]+\*)/g;
|
||||
let lastIndex = 0;
|
||||
let match = null;
|
||||
|
||||
while ((match = tokenRe.exec(text)) !== null) {
|
||||
const idx = match.index;
|
||||
if (idx > lastIndex) {
|
||||
nodes.push({ type: 'text', text: text.slice(lastIndex, idx) });
|
||||
}
|
||||
const token = match[0];
|
||||
if (token.startsWith('**') && token.endsWith('**')) {
|
||||
nodes.push({
|
||||
name: 'strong',
|
||||
attrs: { style: 'font-weight:600;' },
|
||||
children: [{ type: 'text', text: token.slice(2, -2) }]
|
||||
});
|
||||
} else if (token.startsWith('`') && token.endsWith('`')) {
|
||||
nodes.push({
|
||||
name: 'span',
|
||||
attrs: {
|
||||
style: 'font-family:monospace;background:#f2f2f4;padding:1px 4px;border-radius:3px;'
|
||||
},
|
||||
children: [{ type: 'text', text: token.slice(1, -1) }]
|
||||
});
|
||||
} else if (token.startsWith('*') && token.endsWith('*')) {
|
||||
nodes.push({
|
||||
name: 'em',
|
||||
attrs: { style: 'font-style:italic;' },
|
||||
children: [{ type: 'text', text: token.slice(1, -1) }]
|
||||
});
|
||||
} else {
|
||||
nodes.push({ type: 'text', text: token });
|
||||
}
|
||||
lastIndex = idx + token.length;
|
||||
}
|
||||
|
||||
if (lastIndex < text.length) {
|
||||
nodes.push({ type: 'text', text: text.slice(lastIndex) });
|
||||
}
|
||||
if (nodes.length === 0) {
|
||||
nodes.push({ type: 'text', text: '' });
|
||||
}
|
||||
return nodes;
|
||||
},
|
||||
renderMarkdownNodes(text) {
|
||||
try {
|
||||
const raw = String(text || '');
|
||||
const lines = raw.replace(/\r\n/g, '\n').split('\n');
|
||||
const nodes = [];
|
||||
let i = 0;
|
||||
let inCode = false;
|
||||
let codeLines = [];
|
||||
|
||||
while (i < lines.length) {
|
||||
const line = lines[i];
|
||||
|
||||
// 代码块围栏
|
||||
if (line.trim().startsWith('```')) {
|
||||
if (!inCode) {
|
||||
inCode = true;
|
||||
codeLines = [];
|
||||
} else {
|
||||
inCode = false;
|
||||
nodes.push({
|
||||
name: 'div',
|
||||
attrs: {
|
||||
style: 'background:#f7f7f9;border-radius:6px;padding:8px 10px;font-family:monospace;white-space:pre-wrap;word-break:break-word;'
|
||||
},
|
||||
children: [{ type: 'text', text: codeLines.join('\n') }]
|
||||
});
|
||||
}
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inCode) {
|
||||
codeLines.push(line);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 无序列表
|
||||
if (/^\s*-\s+/.test(line)) {
|
||||
const ulChildren = [];
|
||||
while (i < lines.length && /^\s*-\s+/.test(lines[i])) {
|
||||
const content = lines[i].replace(/^\s*-\s+/, '');
|
||||
ulChildren.push({
|
||||
name: 'li',
|
||||
attrs: { style: 'margin:4px 0;' },
|
||||
children: this.parseInlineMarkdownToNodes(content)
|
||||
});
|
||||
i += 1;
|
||||
}
|
||||
nodes.push({
|
||||
name: 'ul',
|
||||
attrs: { style: 'padding-left:18px;margin:6px 0;' },
|
||||
children: ulChildren
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// 空行
|
||||
if (!line.trim()) {
|
||||
nodes.push({ name: 'div', children: [{ type: 'text', text: ' ' }] });
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 普通段落
|
||||
nodes.push({
|
||||
name: 'div',
|
||||
attrs: { style: 'line-height:1.6;margin:2px 0;word-break:break-word;' },
|
||||
children: this.parseInlineMarkdownToNodes(line)
|
||||
});
|
||||
i += 1;
|
||||
}
|
||||
|
||||
// 兜底:如果代码块未闭合,也照样展示
|
||||
if (inCode && codeLines.length > 0) {
|
||||
nodes.push({
|
||||
name: 'div',
|
||||
attrs: {
|
||||
style: 'background:#f7f7f9;border-radius:6px;padding:8px 10px;font-family:monospace;white-space:pre-wrap;word-break:break-word;'
|
||||
},
|
||||
children: [{ type: 'text', text: codeLines.join('\n') }]
|
||||
});
|
||||
}
|
||||
|
||||
return nodes;
|
||||
} catch (e) {
|
||||
return [{ type: 'text', text: String(text || '') }];
|
||||
}
|
||||
},
|
||||
onSend() {
|
||||
const text = (this.message || '').trim();
|
||||
if (!text) {
|
||||
@@ -1060,6 +1228,48 @@ export default {
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
.qa-msg-text-markdown {
|
||||
padding-top: 6rpx;
|
||||
}
|
||||
|
||||
.md-root {
|
||||
font-size: 26rpx;
|
||||
line-height: 1.6;
|
||||
color: #333333;
|
||||
}
|
||||
|
||||
.md-root strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.md-root em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.md-root ul {
|
||||
padding-left: 32rpx;
|
||||
margin: 8rpx 0;
|
||||
}
|
||||
|
||||
.md-root li {
|
||||
margin: 4rpx 0;
|
||||
}
|
||||
|
||||
.md-code-block {
|
||||
background-color: #f7f7f9;
|
||||
border-radius: 8rpx;
|
||||
padding: 10rpx 14rpx;
|
||||
font-family: monospace;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.md-inline-code {
|
||||
font-family: monospace;
|
||||
background-color: #f2f2f4;
|
||||
padding: 2rpx 6rpx;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
/* 复制按钮在角上绝对定位;气泡已有左右 padding,再给正文加一点边距避免与 44rpx 按钮重叠 */
|
||||
.qa-msg--ai .qa-msg-text {
|
||||
padding-left: 40rpx;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -189,7 +189,7 @@ const _sfc_main = {
|
||||
}
|
||||
this.aiQaMainList = body.data || [];
|
||||
} catch (e) {
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_qa/general_qa/general_qa.vue:351", "[general_qa] fetchAiQaMainList error:", e);
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_qa/general_qa/general_qa.vue:365", "[general_qa] fetchAiQaMainList error:", e);
|
||||
common_vendor.index.showToast({ title: "加载失败", icon: "none" });
|
||||
this.aiQaMainList = [];
|
||||
} finally {
|
||||
@@ -276,7 +276,7 @@ const _sfc_main = {
|
||||
this.chatMessages = restored;
|
||||
} catch (e) {
|
||||
common_vendor.index.hideLoading();
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_qa/general_qa/general_qa.vue:448", "[general_qa] listByParentId error:", e);
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_qa/general_qa/general_qa.vue:462", "[general_qa] listByParentId error:", e);
|
||||
common_vendor.index.showToast({ title: "加载失败,请重试", icon: "none" });
|
||||
}
|
||||
},
|
||||
@@ -425,7 +425,10 @@ const _sfc_main = {
|
||||
if (parentId) {
|
||||
this.sessionParentId = String(parentId);
|
||||
}
|
||||
textToAppend = parsed.delta ?? parsed.content ?? parsed.answer ?? parsed.text ?? "";
|
||||
textToAppend = parsed.delta ?? parsed.content ?? parsed.answer ?? parsed.text ?? parsed.data ?? parsed.result ?? parsed.message ?? parsed.output ?? parsed.token ?? "";
|
||||
if ((textToAppend === void 0 || textToAppend === null || String(textToAppend) === "") && raw) {
|
||||
textToAppend = raw;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
}
|
||||
@@ -483,7 +486,7 @@ const _sfc_main = {
|
||||
this.chatMessages.push({ role: "ai", text: this.normalizeText(rawAnswer) });
|
||||
}).catch((err) => {
|
||||
common_vendor.index.hideLoading();
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_qa/general_qa/general_qa.vue:673", "[general_qa] askAI error:", err);
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_qa/general_qa/general_qa.vue:696", "[general_qa] askAI error:", err);
|
||||
this.chatMessages.push({ role: "ai", text: (err == null ? void 0 : err.errMsg) || "调用失败,请重试" });
|
||||
}).finally(() => {
|
||||
this.sending = false;
|
||||
@@ -511,7 +514,7 @@ const _sfc_main = {
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_qa/general_qa/general_qa.vue:770", "[general_qa] askAIStream error:", err);
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_qa/general_qa/general_qa.vue:793", "[general_qa] askAIStream error:", err);
|
||||
const idx = this.streamAiMsgIndex;
|
||||
if (idx >= 0 && this.chatMessages[idx]) {
|
||||
const raw = String(this.chatMessages[idx].text || "").trim();
|
||||
@@ -544,7 +547,7 @@ const _sfc_main = {
|
||||
this.streamBuffer += chunk;
|
||||
this.flushStreamBuffer(false);
|
||||
} catch (e) {
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_qa/general_qa/general_qa.vue:811", "[general_qa] stream chunk parse error:", e);
|
||||
common_vendor.index.__f__("error", "at pages-subpackage/ai_qa/general_qa/general_qa.vue:834", "[general_qa] stream chunk parse error:", e);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@@ -587,6 +590,136 @@ const _sfc_main = {
|
||||
return String(value);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 非常轻量的 Markdown 转换,仅支持:
|
||||
* - 换行 => <br/>
|
||||
* - **加粗** => <strong>
|
||||
* - *斜体* => <em>
|
||||
* - 无序列表行 "- " => <ul><li>
|
||||
* - 代码块 ``` => <pre><code>
|
||||
* 复杂 Markdown 语法暂不完全覆盖,但足够保证结构清晰。
|
||||
*/
|
||||
parseInlineMarkdownToNodes(line) {
|
||||
const text = String(line || "");
|
||||
const nodes = [];
|
||||
const tokenRe = /(\*\*[^*]+\*\*|`[^`\n]+`|\*[^*\n]+\*)/g;
|
||||
let lastIndex = 0;
|
||||
let match = null;
|
||||
while ((match = tokenRe.exec(text)) !== null) {
|
||||
const idx = match.index;
|
||||
if (idx > lastIndex) {
|
||||
nodes.push({ type: "text", text: text.slice(lastIndex, idx) });
|
||||
}
|
||||
const token = match[0];
|
||||
if (token.startsWith("**") && token.endsWith("**")) {
|
||||
nodes.push({
|
||||
name: "strong",
|
||||
attrs: { style: "font-weight:600;" },
|
||||
children: [{ type: "text", text: token.slice(2, -2) }]
|
||||
});
|
||||
} else if (token.startsWith("`") && token.endsWith("`")) {
|
||||
nodes.push({
|
||||
name: "span",
|
||||
attrs: {
|
||||
style: "font-family:monospace;background:#f2f2f4;padding:1px 4px;border-radius:3px;"
|
||||
},
|
||||
children: [{ type: "text", text: token.slice(1, -1) }]
|
||||
});
|
||||
} else if (token.startsWith("*") && token.endsWith("*")) {
|
||||
nodes.push({
|
||||
name: "em",
|
||||
attrs: { style: "font-style:italic;" },
|
||||
children: [{ type: "text", text: token.slice(1, -1) }]
|
||||
});
|
||||
} else {
|
||||
nodes.push({ type: "text", text: token });
|
||||
}
|
||||
lastIndex = idx + token.length;
|
||||
}
|
||||
if (lastIndex < text.length) {
|
||||
nodes.push({ type: "text", text: text.slice(lastIndex) });
|
||||
}
|
||||
if (nodes.length === 0) {
|
||||
nodes.push({ type: "text", text: "" });
|
||||
}
|
||||
return nodes;
|
||||
},
|
||||
renderMarkdownNodes(text) {
|
||||
try {
|
||||
const raw = String(text || "");
|
||||
const lines = raw.replace(/\r\n/g, "\n").split("\n");
|
||||
const nodes = [];
|
||||
let i = 0;
|
||||
let inCode = false;
|
||||
let codeLines = [];
|
||||
while (i < lines.length) {
|
||||
const line = lines[i];
|
||||
if (line.trim().startsWith("```")) {
|
||||
if (!inCode) {
|
||||
inCode = true;
|
||||
codeLines = [];
|
||||
} else {
|
||||
inCode = false;
|
||||
nodes.push({
|
||||
name: "div",
|
||||
attrs: {
|
||||
style: "background:#f7f7f9;border-radius:6px;padding:8px 10px;font-family:monospace;white-space:pre-wrap;word-break:break-word;"
|
||||
},
|
||||
children: [{ type: "text", text: codeLines.join("\n") }]
|
||||
});
|
||||
}
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (inCode) {
|
||||
codeLines.push(line);
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
if (/^\s*-\s+/.test(line)) {
|
||||
const ulChildren = [];
|
||||
while (i < lines.length && /^\s*-\s+/.test(lines[i])) {
|
||||
const content = lines[i].replace(/^\s*-\s+/, "");
|
||||
ulChildren.push({
|
||||
name: "li",
|
||||
attrs: { style: "margin:4px 0;" },
|
||||
children: this.parseInlineMarkdownToNodes(content)
|
||||
});
|
||||
i += 1;
|
||||
}
|
||||
nodes.push({
|
||||
name: "ul",
|
||||
attrs: { style: "padding-left:18px;margin:6px 0;" },
|
||||
children: ulChildren
|
||||
});
|
||||
continue;
|
||||
}
|
||||
if (!line.trim()) {
|
||||
nodes.push({ name: "div", children: [{ type: "text", text: " " }] });
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
nodes.push({
|
||||
name: "div",
|
||||
attrs: { style: "line-height:1.6;margin:2px 0;word-break:break-word;" },
|
||||
children: this.parseInlineMarkdownToNodes(line)
|
||||
});
|
||||
i += 1;
|
||||
}
|
||||
if (inCode && codeLines.length > 0) {
|
||||
nodes.push({
|
||||
name: "div",
|
||||
attrs: {
|
||||
style: "background:#f7f7f9;border-radius:6px;padding:8px 10px;font-family:monospace;white-space:pre-wrap;word-break:break-word;"
|
||||
},
|
||||
children: [{ type: "text", text: codeLines.join("\n") }]
|
||||
});
|
||||
}
|
||||
return nodes;
|
||||
} catch (e) {
|
||||
return [{ type: "text", text: String(text || "") }];
|
||||
}
|
||||
},
|
||||
onSend() {
|
||||
const text = (this.message || "").trim();
|
||||
if (!text) {
|
||||
@@ -659,32 +792,37 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
||||
k: $data.chatMessages.length === 0
|
||||
}, $data.chatMessages.length === 0 ? {} : {
|
||||
l: common_vendor.f($data.chatMessages, (m, i, i0) => {
|
||||
return {
|
||||
return common_vendor.e({
|
||||
a: common_vendor.o(($event) => $options.copyText(m.text), i),
|
||||
b: common_vendor.n(m.role === "ai" ? "qa-msg-actions--left" : "qa-msg-actions--right"),
|
||||
c: common_vendor.t(m.text),
|
||||
d: i,
|
||||
e: common_vendor.n(m.role === "user" ? "qa-msg--user" : "qa-msg--ai")
|
||||
};
|
||||
c: m.role === "user"
|
||||
}, m.role === "user" ? {
|
||||
d: common_vendor.t(m.text)
|
||||
} : {
|
||||
e: $options.renderMarkdownNodes(m.text)
|
||||
}, {
|
||||
f: i,
|
||||
g: common_vendor.n(m.role === "user" ? "qa-msg--user" : "qa-msg--ai")
|
||||
});
|
||||
})
|
||||
}, {
|
||||
m: -1,
|
||||
n: $data.message,
|
||||
o: common_vendor.o(($event) => $data.message = $event.detail.value, "a5"),
|
||||
o: common_vendor.o(($event) => $data.message = $event.detail.value, "ee"),
|
||||
p: common_vendor.p({
|
||||
type: "top",
|
||||
size: "18",
|
||||
color: "#fff"
|
||||
}),
|
||||
q: common_vendor.o((...args) => $options.onSend && $options.onSend(...args), "f0"),
|
||||
q: common_vendor.o((...args) => $options.onSend && $options.onSend(...args), "bc"),
|
||||
r: common_vendor.n($data.useStreamOutput ? "qa-chip-stream--active" : ""),
|
||||
s: common_vendor.o((...args) => $options.toggleStreamOutput && $options.toggleStreamOutput(...args), "c2"),
|
||||
s: common_vendor.o((...args) => $options.toggleStreamOutput && $options.toggleStreamOutput(...args), "35"),
|
||||
t: common_vendor.p({
|
||||
type: "left",
|
||||
size: "18",
|
||||
color: "#666"
|
||||
}),
|
||||
v: common_vendor.o((...args) => $options.goBack && $options.goBack(...args), "d7"),
|
||||
v: common_vendor.o((...args) => $options.goBack && $options.goBack(...args), "bd"),
|
||||
w: $data.safeBottom + "px"
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
<view class="qa-page data-v-135ac533"><view class="qa-header data-v-135ac533" style="{{'padding-top:' + c}}"><view class="qa-header-bar data-v-135ac533"><view class="qa-header-left data-v-135ac533" bindtap="{{a}}"><view class="qa-header-menu-line data-v-135ac533"></view><view class="qa-header-menu-line qa-header-menu-line-short data-v-135ac533"></view></view><text class="qa-header-title data-v-135ac533">新对话</text><view class="qa-header-right data-v-135ac533" bindtap="{{b}}"><text class="qa-header-plus data-v-135ac533">+</text></view></view></view><view wx:if="{{d}}" class="main-list-mask data-v-135ac533" bindtap="{{e}}"></view><view wx:if="{{f}}" class="main-list-drawer data-v-135ac533"><view class="main-list-drawer-header data-v-135ac533"><text class="main-list-drawer-title data-v-135ac533">对话列表</text><view class="main-list-drawer-close data-v-135ac533" catchtap="{{g}}"><text class="data-v-135ac533">关闭</text></view></view><scroll-view class="main-list-scroll data-v-135ac533" scroll-y="true"><view wx:if="{{h}}" class="main-list-loading data-v-135ac533">加载中...</view><view wx:else class="data-v-135ac533"><view wx:for="{{i}}" wx:for-item="g" wx:key="c" class="main-list-group data-v-135ac533"><view class="main-list-group-title data-v-135ac533">{{g.a}}</view><view wx:for="{{g.b}}" wx:for-item="item" wx:key="b" class="main-list-item data-v-135ac533" catchtap="{{item.c}}"><text class="main-list-item-text data-v-135ac533">{{item.a}}</text></view></view><view wx:if="{{j}}" class="main-list-empty data-v-135ac533"> 暂无数据 </view></view></scroll-view></view><view wx:if="{{k}}" class="qa-main data-v-135ac533"><view class="qa-main-icon-wrapper data-v-135ac533"><text class="qa-main-icon data-v-135ac533">Q</text></view><text class="qa-main-text data-v-135ac533" selectable="true">今天有什么可以帮到你?</text></view><scroll-view wx:else class="qa-chat data-v-135ac533" scroll-y="true"><view class="qa-chat-inner data-v-135ac533"><view wx:for="{{l}}" wx:for-item="m" wx:key="d" class="{{['qa-msg', 'data-v-135ac533', m.e]}}"><view class="{{['qa-msg-actions', 'data-v-135ac533', m.b]}}"><view class="qa-copy-btn data-v-135ac533" catchtap="{{m.a}}"><text class="qa-copy-btn-icon data-v-135ac533">⧉</text></view></view><text class="qa-msg-text data-v-135ac533" selectable="true">{{m.c}}</text></view></view></scroll-view><view class="qa-input-wrapper data-v-135ac533" style="{{'padding-bottom:' + w}}"><view class="qa-input-row data-v-135ac533"><view class="qa-input-box data-v-135ac533"><block wx:if="{{r0}}"><textarea class="qa-textarea data-v-135ac533" placeholder="发送消息或按住说话" placeholder-class="qa-input-placeholder" auto-height="{{true}}" maxlength="{{m}}" value="{{n}}" bindinput="{{o}}"></textarea></block></view><view class="qa-input-send data-v-135ac533" bindtap="{{q}}"><uni-icons wx:if="{{p}}" class="data-v-135ac533" u-i="135ac533-0" bind:__l="__l" u-p="{{p}}"></uni-icons></view></view><view class="qa-input-actions data-v-135ac533"><view class="{{['qa-chip', 'qa-chip-stream', 'data-v-135ac533', r]}}" bindtap="{{s}}"><text class="qa-chip-stream-icon data-v-135ac533">∿</text><text class="qa-chip-stream-text data-v-135ac533">流式</text></view><view class="qa-chip data-v-135ac533" bindtap="{{v}}"><uni-icons wx:if="{{t}}" class="data-v-135ac533" u-i="135ac533-1" bind:__l="__l" u-p="{{t}}"></uni-icons></view></view></view></view>
|
||||
<view class="qa-page data-v-135ac533"><view class="qa-header data-v-135ac533" style="{{'padding-top:' + c}}"><view class="qa-header-bar data-v-135ac533"><view class="qa-header-left data-v-135ac533" bindtap="{{a}}"><view class="qa-header-menu-line data-v-135ac533"></view><view class="qa-header-menu-line qa-header-menu-line-short data-v-135ac533"></view></view><text class="qa-header-title data-v-135ac533">新对话</text><view class="qa-header-right data-v-135ac533" bindtap="{{b}}"><text class="qa-header-plus data-v-135ac533">+</text></view></view></view><view wx:if="{{d}}" class="main-list-mask data-v-135ac533" bindtap="{{e}}"></view><view wx:if="{{f}}" class="main-list-drawer data-v-135ac533"><view class="main-list-drawer-header data-v-135ac533"><text class="main-list-drawer-title data-v-135ac533">对话列表</text><view class="main-list-drawer-close data-v-135ac533" catchtap="{{g}}"><text class="data-v-135ac533">关闭</text></view></view><scroll-view class="main-list-scroll data-v-135ac533" scroll-y="true"><view wx:if="{{h}}" class="main-list-loading data-v-135ac533">加载中...</view><view wx:else class="data-v-135ac533"><view wx:for="{{i}}" wx:for-item="g" wx:key="c" class="main-list-group data-v-135ac533"><view class="main-list-group-title data-v-135ac533">{{g.a}}</view><view wx:for="{{g.b}}" wx:for-item="item" wx:key="b" class="main-list-item data-v-135ac533" catchtap="{{item.c}}"><text class="main-list-item-text data-v-135ac533">{{item.a}}</text></view></view><view wx:if="{{j}}" class="main-list-empty data-v-135ac533"> 暂无数据 </view></view></scroll-view></view><view wx:if="{{k}}" class="qa-main data-v-135ac533"><view class="qa-main-icon-wrapper data-v-135ac533"><text class="qa-main-icon data-v-135ac533">Q</text></view><text class="qa-main-text data-v-135ac533" selectable="true">今天有什么可以帮到你?</text></view><scroll-view wx:else class="qa-chat data-v-135ac533" scroll-y="true"><view class="qa-chat-inner data-v-135ac533"><view wx:for="{{l}}" wx:for-item="m" wx:key="f" class="{{['qa-msg', 'data-v-135ac533', m.g]}}"><view class="{{['qa-msg-actions', 'data-v-135ac533', m.b]}}"><view class="qa-copy-btn data-v-135ac533" catchtap="{{m.a}}"><text class="qa-copy-btn-icon data-v-135ac533">⧉</text></view></view><text wx:if="{{m.c}}" class="qa-msg-text data-v-135ac533" selectable="true">{{m.d}}</text><view wx:else class="qa-msg-text qa-msg-text-markdown data-v-135ac533"><rich-text class="data-v-135ac533" nodes="{{m.e}}"></rich-text></view></view></view></scroll-view><view class="qa-input-wrapper data-v-135ac533" style="{{'padding-bottom:' + w}}"><view class="qa-input-row data-v-135ac533"><view class="qa-input-box data-v-135ac533"><block wx:if="{{r0}}"><textarea class="qa-textarea data-v-135ac533" placeholder="发送消息或按住说话" placeholder-class="qa-input-placeholder" auto-height="{{true}}" maxlength="{{m}}" value="{{n}}" bindinput="{{o}}"></textarea></block></view><view class="qa-input-send data-v-135ac533" bindtap="{{q}}"><uni-icons wx:if="{{p}}" class="data-v-135ac533" u-i="135ac533-0" bind:__l="__l" u-p="{{p}}"></uni-icons></view></view><view class="qa-input-actions data-v-135ac533"><view class="{{['qa-chip', 'qa-chip-stream', 'data-v-135ac533', r]}}" bindtap="{{s}}"><text class="qa-chip-stream-icon data-v-135ac533">∿</text><text class="qa-chip-stream-text data-v-135ac533">流式</text></view><view class="qa-chip data-v-135ac533" bindtap="{{v}}"><uni-icons wx:if="{{t}}" class="data-v-135ac533" u-i="135ac533-1" bind:__l="__l" u-p="{{t}}"></uni-icons></view></view></view></view>
|
||||
@@ -142,6 +142,40 @@
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
.qa-msg-text-markdown.data-v-135ac533 {
|
||||
padding-top: 6rpx;
|
||||
}
|
||||
.md-root.data-v-135ac533 {
|
||||
font-size: 26rpx;
|
||||
line-height: 1.6;
|
||||
color: #333333;
|
||||
}
|
||||
.md-root strong.data-v-135ac533 {
|
||||
font-weight: 600;
|
||||
}
|
||||
.md-root em.data-v-135ac533 {
|
||||
font-style: italic;
|
||||
}
|
||||
.md-root ul.data-v-135ac533 {
|
||||
padding-left: 32rpx;
|
||||
margin: 8rpx 0;
|
||||
}
|
||||
.md-root li.data-v-135ac533 {
|
||||
margin: 4rpx 0;
|
||||
}
|
||||
.md-code-block.data-v-135ac533 {
|
||||
background-color: #f7f7f9;
|
||||
border-radius: 8rpx;
|
||||
padding: 10rpx 14rpx;
|
||||
font-family: monospace;
|
||||
overflow-x: auto;
|
||||
}
|
||||
.md-inline-code.data-v-135ac533 {
|
||||
font-family: monospace;
|
||||
background-color: #f2f2f4;
|
||||
padding: 2rpx 6rpx;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
/* 复制按钮在角上绝对定位;气泡已有左右 padding,再给正文加一点边距避免与 44rpx 按钮重叠 */
|
||||
.qa-msg--ai .qa-msg-text.data-v-135ac533 {
|
||||
|
||||
Reference in New Issue
Block a user