Files
electron-opencode/src/renderer/views/home/HomeView.vue
2026-04-12 10:34:33 +08:00

326 lines
6.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="home-container">
<!-- 中间内容区标题副标题卡片 -->
<div class="center-content">
<!-- 第一行标题 -->
<div class="title-section">
<span class="title-highlight"></span>
<span class="title-normal mr-4">鉴万物</span>
<span class="title-highlight"></span>
<span class="title-normal">知明理 </span>
</div>
<!-- 第二行副标题 -->
<div class="subtitle-section">本地运行自主规划安全可控的AI工作搭子</div>
<!-- 第三行卡片 -->
<div class="card-section flex gap-8 items-center">
<div class="feature-card">
<div class="card-icon">
<el-icon :size="42"><Document /></el-icon>
</div>
<div class="card-title">智能文档处理</div>
<div class="card-desc">支持多种格式文档的智能解析与处理</div>
</div>
<div class="feature-card">
<div class="card-icon">
<el-icon :size="42"><Document /></el-icon>
</div>
<div class="card-title">智能文档处理</div>
<div class="card-desc">支持多种格式文档的智能解析与处理</div>
</div>
<div class="feature-card">
<div class="card-icon">
<el-icon :size="42"><Document /></el-icon>
</div>
<div class="card-title">智能文档处理</div>
<div class="card-desc">支持多种格式文档的智能解析与处理</div>
</div>
</div>
</div>
<!-- 底部输入框 -->
<div class="input-section">
<div class="input-wrapper">
<textarea
v-model="inputText"
class="input-textarea"
placeholder="描述任务,/ 调用技能与工具,@调用知识库"
:disabled="isCreating"
@keydown="handleKeydown"
></textarea>
<div class="input-toolbar">
<div class="toolbar-left">
<button class="toolbar-btn file-btn">
<el-icon><Plus /></el-icon>
<span>添加文件</span>
</button>
<button class="toolbar-btn symbol-btn">/</button>
<button class="toolbar-btn symbol-btn">@</button>
</div>
<div class="toolbar-right">
<button class="send-btn" :disabled="!inputText.trim() || isCreating" @click="handleSend">
<el-icon><Promotion /></el-icon>
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { useHistoryStore } from '@/stores/history';
import { Document, Plus, Promotion } from '@element-plus/icons-vue';
const router = useRouter();
const historyStore = useHistoryStore();
const inputText = ref('');
const isCreating = ref(false);
// 处理发送消息
async function handleSend() {
const text = inputText.value.trim();
if (!text || isCreating.value) return;
isCreating.value = true;
try {
// 创建会话title 使用用户输入的文本
const session = await historyStore.createSession(text);
console.log('创建会话成功:', session);
// 清空输入框
inputText.value = '';
// 跳转到对话页面
router.push({
path: '/chat',
query: { sessionId: session.id },
});
} catch (err) {
console.error('创建会话失败:', err);
} finally {
isCreating.value = false;
}
}
// 处理键盘事件
function handleKeydown(e) {
// Enter 发送Shift+Enter 换行
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
handleSend();
}
}
</script>
<style scoped>
.home-container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
background: #ffffff;
position: relative;
}
/* 中间内容区 */
.center-content {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 24px;
width: 100%;
}
/* 第一行:标题 */
.title-section {
display: flex;
align-items: center;
justify-content: center;
gap: 0;
}
.title-highlight {
font-weight: 900;
font-size: 42px;
line-height: 48px;
letter-spacing: -0.39px;
text-align: center;
color: #409eff;
}
.title-normal {
font-weight: 900;
font-size: 42px;
line-height: 48px;
letter-spacing: -0.39px;
text-align: center;
color: #303133;
}
/* 第二行:副标题 */
.subtitle-section {
font-weight: 400;
font-size: 14px;
line-height: 22.75px;
letter-spacing: -0.15px;
text-align: center;
color: #606266;
}
/* 第三行:卡片 */
.card-section {
margin: 16px 0;
}
.feature-card {
width: 220px;
height: 158px;
border: 1px solid #e4e7ed;
border-radius: 8px;
display: flex;
flex-direction: column;
padding: 25px 16px;
gap: 8px;
background: #ffffff;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
}
.card-icon {
width: 42px;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
color: #409eff;
margin-bottom: 4px;
}
.card-title {
font-weight: 600;
font-size: 14px;
line-height: 20px;
letter-spacing: 0.55px;
color: #303133;
}
.card-desc {
font-weight: 400;
font-size: 12px;
line-height: 16px;
color: #909399;
}
/* 底部:输入框 */
.input-section {
margin-top: auto;
padding-top: 24px;
}
.input-wrapper {
width: 760px;
height: 114px;
border-radius: 12px;
border: 1px solid #dcdfe6;
display: flex;
flex-direction: column;
background: #ffffff;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
}
.input-textarea {
width: 758px;
height: 60px;
padding: 16px;
border: none;
outline: none;
resize: none;
font-size: 14px;
line-height: 20px;
color: #303133;
background: transparent;
font-family: inherit;
}
.input-textarea::placeholder {
color: #c0c4cc;
}
.input-toolbar {
height: 54px;
padding: 0 16px;
display: flex;
align-items: center;
justify-content: space-between;
border-top: 1px solid #ebeef5;
}
.toolbar-left {
display: flex;
align-items: center;
gap: 8px;
}
.toolbar-btn {
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #dcdfe6;
background: #ffffff;
cursor: pointer;
transition: all 0.2s ease;
color: #606266;
}
.toolbar-btn:hover {
border-color: #409eff;
color: #409eff;
}
.file-btn {
width: 84px;
height: 28px;
gap: 4px;
padding: 0 8px;
border-radius: 6px;
font-size: 12px;
}
.symbol-btn {
width: 28px;
height: 28px;
padding: 0;
border-radius: 6px;
font-size: 12px;
font-weight: 500;
}
.toolbar-right {
display: flex;
align-items: center;
}
.send-btn {
width: 32px;
height: 32px;
border: none;
background: #409eff;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s ease;
color: #ffffff;
}
.send-btn:hover {
background: #66b1ff;
}
</style>