这里写目录标题
获取gpt-3.5-turbo的API
这是一个非常艰难的过程,很多api的使用都有局限
使用OpenAI
- 首先需要下载OpenAI
npm i openai
- 然后需要获得你的apikey
- 根据官网配置接口,其中await函数的请求方法与往常不同,client是我封装的方法,其中有我的apikey,注意保密自己的密钥
const response = await client.chat.completions.create(
{
messages: [{ role: 'user', content }],
model: 'gpt-3.5-turbo',
//只生成一条信息
n: 1,
max_tokens: 200,
// stream: true,
}
)
还要解析返回的信息
const aiMessage=response.choices[0].message.content
成功发送请求后就可以使用接口了
编写关于AI的其他接口
实现不同用户将保存他与ai的聊天记录,点击图片可以实现清除记录
保存记录
const saveMessage = async (userID, type, text) => {
const query = 'INSERT INTO chatmessages (user_id, type, text) VALUES (?, ?, ?)';
const values = [userID, type, text];
try {
await db.execute(query, values);
} catch (error) {
console.error('保存消息错误:', error);
}
};
获得记录
const getMessages = async (userID) => {
const query = 'SELECT * FROM chatmessages WHERE user_id = ? ORDER BY timestamp ASC';
const values = [userID];
try {
const [rows] = await db.execute(query, values);
return rows; // 返回聊天记录
} catch (error) {
console.error('获取消息错误:', error);
return [];
}
};
然后要封装接口在前端使用
清除记录
// 清除聊天记录的 API
exports.clearChatHistory = async (ctx) => {
const { userID } = ctx.request.body; // 从请求体获取 userID
console.log('获取的 userID:', userID);
if (!userID) {
ctx.response.status = 400;
ctx.response.body = { error: '缺少 userID' };
return;
}
const query = 'DELETE FROM chatmessages WHERE user_id = ?';
const values = [userID];
try {
const result = await db.execute(query, values);
const affectedRows = result[0].affectedRows; // 假设使用的数据库库支持这样获取影响的行数
if (affectedRows === 0) {
ctx.response.status = 404;
ctx.response.body = { error: '未找到聊天记录' };
return;
}
console.log(`用户 ID ${userID} 的聊天记录已被清除`);
ctx.response.body = {
status: 200,
message: `用户 ID ${userID} 的聊天记录已成功删除`,
};
} catch (error) {
console.error('清除消息错误:', error);
ctx.response.status = 500; // 内部服务器错误
ctx.response.body = { error: '清除消息时发生错误' };
}
};
简单画个ai聊天页面(仿豆包)
献上源码,其中使用了yesicon图标库
js实现霓虹灯效果部分·
const text = ref('小智为你答疑解惑'); // 初始文本
const characters = ref(text.value.split('')); // 存储分割后的字符
const checkedItems = ref(new Array(characters.value.length).fill(false)); // 用于存储复选框的状态
const toggleGlow = (index) => {
checkedItems.value[index] = !checkedItems.value[index]; // 切换复选框状态
};
template部分
<div class="title">
<div id="box">
<div
v-for="(char, index) in characters"
:key="index"
class="child"
@click="toggleGlow(index)"
>
<input type="checkbox" v-model="checkedItems[index]" style="display: none;" /> <!-- 隐藏复选框 -->
<div
class="item"
:class="{ glow: checkedItems[index] }"
>
{{ char }}
</div>
</div>
</div>
</div>
<div class="chat-container">
<div class="chat-box" id="chatBox">
<div class="messages" id="chatContainer">
<div v-for="(msg, index) in messages" :key="index" class="chat-message">
<div :class="msg.type === 'user' ? 'user-message' : 'ai-message'">
<p>{{ msg.text }}</p>
</div>
</div>
</div>
</div>
<div class="input-area">
<div class="clear" @click="clear">
<svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" viewBox="0 0 1024 1024"><path fill="#0891b2" d="m899.1 869.6l-53-305.6H864c14.4 0 26-11.6 26-26V346c0-14.4-11.6-26-26-26H618V138c0-14.4-11.6-26-26-26H432c-14.4 0-26 11.6-26 26v182H160c-14.4 0-26 11.6-26 26v192c0 14.4 11.6 26 26 26h17.9l-53 305.6c-.3 1.5-.4 3-.4 4.4c0 14.4 11.6 26 26 26h723c1.5 0 3-.1 4.4-.4c14.2-2.4 23.7-15.9 21.2-30M204 390h272V182h72v208h272v104H204zm468 440V674c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v156H416V674c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v156H202.8l45.1-260H776l45.1 260z"/></svg>
</div>
<input
type="text"
class="input-field"
v-model="inputText"
placeholder="请发消息~您的小助手已上线"
@keyup.enter="sendMessage"
:disabled="isSending"
/>
<button class="send-button" @click="sendMessage" :disabled="isSending">
<svg xmlns="http://www.w3.org/2000/svg" width="1.5em" height="1.5em" viewBox="0 0 24 24"><g fill="none"><path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z"/><path fill="#ffffff" d="M20.25 3.532a1 1 0 0 1 1.183 1.329l-6 15.5a1 1 0 0 1-1.624.362l-3.382-3.235l-1.203 1.202c-.636.636-1.724.186-1.724-.714v-3.288L2.309 9.723a1 1 0 0 1 .442-1.691l17.5-4.5Zm-2.114 4.305l-7.998 6.607l3.97 3.798zm-1.578-1.29L4.991 9.52l3.692 3.53l7.875-6.505Z"/></g></svg>
</button>
</div>
</div>
</template>
css
<style>
.title {
position: relative;
width: 380px;
}
#box {
/* position: relative; */
position: absolute;
display: flex;
flex-wrap: wrap;
}
.child {
display: flex;
align-items: center;
margin-bottom: 5px;
}
.item {
position: relative;
height: 80px;
width: 80px;
background: #cbcbce;
color: #555;
font-size: 46px;
line-height: 80px;
text-align: center;
cursor: pointer;
margin: 0 4px;
border-radius: 20px;
box-shadow: -1px -1px 4px rgba(255, 255, 255, 0.05),
4px 4px 6px rgba(0, 0, 0, 0.2),
inset -1px -1px 4px rgba(255, 255, 255, 0.05),
inset 1px 1px 1px rgba(0, 0, 0, 0.1);
}
.glow {
box-shadow: inset 0 0 2px rgba(255, 255, 255, 0.05),
inset 4px 4px 6px rgba(0, 0, 0, 0.2);
color: rgb(233, 233, 112);
text-shadow: 0 0 15px rgb(233, 233, 112), 0 0 25px rgb(233, 233, 112);
animation: glow 2s ease-in-out infinite;
}
@keyframes glow {
0% {
filter: hue-rotate(0deg);
}
100% {
filter: hue-rotate(360deg);
}
}
.chat-container {
display: flex;
flex-direction: column;
height: 85vh;
max-width: 600px;
margin: auto;
border-radius: 8px;
overflow: hidden;
}
.chat-box {
flex: 1;
overflow-y: auto; /*允许垂直滚动*/
padding: 10px;
}
.messages {
display: flex;
flex-direction: column;
}
.chat-message {
margin: 5px 0;
display: flex;
}
.user-message {
background-color: #d8dad9;
padding: 10px;
border-radius: 10px;
align-self: flex-end;
margin-left: auto; /* 向左的外边距自动填充,从而靠右 */
}
.ai-message {
padding: 10px;
border-radius: 10px;
align-self: flex-start;
margin-right: auto; /* 向右的外边距自动填充,从而靠左 */
}
.input-area {
display: flex;
padding: 10px 28px;
background-color: rgb(242, 243, 245);
border-radius: 20px;
border:1px solid #ccc;
position: relative;
/* box-shadow: 0 6px 10px 0 rgba(42, 60, 79, .1); */
}
.input-field {
flex: 1;
border: none;
border-radius: 4px;
outline: none;
background-color: rgb(242, 243, 245);
font-size: 15px;
}
.send-button {
/* width: 50px; */
border: none;
background-color: #46af5d; /* 发送按钮颜色 */
border-radius: 10px;
cursor: pointer;
}
.clear {
cursor: pointer;
position: absolute;
left: 1px;
top: 17px;
}
.send-button:disabled {
background-color: #99c4a2; /* 禁用状态颜色 */
}
</style>
难点
- 获得一个可以使用的api,并且配置
- 解析获得的数据并用于使用
- 数据库的搭建然后使用,过程中使用到很多名词,可能会混淆导致接收消息错误