diff --git a/.trae/documents/Implementation Plan for Check-in Large Screen.md b/.trae/documents/Implementation Plan for Check-in Large Screen.md new file mode 100644 index 0000000..6a310f4 --- /dev/null +++ b/.trae/documents/Implementation Plan for Check-in Large Screen.md @@ -0,0 +1,34 @@ +I have analyzed the current project structure and designed a "Check-in Large Screen" (签到大屏) solution that integrates seamlessly with your existing system. + +### **Plan Overview** + +I will implement a **"Galaxy Spotlight"** style large screen: +1. **Background (Danmaku/Floating Tags)**: + - `Business Scope` and short `Vision` keywords will float elegantly in the background like stars or drifting clouds. + - Uses the project's blue/cyan tech theme. + +2. **Foreground (Spotlight Card)**: + - A central, animated card that cycles through checked-in guests. + - Displays: **Company Name** (Prominent), **Guest Name/Position**, and **Vision 2026**. + - Updates every 8-10 seconds to ensure everyone gets exposure. + +### **Implementation Steps** + +#### 1. Backend (`main.py`) +- Add a new route `/wall` to serve the large screen page. +- Add an API `/api/wall/data` to fetch approved check-in data (filtering out empty entries). + +#### 2. Frontend (`templates/wall.html`) +- Create a new responsive HTML template. +- **Visuals**: Reusing the `radial-gradient` background and neon aesthetics from `index.html`. +- **Animation**: + - JS-based floating animation for background tags. + - CSS transitions for the central spotlight card. + +#### 3. Admin Integration (`templates/admin.html`) +- Add a button "Open Large Screen" (打开签到大屏) in the Admin Dashboard for easy access. + +### **Technical Details** +- **Tech Stack**: Native JS/CSS (no extra heavy libraries needed), integrated into the existing FastAPI app. +- **Data Source**: Reads directly from `checkin_info` table. +- **Compatibility**: Optimized for 1080p/4K displays (MacOS standard). diff --git a/main.py b/main.py index 11e3baf..d319a25 100644 --- a/main.py +++ b/main.py @@ -46,6 +46,16 @@ DEFAULT_CONFIG = { "position": {"label": "职务", "show": True, "required": False}, "business_scope": {"label": "公司主要经营 / 业务", "show": True, "required": False}, "vision_2026": {"label": "2026年业务愿景", "show": True, "required": False} + }, + "wall_config": { + "show_fields": { + "name": True, + "company_name": True, + "position": True, + "vision_2026": True, + "business_scope": True + }, + "bg_opacity": 0.3 } } @@ -1055,6 +1065,44 @@ async def admin_page(request: Request): secret = os.getenv("ADD_USER_SECRET", "123quant-speed") return templates.TemplateResponse("admin.html", {"request": request, "secret": secret}) +@app.get("/wall", response_class=HTMLResponse) +async def wall_page(request: Request): + """ + 渲染签到大屏页面。 + """ + global CONFIG + CONFIG = load_config() + return templates.TemplateResponse("wall.html", {"request": request, "config": CONFIG}) + +@app.get("/api/wall/data") +def get_wall_data(): + """ + 获取大屏所需的数据: + 1. 所有已签到用户的 Company Name, Vision, Business Scope + 2. 过滤掉空数据 + """ + try: + conn = get_db_connection() + cur = conn.cursor(cursor_factory=RealDictCursor) + + # 获取最新的签到数据(按时间倒序) + query = """ + SELECT name, company_name, position, business_scope, vision_2026, social_point + FROM checkin_info + ORDER BY created_at DESC + """ + cur.execute(query) + rows = cur.fetchall() + + cur.close() + release_db_connection(conn) + + return {"success": True, "data": rows} + except Exception as e: + if 'conn' in locals() and conn: + release_db_connection(conn) + return JSONResponse(content={"success": False, "message": str(e)}, status_code=500) + @app.get("/api/admin/config") def get_config(): """ diff --git a/templates/admin.html b/templates/admin.html index a58d531..27d19f7 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -287,6 +287,14 @@

管理后台

+
+ + + +
+

基本信息设置

@@ -384,6 +392,32 @@
+
+

大屏设置 (Wall Config)

+
+ + +
+
+ +
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+

主题设置

@@ -516,6 +550,16 @@ document.getElementById('db_user').value = config.db_user || ''; document.getElementById('db_password').value = config.db_password || ''; document.getElementById('db_name').value = config.db_name || ''; + + // Wall Config + const wc = config.wall_config || {}; + const show = wc.show_fields || {}; + document.getElementById('wall_bg_opacity').value = wc.bg_opacity !== undefined ? wc.bg_opacity : 0.3; + document.getElementById('wall_show_name').checked = show.name !== false; + document.getElementById('wall_show_company').checked = show.company_name !== false; + document.getElementById('wall_show_position').checked = show.position !== false; + document.getElementById('wall_show_vision').checked = show.vision_2026 !== false; + document.getElementById('wall_show_scope').checked = show.business_scope !== false; }); function renderFieldConfig(fieldConfig) { @@ -605,6 +649,18 @@ // Field Config field_config: getFieldConfig(), + // Wall Config + wall_config: { + bg_opacity: parseFloat(document.getElementById('wall_bg_opacity').value), + show_fields: { + name: document.getElementById('wall_show_name').checked, + company_name: document.getElementById('wall_show_company').checked, + position: document.getElementById('wall_show_position').checked, + vision_2026: document.getElementById('wall_show_vision').checked, + business_scope: document.getElementById('wall_show_scope').checked + } + }, + // DB Config db_host: document.getElementById('db_host').value, db_port: document.getElementById('db_port').value, diff --git a/templates/wall.html b/templates/wall.html new file mode 100644 index 0000000..1296c0b --- /dev/null +++ b/templates/wall.html @@ -0,0 +1,500 @@ + + + + + + {{ config.event_title }} - 签到大屏 + + + +
+
{{ config.event_sub_title }}
+

{{ config.event_title }}

+
+ +
+
+ +
+ + {% set wc = config.wall_config if config.wall_config else {} %} + {% set show = wc.show_fields if wc.show_fields else {} %} + +
+
+ + + {% if show.company_name != false %} +
+ {% endif %} + + {% if show.vision_2026 != false or show.business_scope != false %} +
+ {% endif %} +
+
+ +
+
0
+
已签到嘉宾
+
+ + + + \ No newline at end of file