首先需要申请key: 地址
使用wx.request获取数据
js
const task = wx.request({
url: 'https://api.deepseek.com/chat/completions',
method: 'POST',
responseType: 'text',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
dataType: 'text', // 或 'json'
enableChunked: true,
data: {
messages: [{ role: 'user', 'content'}]
},
success: async function(res) {
const systemInfo = Taro.getSystemInfoSync()
// 兼容企微小程序不能使用onChunkReceived钩子的情况
if (systemInfo.environment === 'wxwork') {
if (res.data) {
const infoList = res.data.match(/data:\s*(\{[^}]*\})/g)
let data = ''
Taro.hideLoading()
for (let index = 0; index < infoList.length; index++) {
await new Promise(resolve => setTimeout(resolve, 80))
const jsonStr = infoList[index].replace(/^data:\s*/, '')
data += JSON.parse(jsonStr).content
that.setState({ deepSeekData: data })
if (index === infoList.length - 1) {
that.setState({
disabled: false
})
}
}
}
}
}
})
let bl = true
task.onChunkReceived((chunk) => {
const chunkText = SimpleTextDecoder(chunk.data); // 解码当前分块
const regList = chunkText.match(/data:\s*(\{[^}]*\})/g)
let deepSeekData = ''
if (chunkText.indexOf('data: [DONE]') > -1) {
request.post('admin/TransferStoreDeepseek', {
transfer_store_id: this.state.transferInfo.id,
deepseek: this.state.deepSeekData
})
this.setState({
disabled: false
})
} else {
if (!regList) return
regList.forEach((item) => {
if (bl) {
Taro.hideLoading()
bl = false
}
const jsonStr = item.replace(/^data:\s*/, '')
try {
deepSeekData += JSON.parse(jsonStr).content
} catch (e) {
console.error('解析JSON失败:', e, '原始数据:', jsonStr)
return null
}
})
this.setState({ deepSeekData: this.state.deepSeekData += deepSeekData });
}
});
渲染数据
使用markdown-it插件
js
npm install [email protected]
js
import { Button, View, RichText, Input } from '@tarojs/components';
import { parseMarkdownToHtml } from '@/utils/markdownParser';
import { filterHtmlForRichText } from '@/utils/htmlFilter';
import { SimpleTextDecoder} from '@/utils/SimpleTextDecoder';
<RichText nodes={filterHtmlForRichText(parseMarkdownToHtml(this.state.deepSeekData))} />
配置markdown
js
// utils/markdownParser.js
import markdownIt from 'markdown-it'
// 初始化 markdown-it 实例
const md = new markdownIt({
html: false, // 允许解析 HTML 标签
breaks: true, // 保留换行符
linkify: true, // 自动转换 URL 为链接
typographer: true // 启用智能标点替换
});
// Markdown 转 HTML
export function parseMarkdownToHtml(mdText) {
return md.render(mdText);
}
标签处理
js
// utils/htmlFilter.js
export function filterHtmlForRichText(html) {
// 转换不支持的标签(示例:表格转 div 布局)
let safeHtml = html
.replace(/<table>/g, '<div class="table">')
.replace(/<\/table>/g, '</div>')
.replace(/<tr>/g, '<div class="tr">')
.replace(/<\/tr>/g, '</div>')
.replace(/<td>/g, '<div class="td">')
.replace(/<\/td>/g, '</div>')
.replace(/<h1>/g, '<h1 class="h1">')
.replace(/<h3>/g, '<h3 class="h3">')
.replace(/<ul>/g, '<ul class="ul">')
.replace(/<li>/g, '<li class="li">')
.replace(/<ol>/g, '<ol class="ol">')
.replace(/<strong>/g, '<strong class="strong">')
// 移除危险标签(如 script)
safeHtml = safeHtml.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
return safeHtml;
}
UTF-8 解码
js
// utils/htmlFilter.js
//
export function SimpleTextDecoder (buffer) {
let str = '';
const uint8Array = new Uint8Array(buffer);
for (let i = 0; i < uint8Array.length; i++) {
str += String.fromCharCode(uint8Array[i]);
}
return decodeURIComponent(escape(str)); // UTF-8 解码
}
样式处理
css
.h1 {
font-size: 40px;
}
.h3 {
font-size: 32px;
line-height: 50px;
}
.ul, .ol {
padding-left: 36px;
}
.strong {
font-weight: normal;
}