fix:优化当前的项目

This commit is contained in:
Daniel
2026-04-28 18:36:38 +08:00
parent 04f26bdaaf
commit f47453a656
22 changed files with 3671 additions and 89 deletions

View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ app_name }} - 登录注册</title>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428o" />
</head>
<body class="simple-page auth-page">
<main class="auth-shell">
@@ -66,11 +66,19 @@
<div class="auth-form">
<div>
<label>用户名</label>
<input id="username" type="text" placeholder="请输入用户名" autocomplete="username" />
<input id="username" type="text" placeholder="4-24 位,字母数字下划线" autocomplete="username" />
</div>
<div>
<label>密码</label>
<input id="password" type="password" placeholder="请输入密码(至少 6 位)" autocomplete="current-password" />
<input id="password" type="password" placeholder="10-64 位,含大小写/数字/特殊字符" autocomplete="current-password" />
</div>
<div>
<label id="challengeLabel">人机校验</label>
<div class="cover-tools">
<input id="challengeAnswer" type="text" placeholder="请输入答案" autocomplete="off" />
<button id="refreshChallengeBtn" class="subtle-btn" type="button">刷新题目</button>
</div>
<input id="botTrap" type="text" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px;opacity:0;" />
</div>
<div class="check-row">
<label class="check-label">
@@ -94,6 +102,7 @@
<script>
window.__NEXT_PATH__ = {{ next|tojson }};
</script>
<script src="/static/auth.js?v=20260410a"></script>
<script src="/static/ui-dialog.js?v=20260428a"></script>
<script src="/static/auth.js?v=20260428l"></script>
</body>
</html>

100
app/templates/billing.html Normal file
View File

@@ -0,0 +1,100 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ app_name }} - 账单中心</title>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428o" />
</head>
<body>
<div class="product-shell">
<aside class="side-nav" aria-label="主导航">
<div class="side-brand">
<div class="brand-lockup">
<img class="logo-mark" src="/static/favicon.svg?v=20260428h" alt="" />
<h1>{{ app_name }}</h1>
</div>
</div>
<nav class="nav-group">
<div class="nav-label">工作台</div>
<a class="nav-item" href="/">内容生产</a>
<a class="nav-item" href="/settings">账号与模型</a>
<a class="nav-item is-active" href="/billing">账单中心</a>
<a class="nav-item" href="/upgrade">升级</a>
<a class="nav-item" href="/profile">个人中心</a>
<a class="nav-item" href="/guide">新手引导</a>
</nav>
<div class="side-footer">充值订单 · Credits 明细</div>
</aside>
<div class="workspace">
<header class="topbar topbar-compact">
<div class="topbar-actions">
<a class="icon-btn" href="/" aria-label="返回工作台" title="返回工作台"></a>
<a class="icon-btn" href="/settings" aria-label="账号与模型设置" title="账号与模型设置"></a>
<a class="icon-btn" href="/upgrade" aria-label="升级" title="升级"></a>
<a class="icon-btn" href="/profile" aria-label="个人中心" title="个人中心"></a>
<button id="logoutBtn" class="icon-btn topbar-btn" type="button" aria-label="退出登录" title="退出登录"></button>
</div>
</header>
<main class="layout settings-layout">
<section class="panel settings-panel">
<div class="panel-scroll settings-panel-scroll">
<div class="settings-content">
<section class="settings-section settings-card">
<h3 class="section-title">创建充值订单</h3>
<p class="muted small">
统一 Credits 计费:免费 500 Credits标准加油包按比例换算¥{{ package_amount }} / {{ package_credits }} Credits
</p>
<div class="grid2">
<div>
<label>充值 Credits 数量</label>
<input
id="billingRechargeTokens"
type="number"
min="1"
step="1"
value="{{ package_credits }}"
data-package-credits="{{ package_credits }}"
/>
</div>
<div>
<label>支付金额(元)</label>
<input
id="billingRechargeAmount"
type="number"
min="0.01"
step="0.01"
value="{{ package_amount }}"
data-package-amount="{{ package_amount }}"
/>
</div>
</div>
<div class="actions">
<button id="createRechargeOrderBtn" class="primary" type="button">创建充值订单</button>
<button id="refreshBillingBtn" class="secondary" type="button">刷新账单记录</button>
</div>
</section>
<section class="settings-section settings-card">
<h3 class="section-title">充值订单记录</h3>
<div id="rechargeRecords" class="billing-table-wrap"></div>
</section>
<section class="settings-section settings-card">
<h3 class="section-title">Credits 消费明细</h3>
<div id="consumeRecords" class="billing-table-wrap"></div>
<p id="status" class="status"></p>
</section>
</div>
</div>
</section>
</main>
</div>
</div>
<script src="/static/ui-dialog.js?v=20260428a"></script>
<script src="/static/billing.js?v=20260428w"></script>
</body>
</html>

