UniApp集成DeepSeek实现跨平台AI对话开发指南

Viewed 0

基于 uni-appvue3 整合对接 deepseek-v3,实战开发一套支持跨平台(小程序、Web、App端)的流式输出AI问答系统。该系统被命名为 uni-vue3-deepseek。

该项目支持暗黑与亮色主题模式,并可编译运行至 H5、小程序及 App 端。

技术栈

项目采用以下技术栈进行构建:

  • 开发工具:Hbuilder X 4.57
  • 核心技术框架:Uniapp + Vue3 + Pinia2 + Vite5.x
  • 大模型框架:DeepSeek-V3
  • UI组件库:uni-ui 与 uv-ui
  • 代码高亮:highlight.js
  • Markdown解析:ua-markdown
  • 本地缓存:pinia-plugin-unistorage
  • 支持平台:H5、小程序、APP端

项目结构与框架

本项目使用 uniapp 搭配 vue3 搭建整体框架,并整合了 deepseek-v3 以实现流式AI对话功能。

核心配置

main.js 配置

main.js 中使用 createSSRApp 创建应用实例,并引入 Pinia 进行状态管理。

import App from './App'
import { createSSRApp } from 'vue'
// 引入pinia状态管理
import pinia from '@/pinia'

export function createApp() {
    const app = createSSRApp(App)
    app.use(pinia)
    return {
        app,
        pinia
    }
}

环境变量配置

在项目根目录下创建 .env 配置文件,用于管理API密钥等敏感信息。

# 项目名称
VITE_APPNAME = 'Uniapp-DeepSeek'

# 运行端口
VITE_PORT = 5173

# DeepSeek API配置
VITE_DEEPSEEK_API_KEY = 替换为你的APIKey
VITE_DEEPSEEK_BASE_URL = https://api.deepseek.com

项目模板与布局

项目采用了一个包含导航栏、聊天主区域和底部输入框的布局。主视图根据当前会话状态动态显示聊天记录或欢迎信息。

欢迎界面展示了项目Logo和简介,并提供了示例提问选项,用户可以点击或更换这些提示语。

聊天编辑器部分支持 Markdown 内容的解析与渲染,具备以下特性:

  • 支持代码块的横向滚动显示。
  • 可显示代码行号(关闭可提升性能)。
  • 提供代码复制功能(H5/App端)。
  • 图片渲染宽度自适应为100%。
  • 支持图片预览功能(H5/App端)。
  • 支持链接跳转功能(H5/App端)。

跨端流式输出实现

为实现不同平台下的流式输出,项目采用了平台特定的实现方案。

H5 和 APP 端:通过 renderjs 模式下的 fetch 方法调用 DeepSeek API,并设置 stream: true 开启流式传输。

// #ifdef APP-PLUS || H5
this.fetchAppH5({
    url: baseURL+'/v1/chat/completions',
    method: 'POST',
    headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${apiKEY}`,
    },
    body: {
        messages: this.multiConversation ? this.historySession : [{role: 'user', content: editorValue}],
        model: 'deepseek-chat', // 也可使用 deepseek-reasoner 推理模型
        stream: true, // 流式输出
        max_tokens: 8192,
        temperature: 0.4,
    }
})
// #endif

小程序端:使用 uni.request 并开启 enableChunked: true 选项以实现分块流式传输,通过 onChunkReceived 事件回调处理接收到的数据块。

// #ifdef MP-WEIXIN
try {
    const requestTask = await uni.request({
        url: baseURL+'/v1/chat/completions',
        method: 'POST',
        header: {
            "Content-Type": "application/json",
            "Authorization": `Bearer ${apiKEY}`,
        },
        data: {
            messages: this.multiConversation ? this.historySession : [{role: 'user', content: editorValue}],
            model: 'deepseek-chat',
            stream: true,
            max_tokens: 8192,
            temperature: 0.4,
        },
        enableChunked: true, // 开启分块传输
    })
    requestTask.onChunkReceived((res) => {
        const uint8Array = new Uint8Array(res.data)
        let text = String.fromCharCode.apply(null, uint8Array)
        const buffer = decodeURIComponent(escape(text))
        this.parseBuffer(buffer) // 解析数据
    })
} catch (error) {
    // 错误处理...
}
// #endif
0 Answers