腾讯云AI代码助手编程挑战赛-知识百科AI
作品简介
知识百科AI这一编程主要用于对于小朋友的探索力的开发,让小朋友在一开始就对学习具有探索精神。在信息化时代下,会主动去学习自己认知以外的知识,同时丰富了眼界,开拓了新的知识。同时催生了在大数据时代下的信息共享化,让我们能了解到更多的知识。
技术架构
使用python语言的TK库莱完成图形化页面的样式,使用python语言来操作对应的逻辑代码。
实现过程
1、创建窗体
2、准备数据集
3、添加按钮与功能
4、页面显示优化
开发环境,开发流程
系统:win11系统
工具:VSCode开发工具
插件:安装腾讯云AI代码助手插件
关键技术解析
过程中的异常解决,如提示没有引进数据包
腾讯云AI代码助手在上述过程中的助力
完整的助力于开发的整个生命周期,包括初始页面到数据展示以及操作。
使用说明
1、解压并配置node.js环境变量
2、使用npm i命令初始化项目
3、使用npm run dev启动项目
4、访问http://localhost:3005/进行提问即可。
在对话框中提问问题,AI就会自动给出答案
项目源码
<template>
<!-- ...其他代码不变 -->
<!-- 新增感谢提示框 -->
<div v-if="showThankYouDialog" class="thank-you-dialog">
感谢您的支持!
</div>
<!-- ...其他代码不变 -->
<t-chat
ref="chatRef"
layout="single"
style="height: 600px"
:clear-history="chatList.length > 0 && !isStreamLoad"
@clear="clearConfirm"
>
<template v-for="(item, index) in chatList" :key="index">
<t-chat-item
:avatar="item.avatar"
:name="item.name"
:role="item.role"
:datetime="item.datetime"
:content="item.content"
:text-loading="index === 0 && loading"
>
<template v-if="!isStreamLoad" #actions>
<t-chat-action
:is-good="isGood"
:is-bad="isBad"
:content="item.content"
@operation="(type, { e }) => handleOperation(type, { e, index })"
/>
</template>
</t-chat-item>
</template>
<template #footer>
<t-chat-input :stop-disabled="isStreamLoad" @send="inputEnter" @stop="onStop"> </t-chat-input>
</template>
</t-chat>
</template>
<script setup>
import { ref } from 'vue';
const fetchCancel = ref(null);
const loading = ref(false);
const isStreamLoad = ref(false);
const isGood = ref(false);
const isBad = ref(false);
const chatRef = ref(null);
// 新增一个ref来控制提示框的显示与隐藏
const showThankYouDialog = ref(false);
// 滚动到底部
const backBottom = () => {
chatRef.value.scrollToBottom({
behavior: 'smooth',
});
};
// 倒序渲染
const chatList = ref([
{
content: `模型由 <span>hunyuan</span> 变为 <span>GPT4</span>`,
role: 'model-change',
},
{
avatar: 'https://tdesign.gtimg.com/site/chat-avatar.png',
name: 'TD&AI',
datetime: '今天16:38',
content: '它叫 McMurdo Station ATM,是美国富国银行安装在南极洲最大科学中心麦克默多站的一台自动提款机。',
role: 'assistant',
},
{
avatar: 'https://tdesign.gtimg.com/site/avatar.jpg',
name: '自己',
datetime: '今天16:38',
content: '南极的自动提款机叫什么名字?',
role: 'user',
},
]);
const clearConfirm = function () {
chatList.value = [];
};
const onStop = function () {
if (fetchCancel.value) {
fetchCancel.value.abort();
loading.value = false;
isStreamLoad.value = false;
}
};
const handleOperation = function (type, options) {
const { index } = options;
if (type === 'good') {
isGood.value = !isGood.value;
isBad.value = false;
// 显示感谢提示框
showThankYouDialog.value = true;
// 1秒后隐藏提示框
setTimeout(() => {
showThankYouDialog.value = false;
}, 1000);
} else if (type === 'bad') {
// ...其他代码不变
} else if (type === 'replay') {
// ...其他代码不变
}
};
const handleData = async (inputValue) => {
loading.value = true;
isStreamLoad.value = true;
const lastItem = chatList.value[0];
const messages = [{
role: 'user',
content: inputValue,
}];
fetchSSE(messages, {
success(result) {
loading.value = false;
const { data } = result;
lastItem.content += data?.delta?.content;
},
complete(isOk, msg) {
if (!isOk || !lastItem.content) {
lastItem.role = 'error';
lastItem.content = msg;
}
// 控制终止按钮
isStreamLoad.value = false;
loading.value = false;
},
cancel(cancel) {
fetchCancel.value = cancel;
},
});
};
const inputEnter = function (inputValue) {
if (isStreamLoad.value) {
return;
}
if (!inputValue) return;
const params = {
avatar: 'https://tdesign.gtimg.com/site/avatar.jpg',
name: '提问人',
datetime: new Date().toDateString(),
content: inputValue,
role: 'user',
};
chatList.value.unshift(params);
// 空消息占位
const params2 = {
avatar: 'https://tdesign.gtimg.com/site/chat-avatar.png',
name: '知识百科AI',
datetime: new Date().toDateString(),
content: '',
role: 'assistant',
};
chatList.value.unshift(params2);
handleData(inputValue);
};
// 解析SSE数据
const fetchSSE = async (messages, options) => {
const { success, fail, complete, cancel } = options;
const controller = new AbortController();
const { signal } = controller;
cancel?.(controller);
// your-api-key
const apiKey = 'sk-6R0hq8U7v3bSbT1u41Lp6kPRwAgf9wnW73WgvSC7WUI73eRO';
const responsePromise = fetch('/v1/chat/completions', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer${apiKey ? ` ${apiKey}` : ''}`,
},
body: JSON.stringify({
messages, // 消息列表
model: 'hunyuan-pro', // 模型
stream: true, // 流式
}),
signal,
}).catch((e) => {
const msg = e.toString() || '流式接口异常';
complete?.(false, msg);
return Promise.reject(e); // 确保错误能够被后续的.catch()捕获
});
responsePromise
.then((response) => {
if (!response?.ok) {
complete?.(false, response.statusText);
fail?.();
throw new Error('Request failed'); // 抛出错误以便链式调用中的下一个.catch()处理
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
if (!reader) throw new Error('No reader available');
const bufferArr = [];
let dataText = ''; // 记录数据
const event = { type: null, data: null };
async function processText({ done, value }) {
if (done) {
complete?.(true);
return Promise.resolve();
}
const chunk = decoder.decode(value);
const buffers = chunk.toString().split(/\r?\n/);
bufferArr.push(...buffers);
const i = 0;
while (i < bufferArr.length) {
const line = bufferArr[i];
if (line) {
dataText += line;
const response = line.slice(6);
if (response === '[DONE]') {
event.type = 'finish';
dataText = '';
} else {
const choices = JSON.parse(response.trim())?.choices?.[0];
if (choices.finish_reason === 'stop') {
event.type = 'finish';
dataText = '';
} else {
event.type = 'delta';
event.data = choices;
}
}
}
if (event.type && event.data) {
const jsonData = JSON.parse(JSON.stringify(event));
// debugger;
success(jsonData);
event.type = null;
event.data = null;
}
bufferArr.splice(i, 1);
}
return reader.read().then(processText);
}
return reader.read().then(processText);
})
.catch(() => {
// 处理整个链式调用过程中发生的任何错误
fail?.();
});
};
</script>
<style lang="less" scoped>
/* 设置对话背景色为淡蓝色 */
.t-chat {
background-color: burlywood; /* 淡蓝色 */
}
/* 设置对话文字颜色为红色并加粗 */
.t-chat-item__content {
color: red; /* 红色 */
font-weight: bold; /* 加粗 */
}
/* 如果您还想改变输入框的样式,可以添加以下规则 */
.t-chat-input {
/* 输入框样式 */
}
</style>
效果展示