<template>
|
<div class="chat-container">
|
<h2 class="chat-title">DeepSeek 聊天室</h2>
|
<div class="message-box">
|
<textarea
|
v-model="inputMessage"
|
placeholder="请输入您的消息..."
|
class="chat-input"
|
:disabled="isLoading"
|
></textarea>
|
<button
|
@click="sendMessage"
|
class="send-button"
|
:disabled="isLoading"
|
>
|
{{ isLoading ? '发送中...' : '发送消息' }}
|
</button>
|
</div>
|
<div class="response-area">
|
<p class="response-label">回复:</p>
|
<div class="response-content">{{ reply || '暂无回复' }}</div>
|
</div>
|
<p v-if="error" class="error-message">{{ error }}</p>
|
|
<!-- 遮罩层和加载动画 -->
|
<div v-if="isLoading" class="loading-overlay">
|
<div class="spinner"></div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
export default {
|
name: 'Chat',
|
data() {
|
return {
|
inputMessage: '',
|
reply: '',
|
error: '',
|
isLoading: false // 新增加载状态
|
};
|
},
|
methods: {
|
async sendMessage() {
|
if (!this.inputMessage.trim()) {
|
this.error = '消息不能为空';
|
return;
|
}
|
this.error = '';
|
this.reply = '';
|
this.isLoading = true; // 开始加载
|
|
try {
|
const response = await fetch('http://localhost:11434/api/chat', {
|
method: 'POST',
|
headers: {
|
'Content-Type': 'application/json'
|
},
|
body: JSON.stringify({
|
model: 'ltkj-jy-ai',
|
messages: [
|
{
|
role: 'system',
|
content: this.inputMessage
|
}
|
],
|
stream: false
|
})
|
});
|
|
if (!response.ok) {
|
throw new Error('网络响应错误');
|
}
|
|
const data = await response.json();
|
this.reply = data.message?.content || '收到回复,但格式可能不正确';
|
} catch (err) {
|
this.error = '请求出错: ' + err.message;
|
console.error('Fetch 错误:', err);
|
} finally {
|
this.isLoading = false; // 结束加载
|
}
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.chat-container {
|
max-width: 600px;
|
margin: 0 auto;
|
padding: 20px;
|
background: #f5f7fa;
|
border-radius: 10px;
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
position: relative; /* 为遮罩层定位 */
|
}
|
|
.chat-title {
|
color: #2c3e50;
|
text-align: center;
|
margin-bottom: 20px;
|
font-family: 'Arial', sans-serif;
|
}
|
|
.message-box {
|
display: flex;
|
flex-direction: column;
|
gap: 10px;
|
}
|
|
.chat-input {
|
width: 100%;
|
height: 120px;
|
padding: 15px;
|
border: 1px solid #ddd;
|
border-radius: 8px;
|
resize: none;
|
font-size: 14px;
|
background: #fff;
|
transition: border-color 0.3s;
|
}
|
|
.chat-input:focus {
|
outline: none;
|
border-color: #3498db;
|
box-shadow: 0 0 5px rgba(52, 152, 219, 0.3);
|
}
|
|
.chat-input:disabled {
|
background: #f0f0f0;
|
cursor: not-allowed;
|
}
|
|
.send-button {
|
padding: 10px 20px;
|
background: #3498db;
|
color: white;
|
border: none;
|
border-radius: 8px;
|
cursor: pointer;
|
font-size: 14px;
|
transition: background 0.3s;
|
align-self: flex-end;
|
}
|
|
.send-button:hover:not(:disabled) {
|
background: #2980b9;
|
}
|
|
.send-button:disabled {
|
background: #95a5a6;
|
cursor: not-allowed;
|
}
|
|
.response-area {
|
margin-top: 20px;
|
background: #fff;
|
padding: 15px;
|
border-radius: 8px;
|
border: 1px solid #eee;
|
}
|
|
.response-label {
|
margin: 0 0 10px 0;
|
color: #7f8c8d;
|
font-size: 14px;
|
}
|
|
.response-content {
|
color: #2c3e50;
|
line-height: 1.5;
|
word-wrap: break-word;
|
}
|
|
.error-message {
|
color: #e74c3c;
|
margin-top: 10px;
|
font-size: 14px;
|
text-align: center;
|
}
|
|
/* 遮罩层样式 */
|
.loading-overlay {
|
position: absolute;
|
top: 0;
|
left: 0;
|
width: 100%;
|
height: 100%;
|
background: rgba(0, 0, 0, 0.3);
|
display: flex;
|
justify-content: center;
|
align-items: center;
|
border-radius: 10px;
|
z-index: 10;
|
}
|
|
/* 加载动画 */
|
.spinner {
|
width: 40px;
|
height: 40px;
|
border: 4px solid #f3f3f3;
|
border-top: 4px solid #3498db;
|
border-radius: 50%;
|
animation: spin 1s linear infinite;
|
}
|
|
@keyframes spin {
|
0% { transform: rotate(0deg); }
|
100% { transform: rotate(360deg); }
|
}
|
</style>
|