图表颜色统一、修复店铺预测图表标题显示错误、统一模型时间显示格式
This commit is contained in:
parent
3aaddcd658
commit
08b26b5fa0
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -324,3 +324,30 @@
|
||||
2. **修正数据访问**: 在 `startPrediction` 方法中,将API响应的核心数据 `response.data.data` 赋值给 `predictionResult`。
|
||||
3. **标准化日期**: 在 `renderChart` 方法的开头,增加了一个 `formatDate` 辅助函数,并在处理数据时立即调用它,将所有日期都统一转换为 `'YYYY-MM-DD'` 格式的字符串,从而一举解决了数据点丢失和标题格式错误的双重问题。
|
||||
- **最终结论**: 至此,所有预测视图的前后端数据链路和UI展示功能均已修复,系统功能恢复正常。
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 2025-07-24:UI/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.
@ -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 路由处理函数中
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user