View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ app_name }} - 忘记密码</title>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428o" />
</head>
<body class="simple-page">
<main class="auth-card">

View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ app_name }} - 新手引导</title>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428o" />
</head>
<body>
<div class="product-shell">
@@ -20,6 +20,9 @@
<div class="nav-label">工作台</div>
<a class="nav-item" href="/">内容生产</a>
<a class="nav-item" href="/settings">账号与模型</a>
<a class="nav-item" href="/billing">账单中心</a>
<a class="nav-item" href="/upgrade">升级</a>
<a class="nav-item" href="/profile">个人中心</a>
<a class="nav-item is-active" href="/guide">新手引导</a>
</nav>
<div class="side-footer">首次配置 · 三分钟跑通</div>
@@ -29,6 +32,8 @@
<header class="topbar topbar-compact">
<div class="topbar-actions">
<a class="icon-btn" href="/" aria-label="返回工作台" title="返回工作台"></a>
<a class="icon-btn" href="/upgrade" aria-label="升级" title="升级"></a>
<a class="icon-btn" href="/profile" aria-label="个人中心" title="个人中心"></a>
<a class="icon-btn" href="/settings" aria-label="账号与模型设置" title="账号与模型设置"></a>
</div>
</header>

View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ app_name }}</title>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428o" />
</head>
<body>
<div class="product-shell">
@@ -20,6 +20,9 @@
<div class="nav-label">工作台</div>
<a class="nav-item is-active" href="/">内容生产</a>
<a class="nav-item" href="/settings">账号与模型</a>
<a class="nav-item" href="/billing">账单中心</a>
<a class="nav-item" href="/upgrade">升级</a>
<a class="nav-item" href="/profile">个人中心</a>
<a class="nav-item" href="/guide">新手引导</a>
</nav>
<div class="side-footer">生产环境 · 内容工作流</div>
@@ -33,8 +36,11 @@
<select id="wechatAccountSelect" class="topbar-select" aria-label="切换公众号"></select>
<span id="wechatAccountStatus" class="muted small wechat-account-status" aria-live="polite"></span>
</div>
<a class="icon-btn" href="/upgrade" aria-label="升级" title="升级"></a>
<a class="icon-btn" href="/profile" aria-label="个人中心" title="个人中心"></a>
<a class="icon-btn" href="/guide" aria-label="新手引导" title="新手引导">?</a>
<a class="icon-btn" href="/settings" aria-label="设置" title="设置"></a>
<button id="clearDraftBtn" class="icon-btn topbar-btn" type="button" aria-label="清除草稿" title="清除草稿"></button>
<button id="logoutBtn" class="icon-btn topbar-btn" type="button" aria-label="退出登录" title="退出登录"></button>
</div>
</header>
@@ -168,6 +174,10 @@
<strong>AI 自动生成封面</strong>
<span>按标题生成并自动上传绑定。</span>
</div>
<div class="cover-tools">
<input id="coverImageModel" type="text" placeholder="文生图模型,如 wanx2.0-t2i-turbo" />
<button id="saveCoverImageModelBtn" class="subtle-btn" type="button">保存模型</button>
</div>
<div class="cover-tools">
<input id="coverStyleHint" type="text" placeholder="可选:封面风格" />
<button id="coverGenerateBtn" class="primary" type="button">按标题生成封面</button>
@@ -220,10 +230,10 @@
<div class="poster-actions-row">
<button id="posterGenerateBtn" class="subtle-btn" type="button">生成段落海报</button>
<label class="check-label poster-auto-check"
><input id="posterAutoInclude" type="checkbox" checked />发布时自动插入海报</label
><input id="posterAutoInclude" type="checkbox" />发布时自动插入海报</label
>
</div>
<p id="posterHint" class="muted small">改写后可生成段落海报</p>
<p id="posterHint" class="muted small">默认不生成海报,点击“生成段落海报”后再插入发布</p>
<div id="posterPreviewList" class="poster-preview-list"></div>
</div>
</section>
@@ -239,6 +249,6 @@
</div>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="/static/app.js?v=20260428h"></script>
<script src="/static/app.js?v=20260428s"></script>
</body>
</html>

