药品预测版本模型改列表展示
This commit is contained in:
parent
e4397c201a
commit
52cb6b74d5
@ -44,25 +44,7 @@
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20" v-if="form.model_type">
|
||||
<el-col :span="5">
|
||||
<el-form-item label="模型版本">
|
||||
<el-select
|
||||
v-model="form.version"
|
||||
placeholder="选择版本"
|
||||
style="width: 100%"
|
||||
:disabled="!availableVersions.length"
|
||||
:loading="versionsLoading"
|
||||
>
|
||||
<el-option
|
||||
v-for="version in availableVersions"
|
||||
:key="version"
|
||||
:label="version"
|
||||
:value="version"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="预测天数">
|
||||
<el-input-number
|
||||
v-model="form.future_days"
|
||||
@ -72,7 +54,7 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="历史天数">
|
||||
<el-input-number
|
||||
v-model="form.history_lookback_days"
|
||||
@ -82,7 +64,7 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="起始日期">
|
||||
<el-date-picker
|
||||
v-model="form.start_date"
|
||||
@ -95,7 +77,7 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-col :span="6">
|
||||
<el-form-item label="预测分析">
|
||||
<el-switch
|
||||
v-model="form.analyze_result"
|
||||
@ -108,17 +90,45 @@
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="prediction-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="large"
|
||||
@click="startPrediction"
|
||||
:loading="predicting"
|
||||
:disabled="!canPredict"
|
||||
>
|
||||
<el-icon><TrendCharts /></el-icon>
|
||||
开始预测
|
||||
</el-button>
|
||||
<div v-if="availableVersions.length > 0" class="versions-list-section">
|
||||
<h4>📦 可用模型版本</h4>
|
||||
<el-table :data="availableVersions" style="width: 100%" v-loading="versionsLoading">
|
||||
<el-table-column prop="product_name" label="药品名称" width="220"></el-table-column>
|
||||
<el-table-column prop="version" label="版本号" width="180"></el-table-column>
|
||||
<el-table-column prop="created_at" label="创建时间" width="200">
|
||||
<template #default="{ row }">
|
||||
{{ new Date(row.created_at).toLocaleString() }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="metrics.mae" label="MAE">
|
||||
<template #default="{ row }">
|
||||
{{ row.metrics && row.metrics.mae ? row.metrics.mae.toFixed(4) : 'N/A' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="metrics.rmse" label="RMSE">
|
||||
<template #default="{ row }">
|
||||
{{ row.metrics && row.metrics.rmse ? row.metrics.rmse.toFixed(4) : 'N/A' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="metrics.mape" label="MAPE (%)">
|
||||
<template #default="{ row }">
|
||||
{{ row.metrics && row.metrics.mape ? (row.metrics.mape * 100).toFixed(2) : 'N/A' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="startPrediction(row.version)"
|
||||
:loading="predicting && form.version === row.version"
|
||||
>
|
||||
<el-icon><TrendCharts /></el-icon>
|
||||
开始预测
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
@ -162,9 +172,7 @@ const form = reactive({
|
||||
analyze_result: true
|
||||
})
|
||||
|
||||
const canPredict = computed(() => {
|
||||
return form.product_id && form.model_type && form.version
|
||||
})
|
||||
|
||||
|
||||
const fetchModelTypes = async () => {
|
||||
try {
|
||||
@ -188,9 +196,7 @@ const fetchAvailableVersions = async () => {
|
||||
const response = await axios.get(url)
|
||||
if (response.data.status === 'success') {
|
||||
availableVersions.value = response.data.data.versions || []
|
||||
if (response.data.data.latest_version) {
|
||||
form.version = response.data.data.latest_version
|
||||
}
|
||||
// No longer setting a default version, the user will choose from the list.
|
||||
}
|
||||
} catch (error) {
|
||||
availableVersions.value = []
|
||||
@ -203,26 +209,29 @@ const handleProductChange = () => {
|
||||
form.model_type = ''
|
||||
form.version = ''
|
||||
availableVersions.value = []
|
||||
predictionResult.value = null;
|
||||
}
|
||||
|
||||
const handleModelTypeChange = () => {
|
||||
form.version = ''
|
||||
availableVersions.value = []
|
||||
predictionResult.value = null;
|
||||
fetchAvailableVersions()
|
||||
}
|
||||
|
||||
const startPrediction = async () => {
|
||||
const startPrediction = async (version) => {
|
||||
form.version = version; // Keep track of which version is running
|
||||
try {
|
||||
predicting.value = true
|
||||
const payload = {
|
||||
product_id: form.product_id,
|
||||
model_type: form.model_type,
|
||||
version: form.version,
|
||||
version: version,
|
||||
future_days: form.future_days,
|
||||
history_lookback_days: form.history_lookback_days,
|
||||
start_date: form.start_date,
|
||||
include_visualization: form.analyze_result,
|
||||
}
|
||||
// Corrected API endpoint from /api/predict to /api/prediction
|
||||
const response = await axios.post('/api/prediction', payload)
|
||||
if (response.data.status === 'success') {
|
||||
// The backend response may have history_data and prediction_data at the top level
|
||||
@ -382,13 +391,14 @@ watch([() => form.product_id, () => form.model_type], () => {
|
||||
.model-selection-section h4 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.prediction-actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
.versions-list-section {
|
||||
margin-top: 20px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #ebeef5;
|
||||
}
|
||||
.versions-list-section h4 {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.prediction-chart {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
Binary file not shown.
@ -3536,15 +3536,17 @@ def get_model_versions_api(product_id, model_type):
|
||||
result = model_manager.list_models(product_id=product_id, model_type=model_type)
|
||||
models = result.get('models', [])
|
||||
|
||||
versions = sorted(list(set(m['version'] for m in models)), key=lambda v: (v != 'best', v))
|
||||
latest_version = versions[0] if versions else None
|
||||
# Sort models: 'best' version first, then by creation date descending
|
||||
models.sort(key=lambda x: (x.get('version') != 'best', x.get('created_at', '')), reverse=True)
|
||||
|
||||
latest_version = models[0]['version'] if models else None
|
||||
|
||||
return jsonify({
|
||||
"status": "success",
|
||||
"data": {
|
||||
"product_id": product_id,
|
||||
"model_type": model_type,
|
||||
"versions": versions,
|
||||
"versions": models, # Return the full list of model details
|
||||
"latest_version": latest_version
|
||||
}
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user