Files
tsp-assistant/src/web/templates/dashboard.html
zhaojie 23f460d997 fix: 修复Agent执行历史为空的问题
- 在Agent初始化时添加示例执行历史
- 添加触发示例动作和清空历史的功能
- 完善Agent执行历史的显示界面
- 添加执行历史的操作按钮(触发示例、刷新、清空)
- 优化执行历史的显示格式,包括优先级、置信度、执行时间等
- 修复前端Agent数据加载逻辑
2025-09-11 00:01:12 +08:00

1492 lines
74 KiB
HTML
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.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TSP智能助手 - 综合管理平台</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.css" rel="stylesheet">
<style>
:root {
--primary-color: #007bff;
--success-color: #28a745;
--warning-color: #ffc107;
--danger-color: #dc3545;
--info-color: #17a2b8;
--dark-color: #343a40;
--light-color: #f8f9fa;
}
body {
background-color: #f5f6fa;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.navbar-brand {
font-weight: bold;
font-size: 1.5rem;
}
.sidebar {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
box-shadow: 2px 0 10px rgba(0,0,0,0.1);
}
.sidebar .nav-link {
color: rgba(255,255,255,0.8);
padding: 0.75rem 1rem;
border-radius: 0.5rem;
margin: 0.25rem 0;
transition: all 0.3s ease;
}
.sidebar .nav-link:hover,
.sidebar .nav-link.active {
color: white;
background-color: rgba(255,255,255,0.1);
transform: translateX(5px);
}
.sidebar .nav-link i {
width: 20px;
margin-right: 0.5rem;
}
.main-content {
padding: 2rem;
}
.card {
border: none;
border-radius: 1rem;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 8px 25px rgba(0,0,0,0.15);
}
.stat-card {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 1rem;
padding: 1.5rem;
margin-bottom: 1rem;
}
.stat-card.success {
background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
}
.stat-card.warning {
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
}
.stat-card.danger {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}
.stat-card.info {
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
}
.stat-number {
font-size: 2.5rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
.stat-label {
font-size: 0.9rem;
opacity: 0.9;
}
.chat-container {
height: 500px;
border-radius: 1rem;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.chat-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 1rem;
}
.chat-messages {
height: 350px;
overflow-y: auto;
padding: 1rem;
background-color: #f8f9fa;
}
.message {
margin-bottom: 1rem;
display: flex;
align-items: flex-start;
}
.message.user {
justify-content: flex-end;
}
.message.assistant {
justify-content: flex-start;
}
.message-content {
max-width: 70%;
padding: 0.75rem 1rem;
border-radius: 1rem;
position: relative;
}
.message.user .message-content {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-bottom-right-radius: 0.25rem;
}
.message.assistant .message-content {
background: white;
color: #333;
border: 1px solid #dee2e6;
border-bottom-left-radius: 0.25rem;
}
.message-time {
font-size: 0.75rem;
opacity: 0.7;
margin-top: 0.25rem;
}
.chat-input {
padding: 1rem;
background: white;
border-top: 1px solid #dee2e6;
}
.alert-item {
border-left: 4px solid;
border-radius: 0.5rem;
margin-bottom: 1rem;
padding: 1rem;
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.alert-item.critical {
border-left-color: var(--danger-color);
}
.alert-item.warning {
border-left-color: var(--warning-color);
}
.alert-item.info {
border-left-color: var(--info-color);
}
.health-indicator {
display: flex;
align-items: center;
gap: 0.5rem;
}
.health-dot {
width: 12px;
height: 12px;
border-radius: 50%;
animation: pulse 2s infinite;
}
.health-dot.excellent { background-color: #28a745; }
.health-dot.good { background-color: #17a2b8; }
.health-dot.fair { background-color: #ffc107; }
.health-dot.poor { background-color: #fd7e14; }
.health-dot.critical { background-color: #dc3545; }
@keyframes pulse {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
.agent-status {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 1rem;
padding: 1rem;
margin-bottom: 1rem;
}
.agent-mode-toggle {
position: relative;
display: inline-block;
width: 60px;
height: 34px;
}
.agent-mode-toggle input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ccc;
transition: .4s;
border-radius: 34px;
}
.slider:before {
position: absolute;
content: "";
height: 26px;
width: 26px;
left: 4px;
bottom: 4px;
background-color: white;
transition: .4s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #2196F3;
}
input:checked + .slider:before {
transform: translateX(26px);
}
.knowledge-item {
background: white;
border-radius: 0.5rem;
padding: 1rem;
margin-bottom: 1rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
border-left: 4px solid var(--info-color);
}
.work-order-item {
background: white;
border-radius: 0.5rem;
padding: 1rem;
margin-bottom: 1rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
border-left: 4px solid var(--success-color);
}
.tab-content {
min-height: 400px;
}
.loading-spinner {
display: flex;
justify-content: center;
align-items: center;
height: 200px;
}
.empty-state {
text-align: center;
padding: 3rem;
color: #6c757d;
}
.empty-state i {
font-size: 3rem;
margin-bottom: 1rem;
}
.btn-agent {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
color: white;
border-radius: 0.5rem;
padding: 0.5rem 1rem;
transition: all 0.3s ease;
}
.btn-agent:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
color: white;
}
.notification {
position: fixed;
top: 20px;
right: 20px;
z-index: 9999;
min-width: 300px;
border-radius: 0.5rem;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
.chart-container {
position: relative;
height: 300px;
margin: 1rem 0;
}
.quick-actions {
display: flex;
gap: 0.5rem;
margin-bottom: 1rem;
flex-wrap: wrap;
}
.quick-action-btn {
padding: 0.5rem 1rem;
border: 1px solid var(--primary-color);
background: white;
color: var(--primary-color);
border-radius: 0.5rem;
cursor: pointer;
transition: all 0.3s ease;
font-size: 0.875rem;
}
.quick-action-btn:hover {
background: var(--primary-color);
color: white;
transform: translateY(-2px);
}
</style>
</head>
<body>
<!-- 导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-primary">
<div class="container-fluid">
<a class="navbar-brand" href="#">
<i class="fas fa-robot me-2"></i>
TSP智能助手
</a>
<div class="navbar-nav ms-auto">
<div class="health-indicator">
<div class="health-dot" id="health-dot"></div>
<span id="health-status">检查中...</span>
</div>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="row">
<!-- 侧边栏 -->
<div class="col-md-2 sidebar p-0">
<div class="p-3">
<h5 class="text-white mb-3">
<i class="fas fa-tachometer-alt me-2"></i>
控制面板
</h5>
<nav class="nav flex-column">
<a class="nav-link active" href="#dashboard" data-tab="dashboard">
<i class="fas fa-home"></i>
仪表板
</a>
<a class="nav-link" href="#chat" data-tab="chat">
<i class="fas fa-comments"></i>
智能对话
</a>
<a class="nav-link" href="#agent" data-tab="agent">
<i class="fas fa-brain"></i>
Agent管理
</a>
<a class="nav-link" href="#alerts" data-tab="alerts">
<i class="fas fa-bell"></i>
预警管理
</a>
<a class="nav-link" href="#knowledge" data-tab="knowledge">
<i class="fas fa-database"></i>
知识库
</a>
<a class="nav-link" href="#workorders" data-tab="workorders">
<i class="fas fa-tasks"></i>
工单管理
</a>
<a class="nav-link" href="#analytics" data-tab="analytics">
<i class="fas fa-chart-line"></i>
数据分析
</a>
<a class="nav-link" href="#settings" data-tab="settings">
<i class="fas fa-cog"></i>
系统设置
</a>
</nav>
</div>
</div>
<!-- 主内容区 -->
<div class="col-md-10 main-content">
<!-- 仪表板标签页 -->
<div id="dashboard-tab" class="tab-content">
<div class="row mb-4">
<div class="col-md-3">
<div class="stat-card success">
<div class="stat-number" id="total-sessions">0</div>
<div class="stat-label">活跃会话</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card warning">
<div class="stat-number" id="total-alerts">0</div>
<div class="stat-label">活跃预警</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card danger">
<div class="stat-number" id="total-workorders">0</div>
<div class="stat-label">待处理工单</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-card info">
<div class="stat-number" id="knowledge-count">0</div>
<div class="stat-label">知识条目</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-chart-line me-2"></i>系统性能趋势</h5>
</div>
<div class="card-body">
<div class="chart-container">
<canvas id="performanceChart"></canvas>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-heartbeat me-2"></i>系统健康状态</h5>
</div>
<div class="card-body">
<div class="health-indicator mb-3">
<div class="health-dot" id="system-health-dot"></div>
<span id="system-health-text">检查中...</span>
</div>
<div class="mb-2">
<small class="text-muted">健康分数</small>
<div class="progress">
<div class="progress-bar" id="health-progress" role="progressbar" style="width: 0%"></div>
</div>
</div>
<div class="mb-2">
<small class="text-muted">内存使用</small>
<div class="progress">
<div class="progress-bar bg-info" id="memory-progress" role="progressbar" style="width: 0%"></div>
</div>
</div>
<div class="mb-2">
<small class="text-muted">CPU使用</small>
<div class="progress">
<div class="progress-bar bg-warning" id="cpu-progress" role="progressbar" style="width: 0%"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 智能对话标签页 -->
<div id="chat-tab" class="tab-content" style="display: none;">
<div class="row">
<div class="col-md-3">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-cog me-2"></i>对话控制</h5>
</div>
<div class="card-body">
<div class="mb-3">
<label class="form-label">用户ID</label>
<input type="text" class="form-control" id="user-id" value="user_001">
</div>
<div class="mb-3">
<label class="form-label">工单ID (可选)</label>
<input type="number" class="form-control" id="work-order-id" placeholder="留空则自动创建">
</div>
<div class="d-grid gap-2">
<button class="btn btn-primary" id="start-chat">
<i class="fas fa-play me-2"></i>开始对话
</button>
<button class="btn btn-secondary" id="end-chat" disabled>
<i class="fas fa-stop me-2"></i>结束对话
</button>
<button class="btn btn-info" id="create-work-order">
<i class="fas fa-plus me-2"></i>创建工单
</button>
</div>
<hr>
<div class="mb-3">
<h6>快速操作</h6>
<div class="quick-actions">
<button class="quick-action-btn" data-message="我的车辆无法远程启动">远程启动问题</button>
<button class="quick-action-btn" data-message="APP显示车辆信息错误">APP显示问题</button>
<button class="quick-action-btn" data-message="蓝牙授权失败">蓝牙授权问题</button>
<button class="quick-action-btn" data-message="如何解绑车辆">解绑车辆</button>
</div>
</div>
<div class="mb-3">
<h6>会话信息</h6>
<div id="session-info" class="text-muted">
未开始对话
</div>
</div>
</div>
</div>
</div>
<div class="col-md-9">
<div class="card chat-container">
<div class="chat-header">
<div class="d-flex justify-content-between align-items-center">
<div>
<h4><i class="fas fa-robot me-2"></i>TSP智能助手</h4>
<small>基于知识库的智能客服系统</small>
</div>
<div id="connection-status" class="badge bg-secondary">
<i class="fas fa-circle me-1"></i>未连接
</div>
</div>
</div>
<div class="chat-messages" id="chat-messages">
<div class="text-center text-muted py-5">
<i class="fas fa-comments fa-3x mb-3"></i>
<h5>欢迎使用TSP智能助手</h5>
<p>请点击"开始对话"按钮开始聊天</p>
</div>
</div>
<div class="chat-input">
<div class="input-group">
<input type="text" class="form-control" id="message-input"
placeholder="请输入您的问题..." disabled>
<button class="btn btn-primary" id="send-button" disabled>
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Agent管理标签页 -->
<div id="agent-tab" class="tab-content" style="display: none;">
<div class="row">
<div class="col-md-4">
<div class="agent-status">
<h5><i class="fas fa-brain me-2"></i>Agent状态</h5>
<div class="mb-3">
<label class="form-label text-white">Agent模式</label>
<div class="agent-mode-toggle">
<input type="checkbox" id="agent-mode-toggle">
<span class="slider"></span>
</div>
</div>
<div class="mb-2">
<small class="text-white-50">当前状态: <span id="agent-current-state">空闲</span></small>
</div>
<div class="mb-2">
<small class="text-white-50">活跃目标: <span id="agent-active-goals">0</span></small>
</div>
<div class="mb-2">
<small class="text-white-50">可用工具: <span id="agent-available-tools">0</span></small>
</div>
</div>
<div class="card">
<div class="card-header">
<h5><i class="fas fa-tools me-2"></i>工具管理</h5>
</div>
<div class="card-body">
<div id="tools-list">
<div class="loading-spinner">
<i class="fas fa-spinner fa-spin"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-cogs me-2"></i>Agent控制</h5>
</div>
<div class="card-body">
<div class="row mb-3">
<div class="col-md-6">
<button class="btn btn-agent w-100" id="start-agent-monitoring">
<i class="fas fa-play me-2"></i>启动Agent监控
</button>
</div>
<div class="col-md-6">
<button class="btn btn-agent w-100" id="stop-agent-monitoring">
<i class="fas fa-stop me-2"></i>停止Agent监控
</button>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<button class="btn btn-agent w-100" id="proactive-monitoring">
<i class="fas fa-search me-2"></i>主动监控检查
</button>
</div>
<div class="col-md-6">
<button class="btn btn-agent w-100" id="intelligent-analysis">
<i class="fas fa-chart-line me-2"></i>智能分析
</button>
</div>
</div>
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h6><i class="fas fa-list me-2"></i>Agent执行历史</h6>
<div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-outline-primary" onclick="dashboard.triggerSampleAction()">
<i class="fas fa-play me-1"></i>触发示例
</button>
<button type="button" class="btn btn-outline-secondary" onclick="dashboard.refreshAgentHistory()">
<i class="fas fa-sync-alt me-1"></i>刷新
</button>
<button type="button" class="btn btn-outline-danger" onclick="dashboard.clearAgentHistory()">
<i class="fas fa-trash me-1"></i>清空
</button>
</div>
</div>
<div class="card-body">
<div id="agent-execution-history">
<div class="empty-state">
<i class="fas fa-history"></i>
<p>暂无执行历史</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 预警管理标签页 -->
<div id="alerts-tab" class="tab-content" style="display: none;">
<div class="row mb-4">
<div class="col-md-3">
<div class="card bg-danger text-white">
<div class="card-body">
<div class="d-flex justify-content-between">
<div>
<h4 id="critical-alerts">0</h4>
<p class="mb-0">严重预警</p>
</div>
<div class="align-self-center">
<i class="fas fa-exclamation-triangle fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-warning text-white">
<div class="card-body">
<div class="d-flex justify-content-between">
<div>
<h4 id="warning-alerts">0</h4>
<p class="mb-0">警告预警</p>
</div>
<div class="align-self-center">
<i class="fas fa-exclamation-circle fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-info text-white">
<div class="card-body">
<div class="d-flex justify-content-between">
<div>
<h4 id="info-alerts">0</h4>
<p class="mb-0">信息预警</p>
</div>
<div class="align-self-center">
<i class="fas fa-info-circle fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-success text-white">
<div class="card-body">
<div class="d-flex justify-content-between">
<div>
<h4 id="total-alerts-count">0</h4>
<p class="mb-0">总预警数</p>
</div>
<div class="align-self-center">
<i class="fas fa-chart-line fa-2x"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5><i class="fas fa-bell me-2"></i>活跃预警</h5>
<div class="d-flex gap-2">
<select class="form-select form-select-sm" id="alert-filter" style="width: auto;">
<option value="all">全部预警</option>
<option value="critical">严重</option>
<option value="warning">警告</option>
<option value="info">信息</option>
</select>
<button class="btn btn-sm btn-outline-primary" id="refresh-alerts">
<i class="fas fa-sync-alt me-1"></i>刷新
</button>
</div>
</div>
<div class="card-body">
<div id="alerts-container">
<div class="loading-spinner">
<i class="fas fa-spinner fa-spin"></i>
</div>
</div>
</div>
</div>
</div>
<!-- 知识库标签页 -->
<div id="knowledge-tab" class="tab-content" style="display: none;">
<div class="row mb-4">
<div class="col-md-8">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5><i class="fas fa-database me-2"></i>知识库管理</h5>
<div class="btn-group">
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#addKnowledgeModal">
<i class="fas fa-plus me-1"></i>添加知识
</button>
<button class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#uploadFileModal">
<i class="fas fa-upload me-1"></i>上传文件
</button>
</div>
</div>
<div class="card-body">
<div class="mb-3">
<div class="input-group">
<input type="text" class="form-control" id="knowledge-search" placeholder="搜索知识库...">
<button class="btn btn-outline-secondary" id="search-knowledge">
<i class="fas fa-search"></i>
</button>
</div>
</div>
<div id="knowledge-list">
<div class="loading-spinner">
<i class="fas fa-spinner fa-spin"></i>
</div>
</div>
<div id="knowledge-pagination" class="mt-3">
<!-- 分页控件将在这里显示 -->
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-chart-pie me-2"></i>知识库统计</h5>
</div>
<div class="card-body">
<div class="mb-3">
<small class="text-muted">总条目数</small>
<h4 id="knowledge-total">0</h4>
</div>
<div class="mb-3">
<small class="text-muted">活跃条目</small>
<h4 id="knowledge-active">0</h4>
</div>
<div class="mb-3">
<small class="text-muted">平均置信度</small>
<div class="progress">
<div class="progress-bar" id="knowledge-confidence" role="progressbar" style="width: 0%"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 工单管理标签页 -->
<div id="workorders-tab" class="tab-content" style="display: none;">
<div class="row mb-4">
<div class="col-md-8">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5><i class="fas fa-tasks me-2"></i>工单管理</h5>
<div class="btn-group" role="group">
<button class="btn btn-success btn-sm" onclick="dashboard.downloadTemplate()">
<i class="fas fa-download me-1"></i>下载模板
</button>
<button class="btn btn-info btn-sm" onclick="dashboard.showImportModal()">
<i class="fas fa-upload me-1"></i>导入工单
</button>
<button class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#createWorkOrderModal">
<i class="fas fa-plus me-1"></i>创建工单
</button>
</div>
</div>
<div class="card-body">
<div class="mb-3">
<div class="row">
<div class="col-md-4">
<select class="form-select" id="workorder-status-filter">
<option value="all">全部状态</option>
<option value="open">待处理</option>
<option value="in_progress">处理中</option>
<option value="resolved">已解决</option>
<option value="closed">已关闭</option>
</select>
</div>
<div class="col-md-4">
<select class="form-select" id="workorder-priority-filter">
<option value="all">全部优先级</option>
<option value="low"></option>
<option value="medium"></option>
<option value="high"></option>
<option value="urgent">紧急</option>
</select>
</div>
<div class="col-md-4">
<button class="btn btn-outline-secondary w-100" id="refresh-workorders">
<i class="fas fa-sync-alt me-1"></i>刷新
</button>
</div>
</div>
</div>
<div id="workorders-list">
<div class="loading-spinner">
<i class="fas fa-spinner fa-spin"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-chart-bar me-2"></i>工单统计</h5>
</div>
<div class="card-body">
<div class="mb-3">
<small class="text-muted">总工单数</small>
<h4 id="workorders-total">0</h4>
</div>
<div class="mb-3">
<small class="text-muted">待处理</small>
<h4 id="workorders-open">0</h4>
</div>
<div class="mb-3">
<small class="text-muted">处理中</small>
<h4 id="workorders-progress">0</h4>
</div>
<div class="mb-3">
<small class="text-muted">已解决</small>
<h4 id="workorders-resolved">0</h4>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 数据分析标签页 -->
<div id="analytics-tab" class="tab-content" style="display: none;">
<!-- 图表控制面板 -->
<div class="row mb-4">
<div class="col-12">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-chart-bar me-2"></i>数据分析控制面板</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-3">
<label class="form-label">时间范围</label>
<select class="form-select" id="timeRange">
<option value="7">最近7天</option>
<option value="30" selected>最近30天</option>
<option value="90">最近90天</option>
<option value="365">最近1年</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label">图表类型</label>
<select class="form-select" id="chartType">
<option value="line">折线图</option>
<option value="bar" selected>柱状图</option>
<option value="pie">饼图</option>
<option value="doughnut">环形图</option>
<option value="radar">雷达图</option>
<option value="polar">极坐标图</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label">数据维度</label>
<select class="form-select" id="dataDimension">
<option value="workorders" selected>工单统计</option>
<option value="alerts">预警统计</option>
<option value="performance">性能指标</option>
<option value="satisfaction">满意度分析</option>
</select>
</div>
<div class="col-md-3">
<label class="form-label">操作</label>
<div class="d-grid">
<button class="btn btn-primary" onclick="dashboard.updateCharts()">
<i class="fas fa-sync-alt me-1"></i>刷新图表
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 主要图表区域 -->
<div class="row mb-4">
<div class="col-md-8">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5><i class="fas fa-chart-line me-2"></i>主要趋势分析</h5>
<div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-outline-primary" onclick="dashboard.exportChart('mainChart')">
<i class="fas fa-download me-1"></i>导出
</button>
<button type="button" class="btn btn-outline-secondary" onclick="dashboard.fullscreenChart('mainChart')">
<i class="fas fa-expand me-1"></i>全屏
</button>
</div>
</div>
<div class="card-body">
<div class="chart-container" style="position: relative; height: 400px;">
<canvas id="mainChart"></canvas>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-chart-pie me-2"></i>分布分析</h5>
</div>
<div class="card-body">
<div class="chart-container" style="position: relative; height: 300px;">
<canvas id="distributionChart"></canvas>
</div>
</div>
</div>
</div>
</div>
<!-- 详细统计卡片 -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="d-flex align-items-center justify-content-center mb-2">
<i class="fas fa-tasks fa-2x text-primary me-3"></i>
<div>
<h3 class="mb-0" id="totalWorkorders">0</h3>
<small class="text-muted">总工单数</small>
</div>
</div>
<div class="progress" style="height: 4px;">
<div class="progress-bar bg-primary" role="progressbar" style="width: 100%"></div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="d-flex align-items-center justify-content-center mb-2">
<i class="fas fa-exclamation-triangle fa-2x text-warning me-3"></i>
<div>
<h3 class="mb-0" id="openWorkorders">0</h3>
<small class="text-muted">待处理</small>
</div>
</div>
<div class="progress" style="height: 4px;">
<div class="progress-bar bg-warning" role="progressbar" id="openProgress" style="width: 0%"></div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="d-flex align-items-center justify-content-center mb-2">
<i class="fas fa-check-circle fa-2x text-success me-3"></i>
<div>
<h3 class="mb-0" id="resolvedWorkorders">0</h3>
<small class="text-muted">已解决</small>
</div>
</div>
<div class="progress" style="height: 4px;">
<div class="progress-bar bg-success" role="progressbar" id="resolvedProgress" style="width: 0%"></div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="d-flex align-items-center justify-content-center mb-2">
<i class="fas fa-star fa-2x text-info me-3"></i>
<div>
<h3 class="mb-0" id="avgSatisfaction">0</h3>
<small class="text-muted">平均满意度</small>
</div>
</div>
<div class="progress" style="height: 4px;">
<div class="progress-bar bg-info" role="progressbar" id="satisfactionProgress" style="width: 0%"></div>
</div>
</div>
</div>
</div>
</div>
<!-- 多维度分析图表 -->
<div class="row mb-4">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-chart-area me-2"></i>时间趋势分析</h5>
</div>
<div class="card-body">
<div class="chart-container" style="position: relative; height: 300px;">
<canvas id="trendChart"></canvas>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-chart-bar me-2"></i>优先级分布</h5>
</div>
<div class="card-body">
<div class="chart-container" style="position: relative; height: 300px;">
<canvas id="priorityChart"></canvas>
</div>
</div>
</div>
</div>
</div>
<!-- 详细分析报告 -->
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header d-flex justify-content-between align-items-center">
<h5><i class="fas fa-table me-2"></i>详细分析报告</h5>
<div class="btn-group btn-group-sm" role="group">
<button type="button" class="btn btn-outline-primary" onclick="dashboard.exportReport()">
<i class="fas fa-file-excel me-1"></i>导出Excel
</button>
<button type="button" class="btn btn-outline-secondary" onclick="dashboard.printReport()">
<i class="fas fa-print me-1"></i>打印报告
</button>
</div>
</div>
<div class="card-body">
<div id="analytics-report">
<div class="loading-spinner text-center">
<i class="fas fa-spinner fa-spin fa-2x"></i>
<p class="mt-2">正在生成分析报告...</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 系统设置标签页 -->
<div id="settings-tab" class="tab-content" style="display: none;">
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-cog me-2"></i>系统配置</h5>
</div>
<div class="card-body">
<form id="system-settings-form">
<div class="mb-3">
<label class="form-label">API超时时间(秒)</label>
<input type="number" class="form-control" id="api-timeout" value="30">
</div>
<div class="mb-3">
<label class="form-label">最大历史记录数</label>
<input type="number" class="form-control" id="max-history" value="10">
</div>
<div class="mb-3">
<label class="form-label">自动刷新间隔(秒)</label>
<input type="number" class="form-control" id="refresh-interval" value="10">
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="auto-monitoring" checked>
<label class="form-check-label">自动监控</label>
</div>
</div>
<div class="mb-3">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="agent-mode" checked>
<label class="form-check-label">启用Agent模式</label>
</div>
</div>
<button type="submit" class="btn btn-primary">
<i class="fas fa-save me-2"></i>保存设置
</button>
</form>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-info-circle me-2"></i>系统信息</h5>
</div>
<div class="card-body">
<div id="system-info">
<div class="loading-spinner">
<i class="fas fa-spinner fa-spin"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 模态框 -->
<!-- 创建工单模态框 -->
<div class="modal fade" id="createWorkOrderModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">创建工单</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="work-order-form">
<div class="mb-3">
<label class="form-label">工单标题</label>
<input type="text" class="form-control" id="wo-title" required>
</div>
<div class="mb-3">
<label class="form-label">问题描述</label>
<textarea class="form-control" id="wo-description" rows="3" required></textarea>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">问题分类</label>
<select class="form-select" id="wo-category">
<option value="技术问题">技术问题</option>
<option value="APP功能">APP功能</option>
<option value="远程控制">远程控制</option>
<option value="车辆绑定">车辆绑定</option>
<option value="其他">其他</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">优先级</label>
<select class="form-select" id="wo-priority">
<option value="low"></option>
<option value="medium" selected></option>
<option value="high"></option>
<option value="urgent">紧急</option>
</select>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="create-work-order-btn">创建工单</button>
</div>
</div>
</div>
</div>
<!-- 工单导入模态框 -->
<div class="modal fade" id="importWorkOrderModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">导入工单</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="alert alert-info">
<i class="fas fa-info-circle me-2"></i>
请先下载模板文件按照模板格式填写工单信息然后上传Excel文件进行导入。
</div>
<div class="mb-3">
<label class="form-label">选择Excel文件</label>
<input type="file" class="form-control" id="excel-file-input" accept=".xlsx,.xls">
<div class="form-text">支持 .xlsx 和 .xls 格式文件大小不超过16MB</div>
</div>
<div class="mb-3">
<div class="d-flex justify-content-between align-items-center">
<span>Excel文件列名说明</span>
<button class="btn btn-outline-primary btn-sm" onclick="dashboard.downloadTemplate()">
<i class="fas fa-download me-1"></i>下载模板
</button>
</div>
<div class="table-responsive mt-2">
<table class="table table-sm table-bordered">
<thead class="table-light">
<tr>
<th>列名</th>
<th>说明</th>
<th>必填</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td>标题</td>
<td>工单标题</td>
<td><span class="badge bg-danger"></span></td>
<td>车辆无法启动</td>
</tr>
<tr>
<td>描述</td>
<td>工单详细描述</td>
<td><span class="badge bg-danger"></span></td>
<td>用户反映车辆无法正常启动</td>
</tr>
<tr>
<td>分类</td>
<td>工单分类</td>
<td><span class="badge bg-secondary"></span></td>
<td>技术问题</td>
</tr>
<tr>
<td>优先级</td>
<td>工单优先级</td>
<td><span class="badge bg-secondary"></span></td>
<td>high</td>
</tr>
<tr>
<td>状态</td>
<td>工单状态</td>
<td><span class="badge bg-secondary"></span></td>
<td>open</td>
</tr>
<tr>
<td>解决方案</td>
<td>解决方案描述</td>
<td><span class="badge bg-secondary"></span></td>
<td>检查电池和启动系统</td>
</tr>
<tr>
<td>满意度</td>
<td>满意度评分(1-5)</td>
<td><span class="badge bg-secondary"></span></td>
<td>5</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="import-progress" class="d-none">
<div class="progress mb-3">
<div class="progress-bar" role="progressbar" style="width: 0%"></div>
</div>
<div class="text-center">
<i class="fas fa-spinner fa-spin me-2"></i>
<span id="import-status">正在导入工单...</span>
</div>
</div>
<div id="import-result" class="d-none">
<div class="alert alert-success">
<i class="fas fa-check-circle me-2"></i>
<span id="import-success-message"></span>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="import-workorder-btn" onclick="dashboard.importWorkOrders()">
<i class="fas fa-upload me-1"></i>开始导入
</button>
</div>
</div>
</div>
</div>
<!-- 添加知识模态框 -->
<div class="modal fade" id="addKnowledgeModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">添加知识</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="knowledge-form">
<div class="mb-3">
<label class="form-label">问题</label>
<input type="text" class="form-control" id="knowledge-question" required>
</div>
<div class="mb-3">
<label class="form-label">答案</label>
<textarea class="form-control" id="knowledge-answer" rows="3" required></textarea>
</div>
<div class="mb-3">
<label class="form-label">分类</label>
<select class="form-select" id="knowledge-category">
<option value="技术问题">技术问题</option>
<option value="APP功能">APP功能</option>
<option value="远程控制">远程控制</option>
<option value="车辆绑定">车辆绑定</option>
<option value="其他">其他</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">置信度</label>
<input type="range" class="form-range" id="knowledge-confidence" min="0" max="1" step="0.1" value="0.8">
<div class="d-flex justify-content-between">
<small>0</small>
<small id="confidence-value">0.8</small>
<small>1</small>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-primary" id="add-knowledge-btn">添加知识</button>
</div>
</div>
</div>
</div>
<!-- 文件上传模态框 -->
<div class="modal fade" id="uploadFileModal" tabindex="-1">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">上传文件生成知识库</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="file-upload-form" enctype="multipart/form-data">
<div class="mb-3">
<label class="form-label">选择文件</label>
<input type="file" class="form-control" id="file-input" accept=".txt,.pdf,.doc,.docx,.md" required>
<div class="form-text">支持的文件格式TXT, PDF, DOC, DOCX, MD</div>
</div>
<div class="mb-3">
<label class="form-label">处理方式</label>
<select class="form-select" id="process-method">
<option value="auto">自动提取Q&A</option>
<option value="manual">手动指定问题</option>
<option value="summary">生成摘要</option>
</select>
</div>
<div class="mb-3" id="manual-question-div" style="display: none;">
<label class="form-label">指定问题</label>
<input type="text" class="form-control" id="manual-question" placeholder="请输入要提取的问题">
</div>
<div class="mb-3">
<label class="form-label">分类</label>
<select class="form-select" id="file-category">
<option value="技术问题">技术问题</option>
<option value="APP功能">APP功能</option>
<option value="远程控制">远程控制</option>
<option value="车辆绑定">车辆绑定</option>
<option value="其他">其他</option>
</select>
</div>
<div class="mb-3">
<label class="form-label">置信度</label>
<input type="range" class="form-range" id="file-confidence" min="0" max="1" step="0.1" value="0.7">
<div class="d-flex justify-content-between">
<small>0</small>
<small id="file-confidence-value">0.7</small>
<small>1</small>
</div>
</div>
</form>
<div id="upload-progress" class="mt-3" style="display: none;">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: 0%"></div>
</div>
<div class="text-center mt-2">
<small id="upload-status">正在处理文件...</small>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
<button type="button" class="btn btn-success" id="upload-file-btn">上传处理</button>
</div>
</div>
</div>
</div>
<!-- 脚本 -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
<script src="{{ url_for('static', filename='js/dashboard.js') }}"></script>
</body>
</html>