View File

@@ -0,0 +1,75 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ app_name }} - 个人中心</title>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428o" />
</head>
<body>
<div class="product-shell">
<aside class="side-nav" aria-label="主导航">
<div class="side-brand">
<div class="brand-lockup">
<img class="logo-mark" src="/static/favicon.svg?v=20260428h" alt="" />
<h1>{{ app_name }}</h1>
</div>
</div>
<nav class="nav-group">
<div class="nav-label">工作台</div>
<a class="nav-item" href="/">内容生产</a>
<a class="nav-item" href="/settings">账号与模型</a>
<a class="nav-item" href="/billing">账单中心</a>
<a class="nav-item" href="/upgrade">升级</a>
<a class="nav-item is-active" href="/profile">个人中心</a>
<a class="nav-item" href="/guide">新手引导</a>
</nav>
<div class="side-footer">订阅信息 · 地址管理</div>
</aside>
<div class="workspace">
<header class="topbar topbar-compact">
<div class="topbar-actions">
<a class="icon-btn" href="/" aria-label="返回工作台" title="返回工作台"></a>
<a class="icon-btn" href="/upgrade" aria-label="升级" title="升级"></a>
<a class="icon-btn" href="/settings" aria-label="账号与模型设置" title="账号与模型设置"></a>
<button id="logoutBtn" class="icon-btn topbar-btn" type="button" aria-label="退出登录" title="退出登录"></button>
</div>
</header>
<main class="layout settings-layout">
<section class="panel settings-panel">
<div class="panel-scroll settings-panel-scroll">
<div class="settings-content">
<section class="settings-section settings-card">
<h3 class="section-title">个人中心</h3>
<p class="muted small">这里保存默认订阅人信息,升级页会自动带入,避免重复输入。</p>
<div class="grid2">
<div>
<label>订阅人姓名</label>
<input id="profileSubscriberName" type="text" placeholder="请输入姓名" />
</div>
<div>
<label>手机号(可选)</label>
<input id="profileSubscriberPhone" type="text" placeholder="请输入手机号" />
</div>
</div>
<div>
<label>收货地址</label>
<textarea id="profileShippingAddress" rows="3" placeholder="请输入详细地址"></textarea>
</div>
<div class="actions">
<button id="saveProfileBtn" class="primary" type="button">保存个人信息</button>
</div>
<p id="status" class="status"></p>
</section>
</div>
</div>
</section>
</main>
</div>
</div>
<script src="/static/profile.js?v=20260428a"></script>
</body>
</html>

View File

