Archived
X platform fix #3
@@ -20,7 +20,7 @@ import sqlite3
|
||||
from datetime import timedelta
|
||||
|
||||
import requests
|
||||
from flask import Flask, render_template, request, jsonify, send_from_directory
|
||||
from flask import Flask, render_template, request, jsonify, send_from_directory, redirect
|
||||
|
||||
# ---- 初始化 Flask 应用 ----
|
||||
app = Flask(__name__)
|
||||
@@ -257,17 +257,8 @@ def load_seed_videos():
|
||||
|
||||
@app.route("/")
|
||||
def index():
|
||||
"""
|
||||
主页路由 — 返回 SPA(单页应用)的 HTML。
|
||||
前端所有页面切换都在这一个 HTML 里完成,不刷新浏览器。
|
||||
"""
|
||||
return render_template("index.html")
|
||||
|
||||
|
||||
@app.route("/demo")
|
||||
def demo():
|
||||
"""返回独立静态 Demo 页面"""
|
||||
return send_from_directory(BASE_DIR, "mathbrain-demo.html")
|
||||
"""主页路由 — 重定向到桌面端网页版"""
|
||||
return redirect("/web", code=302)
|
||||
|
||||
|
||||
@app.route("/web")
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Vendored
-1
File diff suppressed because one or more lines are too long
-1509
File diff suppressed because it is too large
Load Diff
Vendored
-1263
File diff suppressed because it is too large
Load Diff
@@ -1,386 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<title>葫芦数学 · Hulu Math</title>
|
||||
<link rel="stylesheet" href="/static/css/style.min.css?v=10.0">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- =========================================================
|
||||
葫芦数学 · MVP v6.0 — 底部TabBar布局
|
||||
仿微信小程序风格:底部导航 + 顶部内容区
|
||||
========================================================= -->
|
||||
|
||||
<div class="app-container">
|
||||
|
||||
<!-- ====== 顶部状态栏 ====== -->
|
||||
<header class="top-bar" id="topBar">
|
||||
<div class="top-bar-brand">
|
||||
<span class="brand-icon-sm">葫</span>
|
||||
<span class="brand-text-sm">葫芦数学</span>
|
||||
</div>
|
||||
<div class="top-bar-actions">
|
||||
<button class="icon-btn" onclick="openChat()" title="AI问答">?</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ====== 内容区 ====== -->
|
||||
<main class="content-area">
|
||||
|
||||
<!-- 搜索栏 -->
|
||||
<div class="search-header" id="searchHeader">
|
||||
<div class="search-bar-wrap">
|
||||
<span class="search-icon">🔍</span>
|
||||
<input type="text" id="videoSearch" placeholder="搜索你想看的数学内容..." oninput="handleSearch()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 子导航 (热门/推荐/专业分区) -->
|
||||
<div class="sub-nav" id="subNav">
|
||||
<button class="sub-nav-btn active" data-tab="recommend" onclick="switchSubTab('recommend')">推荐</button>
|
||||
<button class="sub-nav-btn" data-tab="hot" onclick="switchSubTab('hot')">热门</button>
|
||||
<button class="sub-nav-btn" data-tab="discipline" onclick="switchSubTab('discipline')">专业分区</button>
|
||||
</div>
|
||||
|
||||
<!-- 知识 / 我的 标题 -->
|
||||
<div class="section-title-bar" id="sectionTitleBar" style="display:none;">
|
||||
<h1 class="section-title" id="contentTitle">知识 · 数学发现</h1>
|
||||
</div>
|
||||
|
||||
<!-- 剧本广场(数学人生入口) -->
|
||||
<div class="script-square" id="scriptSquare" style="display:none;">
|
||||
<!-- 快捷继续 -->
|
||||
<div class="ss-continue" id="ssContinue" style="display:none;">
|
||||
<div class="ss-continue-card" id="ssContinueCard" onclick="">
|
||||
<div class="ss-continue-badge">▶ 继续冒险</div>
|
||||
<div class="ss-continue-info">
|
||||
<div class="ss-continue-title" id="ssContinueTitle"></div>
|
||||
<div class="ss-continue-sub" id="ssContinueSub"></div>
|
||||
</div>
|
||||
<div class="ss-continue-arrow">→</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 精选剧本大卡 -->
|
||||
<div class="ss-section-title">精选剧本</div>
|
||||
<div class="ss-hero-cards" id="ssHeroCards">
|
||||
<!-- JS 动态渲染 -->
|
||||
</div>
|
||||
|
||||
<!-- 即将上线小卡 -->
|
||||
<div class="ss-section-title">即将上线</div>
|
||||
<div class="ss-coming-cards" id="ssComingCards">
|
||||
<!-- JS 动态渲染 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 剧本内子导航(退出剧本用) -->
|
||||
<div class="life-sub-nav" id="lifeSubNav" style="display:none;">
|
||||
<button class="life-sub-btn" onclick="backToSquare()">← 剧本广场</button>
|
||||
<button class="life-sub-btn active" data-life="story" onclick="switchLifeTab('story')">📖 葫芦侠行</button>
|
||||
<button class="life-sub-btn" data-life="simulator" onclick="switchLifeTab('simulator')">🎓 专业模拟器</button>
|
||||
</div>
|
||||
|
||||
<!-- 模块简介 -->
|
||||
<div class="module-banner" id="moduleBanner">
|
||||
<span class="banner-icon">◎</span>
|
||||
<div class="banner-text">
|
||||
<div class="banner-title">发现值得一看的数学内容</div>
|
||||
<div class="banner-sub">从大学专业到现实问题,快速进入你感兴趣的主题</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 学科分类筛选 (仅在点击具体分区后显示) -->
|
||||
<div class="category-filter" id="categoryFilter" style="display: none;">
|
||||
<button class="cat-btn active" data-cat="all" onclick="filterCategory('all')">全部</button>
|
||||
</div>
|
||||
|
||||
<!-- 专业分区网格 (类似B站分区页) -->
|
||||
<div class="discipline-grid-container" id="disciplineGridContainer" style="display: none;">
|
||||
<div class="grid-section-title">全部分区</div>
|
||||
<div class="discipline-grid" id="disciplineGrid">
|
||||
<!-- JS 动态渲染图标 -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选中分区后的顶部导航 -->
|
||||
<div class="discipline-active-header" id="disciplineActiveHeader" style="display: none;">
|
||||
<button class="back-to-grid" onclick="backToDisciplineGrid()">
|
||||
<span class="back-icon">←</span>
|
||||
<span id="activeDisciplineName">专业名</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- 加载状态 -->
|
||||
<div class="loading" id="loadingArea">
|
||||
<div class="spinner"></div>
|
||||
<p>加载中...</p>
|
||||
</div>
|
||||
|
||||
<!-- 视频列表(数人/数思用) -->
|
||||
<div class="video-list" id="videoList"></div>
|
||||
|
||||
<!-- ====== 数说专属:发现Feed ====== -->
|
||||
<!-- Hero大卡 -->
|
||||
<div class="shushuo-hero" id="shushuoHero" style="display:none;">
|
||||
<div class="hero-card">
|
||||
<div class="hero-badge">✦ 今日数学发现</div>
|
||||
<div class="hero-title" id="heroTitle">数学不是公式,是你理解世界的方式</div>
|
||||
<div class="hero-desc" id="heroDesc">每天一个数学概念,让思维变得更清晰</div>
|
||||
<div class="hero-stats">
|
||||
<span>📖 3个概念</span><span>⏱ 阅读约15分钟</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 横向滚动话题 -->
|
||||
<div class="shushuo-topics" id="shushuoTopics" style="display:none;">
|
||||
<div class="topics-scroll" id="topicsScroll">
|
||||
<!-- JS 动态渲染 -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- 信息流卡片 -->
|
||||
<div class="shushuo-feed" id="shushuoFeed" style="display:none;">
|
||||
<!-- JS 动态渲染 -->
|
||||
</div>
|
||||
|
||||
<!-- 数学人生故事容器 -->
|
||||
<div id="storyContainer" style="display:none;"></div>
|
||||
|
||||
<!-- 模拟器容器 -->
|
||||
<div id="simulatorContainer" style="display:none;"></div>
|
||||
|
||||
<!-- 我的页面 -->
|
||||
<div class="profile-page" id="profilePage" style="display:none;">
|
||||
<div class="profile-card" onclick="openAvatarPicker()">
|
||||
<div class="profile-main">
|
||||
<div class="profile-avatar" id="profileAvatar">葫</div>
|
||||
<div class="profile-meta">
|
||||
<div class="profile-name" id="profileName">游客用户</div>
|
||||
<div class="profile-id" id="profileId">ID: ---</div>
|
||||
<div class="profile-tags">
|
||||
<span>数学爱好者</span>
|
||||
<span>开放体验版</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="profile-edit">编辑资料</div>
|
||||
</div>
|
||||
|
||||
<div class="profile-stats">
|
||||
<div class="profile-stat" onclick="showHistory()">
|
||||
<div class="profile-stat-num">0</div>
|
||||
<div class="profile-stat-label">已看内容</div>
|
||||
</div>
|
||||
<div class="profile-stat" onclick="showFavorites()">
|
||||
<div class="profile-stat-num">0</div>
|
||||
<div class="profile-stat-label">收藏专题</div>
|
||||
</div>
|
||||
<div class="profile-stat">
|
||||
<div class="profile-stat-num">2</div>
|
||||
<div class="profile-stat-label">剧情存档</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="profile-section">
|
||||
<div class="profile-section-title">个人信息</div>
|
||||
<div class="profile-menu-card">
|
||||
<div class="profile-menu-item" onclick="editNickname()">
|
||||
<div class="profile-menu-left"><span class="menu-icon">◉</span><span>昵称与头像</span></div>
|
||||
<span class="menu-arrow">›</span>
|
||||
</div>
|
||||
<div class="profile-menu-item">
|
||||
<div class="profile-menu-left"><span class="menu-icon">◎</span><span>兴趣方向</span></div>
|
||||
<span class="menu-arrow">›</span>
|
||||
</div>
|
||||
<div class="profile-menu-item">
|
||||
<div class="profile-menu-left"><span class="menu-icon">◌</span><span>学习偏好</span></div>
|
||||
<span class="menu-arrow">›</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="profile-section">
|
||||
<div class="profile-section-title">我的内容</div>
|
||||
<div class="profile-menu-card">
|
||||
<div class="profile-menu-item" onclick="showFavorites()">
|
||||
<div class="profile-menu-left"><span class="menu-icon">◇</span><span>我的收藏</span></div>
|
||||
<span class="menu-arrow">›</span>
|
||||
</div>
|
||||
<div class="profile-menu-item" onclick="showHistory()">
|
||||
<div class="profile-menu-left"><span class="menu-icon">▣</span><span>观看记录</span></div>
|
||||
<span class="menu-arrow">›</span>
|
||||
</div>
|
||||
<div class="profile-menu-item">
|
||||
<div class="profile-menu-left"><span class="menu-icon">◆</span><span>数学人生存档</span></div>
|
||||
<span class="menu-arrow">›</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="profile-section">
|
||||
<div class="profile-section-title">更多</div>
|
||||
<div class="profile-menu-card">
|
||||
<div class="profile-menu-item">
|
||||
<div class="profile-menu-left"><span class="menu-icon">✦</span><span>设置与帮助</span></div>
|
||||
<span class="menu-arrow">›</span>
|
||||
</div>
|
||||
<div class="profile-menu-item">
|
||||
<div class="profile-menu-left"><span class="menu-icon">⊕</span><span>意见反馈</span></div>
|
||||
<span class="menu-arrow">›</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</main>
|
||||
|
||||
<!-- ====== 底部导航栏 TabBar ====== -->
|
||||
<nav class="bottom-tab-bar">
|
||||
<button class="tab-btn active" data-module="发现" onclick="switchModule('发现')">
|
||||
<span class="tab-icon tab-icon-discover"></span>
|
||||
<span class="tab-label">发现</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-module="知识" onclick="switchModule('知识')">
|
||||
<span class="tab-icon tab-icon-knowledge"></span>
|
||||
<span class="tab-label">知识</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-module="数学人生" onclick="switchModule('数学人生')">
|
||||
<span class="tab-icon tab-icon-life"></span>
|
||||
<span class="tab-label">数学人生</span>
|
||||
</button>
|
||||
<button class="tab-btn" data-module="我的" onclick="switchModule('我的')">
|
||||
<span class="tab-icon tab-icon-mine"></span>
|
||||
<span class="tab-label">我的</span>
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<!-- ====== AI 聊天弹出层 ====== -->
|
||||
<div class="chat-overlay" id="chatOverlay">
|
||||
<div class="chat-panel">
|
||||
<div class="chat-header">
|
||||
<div class="chat-header-left">
|
||||
<div class="ai-avatar">?</div>
|
||||
<span>AI 数学助教</span>
|
||||
</div>
|
||||
<button class="chat-close" onclick="closeChat()">✕</button>
|
||||
</div>
|
||||
<div class="chat-messages" id="chatMessages">
|
||||
<div class="chat-msg assistant">
|
||||
<div class="msg-bubble">
|
||||
你好!我是数学桥梁计划的 AI 助教<br><br>
|
||||
<b>试试问我:</b><br>
|
||||
· 学数学对学医有什么用?<br>
|
||||
· 数学在建筑里怎么用?<br>
|
||||
· 为什么学数学很重要?
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="quick-asks">
|
||||
<button class="quick-ask" onclick="quickAsk('学数学对学医有什么用?')">数学与医学</button>
|
||||
<button class="quick-ask" onclick="quickAsk('数学在建筑里怎么用?')">数学与建筑</button>
|
||||
<button class="quick-ask" onclick="quickAsk('AI和数学有什么关系?')">数学与AI</button>
|
||||
<button class="quick-ask" onclick="quickAsk('为什么学数学很重要?')">为什么要学</button>
|
||||
</div>
|
||||
<div class="chat-input-area">
|
||||
<input type="text" id="chatInput" placeholder="输入你的问题..." onkeydown="if(event.key==='Enter')sendMessage()">
|
||||
<button class="send-btn" onclick="sendMessage()">➤</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====== 视频弹窗 ====== -->
|
||||
<div class="video-modal" id="videoModal">
|
||||
<div class="video-modal-content">
|
||||
<div class="video-modal-header">
|
||||
<h3 id="videoModalTitle">视频标题</h3>
|
||||
<button onclick="closeVideo()">✕</button>
|
||||
</div>
|
||||
<div class="video-player-area">
|
||||
<div class="video-placeholder">
|
||||
<div class="play-icon">▶</div>
|
||||
<p id="videoPlaceholderText">点击下方按钮在浏览器中查看完整课程</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="video-info">
|
||||
<p class="video-desc" id="videoModalDesc"></p>
|
||||
<div class="video-meta">
|
||||
<span id="videoModalAuthor">--</span>
|
||||
<span id="videoModalCat">--</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="video-actions">
|
||||
<button class="btn-secondary" onclick="toggleVideoFav()" id="videoModalFav">☆ 收藏</button>
|
||||
<button class="btn-secondary" onclick="closeVideo();openChat();quickAsk(document.getElementById('videoModalTitle').textContent+' 这个视频讲了什么?')">? 问AI</button>
|
||||
<button class="btn-primary" id="videoLinkBtn" onclick="openVideoLink()">查看原视频</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====== 个人中心列表面板 ====== -->
|
||||
<div class="profile-list-panel" id="profileListPanel" style="display:none;">
|
||||
<div class="plp-header">
|
||||
<button class="plp-back" onclick="hideProfileListPanel()">← 返回</button>
|
||||
<span class="plp-title" id="profileListTitle">列表</span>
|
||||
</div>
|
||||
<div class="plp-content" id="profileListContent"></div>
|
||||
</div>
|
||||
|
||||
<!-- ====== 头像选择器 ====== -->
|
||||
<div class="avatar-picker-overlay" id="avatarPickerOverlay" onclick="closeAvatarPicker(event)">
|
||||
<div class="avatar-picker-card" onclick="event.stopPropagation()">
|
||||
<div class="picker-title">选择头像</div>
|
||||
<div class="picker-emoji-grid" id="pickerEmojiGrid"></div>
|
||||
<div class="picker-color-row" id="pickerColorRow"></div>
|
||||
<div class="picker-actions">
|
||||
<button class="picker-btn" onclick="editNickname()">✏️ 改昵称</button>
|
||||
<button class="picker-btn primary" onclick="closeAvatarPicker()">完成</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====== 模拟器结局面板 ====== -->
|
||||
<div class="ending-overlay" id="endingOverlay" onclick="closeEnding()">
|
||||
<div class="ending-card" onclick="event.stopPropagation()">
|
||||
<div class="ending-badge" id="endingBadge">🎓</div>
|
||||
<h3 class="ending-type" id="endingType">结局</h3>
|
||||
<p class="ending-title" id="endingTitle"></p>
|
||||
<div class="ending-stats" id="endingStats"></div>
|
||||
<p class="ending-scene" id="endingScene"></p>
|
||||
<button class="picker-btn primary" onclick="closeEnding();resetSimulator()">重新开始</button>
|
||||
<button class="picker-btn" onclick="closeEnding()">关闭</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====== 存档面板 ====== -->
|
||||
<div class="save-panel-overlay" id="savePanelOverlay" onclick="closeSavePanel()">
|
||||
<div class="save-panel" onclick="event.stopPropagation()">
|
||||
<div class="save-panel-header">
|
||||
<button class="sp-back" onclick="closeSavePanel()">← 返回</button>
|
||||
<span class="sp-title">存档管理</span>
|
||||
</div>
|
||||
<div class="save-slots" id="saveSlots">
|
||||
<!-- JS 动态渲染 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ====== 结局画廊 ====== -->
|
||||
<div class="gallery-overlay" id="galleryOverlay" onclick="closeGallery()">
|
||||
<div class="gallery-panel" onclick="event.stopPropagation()">
|
||||
<div class="gallery-header">
|
||||
<button class="sp-back" onclick="closeGallery()">← 返回</button>
|
||||
<span class="sp-title">结局画廊</span>
|
||||
<span class="gallery-progress" id="galleryProgress"></span>
|
||||
</div>
|
||||
<div class="gallery-grid" id="galleryGrid">
|
||||
<!-- JS 动态渲染 -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/js/app.min.js?v=10.1"></script>
|
||||
</body>
|
||||
</html>
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
{
|
||||
"rewrites": [
|
||||
{ "source": "/", "destination": "/templates/index.html" },
|
||||
{ "source": "/", "destination": "/templates/desktop.html" },
|
||||
{ "source": "/mathbti", "destination": "/templates/mathbti.html" },
|
||||
{ "source": "/web", "destination": "/templates/desktop.html" },
|
||||
{ "source": "/desktop", "destination": "/templates/desktop.html" }
|
||||
],
|
||||
"headers": [
|
||||
|
||||
Reference in New Issue
Block a user