CoolFace
Apppublic

UnionGas/gaasu-tools

sourceHugging Faceotherupdated 4mo agoView on Hugging Face
0likes
app.py174 linesDownload Raw Back to root
1#!/usr/bin/env python32# -*- coding: utf-8 -*-3"""4高本爐具(中山)有限公司 — 報告工具 Dashboard5════════════════════════════════════════════════6只負責:頁面設定、路由分發、工具載入。7 8新增部門(零改此檔):9  → 在 core/config.py DEPTS 加入 ready=False 條目(自動顯示佔位頁)10  → 若需自定義部門頁:在 departments/ 建新 .py,再在下方路由 elif 加一行11 12新增工具(只改兩處):13  → core/config.py TOOLS 加一個 dict14  → 下方 TOOL_LOADERS 加一行  { "key": loader_func }15════════════════════════════════════════════════16"""17from __future__ import annotations18import os, sys19from pathlib import Path20import streamlit as st21 22# ─── 路徑設定 ─────────────────────────────────────────────────────────────────23PROJECT_ROOT = Path(__file__).resolve().parent24 25# 確保 PROJECT_ROOT 在 sys.path(HF 工作目錄不一定與 app.py 相同)26if str(PROJECT_ROOT) not in sys.path:27    sys.path.insert(0, str(PROJECT_ROOT))28 29TOOLS_DIR    = PROJECT_ROOT / "tools"30ASSETS_DIR   = PROJECT_ROOT / "assets"31OUTPUTS_DIR  = PROJECT_ROOT / "outputs"32RECON_DIR         = TOOLS_DIR / "supplier_reconciliation"33MATCALC_DIR       = TOOLS_DIR / "material_calc"34INV_RECON_DIR     = TOOLS_DIR / "invoice_recon"35FINBUDGET_DIR     = TOOLS_DIR / "financial_budget"36PO_GENERATOR_DIR  = TOOLS_DIR / "po_generator"37 38for _d in [OUTPUTS_DIR,39           RECON_DIR / "scripts",40           MATCALC_DIR / "scripts",41           INV_RECON_DIR / "scripts",42           FINBUDGET_DIR / "scripts",43           PO_GENERATOR_DIR / "scripts"]:44    _d.mkdir(parents=True, exist_ok=True)45for _p in [str(RECON_DIR / "scripts"),46           str(MATCALC_DIR / "scripts"),47           str(INV_RECON_DIR / "scripts"),48           str(FINBUDGET_DIR / "scripts"),49           str(PO_GENERATOR_DIR / "scripts")]:50    if _p not in sys.path:51        sys.path.insert(0, _p)52 53IS_CLOUD = bool(os.environ.get("SPACE_ID") or os.environ.get("STREAMLIT_CLOUD"))54 55# ─── 頁面設定(必須最先執行) ─────────────────────────────────────────────────56st.set_page_config(57    page_title="高本爐具(中山)有限公司",58    page_icon="🏭",59    layout="wide",60    initial_sidebar_state="collapsed",61)62 63# ─── 核心模組 ─────────────────────────────────────────────────────────────────64from core.config import VALID_PAGES, DEPT_MAP65from core.styles import inject_global_css66from core.nav   import render_tool_topbar67from departments.company     import render_company_home68from departments.material    import render_dept_material69from departments.finance     import render_dept_finance70from departments.placeholder import render_dept_placeholder71 72# ─── 全站 CSS 注入(每次 rerun 執行一次) ────────────────────────────────────73inject_global_css()74 75# ─── 路由(URL query_params 為唯一真相來源) ─────────────────────────────────76_q = st.query_params.get("page", "company_home")77st.session_state["page"] = _q if _q in VALID_PAGES else "company_home"78page = st.session_state["page"]79 80 81# ══════════════════════════════════════════════════════════════════════════════82# 工具載入函數83# 新增工具:在此加一個 def,然後在 TOOL_LOADERS 加一行84# ══════════════════════════════════════════════════════════════════════════════85def _load_material_calc():86    render_tool_topbar("material_calc")87    try:88        import material_calc as matcalc  # noqa: PLC041589        matcalc.render(PROJECT_ROOT, MATCALC_DIR, OUTPUTS_DIR, IS_CLOUD)90    except Exception as e:91        st.error(f"物料計算載入失敗:{e}")92        st.exception(e)93 94 95def _load_supplier_recon():96    render_tool_topbar("supplier_recon")97    try:98        import supplier_recon_ui as recon_ui  # noqa: PLC041599        recon_ui.render(PROJECT_ROOT, RECON_DIR, ASSETS_DIR, OUTPUTS_DIR, IS_CLOUD)100    except Exception as e:101        st.error(f"供應商對帳載入失敗:{e}")102        st.exception(e)103 104 105def _load_financial_budget():106    render_tool_topbar("financial_budget")107    try:108        import financial_budget as fin_budget  # noqa: PLC0415109        fin_budget.render(PROJECT_ROOT, FINBUDGET_DIR, OUTPUTS_DIR, IS_CLOUD)110    except Exception as e:111        st.error(f"財務預算載入失敗:{e}")112        st.exception(e)113 114 115def _load_invoice_recon():116    render_tool_topbar("invoice_recon")117    try:118        import invoice_recon_ui as inv_ui  # noqa: PLC0415119        inv_ui.render(PROJECT_ROOT, INV_RECON_DIR, ASSETS_DIR, OUTPUTS_DIR, IS_CLOUD)120    except Exception as e:121        st.error(f"供應商付款發票對帳單載入失敗:{e}")122        st.exception(e)123 124 125def _load_po_generator():126    render_tool_topbar("po_generator")127    try:128        import po_generator as pg  # noqa: PLC0415129        pg.render()130    except Exception as e:131        st.error(f"採購單生成載入失敗:{e}")132        st.exception(e)133 134 135# ── 工具分發表(key → loader),新增工具只需在此加一行 ──────────────────────136TOOL_LOADERS: dict[str, object] = {137    "material_calc":    _load_material_calc,138    "supplier_recon":   _load_supplier_recon,139    "invoice_recon":    _load_invoice_recon,140    "financial_budget": _load_financial_budget,141    "po_generator":     _load_po_generator,142}143 144 145# ══════════════════════════════════════════════════════════════════════════════146# 路由分發147# ══════════════════════════════════════════════════════════════════════════════148if page == "company_home":149    render_company_home()150 151elif page == "dept_material":152    render_dept_material()153 154elif page == "dept_finance":155    render_dept_finance()156 157elif page.startswith("dept_"):158    # 所有其他部門 → 自動佔位頁(ready=False 時)159    # 若部門已上線,在此加 elif page == "dept_xxx": render_dept_xxx()160    dept_key = page[5:]   # 去掉 "dept_" 前綴161    if dept_key in DEPT_MAP:162        render_dept_placeholder(dept_key)163    else:164        st.query_params["page"] = "company_home"165        st.rerun()166 167elif page in TOOL_LOADERS:168    TOOL_LOADERS[page]()169 170else:171    # 未知頁面 → 導回主頁172    st.query_params["page"] = "company_home"173    st.rerun()174