From 15b3bae9cb33fe4947c5b213f2b15db91183c9aa Mon Sep 17 00:00:00 2001
From: OoO
Date: Fri, 1 May 2026 00:21:26 +0800
Subject: [PATCH] =?UTF-8?q?feat(frontend):=20=E6=96=B0=E5=A2=9E=E5=BB=A0?=
=?UTF-8?q?=E5=95=86=E7=BC=BA=E8=B2=A8=E5=8C=AF=E5=85=A5=20V2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
CONSTITUTION.md | 2 +-
app.py | 4 +-
routes/vendor_routes.py | 33 +-
templates/vendor_stockout_import_v2.html | 574 +++++++++++++++++++++++
templates/vendor_stockout_index_v2.html | 4 +-
templates/vendor_stockout_list_v2.html | 2 +-
tests/test_frontend_v2_assets.py | 15 +
7 files changed, 606 insertions(+), 28 deletions(-)
create mode 100644 templates/vendor_stockout_import_v2.html
diff --git a/CONSTITUTION.md b/CONSTITUTION.md
index 59695e2..65e97b3 100644
--- a/CONSTITUTION.md
+++ b/CONSTITUTION.md
@@ -2,7 +2,7 @@
> 本文件定義專案開發的核心準則與不可違反的規範
> **建立日期**: 2026-01-12
-> **當前版本**: V10.38 (Vendor stockout list v2 feature flag)
+> **當前版本**: V10.39 (Vendor stockout import v2 feature flag)
> **最後更新**: 2026-05-01
---
diff --git a/app.py b/app.py
index 2b2a944..a5241c9 100644
--- a/app.py
+++ b/app.py
@@ -95,8 +95,8 @@ except Exception as e:
sys_log.error(f"無法檢測磁碟空間: {e}")
# 🚩 系統版本定義 (備份與顯示用)
-# 🚩 2026-05-01 V10.38: Vendor stockout list v2 feature flag
-SYSTEM_VERSION = "V10.38"
+# 🚩 2026-05-01 V10.39: Vendor stockout import v2 feature flag
+SYSTEM_VERSION = "V10.39"
# ==========================================
# 🔒 SQL Injection 防護函數
diff --git a/routes/vendor_routes.py b/routes/vendor_routes.py
index cc56f5c..88f3353 100644
--- a/routes/vendor_routes.py
+++ b/routes/vendor_routes.py
@@ -211,6 +211,11 @@ def index():
def import_page():
"""Excel 匯入頁面"""
sys_log.info("[VendorStockout] 進入匯入頁面")
+ if request.args.get('ui') == 'v2':
+ return render_template(
+ 'vendor_stockout_import_v2.html',
+ active_page='vendor_stockout'
+ )
return render_template('vendor_stockout/import.html')
@@ -428,28 +433,12 @@ def api_import_excel():
def api_import_template():
"""下載 Excel 匯入範本(使用實際欄位名稱)"""
try:
- # 建立範本 DataFrame(使用實際的欄位名稱)
- template_data = {
- '當前日期': ['2026-01-12'],
- '處別': ['範例處別'],
- '科別': ['範例科別'],
- 'PM姓名': ['王小明'],
- '區ID': ['A01'],
- '區名稱': ['範例區域'],
- '商品ID': ['123456789'],
- '商品名稱': ['範例商品名稱'],
- '單品/組合商品': ['單品'],
- '借採轉': ['否'],
- '來源供應商編號': ['V001'],
- '來源供應商名稱': ['範例供應商股份有限公司'],
- '商品可賣量': [50],
- '缺貨日期': ['2026-01-10'],
- '缺貨天數': [2],
- '缺貨商品前30天業績': [150000],
- '最近30天銷售量': [300],
- '庫存水位': ['低']
- }
- df = pd.DataFrame(template_data)
+ template_columns = [
+ '當前日期', '處別', '科別', 'PM姓名', '區ID', '區名稱', '商品ID', '商品名稱',
+ '單品/組合商品', '借採轉', '來源供應商編號', '來源供應商名稱', '商品可賣量',
+ '缺貨日期', '缺貨天數', '缺貨商品前30天業績', '最近30天銷售量', '庫存水位'
+ ]
+ df = pd.DataFrame(columns=template_columns)
# 輸出到記憶體
output = io.BytesIO()
diff --git a/templates/vendor_stockout_import_v2.html b/templates/vendor_stockout_import_v2.html
new file mode 100644
index 0000000..96caf9c
--- /dev/null
+++ b/templates/vendor_stockout_import_v2.html
@@ -0,0 +1,574 @@
+{% extends 'ewoooc_base.html' %}
+
+{% block title %}EwoooC 缺貨匯入{% endblock %}
+
+{% block extra_css %}
+
+{% endblock %}
+
+{% block ewooo_content %}
+
+{% endblock %}
+
+{% block extra_js %}
+
+{% endblock %}
diff --git a/templates/vendor_stockout_index_v2.html b/templates/vendor_stockout_index_v2.html
index 226eea1..f23dfe3 100644
--- a/templates/vendor_stockout_index_v2.html
+++ b/templates/vendor_stockout_index_v2.html
@@ -341,7 +341,7 @@
-
+
Excel 匯入
diff --git a/templates/vendor_stockout_list_v2.html b/templates/vendor_stockout_list_v2.html
index 0f1cb01..277b993 100644
--- a/templates/vendor_stockout_list_v2.html
+++ b/templates/vendor_stockout_list_v2.html
@@ -334,7 +334,7 @@
回總覽
-
+
匯入 Excel
diff --git a/tests/test_frontend_v2_assets.py b/tests/test_frontend_v2_assets.py
index d8edfa5..517fb79 100644
--- a/tests/test_frontend_v2_assets.py
+++ b/tests/test_frontend_v2_assets.py
@@ -99,3 +99,18 @@ def test_vendor_stockout_list_v2_is_feature_flagged_and_uses_real_stockout_rows(
assert "record.vendor_name" in template
assert "mock" not in template.lower()
assert "假" not in template
+
+
+def test_vendor_stockout_import_v2_is_feature_flagged_and_does_not_ship_sample_rows():
+ route_source = (ROOT / "routes/vendor_routes.py").read_text(encoding="utf-8")
+ template = (ROOT / "templates/vendor_stockout_import_v2.html").read_text(encoding="utf-8")
+ template_function = route_source.split("def api_import_template():", 1)[1].split("@vendor_bp.route('/api/stockout/list'", 1)[0]
+
+ assert "vendor_stockout_import_v2.html" in route_source
+ assert "template_columns = [" in template_function
+ assert "pd.DataFrame(columns=template_columns)" in template_function
+ assert "fetchWithCSRF('/vendor-stockout/api/import/excel'" in template
+ assert "vendor_stockout" in template
+ assert "範例" not in template_function
+ assert "mock" not in template.lower()
+ assert "假" not in template