图表颜色统一、修复店铺预测图表标题显示错误、统一模型时间显示格式

This commit is contained in:
LYFxiaoan 2025-07-24 15:16:19 +08:00
parent 3aaddcd658
commit 08b26b5fa0
6 changed files with 147 additions and 19 deletions

View File

@ -47,7 +47,7 @@
<el-table :data="paginatedModelList" style="width: 100%" v-loading="modelsLoading">
<el-table-column prop="model_type" label="模型类型" sortable />
<el-table-column prop="version" label="版本" />
<el-table-column prop="created_at" label="创建时间" />
<el-table-column prop="created_at" label="创建时间" :formatter="formatDateTime" />
<el-table-column label="操作">
<template #default="{ row }">
<el-button
@ -136,6 +136,20 @@ const handlePageChange = (page) => {
pagination.currentPage = page
}
const formatDateTime = (row, column, cellValue) => {
if (!cellValue) return ''
const date = new Date(cellValue)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).replace(/\//g, '-')
}
const fetchModelTypes = async () => {
try {
const response = await axios.get('/api/model_types')
@ -263,10 +277,15 @@ const renderChart = () => {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
color: 'white' //
}
},
title: {
display: true,
text: `全局模型 (${predictionResult.value.model_type}) - 销量预测趋势图`,
color: '#303133',
color: 'white',
font: {
size: 20,
weight: 'bold',
@ -275,7 +294,7 @@ const renderChart = () => {
subtitle: {
display: true,
text: subtitleText,
color: '#606266',
color: 'white',
font: {
size: 14,
},
@ -288,7 +307,11 @@ const renderChart = () => {
x: {
title: {
display: true,
text: '日期'
text: '日期',
color: 'white'
},
ticks: {
color: 'white' // X
},
grid: {
display: false
@ -297,10 +320,14 @@ const renderChart = () => {
y: {
title: {
display: true,
text: '销量'
text: '销量',
color: 'white'
},
ticks: {
color: 'white' // Y
},
grid: {
color: '#e9e9e9',
color: 'rgba(255, 255, 255, 0.2)', // 线
drawBorder: false,
},
beginAtZero: true

View File

@ -56,7 +56,7 @@
<el-table-column prop="product_name" label="药品名称" sortable />
<el-table-column prop="model_type" label="模型类型" sortable />
<el-table-column prop="version" label="版本" />
<el-table-column prop="created_at" label="创建时间" />
<el-table-column prop="created_at" label="创建时间" :formatter="formatDateTime" />
<el-table-column label="操作">
<template #default="{ row }">
<el-button
@ -146,6 +146,20 @@ const handlePageChange = (page) => {
pagination.currentPage = page
}
const formatDateTime = (row, column, cellValue) => {
if (!cellValue) return ''
const date = new Date(cellValue)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).replace(/\//g, '-')
}
const fetchModelTypes = async () => {
try {
const response = await axios.get('/api/model_types')
@ -273,10 +287,15 @@ const renderChart = () => {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
color: 'white' //
}
},
title: {
display: true,
text: `${predictionResult.value.product_name} - 销量预测趋势图`,
color: '#303133',
color: 'white',
font: {
size: 20,
weight: 'bold',
@ -285,7 +304,7 @@ const renderChart = () => {
subtitle: {
display: true,
text: subtitleText,
color: '#606266',
color: 'white',
font: {
size: 14,
},
@ -298,7 +317,11 @@ const renderChart = () => {
x: {
title: {
display: true,
text: '日期'
text: '日期',
color: 'white'
},
ticks: {
color: 'white' // X
},
grid: {
display: false
@ -307,10 +330,14 @@ const renderChart = () => {
y: {
title: {
display: true,
text: '销量'
text: '销量',
color: 'white'
},
ticks: {
color: 'white' // Y
},
grid: {
color: '#e9e9e9',
color: 'rgba(255, 255, 255, 0.2)', // 线
drawBorder: false,
},
beginAtZero: true

View File

@ -56,7 +56,7 @@
<el-table-column prop="store_name" label="店铺名称" sortable />
<el-table-column prop="model_type" label="模型类型" sortable />
<el-table-column prop="version" label="版本" />
<el-table-column prop="created_at" label="创建时间" />
<el-table-column prop="created_at" label="创建时间" :formatter="formatDateTime" />
<el-table-column label="操作">
<template #default="{ row }">
<el-button
@ -161,6 +161,20 @@ const handlePageChange = (page) => {
pagination.currentPage = page
}
const formatDateTime = (row, column, cellValue) => {
if (!cellValue) return ''
const date = new Date(cellValue)
return date.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).replace(/\//g, '-')
}
const fetchModelTypes = async () => {
try {
const response = await axios.get('/api/model_types')
@ -300,10 +314,15 @@ const renderChart = () => {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
labels: {
color: 'white' //
}
},
title: {
display: true,
text: `${predictionResult.value.store_name} - 销量预测趋势图`,
color: '#303133',
color: 'white',
font: {
size: 20,
weight: 'bold',
@ -312,7 +331,7 @@ const renderChart = () => {
subtitle: {
display: true,
text: subtitleText,
color: '#606266',
color: 'white',
font: {
size: 14,
},
@ -325,7 +344,11 @@ const renderChart = () => {
x: {
title: {
display: true,
text: '日期'
text: '日期',
color: 'white'
},
ticks: {
color: 'white' // X
},
grid: {
display: false
@ -334,10 +357,14 @@ const renderChart = () => {
y: {
title: {
display: true,
text: '销量'
text: '销量',
color: 'white'
},
ticks: {
color: 'white' // Y
},
grid: {
color: '#e9e9e9',
color: 'rgba(255, 255, 255, 0.2)', // 线
drawBorder: false,
},
beginAtZero: true

View File

@ -324,3 +324,30 @@
2. **修正数据访问**: 在 `startPrediction` 方法中将API响应的核心数据 `response.data.data` 赋值给 `predictionResult`
3. **标准化日期**: 在 `renderChart` 方法的开头,增加了一个 `formatDate` 辅助函数,并在处理数据时立即调用它,将所有日期都统一转换为 `'YYYY-MM-DD'` 格式的字符串,从而一举解决了数据点丢失和标题格式错误的双重问题。
- **最终结论**: 至此所有预测视图的前后端数据链路和UI展示功能均已修复系统功能恢复正常。
---
## 2025-07-24UI/UX 优化与后端逻辑统一
**开发者**: Roo (AI Assistant) & lyf
### 14:30 - 统一预测图表颜色风格
- **任务**: 根据用户反馈将所有预测结果图表的文字颜色包括标题、副标题、图例、坐标轴统一修改为白色以适应深色UI背景。
- **实施**:
- 逐一修改了 `ProductPredictionView.vue`, `StorePredictionView.vue`, 和 `GlobalPredictionView.vue`
- 在 `Chart.js``options` 配置中,将所有相关的 `color` 属性设置为 `'white'`,并将网格线颜色调整为半透明白色 `rgba(255, 255, 255, 0.2)`
### 14:50 - 修复“按店铺预测”图表标题显示错误
- **问题**: “按店铺预测”的图表标题显示为 `undefined`
- **根本原因**: 后端 `server/api.py` 在处理店铺预测时,没有查询并返回真实的店铺名称,导致前端无法获取该数据。
- **修复方案 (后端优先)**:
1. 在 `server/api.py` 中新增了 `get_store_name` 辅助函数,用于根据 `store_id` 查询店铺名称。
2. 修改了 `/api/prediction` 接口,在 `training_mode``'store'` 时,调用新函数获取店铺名,并将其以 `store_name` 字段返回给前端。
- **结论**: 通过统一后端逻辑,确保了数据源的正确性,从根本上解决了问题。
### 15:05 - 统一模型列表时间显示格式
- **任务**: 根据用户要求将所有预测页面模型列表中的“创建时间”从ISO格式统一为 `YYYY-MM-DD HH:MM:SS` 的24小时制格式。
- **实施**:
- 逐一修改了 `ProductPredictionView.vue`, `StorePredictionView.vue`, 和 `GlobalPredictionView.vue`
- 在 `<script setup>` 中添加了 `formatDateTime` 辅助函数。
- 在 `<el-table-column>` 中使用 `:formatter="formatDateTime"` 属性来应用该格式化函数实现了UI显示的统一。

Binary file not shown.

View File

@ -1389,7 +1389,9 @@ def predict():
if not store_id:
return jsonify({"status": "error", "error": "店铺模式需要 store_id"}), 400
model_identifier = f"store_{store_id}"
product_name = f"店铺 {store_id} 整体"
# 修复:调用 get_store_name 获取真实的店铺名称
store_name = get_store_name(store_id) or f"店铺 {store_id}"
product_name = store_name # 保持product_name字段用于日志和历史记录
else: # 默认为 'product' 模式
if not product_id:
return jsonify({"status": "error", "error": "药品模式需要 product_id"}), 400
@ -1466,6 +1468,10 @@ def predict():
'prediction_data': prediction_result.get('prediction_data', [])
}
# 修复:如果是在店铺模式下,确保返回结果中包含 store_name
if training_mode == 'store':
response_data['data']['store_name'] = store_name
# 调试日志
print("=== 预测API响应数据结构 (v3) ===")
print(f"history_data 长度: {len(response_data['history_data'])}")
@ -2556,6 +2562,20 @@ def get_product_name(product_id):
except Exception as e:
print(f"获取产品名称失败: {str(e)}")
return None
# 获取店铺名称的辅助函数
def get_store_name(store_id):
"""根据店铺ID获取店铺名称"""
try:
from utils.multi_store_data_utils import get_available_stores
stores = get_available_stores()
for store in stores:
if store['store_id'] == store_id:
return store['store_name']
return None
except Exception as e:
print(f"获取店铺名称失败: {str(e)}")
return None
# run_prediction 函数已被移除,因为其逻辑已完全整合到 /api/prediction 路由处理函数中