branch1: root-path deployment variant with chat UI hidden

- BASE_PATH="" for deployment at www.ityb.me root (no /careerbot prefix)
- Root redirect route only registered when BASE is non-empty
- Add secondary /careerbot/uploads mount for backward compat with
  trunk-uploaded photo URLs (shared DB scenario)
- Hide chat FAB and chat panel on index.html (display:none)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
ln0422 2026-04-21 12:15:58 +08:00
parent 5472649e89
commit cab5181fd3
3 changed files with 16 additions and 9 deletions

View File

@ -8,7 +8,7 @@ class Settings(BaseSettings):
ALGORITHM: str = "HS256" ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 480 ACCESS_TOKEN_EXPIRE_MINUTES: int = 480
UPLOAD_DIR: str = "./uploads" UPLOAD_DIR: str = "./uploads"
BASE_PATH: str = "/careerbot" BASE_PATH: str = ""
model_config = {"env_file": ".env", "env_file_encoding": "utf-8"} model_config = {"env_file": ".env", "env_file_encoding": "utf-8"}

View File

@ -10,7 +10,7 @@ from app.models import AdminUser, Profile
from app.routers import auth, public, admin, chat from app.routers import auth, public, admin, chat
from app.routers.auth import hash_password from app.routers.auth import hash_password
BASE = settings.BASE_PATH BASE = settings.BASE_PATH # "" for root deployment, or "/careerbot" for subpath
app = FastAPI(title="CareerBot", description="Personal Career Showcase with AI Assistant") app = FastAPI(title="CareerBot", description="Personal Career Showcase with AI Assistant")
@ -19,6 +19,12 @@ app.mount(f"{BASE}/static", StaticFiles(directory="app/static"), name="static")
os.makedirs(settings.UPLOAD_DIR, exist_ok=True) os.makedirs(settings.UPLOAD_DIR, exist_ok=True)
app.mount(f"{BASE}/uploads", StaticFiles(directory=settings.UPLOAD_DIR), name="uploads") app.mount(f"{BASE}/uploads", StaticFiles(directory=settings.UPLOAD_DIR), name="uploads")
# When BASE="" and DB is shared with a /careerbot deployment, photo_url values
# stored by the sibling deployment begin with "/careerbot/uploads/...".
# Add a secondary mount so those URLs keep resolving here.
if BASE == "":
app.mount("/careerbot/uploads", StaticFiles(directory=settings.UPLOAD_DIR), name="uploads_legacy")
# Include routers with BASE_PATH prefix # Include routers with BASE_PATH prefix
app.include_router(auth.router, prefix=BASE) app.include_router(auth.router, prefix=BASE)
app.include_router(public.router, prefix=BASE) app.include_router(public.router, prefix=BASE)
@ -30,9 +36,10 @@ admin.templates.env.globals["base"] = BASE
public.templates.env.globals["base"] = BASE public.templates.env.globals["base"] = BASE
# Root redirect to CareerBot # Root redirect only needed when deployed under a subpath (otherwise "/" is already the app root)
@app.get("/") if BASE:
def root_redirect(): @app.get("/")
def root_redirect():
return RedirectResponse(url=f"{BASE}/", status_code=302) return RedirectResponse(url=f"{BASE}/", status_code=302)

View File

@ -34,8 +34,8 @@
<div class="accordion" id="experience-container"></div> <div class="accordion" id="experience-container"></div>
</div> </div>
<!-- Chat Widget --> <!-- Chat Widget (FAB hidden in branch1: display-only variant for main domain www.ityb.me) -->
<button class="chat-fab" id="chat-fab" title="智能职业助手"> <button class="chat-fab" id="chat-fab" title="智能职业助手" style="display:none;">
<span class="fab-inner"> <span class="fab-inner">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path> <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
@ -44,7 +44,7 @@
</span> </span>
</button> </button>
<div class="chat-panel" id="chat-panel"> <div class="chat-panel" id="chat-panel" style="display:none;">
<div class="chat-header"> <div class="chat-header">
<span>智能职业助手</span> <span>智能职业助手</span>
<button id="chat-close">&times;</button> <button id="chat-close">&times;</button>