import MarkdownIt from '@/lib/markdown-it.min.js'; import hljs from "@/lib/highlight/highlight-uni.min.js"; import parseHtml from '@/lib/html-parser.js'; // import DOMPurify from '@/lib/dompurify@3.2.4es.js'; export let codeDataList = [] export let jobMoreMap = new Map() const md = new MarkdownIt({ html: true, // 允许 HTML 标签 linkify: true, // 自动解析 URL typographer: true, // 美化标点符号 tables: true, breaks: true, // 让 \n 自动换行 langPrefix: 'language-', // 代码高亮前缀 // 如果结果以
${result.jobTitle}
${result.salary}
${result.location}·${result.companyName}
${result.education}
${result.experience}
查看详情
` if (result.data) { jobMoreMap.set(jobId, result.data) domContext += `查看更多岗位
` } return domContext } } // 代码块 let preCode = "" try { preCode = hljs.highlightAuto(str).value } catch (err) { preCode = md.utils.escapeHtml(str); } // 以换行进行分割 , 按行拆分代码 const lines = preCode.split(/\n/).slice(0, -1); const html = lines .map((line, index) => line ? `
  • ${line}
  • ` : '
  • ' ) .join(''); // 代码复制功能 const cacheIndex = codeDataList.length; codeDataList.push(str); return `
    ${lang || 'plaintext'} 复制代码
      ${html}
    `; } }) function extractFirstJson(text) { let stack = []; let startIndex = -1; let endIndex = -1; for (let i = 0; i < text.length; i++) { const char = text[i]; if (char === '{') { if (stack.length === 0) startIndex = i; // 记录第一个 '{' 的位置 stack.push(char); } else if (char === '}') { stack.pop(); if (stack.length === 0) { endIndex = i; // 找到配对的 '}' break; } } } if (startIndex !== -1 && endIndex !== -1) { const jsonString = text.slice(startIndex, endIndex + 1); try { const jsonObject = JSON.parse(jsonString); return jsonObject; } catch (e) { return null; // 如果不是有效的 JSON } } return null; // 如果没有找到有效的 JSON 对象 } function safeExtractJson(text) { try { const jsonObject = extractFirstJson(text); return jsonObject } catch (e) { console.error('JSON 解析失败:', e); } return null; } export function clearJobMoreMap() { // 切换对话清空 jobMoreMap.clear() } export function parseMarkdown(content) { if (!content) { return [] //处理特殊情况,比如网络异常导致的响应的 content 的值为空 } // 过滤掉标签及其内容,这些是AI内部思考过程,不应该显示给用户 // 1. 处理原始标签(支持多行) content = content.replace(/<\s*think\s*>[\s\S]*?<\s*\/\s*think\s*>/gi, '') // 2. 处理HTML编码的标签 content = content.replace(/<\s*think\s*>[\s\S]*?<\s*\/\s*think\s*>/gi, '') // 3. 处理部分编码的标签 content = content.replace(/<\s*think\s*>/gi, '') content = content.replace(/<\s*\/\s*think\s*>/gi, '') codeDataList = [] const unsafeHtml = md.render(content || '') // 在markdown渲染后再次过滤,确保没有遗漏 let filteredHtml = unsafeHtml // 1. 处理原始标签(支持多行) filteredHtml = filteredHtml.replace(/<\s*think\s*>[\s\S]*?<\s*\/\s*think\s*>/gi, '') // 2. 处理HTML编码的标签 filteredHtml = filteredHtml.replace(/<\s*think\s*>[\s\S]*?<\s*\/\s*think\s*>/gi, '') // 3. 处理部分编码的标签 filteredHtml = filteredHtml.replace(/<\s*think\s*>/gi, '') filteredHtml = filteredHtml.replace(/<\s*\/\s*think\s*>/gi, '') // 4. 单独处理剩余的think标签对 filteredHtml = filteredHtml.replace(/<think>/gi, '') filteredHtml = filteredHtml.replace(/<\/think>/gi, '') filteredHtml = filteredHtml.replace(//gi, '') filteredHtml = filteredHtml.replace(/<\/think>/gi, '') // 根据平台返回不同的内容格式 // 微信小程序:返回rich-text组件支持的nodes格式 // H5:直接返回HTML字符串,避免HTML解析错误 if (process.env.UNI_PLATFORM === 'mp-weixin') { try { return parseHtml(filteredHtml) } catch (error) { console.error('HTML解析失败:', error) // 解析失败时返回空数组,避免页面崩溃 return [] } } else { // H5端直接返回HTML字符串 return filteredHtml } }