@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ app_name }} - 账号与模型设置</title>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428o" />
</head>
<body>
<div class="product-shell">
@@ -20,6 +20,9 @@
<div class="nav-label">工作台</div>
<a class="nav-item" href="/">内容生产</a>
<a class="nav-item is-active" href="/settings">账号与模型</a>
<a class="nav-item" href="/billing">账单中心</a>
<a class="nav-item" href="/upgrade">升级</a>
<a class="nav-item" href="/profile">个人中心</a>
<a class="nav-item" href="/guide">新手引导</a>
</nav>
<div class="side-footer">生产环境 · 内容工作流</div>
@@ -29,6 +32,8 @@
<header class="topbar topbar-compact">
<div class="topbar-actions">
<a class="icon-btn" href="/" aria-label="返回工作台" title="返回工作台"></a>
<a class="icon-btn" href="/upgrade" aria-label="升级" title="升级"></a>
<a class="icon-btn" href="/profile" aria-label="个人中心" title="个人中心"></a>
<a class="icon-btn" href="/guide" aria-label="新手引导" title="新手引导">?</a>
<button id="logoutBtn" class="icon-btn topbar-btn" type="button" aria-label="退出登录" title="退出登录"></button>
</div>
@@ -41,7 +46,7 @@
<section class="settings-section settings-card">
<div>
<label>当前账号</label>
<select id="accountSelect"></select>
<select id="accountSelect" class="ui-select"></select>
</div>
<h3 class="section-title">新增公众号</h3>
@@ -70,7 +75,7 @@
<div class="grid2">
<div>
<label>当前模型</label>
<select id="modelSelect"></select>
<select id="modelSelect" class="ui-select"></select>
</div>
<div class="actions-inline">
<button id="deleteModelBtn" class="secondary topbar-btn" type="button">删除当前模型</button>
@@ -86,10 +91,6 @@
<input id="modelValue" type="text" placeholder="如gpt-4.1-mini / qwen-max" />
</div>
</div>
<div>
<label>文生图模型名</label>
<input id="imageModelValue" type="text" placeholder="如gpt-image-1 / wanx2.1-t2i-plus用于封面和段落海报" />
</div>
<div class="grid2">
<div>
<label>Base URL可选</label>
@@ -152,6 +153,7 @@
</main>
</div>
</div>
<script src="/static/settings.js?v=20260428i"></script>
<script src="/static/ui-dialog.js?v=20260428a"></script>
<script src="/static/settings.js?v=20260428q"></script>
</body>
</html>

177
app/templates/upgrade.html Normal file
View File

