134 lines
6.1 KiB
Plaintext
134 lines
6.1 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>A股AI分析Agent系统</title>
|
|
|
|
<!-- Bootstrap 5 CSS -->
|
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
|
|
|
<!-- 自定义样式 -->
|
|
<link rel="stylesheet" href="/static/css/style.css">
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<!-- 导航栏 -->
|
|
<nav class="navbar navbar-dark bg-primary">
|
|
<div class="container-fluid">
|
|
<span class="navbar-brand mb-0 h1">📈 A股AI分析Agent</span>
|
|
<button class="btn btn-outline-light btn-sm" @click="showSkillPanel = !showSkillPanel">
|
|
技能管理
|
|
</button>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="container-fluid h-100">
|
|
<div class="row h-100">
|
|
<!-- 主聊天区域 -->
|
|
<div class="col-md-9 chat-container">
|
|
<!-- 消息列表 -->
|
|
<div class="messages-container" ref="messagesContainer">
|
|
<div v-if="messages.length === 0" class="text-center text-muted mt-5">
|
|
<h4>欢迎使用A股AI分析Agent</h4>
|
|
<p>请输入股票代码或问题,例如:</p>
|
|
<ul class="list-unstyled">
|
|
<li>查询600519的实时行情</li>
|
|
<li>贵州茅台的技术指标</li>
|
|
<li>000001的K线图</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div v-for="(msg, index) in messages" :key="index"
|
|
:class="['message', msg.role === 'user' ? 'user-message' : 'assistant-message']">
|
|
<div class="message-content">
|
|
<div class="message-header">
|
|
<strong>{{ msg.role === 'user' ? '您' : 'AI助手' }}</strong>
|
|
<span class="message-time">{{ formatTime(msg.timestamp) }}</span>
|
|
</div>
|
|
<div class="message-body">
|
|
<pre v-if="msg.role === 'assistant'" class="mb-0">{{ msg.content }}</pre>
|
|
<p v-else class="mb-0">{{ msg.content }}</p>
|
|
|
|
<!-- 图表展示 -->
|
|
<div v-if="msg.metadata && msg.metadata.type === 'chart'" class="mt-3">
|
|
<div :id="'chart-' + index" class="chart-container"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="loading" class="message assistant-message">
|
|
<div class="message-content">
|
|
<div class="spinner-border spinner-border-sm" role="status">
|
|
<span class="visually-hidden">加载中...</span>
|
|
</div>
|
|
<span class="ms-2">AI正在思考...</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 输入框 -->
|
|
<div class="input-container">
|
|
<div class="input-group">
|
|
<input
|
|
type="text"
|
|
class="form-control"
|
|
v-model="userInput"
|
|
@keyup.enter="sendMessage"
|
|
placeholder="输入股票代码或问题..."
|
|
:disabled="loading"
|
|
>
|
|
<button
|
|
class="btn btn-primary"
|
|
@click="sendMessage"
|
|
:disabled="loading || !userInput.trim()"
|
|
>
|
|
发送
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 技能面板 -->
|
|
<div v-if="showSkillPanel" class="col-md-3 skill-panel">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">技能列表</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div v-if="skills.length === 0" class="text-muted">
|
|
加载中...
|
|
</div>
|
|
<div v-for="skill in skills" :key="skill.name" class="skill-item mb-3">
|
|
<div class="d-flex justify-content-between align-items-center">
|
|
<strong>{{ skill.name }}</strong>
|
|
<div class="form-check form-switch">
|
|
<input
|
|
class="form-check-input"
|
|
type="checkbox"
|
|
:checked="skill.enabled"
|
|
@change="toggleSkill(skill.name, $event.target.checked)"
|
|
>
|
|
</div>
|
|
</div>
|
|
<small class="text-muted">{{ skill.description }}</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Vue 3 -->
|
|
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
|
|
|
|
<!-- Lightweight Charts -->
|
|
<script src="https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js"></script>
|
|
|
|
<!-- 应用脚本 -->
|
|
<script src="/static/js/app.js"></script>
|
|
</body>
|
|
</html>
|