CareerBot/app/routers/public.py
ln0422 96997daed0 Initial commit: CareerBot full-stack career showcase with AI chatbot
- FastAPI backend with SQLAlchemy ORM and SQLite
- AI chatbot with OpenAI-compatible LLM integration (SSE streaming)
- Admin panel for content management, LLM config, token management
- Anonymous access with 3-question limit, token-based access control
- Recruiter intent detection with admin notification
- Resume generator (JD-based, Markdown to Word export)
- Chinese localized public interface

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-07 20:36:38 +08:00

93 lines
2.8 KiB
Python

from fastapi import APIRouter, Depends, Request
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.orm import Session
from app.database import get_db
from app.models import Profile, Skill, Education, WorkExperience, AccessToken
router = APIRouter()
templates = Jinja2Templates(directory="templates")
@router.get("/", response_class=HTMLResponse)
def index_page(request: Request, db: Session = Depends(get_db)):
token = request.cookies.get("visitor_token")
if not token:
return RedirectResponse(url="/login", status_code=302)
# Allow both valid tokens and anonymous
if token != "__anonymous__":
record = db.query(AccessToken).filter(
AccessToken.token == token, AccessToken.is_active == True
).first()
if not record:
return RedirectResponse(url="/login", status_code=302)
return templates.TemplateResponse(request, "index.html")
@router.get("/login", response_class=HTMLResponse)
def login_page(request: Request):
return templates.TemplateResponse(request, "login.html")
@router.get("/api/profile")
def get_profile(db: Session = Depends(get_db)):
profile = db.query(Profile).first()
if not profile:
return {}
return {
"name": profile.name,
"phone": profile.phone,
"location": profile.location,
"birthday": profile.birthday,
"party": profile.party,
"education_level": profile.education_level,
"email": profile.email,
"photo_url": profile.photo_url,
"self_summary": profile.self_summary,
}
@router.get("/api/skills")
def get_skills(db: Session = Depends(get_db)):
skills = db.query(Skill).order_by(Skill.sort_order).all()
return [
{"id": s.id, "category": s.category, "content": s.content}
for s in skills
]
@router.get("/api/education")
def get_education(db: Session = Depends(get_db)):
items = db.query(Education).order_by(Education.sort_order).all()
return [
{
"id": e.id,
"start_date": e.start_date,
"end_date": e.end_date,
"school": e.school,
"major": e.major,
"degree": e.degree,
"details": e.details,
}
for e in items
]
@router.get("/api/experience")
def get_experience(db: Session = Depends(get_db)):
items = db.query(WorkExperience).order_by(WorkExperience.sort_order).all()
return [
{
"id": exp.id,
"start_date": exp.start_date,
"end_date": exp.end_date,
"company": exp.company,
"position": exp.position,
"company_intro": exp.company_intro,
"responsibilities": exp.responsibilities,
"achievements": exp.achievements,
}
for exp in items
]