feat: 优化数据分析页面,添加Excel工单导入功能

- 优化数据分析页面,添加可定制的图表功能
- 支持多种图表类型:折线图、柱状图、饼图、环形图、雷达图、极坐标图
- 添加图表定制功能:时间范围选择、数据维度选择
- 实现Excel工单导入功能,支持详情.xlsx文件
- 添加工单编辑功能,包括前端UI和后端API
- 修复WebSocket连接错误,处理invalid Connection header问题
- 简化预警管理参数,改为卡片式选择
- 实现Agent主动调用,无需人工干预
- 改进知识库导入,结合累计工单内容与大模型输出
This commit is contained in:
zhaojie
2025-09-10 23:13:08 +08:00
parent e08b570f22
commit 0c03ff20aa
16 changed files with 3077 additions and 51 deletions

View File

@@ -844,9 +844,17 @@
<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>
<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 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">
@@ -914,43 +922,210 @@
<!-- 数据分析标签页 -->
<div id="analytics-tab" class="tab-content" style="display: none;">
<!-- 图表控制面板 -->
<div class="row mb-4">
<div class="col-md-6">
<div class="col-12">
<div class="card">
<div class="card-header">
<h5><i class="fas fa-chart-line me-2"></i>性能趋势</h5>
<h5><i class="fas fa-chart-bar me-2"></i>数据分析控制面板</h5>
</div>
<div class="card-body">
<div class="chart-container">
<canvas id="analyticsChart"></canvas>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<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">
<canvas id="categoryChart"></canvas>
<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">
<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">
<i class="fas fa-spinner fa-spin"></i>
<div class="loading-spinner text-center">
<i class="fas fa-spinner fa-spin fa-2x"></i>
<p class="mt-2">正在生成分析报告...</p>
</div>
</div>
</div>
@@ -1074,6 +1249,118 @@
</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">