From adb5e0f2b41634d52e1e6bf0d84830e64eb35782 Mon Sep 17 00:00:00 2001 From: xz2000 Date: Thu, 24 Jul 2025 18:37:58 +0800 Subject: [PATCH] =?UTF-8?q?=E7=AC=AC=E4=B8=80=E9=98=B6=E6=AE=B5=EF=BC=9A?= =?UTF-8?q?=E5=88=9D=E6=AD=A5=E9=87=8D=E6=9E=84=E4=B8=8E=E6=A0=87=E5=87=86?= =?UTF-8?q?=E5=8C=96=20=E8=B5=B7=E7=82=B9:=20=E6=9C=80=E5=88=9D=E7=9A=84?= =?UTF-8?q?=E7=B3=BB=E7=BB=9F=E5=8A=9F=E8=83=BD=E5=9F=BA=E6=9C=AC=EF=BC=8C?= =?UTF-8?q?=E4=BD=86=E4=BB=A3=E7=A0=81=E5=AD=98=E5=9C=A8=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=EF=BC=8C=E7=BC=BA=E4=B9=8F=E7=BB=9F=E4=B8=80=E6=A0=87=E5=87=86?= =?UTF-8?q?=E3=80=82=E6=88=91=E4=BB=AC=E4=BB=8E=E4=BF=AE=E5=A4=8D=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=20xgboost=5Ftrainer.py=20=E4=B8=AD=E7=9A=84=20NameErr?= =?UTF-8?q?or=20=E5=BC=80=E5=A7=8B=E3=80=82=20=E6=A0=B8=E5=BF=83=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C:=20=E7=BB=9F=E4=B8=80=E5=B7=A5=E4=BB=B6=E4=BF=9D?= =?UTF-8?q?=E5=AD=98:=20=E5=B0=86=E6=89=80=E6=9C=89=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E8=AE=AD=E7=BB=83=E8=84=9A=E6=9C=AC=20(xgboost,=20kan,=20tcn?= =?UTF-8?q?=20=E7=AD=89)=20=E4=B8=AD=E4=BF=9D=E5=AD=98=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E5=92=8C=E5=9B=BE=E8=A1=A8=E7=9A=84=E9=80=BB=E8=BE=91=E8=BF=9B?= =?UTF-8?q?=E8=A1=8C=E4=BA=86=E9=87=8D=E6=9E=84=EF=BC=8C=E6=8F=90=E5=8F=96?= =?UTF-8?q?=E5=88=B0=20server/utils/visualization.py=20=E5=92=8C=20server/?= =?UTF-8?q?utils/model=5Fmanager.py=20=E4=B8=AD=EF=BC=8C=E7=A1=AE=E4=BF=9D?= =?UTF-8?q?=E4=BA=86=E6=89=80=E6=9C=89=E8=AE=AD=E7=BB=83=E5=99=A8=E9=83=BD?= =?UTF-8?q?=E9=81=B5=E5=BE=AA=E7=BB=9F=E4=B8=80=E3=80=81=E5=81=A5=E5=A3=AE?= =?UTF-8?q?=E7=9A=84=E6=A8=A1=E5=BC=8F=E3=80=82=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=BB=98=E5=9B=BEBug:=20=E4=BF=AE=E6=AD=A3=E4=BA=86=20visualiz?= =?UTF-8?q?ation.py=20=E4=B8=AD=E6=8D=9F=E5=A4=B1=E6=9B=B2=E7=BA=BF?= =?UTF-8?q?=E5=9B=BE=E6=96=87=E4=BB=B6=E5=90=8D=E7=94=9F=E6=88=90=E4=B8=8D?= =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E7=9A=84bug=EF=BC=8C=E5=B9=B6=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E4=BA=86=E6=89=80=E6=9C=89=E8=AE=AD=E7=BB=83=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E4=BB=A5=E9=80=82=E5=BA=94=E6=96=B0=E7=9A=84=E3=80=81?= =?UTF-8?q?=E6=9B=B4=E9=80=9A=E7=94=A8=E7=9A=84=20plot=5Floss=5Fcurve=20?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E3=80=82=20=E7=AC=AC=E4=BA=8C=E9=98=B6?= =?UTF-8?q?=E6=AE=B5=EF=BC=9A=E6=95=B0=E6=8D=AE=E5=BA=93=E4=B8=8EAPI?= =?UTF-8?q?=E7=9A=84=E7=8E=B0=E4=BB=A3=E5=8C=96=E6=94=B9=E9=80=A0=20?= =?UTF-8?q?=E9=97=AE=E9=A2=98:=20=E5=8E=9F=E6=9C=89=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E8=AE=BE=E8=AE=A1=E8=BF=87=E4=BA=8E=E7=AE=80?= =?UTF-8?q?=E5=8D=95=EF=BC=8C=E4=BE=9D=E8=B5=96=E6=96=87=E4=BB=B6=E5=90=8D?= =?UTF-8?q?=E6=88=96=E5=A4=8D=E5=90=88=E9=94=AE=E6=9D=A5=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=EF=BC=8C=E9=9D=9E=E5=B8=B8=E8=84=86=E5=BC=B1?= =?UTF-8?q?=E4=B8=94=E9=9A=BE=E4=BB=A5=E6=89=A9=E5=B1=95=E3=80=82=20?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E5=B7=A5=E4=BD=9C:=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E9=87=8D=E6=96=B0=E8=AE=BE=E8=AE=A1:=20=E5=9C=A8=20se?= =?UTF-8?q?rver/api.py=20=E4=B8=AD=EF=BC=8C=E6=88=91=E5=AF=B9=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E8=BF=9B=E8=A1=8C=E4=BA=86=E5=BD=BB=E5=BA=95?= =?UTF-8?q?=E7=9A=84=E9=87=8D=E6=96=B0=E8=AE=BE=E8=AE=A1=E3=80=82=20?= =?UTF-8?q?=E5=BA=9F=E5=BC=83=E4=BA=86=E6=97=A7=E7=9A=84=20model=5Fversion?= =?UTF-8?q?s=20=E8=A1=A8=EF=BC=8C=E5=BC=95=E5=85=A5=E4=BA=86=E6=96=B0?= =?UTF-8?q?=E7=9A=84=20models=20=E8=A1=A8=EF=BC=8C=E4=B8=BA=E6=AF=8F?= =?UTF-8?q?=E4=B8=AA=E6=A8=A1=E5=9E=8B=E5=AE=9E=E4=BE=8B=E5=88=86=E9=85=8D?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E5=94=AF=E4=B8=80=E7=9A=84=20model=5Fuid?= =?UTF-8?q?=E3=80=82=E6=AD=A4=E8=A1=A8=E7=8E=B0=E5=9C=A8=E5=AD=98=E5=82=A8?= =?UTF-8?q?=E4=BA=86=E6=A8=A1=E5=9E=8B=E7=9A=84=E5=85=A8=E6=96=B9=E4=BD=8D?= =?UTF-8?q?=E5=85=83=E6=95=B0=E6=8D=AE=EF=BC=8C=E5=A6=82=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E3=80=81=E8=AE=AD=E7=BB=83=E8=8C=83=E5=9B=B4=E3=80=81=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E3=80=81=E6=80=A7=E8=83=BD=E6=8C=87=E6=A0=87=E5=92=8C?= =?UTF-8?q?=E5=B7=A5=E4=BB=B6=E8=B7=AF=E5=BE=84=E3=80=82=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E4=BA=86=20prediction=5Fhistory=20=E8=A1=A8=EF=BC=8C?= =?UTF-8?q?=E4=BD=BF=E5=85=B6=E9=80=9A=E8=BF=87=20model=5Fuid=20=E4=B8=8E?= =?UTF-8?q?=20models=20=E8=A1=A8=E5=85=B3=E8=81=94=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=81=B5=E6=B4=BB=E7=9A=84=20JSON=20?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=EF=BC=88=E5=A6=82=20prediction=5Fscope?= =?UTF-8?q?=EF=BC=89=E6=9D=A5=E5=AD=98=E5=82=A8=E9=A2=84=E6=B5=8B=E8=8C=83?= =?UTF-8?q?=E5=9B=B4=EF=BC=8C=E4=BB=A5=E4=BC=98=E9=9B=85=E5=9C=B0=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E2=80=9C=E6=8C=89=E4=BA=A7=E5=93=81=E2=80=9D=E3=80=81?= =?UTF-8?q?=E2=80=9C=E6=8C=89=E5=BA=97=E9=93=BA=E2=80=9D=E5=92=8C=E2=80=9C?= =?UTF-8?q?=E5=85=A8=E5=B1=80=E2=80=9D=E7=AD=89=E4=B8=8D=E5=90=8C=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=E3=80=82=20API=E5=A4=A7=E8=A7=84=E6=A8=A1=E9=87=8D?= =?UTF-8?q?=E6=9E=84:=20=E6=95=B0=E6=8D=AE=E5=BA=93=E7=9A=84=E5=8F=98?= =?UTF-8?q?=E6=9B=B4=E5=BC=95=E5=8F=91=E4=BA=86=E5=AF=B9=E5=90=8E=E7=AB=AF?= =?UTF-8?q?API=E7=9A=84=E5=85=A8=E9=9D=A2=E9=87=8D=E6=9E=84=E3=80=82=20/ap?= =?UTF-8?q?i/models:=20=E5=AE=8C=E5=85=A8=E9=87=8D=E5=86=99=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E4=BB=8E=E6=96=B0=E7=9A=84=20models=20=E8=A1=A8?= =?UTF-8?q?=E4=B8=AD=E6=9F=A5=E8=AF=A2=E6=95=B0=E6=8D=AE=E3=80=82=20/api/p?= =?UTF-8?q?rediction:=20=E6=8E=A5=E5=8F=A3=E8=A2=AB=E7=AE=80=E5=8C=96?= =?UTF-8?q?=EF=BC=8C=E7=8E=B0=E5=9C=A8=E5=8F=AA=E6=8E=A5=E5=8F=97=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=E6=A0=B8=E5=BF=83=E5=8F=82=E6=95=B0=20model=5Fuid?= =?UTF-8?q?=EF=BC=8C=E8=80=8C=E4=B8=8D=E6=98=AF=E4=B9=8B=E5=89=8D=E7=9A=84?= =?UTF-8?q?=E4=B8=80=E7=B3=BB=E5=88=97=E9=9B=B6=E6=95=A3=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E3=80=82=20/api/prediction/history:=20=E5=90=8C=E6=A0=B7?= =?UTF-8?q?=E8=A2=AB=E9=87=8D=E5=86=99=E4=BB=A5=E9=80=82=E5=BA=94=E6=96=B0?= =?UTF-8?q?=E7=9A=84=E8=A1=A8=E7=BB=93=E6=9E=84=E3=80=82=20=E7=AC=AC?= =?UTF-8?q?=E4=B8=89=E9=98=B6=E6=AE=B5=EF=BC=9A=E5=89=8D=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E8=81=94=E8=B0=83=E4=B8=8EBug=E4=BF=AE=E5=A4=8D=E5=91=A8?= =?UTF-8?q?=E6=9C=9F=20=E9=97=AE=E9=A2=98:=20=E5=90=8E=E7=AB=AF=E7=9A=84?= =?UTF-8?q?=E9=87=8D=E5=A4=A7=E9=87=8D=E6=9E=84=E5=AF=BC=E8=87=B4=E4=BA=86?= =?UTF-8?q?=E5=89=8D=E7=AB=AF=E5=8A=9F=E8=83=BD=E5=A4=B1=E6=95=88=EF=BC=8C?= =?UTF-8?q?=E6=9A=B4=E9=9C=B2=E5=87=BA=E5=89=8D=E5=90=8E=E7=AB=AF=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=AE=9A=E4=B9=89=E4=B8=8D=E5=8C=B9=E9=85=8D=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=82=20=E6=A0=B8=E5=BF=83=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C:=20=E4=BF=AE=E5=A4=8D=E6=A8=A1=E5=9E=8B=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=98=BE=E7=A4=BA:=20=E8=A7=A3=E5=86=B3=E4=BA=86?= =?UTF-8?q?=E5=9B=A0=E5=90=8E=E7=AB=AF=20/api/models=20=E8=BF=94=E5=9B=9E?= =?UTF-8?q?=E7=9A=84JSON=E9=94=AE=E4=B8=8E=E5=89=8D=E7=AB=AF=E6=9C=9F?= =?UTF-8?q?=E6=9C=9B=EF=BC=88product=5Fname,=20store=5Fname=EF=BC=89?= =?UTF-8?q?=E4=B8=8D=E7=AC=A6=EF=BC=8C=E8=80=8C=E5=AF=BC=E8=87=B4=E7=9A=84?= =?UTF-8?q?=E2=80=9C=E8=8D=AF=E5=93=81=E5=90=8D=E7=A7=B0=E2=80=9D=E5=92=8C?= =?UTF-8?q?=E2=80=9C=E5=BA=97=E9=93=BA=E5=90=8D=E7=A7=B0=E2=80=9D=E5=88=97?= =?UTF-8?q?=E4=B8=BA=E7=A9=BA=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=A2=84=E6=B5=8B=E5=8A=9F=E8=83=BD:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BA=86=E5=9B=A0=E5=89=8D=E7=AB=AF=E5=90=91?= =?UTF-8?q?=20/api/prediction=20=E5=8F=91=E9=80=81=E6=97=A7=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E7=9A=84=E8=AF=B7=E6=B1=82=E4=BD=93=E8=80=8C=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=9A=84=E2=80=9C=E9=A2=84=E6=B5=8B=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E2=80=9D=E9=97=AE=E9=A2=98=E3=80=82=E6=88=91=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BA=86=E6=89=80=E6=9C=89=E4=B8=89=E4=B8=AA=E9=A2=84=E6=B5=8B?= =?UTF-8?q?=E8=A7=86=E5=9B=BE=EF=BC=88ProductPredictionView.vue,=20StorePr?= =?UTF-8?q?edictionView.vue,=20GlobalPredictionView.vue=EF=BC=89=EF=BC=8C?= =?UTF-8?q?=E4=BD=BF=E5=85=B6=E5=8F=91=E9=80=81=E5=90=8E=E7=AB=AF=E7=8E=B0?= =?UTF-8?q?=E5=9C=A8=E9=9C=80=E8=A6=81=E7=9A=84=20model=5Fuid=E3=80=82=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8DUI=E8=A7=86=E8=A7=89=E9=97=AE=E9=A2=98:=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BA=86=E9=A2=84=E6=B5=8B=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E4=B8=8A=E7=9A=84=E5=8A=A0=E8=BD=BD=E5=8A=A8=E7=94=BB=EF=BC=88?= =?UTF-8?q?spinner=EF=BC=89=E5=A4=B1=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E3=80=82=E5=8E=9F=E5=9B=A0=E6=98=AF=E5=89=8D=E7=AB=AF=E8=84=9A?= =?UTF-8?q?=E6=9C=AC=E9=80=BB=E8=BE=91=E4=B8=AD=E7=9A=84=E9=94=AE=E5=B7=B2?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=B8=BA=20model=5Fuid=EF=BC=8C=E4=BD=86?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E4=B8=AD=E7=9A=84=20:loading=20=E7=BB=91?= =?UTF-8?q?=E5=AE=9A=E4=BB=8D=E9=94=99=E8=AF=AF=E5=9C=B0=E6=8C=87=E5=90=91?= =?UTF-8?q?=E4=BA=86=E6=97=A7=E7=9A=84=20model=5Fid=E3=80=82=20=E7=AC=AC?= =?UTF-8?q?=E5=9B=9B=E9=98=B6=E6=AE=B5=EF=BC=9A=E5=8E=86=E5=8F=B2=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E9=A1=B5=E9=9D=A2=E7=9A=84=E6=9C=80=E7=BB=88=E5=AE=8C?= =?UTF-8?q?=E5=96=84=20=E9=97=AE=E9=A2=98:=20=E5=8E=86=E5=8F=B2=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E9=A1=B5=E9=9D=A2=E5=AD=98=E5=9C=A8=E5=A4=9A=E4=B8=AA?= =?UTF-8?q?=E6=B7=B1=E5=B1=82bug=EF=BC=8C=E5=8C=85=E6=8B=AC=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E4=B8=BA=E7=A9=BA=E3=80=81=E6=95=B0=E6=8D=AE=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E4=B8=8D=E6=AD=A3=E7=A1=AE=E4=BB=A5=E5=8F=8A=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E5=8A=9F=E8=83=BD=E5=A4=B1=E6=95=88=E3=80=82=20?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E5=B7=A5=E4=BD=9C:=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=A9=BA=E5=88=97=E8=A1=A8:=20=E8=A7=A3=E5=86=B3=E4=BA=86?= =?UTF-8?q?=E5=9B=A0=E5=90=8E=E7=AB=AF=20get=5Fprediction=5Fhistory=20?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E6=9F=A5=E8=AF=A2=E4=BA=86=E4=B8=8D=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E7=9A=84=E6=95=B0=E6=8D=AE=E5=BA=93=E5=88=97=E8=80=8C?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95=E4=B8=BA?= =?UTF-8?q?=E7=A9=BA=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=96=B9=E6=A1=88=E6=98=AF=E6=94=B9=E7=94=A8=20json=5Fextract?= =?UTF-8?q?=20=E5=87=BD=E6=95=B0=E6=9D=A5=E6=AD=A3=E7=A1=AE=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E5=B5=8C=E5=A5=97=E5=9C=A8JSON=E5=AD=97=E6=AE=B5?= =?UTF-8?q?=E4=B8=AD=E7=9A=84=20product=5Fid=E3=80=82=20=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E5=90=8D=E7=A7=B0=E6=98=BE=E7=A4=BA:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BA=86=E5=88=97=E8=A1=A8=E4=B8=AD=E4=BA=A7?= =?UTF-8?q?=E5=93=81=E5=90=8D=E7=A7=B0=E6=98=BE=E7=A4=BA=E4=B8=BA=E5=86=85?= =?UTF-8?q?=E9=83=A8=E6=A0=87=E8=AF=86=E7=AC=A6=E7=9A=84bug=E3=80=82?= =?UTF-8?q?=E6=A0=B9=E6=8D=AE=E6=82=A8=E7=9A=84=E8=A6=81=E6=B1=82=EF=BC=8C?= =?UTF-8?q?=E6=88=91=E5=9C=A8=E4=B8=8D=E4=BF=AE=E6=94=B9=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E8=AE=B0=E5=BD=95=E7=9A=84=E5=89=8D=E6=8F=90=E4=B8=8B?= =?UTF-8?q?=EF=BC=8C=E9=80=9A=E8=BF=87=E5=9C=A8=E5=90=8E=E7=AB=AF=E8=AF=BB?= =?UTF-8?q?=E5=8F=96=E6=95=B0=E6=8D=AE=E6=97=B6=E5=8A=A8=E6=80=81=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E4=BA=A7=E5=93=81=E5=90=8D=E5=B9=B6=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E7=BB=99=E5=89=8D=E7=AB=AF=E7=9A=84=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=EF=BC=8C=E8=A7=A3=E5=86=B3=E4=BA=86=E8=BF=99=E4=B8=AA?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E3=80=82=20=E5=AE=9E=E7=8E=B0=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E7=AD=9B=E9=80=89=E4=B8=8B=E6=8B=89=E6=A1=86:=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E4=BA=86=E4=BA=A7=E5=93=81=E7=AD=9B=E9=80=89?= =?UTF-8?q?=E4=B8=8B=E6=8B=89=E6=A1=86=E4=B8=BA=E7=A9=BA=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=82=E6=A0=B9=E6=8D=AE=E6=82=A8=E7=9A=84=E6=9C=80?= =?UTF-8?q?=E7=BB=88=E6=8C=87=E7=A4=BA=EF=BC=8C=E6=88=91=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=BA=86=20HistoryView.vue=EF=BC=8C=E4=BD=BF=E5=85=B6=E4=BB=8E?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E7=9A=84=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E4=B8=AD=E5=8A=A8=E6=80=81=E6=8F=90=E5=8F=96?= =?UTF-8?q?=E5=94=AF=E4=B8=80=E7=9A=84=E4=BA=A7=E5=93=81=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=9D=A5=E5=A1=AB=E5=85=85=E4=B8=8B=E6=8B=89=E6=A1=86=EF=BC=8C?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=BA=86=E5=8E=9F=E6=9C=89=E7=9A=84=E7=8B=AC?= =?UTF-8?q?=E7=AB=8BAPI=E8=B0=83=E7=94=A8=EF=BC=8C=E4=BD=BF=E7=AD=9B?= =?UTF-8?q?=E9=80=89=E5=8A=9F=E8=83=BD=E6=9B=B4=E5=8A=A0=E6=99=BA=E8=83=BD?= =?UTF-8?q?=E5=92=8C=E9=AB=98=E6=95=88=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UI/src/views/HistoryView.vue | 26 +++---- .../views/prediction/GlobalPredictionView.vue | 32 ++++----- .../prediction/ProductPredictionView.vue | 12 ++-- .../views/prediction/StorePredictionView.vue | 33 ++++----- prediction_history.db | Bin 167936 -> 167936 bytes server/api.py | 65 +++++++++++------- xz数据库2025_07_24.md | 1 + 7 files changed, 89 insertions(+), 80 deletions(-) diff --git a/UI/src/views/HistoryView.vue b/UI/src/views/HistoryView.vue index b223167..2cc9131 100644 --- a/UI/src/views/HistoryView.vue +++ b/UI/src/views/HistoryView.vue @@ -18,7 +18,7 @@ - + { } }; -const fetchProducts = async () => { - try { - const response = await axios.get('/api/products'); - if (response.data.status === 'success') { - products.value = response.data.data; - } - } catch (error) { - ElMessage.error('获取产品列表失败'); - } -}; +// fetchProducts 函数不再需要,将从历史记录中动态生成产品列表 const fetchHistory = async () => { loading.value = true; @@ -309,6 +300,17 @@ const fetchHistory = async () => { if (response.data.status === 'success') { history.value = response.data.data; pagination.total = response.data.total; + + // 从返回的历史记录中动态提取唯一的产品列表 + if (response.data.data && response.data.data.length > 0) { + const uniqueProducts = new Map(); + response.data.data.forEach(record => { + if (record.product_id && record.product_name) { + uniqueProducts.set(record.product_id, record.product_name); + } + }); + products.value = Array.from(uniqueProducts, ([product_id, product_name]) => ({ product_id, product_name })); + } } } catch (error) { ElMessage.error('获取历史记录失败'); @@ -1120,7 +1122,7 @@ onUnmounted(() => { }); onMounted(() => { - fetchProducts(); + // fetchProducts(); // 不再需要独立获取产品列表 fetchModelTypes(); fetchHistory(); }); diff --git a/UI/src/views/prediction/GlobalPredictionView.vue b/UI/src/views/prediction/GlobalPredictionView.vue index abd4fcf..24824cc 100644 --- a/UI/src/views/prediction/GlobalPredictionView.vue +++ b/UI/src/views/prediction/GlobalPredictionView.vue @@ -54,7 +54,7 @@ type="primary" size="small" @click="startPrediction(row)" - :loading="predicting[row.model_id]" + :loading="predicting[row.model_uid]" > 开始预测 @@ -164,33 +164,31 @@ const fetchModels = async () => { } const startPrediction = async (model) => { - predicting[model.model_id] = true + predicting[model.model_uid] = true; // 使用 model_uid 作为唯一的键 try { const payload = { - training_mode: 'global', - model_type: model.model_type, - version: model.version, + model_uid: model.model_uid, // 关键修复:使用 model_uid future_days: form.future_days, history_lookback_days: form.history_lookback_days, start_date: form.start_date, - analyze_result: form.analyze_result, - } - const response = await axios.post('/api/prediction', payload) + include_visualization: true, + }; + const response = await axios.post('/api/prediction', payload); if (response.data.status === 'success') { - predictionResult.value = response.data.data - ElMessage.success('预测完成!') - dialogVisible.value = true - await nextTick() - renderChart() + predictionResult.value = response.data.data; + ElMessage.success('预测完成!'); + dialogVisible.value = true; + await nextTick(); + renderChart(); } else { - ElMessage.error(response.data.error || '预测失败') + ElMessage.error(response.data.error || '预测失败'); } } catch (error) { - ElMessage.error(error.response?.data?.error || '预测请求失败') + ElMessage.error(error.response?.data?.error || '预测请求失败'); } finally { - predicting[model.model_id] = false + predicting[model.model_uid] = false; // 保持键的一致性 } -} +}; const renderChart = () => { if (!chartCanvas.value || !predictionResult.value) return diff --git a/UI/src/views/prediction/ProductPredictionView.vue b/UI/src/views/prediction/ProductPredictionView.vue index 47a76a0..451ae25 100644 --- a/UI/src/views/prediction/ProductPredictionView.vue +++ b/UI/src/views/prediction/ProductPredictionView.vue @@ -63,7 +63,7 @@ type="primary" size="small" @click="startPrediction(row)" - :loading="predicting[row.model_id]" + :loading="predicting[row.model_uid]" > 开始预测 @@ -174,16 +174,14 @@ const fetchModels = async () => { } const startPrediction = async (model) => { - predicting[model.model_id] = true + predicting[model.model_uid] = true // 使用 model_uid 作为唯一的键 try { const payload = { - product_id: model.product_id, - model_type: model.model_type, - version: model.version, + model_uid: model.model_uid, // 关键修复:使用 model_uid future_days: form.future_days, history_lookback_days: form.history_lookback_days, start_date: form.start_date, - include_visualization: true, // 分析功能硬编码为开启 + include_visualization: true, } const response = await axios.post('/api/prediction', payload) if (response.data.status === 'success') { @@ -198,7 +196,7 @@ const startPrediction = async (model) => { } catch (error) { ElMessage.error(error.response?.data?.error || '预测请求失败') } finally { - predicting[model.model_id] = false + predicting[model.model_uid] = false } } diff --git a/UI/src/views/prediction/StorePredictionView.vue b/UI/src/views/prediction/StorePredictionView.vue index 88f6b93..e17179c 100644 --- a/UI/src/views/prediction/StorePredictionView.vue +++ b/UI/src/views/prediction/StorePredictionView.vue @@ -63,7 +63,7 @@ type="primary" size="small" @click="startPrediction(row)" - :loading="predicting[row.model_id]" + :loading="predicting[row.model_uid]" > 开始预测 @@ -187,34 +187,31 @@ const fetchStores = async () => { } const startPrediction = async (model) => { - predicting[model.model_id] = true + predicting[model.model_uid] = true; // 使用 model_uid 作为唯一的键 try { const payload = { - training_mode: 'store', - store_id: model.store_id, - model_type: model.model_type, - version: model.version, + model_uid: model.model_uid, // 关键修复:使用 model_uid future_days: form.future_days, history_lookback_days: form.history_lookback_days, start_date: form.start_date, - analyze_result: form.analyze_result, - } - const response = await axios.post('/api/prediction', payload) + include_visualization: true, + }; + const response = await axios.post('/api/prediction', payload); if (response.data.status === 'success') { - predictionResult.value = response.data.data - ElMessage.success('预测完成!') - dialogVisible.value = true - await nextTick() - renderChart() + predictionResult.value = response.data.data; + ElMessage.success('预测完成!'); + dialogVisible.value = true; + await nextTick(); + renderChart(); } else { - ElMessage.error(response.data.error || '预测失败') + ElMessage.error(response.data.error || '预测失败'); } } catch (error) { - ElMessage.error(error.response?.data?.error || '预测请求失败') + ElMessage.error(error.response?.data?.error || '预测请求失败'); } finally { - predicting[model.model_id] = false + predicting[model.model_uid] = false; // 保持键的一致性 } -} +}; const renderChart = () => { if (!chartCanvas.value || !predictionResult.value) return diff --git a/prediction_history.db b/prediction_history.db index 75a2a128203ef5436e137ded173ee0d42bb0a3ee..167ec843029259a49102f5721aa4482c90d1b4f5 100644 GIT binary patch delta 1888 zcmc(gPfHs?7{+(ACL~ca5lU%MsErgAIx;&uvzysNEn4VBp+$letZ}n5OVg?e`6Eb> z*oAs+${xIW=v8d-Snw;W%KU4%kz7mXWrf1NpJ3?JA>-M zyP;|I;N#MJkWD13O6F7lS|3S&OYJ7B`vcj9q~Y6%KBZ8gbI-~HuWuW!Lqy*7D9mG~ zLxO}3S)K^!AewiPAdV$ykSPuYdyC27>Ej#QPiA5x?N+W@tMI1VD3*E79$sxOFW(=| z)f<(XIIC>5a$d91lqK%0*JYb^(&N+`vd|E+ki!U5h%AUnZlkqPch&?iR%?Qn-A1{x zT3eb1iFL;=BDRC#w-R2#sZc&L(t6= zf(&6`$3(&5qkAE6QnwJoCdzM5ti*=YR`6hYuzjVZ(duSRbRH?T5%MQ{BC>MLWH zdS68eKA#<%{#2|x+YCFF#SwwhBq9$q5)#`IGTTDu7AXl%t})xu>SoDb*$!Q{Y(o7h zwVM<U4p61w#6wdQPY94Rx(PIIGplesd!DNI9lBV<>z@SNl{u+lmzHiz*q1b zY=J#MK(AciKQiqxt)OSQ4W{#dSd^0GW#%_0BHrJ!7ebs7dgT=@|o|M v;O*jAJTb1#tKo82