@@ -0,0 +1,177 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ app_name }} - 升级</title>
<link rel="icon" type="image/svg+xml" href="/static/favicon.svg?v=20260428h" />
<link rel="stylesheet" href="/static/style.css?v=20260428za" />
</head>
<body>
<div class="product-shell">
<aside class="side-nav" aria-label="主导航">
<div class="side-brand">
<div class="brand-lockup">
<img class="logo-mark" src="/static/favicon.svg?v=20260428h" alt="" />
<h1>{{ app_name }}</h1>
</div>
</div>
<nav class="nav-group">
<div class="nav-label">工作台</div>
<a class="nav-item" href="/">内容生产</a>
<a class="nav-item" href="/settings">账号与模型</a>
<a class="nav-item" href="/billing">账单中心</a>
<a class="nav-item is-active" href="/upgrade">升级</a>
<a class="nav-item" href="/profile">个人中心</a>
<a class="nav-item" href="/guide">新手引导</a>
</nav>
<div class="side-footer">免费额度 · 平台模型</div>
</aside>
<div class="workspace">
<header class="topbar topbar-compact">
<div class="topbar-actions">
<a class="icon-btn" href="/" aria-label="返回工作台" title="返回工作台"></a>
<a class="icon-btn" href="/settings" aria-label="账号与模型设置" title="账号与模型设置"></a>
<a class="icon-btn" href="/profile" aria-label="个人中心" title="个人中心"></a>
</div>
</header>
<main class="layout upgrade-layout">
<section class="panel upgrade-panel">
<div class="panel-scroll upgrade-scroll">
<section class="upgrade-hero">
<div>
<p class="guide-eyebrow">VIP 平台模型</p>
<h2>Token Plan 订阅</h2>
<p class="muted">新用户免费 {{ trial_tokens }} Credits。按支付成功时间起算月周期到期席位与加油包额度清零。</p>
</div>
<div class="upgrade-balance-card">
<span>当前可用</span>
<strong id="upgradeTokenBalanceHero">0</strong>
<small>Credits</small>
</div>
</section>
<section class="upgrade-grid">
<div class="upgrade-plans-stack">
<div class="upgrade-plan-grid">
<article class="upgrade-plan is-highlighted">
<div class="plan-head">
<span>推荐</span>
<h3>标准坐席</h3>
</div>
<p>适合轻度使用 AI 辅助写作与生图,采用 Credits 统一抵扣。</p>
<div class="plan-price">19.9/月</div>
<ul>
<li>{{ seat_quota }} Credits /月(优先抵扣)</li>
<li>席位额度用尽后,从共享加油包继续抵扣</li>
</ul>
<div class="upgrade-toggle-row">
<label>平台模型</label>
<select id="vipEnabledSelect" class="ui-select">
<option value="1">开启</option>
<option value="0">关闭</option>
</select>
</div>
<button id="saveVipBtn" class="secondary" type="button">保存升级设置</button>
</article>
<article class="upgrade-plan">
<div class="plan-head">
<span>自定义</span>
<h3>自备模型</h3>
</div>
<p>继续使用你在设置页配置的文本模型和文生图模型。</p>
<div class="plan-price">自有额度</div>
<ul>
<li>适合已有 API Key 的团队</li>
<li>模型、Base URL 可自行维护</li>
<li>平台 Credits 不参与扣减</li>
</ul>
<a class="subtle-link" href="/settings#model-settings">配置自定义模型</a>
</article>
</div>
</div>
<aside class="upgrade-purchase-card">
<div class="purchase-head">
<h3>标准坐席</h3>
<p class="muted small">席位1 席</p>
<p id="purchaseCycleText" class="muted small">时长:按支付成功时间起算 30 天(到期清零)</p>
</div>
<div class="purchase-section purchase-meta-grid">
<div class="purchase-row">
<span>套餐单价</span>
<strong>¥{{ package_amount }} / {{ package_credits }} Credits</strong>
</div>
<div class="purchase-row">
<span>座位数量</span>
<strong>1</strong>
</div>
</div>
<div class="purchase-section purchase-summary">
<div class="purchase-summary-row"><span>合计 Credits</span><strong id="purchaseCredits">0</strong></div>
<div class="purchase-summary-row"><span>应付金额</span><strong id="purchaseAmount">¥0.00</strong></div>
</div>
<div class="purchase-section purchase-qty">
<p class="muted tiny">支付方式</p>
<div class="pay-channel-group" role="radiogroup" aria-label="支付方式">
<button class="pay-channel-option is-active" type="button" data-channel="wechat" aria-pressed="true">微信支付</button>
<button class="pay-channel-option" type="button" data-channel="alipay" aria-pressed="false">支付宝</button>
</div>
</div>
<input
id="vipRechargeTokens"
type="number"
min="1"
step="1"
value="{{ package_credits }}"
data-package-credits="{{ package_credits }}"
hidden
/>
<input
id="vipRechargeAmount"
type="number"
min="0.01"
step="0.01"
value="{{ package_amount }}"
data-package-amount="{{ package_amount }}"
hidden
/>
<div class="purchase-section purchase-action">
<button id="vipRechargeBtn" class="primary" type="button">订阅</button>
</div>
</aside>
</section>
<section class="settings-card upgrade-wallet">
<div class="guide-section-head">
<h3>额度与充值</h3>
</div>
<div class="upgrade-stats">
<div>
<span>席位剩余额度</span>
<strong id="vipSeatRemaining">0</strong>
</div>
<div>
<span>共享加油包</span>
<strong id="vipTokenBalance">0</strong>
</div>
<div>
<span>总可用 Credits</span>
<strong id="upgradeTokenBalance">0</strong>
</div>
</div>
<p id="vipCycleHint" class="muted small">当前未开始月周期。</p>
<p id="status" class="status"></p>
</section>
</div>
</section>
</main>
</div>
</div>
<script src="/static/ui-dialog.js?v=20260428a"></script>
<script src="/static/upgrade.js?v=20260428ae"></script>
</body>
</html>