diff --git a/config.py b/config.py index 4db4ffb..dd7d29f 100644 --- a/config.py +++ b/config.py @@ -320,7 +320,7 @@ YOUTUBE_API_KEY = os.getenv('YOUTUBE_API_KEY', '') # ========================================== # 系統版本與路徑 # ========================================== -SYSTEM_VERSION = "V10.123" +SYSTEM_VERSION = "V10.124" LOG_FILE_PATH = os.path.join(BASE_DIR, 'logs/system.log') public_url = PUBLIC_URL # 用於模板顯示 diff --git a/templates/vendor_stockout_list_v2.html b/templates/vendor_stockout_list_v2.html index 7860eca..c4b9b20 100644 --- a/templates/vendor_stockout_list_v2.html +++ b/templates/vendor_stockout_list_v2.html @@ -8,17 +8,17 @@ {% endblock %} {% block ewooo_content %} -{% set status_labels = {'pending': '待發送', 'sent': '已發送', 'failed': '失敗'} %} +{% set status_labels = {'pending': '待發送', 'sent': '已發送', 'failed': '失敗', 'duplicate': '重複', 'unknown': '未標記'} %}
- STOCKOUT LIST + 缺貨清單 · 即時狀態

缺貨清單

- 依現有缺貨匯入資料呈現,可用批次、廠商、商品與發送狀態篩選;所有數字皆來自 vendor_stockout。 + 依正式缺貨資料呈現,可用批次、廠商、商品與發送狀態篩選;桌機保留密度,手機改為逐筆資料卡。

@@ -31,6 +31,8 @@
+ +
符合筆數
@@ -62,6 +64,9 @@
+ {% if current_status and current_status != 'all' %} + + {% endif %} + @@ -85,15 +95,15 @@
@@ -124,33 +134,34 @@ {% for record in records %} {% set record_status = record.status or 'pending' %} + {% set status_class = record_status if record_status in status_labels else 'unknown' %} - - + + {{ status_labels.get(record_status, record_status) }} {% if record.is_duplicate %}
重複 {{ record.duplicate_count or 0 }}
{% endif %} - +
{{ record.product_name }}
{{ record.product_code }}
- +
{{ record.vendor_name }}
{{ record.vendor_code }}
- {{ record.batch_id }} - {{ record.current_stock if record.current_stock is not none else '—' }} - {{ record.stockout_date.strftime('%Y-%m-%d') if record.stockout_date else '—' }} - {{ record.stockout_days if record.stockout_days is not none else '—' }} - + {{ record.batch_id }} + {{ record.current_stock if record.current_stock is not none else '—' }} + {{ record.stockout_date.strftime('%Y-%m-%d') if record.stockout_date else '—' }} + {{ record.stockout_days if record.stockout_days is not none else '—' }} + {% if record.monthly_sales_amount is not none %} ${{ record.monthly_sales_amount | int | number_format }} {% else %}—{% endif %} - {{ record.created_at.strftime('%Y-%m-%d %H:%M') if record.created_at else '—' }} + {{ record.created_at.strftime('%Y-%m-%d %H:%M') if record.created_at else '—' }} {% endfor %} diff --git a/web/static/css/page-vendor-list.css b/web/static/css/page-vendor-list.css index b8c97e5..081c87c 100644 --- a/web/static/css/page-vendor-list.css +++ b/web/static/css/page-vendor-list.css @@ -5,7 +5,8 @@ .stockout-list-stack { display: grid; - gap: 22px; + min-width: 0; + gap: 18px; } .stockout-header { @@ -46,6 +47,7 @@ } .stockout-subtitle { + max-width: 720px; margin: 8px 0 0; color: var(--momo-text-secondary); font-size: 13px; @@ -98,6 +100,7 @@ display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 12px; + min-width: 0; } .stockout-kpi, @@ -108,7 +111,11 @@ border-radius: 8px; } -.stockout-kpi { padding: 16px; } +.stockout-kpi { + min-width: 0; + padding: 16px; + box-shadow: inset 3px 0 0 var(--momo-border-strong); +} .stockout-kpi-label { color: var(--momo-text-secondary); @@ -137,7 +144,7 @@ .stockout-filter-form { display: grid; - grid-template-columns: minmax(220px, 1.4fr) minmax(180px, 0.9fr) minmax(160px, 0.8fr) auto; + grid-template-columns: minmax(220px, 1.6fr) minmax(180px, 0.9fr) minmax(160px, 0.8fr) minmax(130px, 0.62fr) auto; gap: 10px; align-items: center; } @@ -183,7 +190,10 @@ font-size: 11px; } -.stockout-table-wrap { overflow-x: auto; } +.stockout-table-wrap { + max-width: 100%; + overflow-x: auto; +} .stockout-table { width: 100%; @@ -256,6 +266,18 @@ border-color: rgba(214, 83, 68, 0.2); } +.stockout-chip.is-duplicate { + color: var(--momo-warning-text); + background: var(--momo-tag-honey-bg); + border-color: var(--momo-tag-honey-border); +} + +.stockout-chip.is-unknown { + color: var(--momo-text-tertiary); + background: var(--momo-bg-paper); + border-color: var(--momo-border-light); +} + .stockout-empty { padding: 34px; color: var(--momo-text-secondary); @@ -358,6 +380,82 @@ padding: 12px; } + .stockout-table-wrap { + overflow: visible; + } + + .stockout-table { + min-width: 0; + } + + .stockout-table, + .stockout-table thead, + .stockout-table tbody, + .stockout-table tr, + .stockout-table td { + display: block; + width: 100%; + } + + .stockout-table thead { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip: rect(0 0 0 0); + white-space: nowrap; + } + + .stockout-table tbody { + display: grid; + gap: 10px; + padding: 12px; + background: var(--momo-bg-paper); + } + + .stockout-table tr { + background: var(--momo-bg-surface); + border: 1px solid var(--momo-border-light); + border-radius: 8px; + overflow: hidden; + } + + .stockout-table td { + display: grid; + grid-template-columns: minmax(86px, 0.36fr) minmax(0, 1fr); + gap: 10px; + align-items: start; + padding: 10px 12px; + border-bottom: 1px solid var(--momo-border-light); + font-size: 12px; + } + + .stockout-table td:last-child { + border-bottom: 0; + } + + .stockout-table td::before { + content: attr(data-label); + color: var(--momo-text-tertiary); + font-family: var(--momo-font-mono); + font-size: 10px; + font-weight: 800; + } + + .stockout-product-name, + .stockout-vendor-name { + max-width: 100%; + white-space: normal; + } + + .stockout-pagination { + justify-content: stretch; + } + + .stockout-page-link { + flex: 1 1 auto; + } + .stockout-title { font-size: 26px; } }