1. 配置基础的uni.request服务
ts
复制代码
// 基础URL
const baseUrl = 'localhost:3000';
// 扩展请求方法参数,新增 headers 配置
type Method = 'GET' | 'POST' | 'PUT' | 'DELETE';
// 通用请求函数(新增 headers 参数)
const request = (
url: string,
method: Method,
data?: any,
headers?: Record<string, string>
) => {
return new Promise((resolve, reject) => {
const fullUrl = url.startsWith('http') ? url : `${baseUrl}${url}`;
// 合并默认 header 和自定义 header
const mergedHeaders: Record<string, string> = {
'Content-Type': 'application/json', // 默认保留
...headers, // 合并自定义 header(可覆盖默认值)
};
// 创建一个请求task
const requestTask = uni.request({
url: fullUrl,
method: method,
data: data,
header: mergedHeaders, // 使用合并后的 header
enableChunked: true,
success: (res) => {
resolve(res);
},
fail: (err) => {
reject(err);
},
});
// 返回一个包含流式处理方法的对象
resolve({
onHeadersReceived: (callback: (headers: any) => void) => {
requestTask.onHeadersReceived((res) => {
callback(res.header);
});
},
onChunkReceived: (callback: (chunk: any) => void) => {
(requestTask as any).onChunkReceived((res: any) => {
callback(res.data);
});
},
abort: () => {
requestTask.abort();
},
});
});
};
// GET请求方法(保持原有参数)
const get = (url: string, data?: any) => {
return request(url, 'GET', data);
};
// POST请求方法(新增 headers 参数)
const post = (url: string, data: any, headers?: Record<string, string>) => {
return request(url, 'POST', data, headers);
};
// 导出GET和POST方法
export { get, post };
2.编程专属的ai请求文件
ts
复制代码
// 引入基础请求方法
import { post } from './api.config';
import { SSEHandler } from "@/types/baseType";
const accessToken = 'sk-xxx';
export const callAliyunAI = async (userInput: string, history: Array<{ role: string, content: string }> = []): Promise<SSEHandler> => {
const url = 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions';
const headers = {
'Authorization': `Bearer ${accessToken}`,
// 'Content-Type': 'text/event-stream',
// 'Cache-Control': 'no-cache',
'X-DashScope-SSE': 'enable',
// 'Coneection': 'keep-alive'
};
const messages = [
...history, // 添加历史对话记录
{
role: "user",
content: userInput // 当前用户输入
}
];
const data = {
model: 'qwen-plus',
messages: messages,
stream: true,
};
try {
const response = await post(url, data, headers);
return response as SSEHandler;
} catch (error: any) {
throw new Error(`调用AI模型失败: ${error.message}`);
}
};
- 页面中多轮对话关键代码
ts
复制代码
// 发送消息
const sendMessage = async () => {
if (input.value.trim() !== "") {
messages.value.push({ role: "user", content: input.value });
const userInput = input.value;
input.value = "";
try {
// 调用 AI 接口,传入用户输入
const sseHandler = await callAliyunAI(userInput, messages.value);
sseHandler.onHeadersReceived((headers: Record<string, string>) => {
console.log("响应头:", headers);
});
// // 处理流式数据
sseHandler.onChunkReceived((chunk: ArrayBuffer) => {
console.log("接收到数据:", chunk);
parseData(chunk); // 数据解析 并填充到对话框
});
} catch (error) {
console.error("调用AI模型失败:", error);
messages.value.push({
role: "system",
content: "调用AI模型失败,请重试。",
});
}
}
};
// 解析函数
const parseData = (data: ArrayBuffer) => {
// 将 ArrayBuffer 转换为字符串
const decoder = new TextDecoder("utf-8");
const rawString = decoder.decode(data);
// 按 "data: " 分割字符串,处理多条数据
const jsonStrings = rawString
.split("data: ")
.filter((str) => str.trim() !== "");
console.log("jsonStrings", jsonStrings);
jsonStrings.forEach((jsonString) => {
try {
// 判断是否结束
if (jsonString.indexOf("[DONE]") !== -1) {
console.log("数据流结束");
return;
}
// 解析 JSON 字符串
const messageData = JSON.parse(jsonString);
const message = messageData.choices[0].delta.content || "";
const lastMessage = messages.value[messages.value.length - 1];
if (lastMessage.role === "assistant") {
lastMessage.content += message;
} else {
messages.value.push({ role: "assistant", content: message });
}
nextTick(() => {
scrollIntoView.value = `msg-${messages.value.length - 1}`;
});
} catch (error) {
console.error("解析数据失败:", error);
}
});
};