uniapp+vue3 接入deepseek Ai

先注册deepseek开放平台账号,充值2元。

ai.js文件为封装的ai请求,其中'Authorization': 'Bearer (deepseek开放平台你自己注册的key)',

Bearer要保留并且后面留一个空格。

Ai.vue文件为对话页面。

ai.js全部代码:

复制代码
// ai.js

export function requestAI(prompt, history = []) {
  return new Promise((resolve, reject) => {
    // 构建消息历史
    const messages = [...history]
    if (messages.length === 0 || messages[messages.length - 1].role !== 'user') {
      messages.push({ role: "user", content: prompt })
    }

    uni.request({
      url: 'https://api.deepseek.com/chat/completions',
      method: 'POST',
      header: {
        'Authorization': 'Bearer (替换成自己的key)',
        'Content-Type': 'application/json'
      },
	  timeout: 300000, // 增加超时时间
      data: {
        model: "deepseek-chat",
        messages: messages,
        stream: false
      },
      success: (res) => {
		  console.log('ai:',res)
        if (res.statusCode === 200) {
          resolve(res.data.choices[0].message.content)
        } else {
          reject(new Error(`请求失败: ${res.statusCode}`))
        }
      },
      fail: (err) => {
        reject(err)
      }
    })
  })
}

Ai.vue全部代码:

复制代码
<template>
	<view class="container">
		<scroll-view class="chat-container" scroll-y="true" :scroll-top="scrollTop">
			<view v-for="(msg, index) in messages" :key="index" style="display: flex;justify-content: flex-end;">
				<!-- ai头像 -->
				<image v-if="msg.role == 'assistant'" src="/static/logo.png" mode="" style="width: 30px;height: 30px;border-radius: 50%;margin-right: 10px;"></image>
				<!-- 对话内容 -->
				<view :class="['message', msg.role]">
					<text class="content">{{ msg.content }}</text>
				</view>
				<!-- 自己头像 -->
				<image v-if="msg.role == 'user'" src="/static/img/touxiang1x.png" mode="" style="width: 30px;height: 30px;border-radius: 50%;margin-left: 10px;"></image>
			</view>
			<view v-if="status" class="Thinking">
				<text class="fontSize26" style="margin-right: 5px;">深度思考</text>
				<uv-loading-icon color="#a3a3a3" size="16"></uv-loading-icon>
			</view>
		</scroll-view>
		<view class="input-area">
			<input v-model="userInput" placeholder="请输入问题" @confirm="sendMessage" />
			<button @click="sendMessage">发送</button>
		</view>
	</view>
</template>

<script setup>
	import {
		ref,
		reactive,
		nextTick,
		onMounted
	} from 'vue'
	import {
		requestAI
	} from '@/common/ai.js'

	const userInput = ref('')
	const messages = reactive([])
	const scrollTop = ref(0)
	const status = ref(false)

	 // 页面加载时自动发送欢迎消息 
	onMounted(async () => { 
		messages.push({ role: 'assistant', content: '你好!我是AI助手,有什么我可以帮助你的吗?' }) 
		// 滚动到底部
		await nextTick() 
		scrollToBottom() 
	}) 
	// 添加用户消息
	const sendMessage = async () => {
		if (!userInput.value.trim()) return
		if (status.value) return

		// 添加用户消息
		messages.push({
			role: 'user',
			content: userInput.value
		})
		const userMessage = userInput.value
		userInput.value = ''

		// 滚动到底部
		await nextTick()
		scrollToBottom()
		status.value = true;//正在思考状态
		try {
			// 请求AI回复
			const res = await requestAI(userMessage, messages)
			messages.push({
				role: 'assistant',
				content: res
			})
		} catch (err) {
			console.error('调用AI失败:', err)
			messages.push({
				role: 'assistant',
				content: '抱歉,暂时无法获取回答'
			})
		}
		status.value = false;//正在思考状态
		// 滚动到底部
		await nextTick()
		scrollToBottom()
	}

	const scrollToBottom = () => {
		scrollTop.value = 999999
	}
</script>

<style lang="scss" scoped>
	.container {
		display: flex;
		flex-direction: column;
		padding: 10px;
		background-color: #f5f5f5;
	}

	.chat-container {
		height: 100%;
		flex: 1;
		margin-bottom: 10px;
		padding-bottom: 100px;
	}

	.message {
		padding: 10px;
		margin-bottom: 10px;
		border-radius: 10px;
		max-width: 80%;
	}

	.message.user {
		background-color: #007AFF;
		color: white;
		margin-left: auto;
		width: max-content;
	}

	.message.assistant {
		background-color: #eaeaea;
		color: black;
		margin-right: auto;
		width: max-content;
	}

	.input-area {
		display: flex;
		background-color: #fff;
		gap: 10px;
		position: fixed;
		width: 100%;
		left: 0;
		bottom: 0;
		padding: 10px;
		box-sizing: border-box;
	}

	input {
		flex: 1;
		padding: 0 10px;
		height: 40px;
		line-height: 40px;
		font-size: 30rpx;
		border: 1px solid #ddd;
		border-radius: 20px;
	}

	button {
		background-color: #007AFF;
		color: white;
		padding: 0px 20px;
		height: 40px;
		line-height: 40px;
		border: none;
		border-radius: 32px;
		cursor: pointer;
		font-size: 30rpx;
	}
	.Thinking{
		display: flex;
		justify-content: flex-start;
		align-items: center;
		background-color: #fff;
		border-radius: 3px;
		padding: 10rpx 20rpx;
		box-sizing: border-box;
		width: max-content;
		color: #666;
	}
</style>
相关推荐
weixin_449290013 小时前
Dify 三模式安全配置清单
ai
YDS8294 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
Agent手记5 小时前
异常考勤智能预警与处理与流程优化方案 | 基于企业级Agent的超自动化实战教程
运维·人工智能·ai·自动化
彦为君7 小时前
Agent 安全:从权限提示到沙箱隔离
python·ai·ai编程
程序鉴定师8 小时前
西安小程序制作的可靠选择与发展前景
大数据·小程序
一颗小青松8 小时前
uniapp输入框fixed定位,导致页面顶起解决方案
前端·uni-app
武子康9 小时前
调查研究-138 全球机器人产业深度调研报告【01 篇】:市场规模、竞争格局与商业化成熟 2026
服务器·数据库·ai·chatgpt·机器人·具身智能
创世宇图9 小时前
【AI入门知识点】LLM 原理是什么?为什么 ChatGPT 看起来像“会思考”?
人工智能·ai·llm·token
码途漫谈9 小时前
让 AI 编程不断线:9Router 的本地模型路由与 Token 节流术
人工智能·ai·开源·ai编程
周杰伦的稻香10 小时前
Ollama访问限制
nginx·ai