diff --git a/.local.config.js b/.local.config.js
index 1902e69..4d86284 100644
--- a/.local.config.js
+++ b/.local.config.js
@@ -62,5 +62,5 @@ const localDevConfig = ({
uniacid: 2075,
domain: 'https://xcx.aigc-quickapp.com/',
},
-})['2811']; // 选择要使用的环境配置
+})['1']; // 选择要使用的环境配置
export default localDevConfig;
\ No newline at end of file
diff --git a/pages_tool/ai-chat/ai-chat-message.vue b/pages_tool/ai-chat/ai-chat-message.vue
index 2eddd4d..60ce73a 100644
--- a/pages_tool/ai-chat/ai-chat-message.vue
+++ b/pages_tool/ai-chat/ai-chat-message.vue
@@ -1126,20 +1126,190 @@ async loadChatHistoryIfExist() {
}
return `感谢您的咨询!关于"${userMessage}"的问题,我们的专业客服会尽快为您解答。您也可以查看我们的帮助文档获取更多信息。`;
},
-
-
- // 解析Markdown
+
+
+ // 增强版Markdown解析(无第三方依赖)
parseMarkdown(content) {
if (!content) return ''
-
- // 简单的Markdown解析
+
+ // 辅助:内联格式处理
+ const parseInline = (text) => {
+ return text
+ // 行内图片
+ .replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '
')
+ // 链接
+ .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1')
+ // 行内代码
+ .replace(/`([^`]+)`/g, '$1')
+ // 粗体(优先匹配**)
+ .replace(/\*\*(.+?)\*\*/g, '$1')
+ // 斜体
+ .replace(/\*(.+?)\*/g, '$1')
+ // 删除线
+ .replace(/~~(.+?)~~/g, '$1')
+ // 手机号
+ .replace(/\b(1[3-9]\d{9})\b/g, '$1')
+ // 400电话
+ .replace(/\b(400[\d-]{7,10})\b/g, '$1')
+ }
+
+ // 1. 转义HTML特殊字符
let html = content
- .replace(/\*\*(.*?)\*\*/g, '$1') // 粗体
- .replace(/\*(.*?)\*/g, '$1') // 斜体
- .replace(/`(.*?)`/g, '$1') // 代码
- .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1') // 链接
- .replace(/\n/g, '
') // 换行
-
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+
+ // 2. 提取代码块(保护其内容不被后续处理污染)
+ const codeBlocks = []
+ html = html.replace(/```(\w*)\n?([\s\S]*?)```/g, (m, lang, code) => {
+ const idx = codeBlocks.length
+ const safe = code.replace(//g, '>')
+ codeBlocks.push(
+ `
` +
+ `${safe}
`
+ )
+ return `%%CODEBLOCK_${idx}%%`
+ })
+
+ // 3. 按行处理,用
连接单换行,双换行分割段落块
+ const lines = html.split('\n')
+ const out = []
+ let inList = false
+ let buf = [] // 普通文本行缓冲区
+ let inTable = false
+ let tableRows = [] // 表格行缓冲区
+
+ const closeList = () => {
+ if (inList === 'ul') { inList = false; return '' }
+ if (inList === 'ol') { inList = false; return '' }
+ return ''
+ }
+ const flushBuf = () => {
+ if (buf.length === 0) return
+ // 去掉首尾的空串,避免产生尾随
+ while (buf.length > 0 && buf[0] === '') buf.shift()
+ while (buf.length > 0 && buf[buf.length - 1] === '') buf.pop()
+ if (buf.length === 0) return
+ const content = buf.map(l => parseInline(l)).join('
')
+ out.push(`${content}
`)
+ buf = []
+ }
+ const flushTable = () => {
+ if (!inTable || tableRows.length === 0) return
+ const thead = tableRows[0].map(c =>
+ `${parseInline(c)} | `
+ ).join('')
+ const tbody = tableRows.slice(1).map(row =>
+ '' + row.map(c =>
+ `| ${parseInline(c)} | `
+ ).join('') + '
'
+ ).join('')
+ out.push(
+ ``
+ )
+ tableRows = []
+ inTable = false
+ }
+
+ for (let i = 0; i < lines.length; i++) {
+ const line = lines[i]
+ const trimmed = line.trim()
+
+ // 代码块占位符
+ if (/^%%CODEBLOCK_\d+%%$/.test(trimmed)) {
+ flushBuf(); flushTable(); out.push(closeList())
+ out.push(line)
+ continue
+ }
+
+ // 表格行(以 | 开头)
+ if (trimmed.charAt(0) === '|') {
+ flushBuf(); out.push(closeList())
+ // 去除首尾空 cell
+ const rawCells = trimmed.split('|').filter((c, j, a) => j > 0 && j < a.length - 1)
+ if (rawCells.length === 0) continue
+ // 跳过分隔行 | --- | :--- | :---: | ---: |
+ const isSep = rawCells.every(c => /^[\s:\-|]+$/.test(c.trim()))
+ if (isSep) continue
+ if (!inTable) { inTable = true; tableRows = [] }
+ tableRows.push(rawCells.map(c => c.trim()))
+ continue
+ }
+ // 非表格行 → 刷新已积累的表格
+ if (inTable) flushTable()
+
+ // 标题
+ const hMatch = line.match(/^(#{1,6})\s+(.+)$/)
+ if (hMatch) {
+ flushBuf(); out.push(closeList())
+ const lv = hMatch[1].length
+ const size = ['', '40rpx', '36rpx', '32rpx', '28rpx', '26rpx', '24rpx'][lv]
+ const wgt = ['', '700', '700', '600', '600', '500', '500'][lv]
+ const mg = ['', '20rpx 0 10rpx', '16rpx 0 8rpx', '14rpx 0 6rpx', '12rpx 0 6rpx', '10rpx 0 4rpx', '8rpx 0 4rpx'][lv]
+ out.push(`${parseInline(hMatch[2])}`)
+ continue
+ }
+
+ // 分隔线
+ if (/^(-{3,}|\*{3,}|_{3,})\s*$/.test(trimmed)) {
+ flushBuf(); out.push(closeList())
+ out.push('
')
+ continue
+ }
+
+ // 引用
+ const bqMatch = line.match(/^>\s?(.+)$/)
+ if (bqMatch) {
+ flushBuf(); out.push(closeList())
+ out.push(`${parseInline(bqMatch[1])}
`)
+ continue
+ }
+
+ // 无序列表
+ const ulMatch = line.match(/^[-*+]\s+(.+)$/)
+ if (ulMatch) {
+ flushBuf()
+ if (!inList) { out.push(''); inList = 'ul' }
+ out.push(`- ${parseInline(ulMatch[1])}
`)
+ continue
+ }
+
+ // 有序列表
+ const olMatch = line.match(/^\d+\.\s+(.+)$/)
+ if (olMatch) {
+ flushBuf()
+ if (!inList) { out.push(''); inList = 'ol' }
+ out.push(`- ${parseInline(olMatch[1])}
`)
+ continue
+ }
+
+ // 空行 → 加入缓冲区作段落分隔(
),同时关闭列表
+ if (trimmed === '') {
+ // 关闭列表(标准Markdown行为)
+ if (inList) {
+ flushBuf()
+ out.push(closeList())
+ }
+ // 避免连续空行推入多个空串
+ if (buf.length > 0 && buf[buf.length - 1] !== '') {
+ buf.push('')
+ }
+ continue
+ }
+
+ // 普通文本行 => 加入缓冲区
+ buf.push(line)
+ }
+
+ // 扫尾
+ flushBuf(); flushTable(); out.push(closeList())
+
+ html = out.join('')
+
+ // 4. 还原代码块
+ html = html.replace(/%%CODEBLOCK_(\d+)%%/g, (m, idx) => codeBlocks[parseInt(idx)])
+
return html
},
@@ -2045,7 +2215,7 @@ $radius-lg: 36rpx;
.message-content {
flex: 1;
margin-left: 24rpx;
- max-width: calc(100% - 112rpx);
+ max-width: calc(100% - 96rpx);
min-width: 0;
width: 0; /* 添加这个属性防止flex元素溢出 */
@@ -2543,7 +2713,6 @@ $radius-lg: 36rpx;
height: auto;
padding: 16rpx 20rpx; /* 微信风格内边距 */
display: inline-block;
- max-width: 70%; /* 微信风格宽度 */
word-break: break-word;
white-space: pre-wrap;
line-height: 1.5;
@@ -2580,7 +2749,6 @@ $radius-lg: 36rpx;
height: auto;
padding: 16rpx 20rpx; /* 微信风格内边距 */
display: inline-block;
- max-width: 70%; /* 微信风格宽度 */
word-break: break-word;
white-space: pre-wrap;
line-height: 1.5;
@@ -3513,7 +3681,7 @@ $radius-lg: 36rpx;
.message-content {
margin-left: 16rpx;
- max-width: calc(100% - 88rpx);
+ max-width: calc(100% - 72rpx);
.message-bubble {
padding: 16rpx 24rpx;