feat: 邮箱注册验证 + 9项功能修复与优化

【认证系统】
- 新增邮箱验证码注册/登录流程 (sendEmailCode / verifyEmail / forgotPassword / resetPassword)
- register-email 现在需要验证码
- 服务端新增 email_verification_codes 表 + patch-email-verification.js
- App.tsx 登录后 emailVerified 检查提醒
- keyServerClient token 显式传递修复 401 错误

【电商模块】
- 自动推进: 策划完成后自动生成分镜图/视频
- 模特图选项 (性别/年龄/种族/体型/场景) 注入 AI 提示词
- 任务持久化指纹修复 (图片数量替代 blob URL)
- 新增「视频换装」入口 (happyhorse-1.0-video-edit)

【剧本评分】
- 新增 .docx/.doc Word 文档支持 (ZIP解压+XML提取)
- 历史记录支持点击查看/恢复评测结果

【画布】
- ReactFlow 节点禁止内置拖拽避免冲突
- 连接线拖拽弹窗优化 (预览线不消失, 弹窗跟踪鼠标)

【页面修复】
- 首页轮播图改为 aspect-ratio: 16/9 解决尺寸问题
- 资产库新增悬停删除按钮
- scriptEvalClient 改用服务端 /api/ai/chat 端点
- TokenUsagePage 未登录跳过 API 调用
This commit is contained in:
2026-06-03 20:19:07 +08:00
parent 56dabf1f7d
commit f5a75074a4
30 changed files with 1697 additions and 1249 deletions
+2 -18
View File
@@ -6,7 +6,6 @@ import {
LineChartOutlined,
ReloadOutlined,
RightOutlined,
SettingOutlined,
TeamOutlined,
UserOutlined,
WarningOutlined,
@@ -143,29 +142,22 @@ function TokenUsagePage({
onSelectView,
}: TokenUsagePageProps) {
const [enterpriseUsage, setEnterpriseUsage] = useState<WebEnterpriseUsageSummary | null>(null);
const [enterpriseUsageLoading, setEnterpriseUsageLoading] = useState(false);
const [enterpriseUsageError, setEnterpriseUsageError] = useState<string | null>(null);
const isEnterpriseAdmin = session?.user.enterpriseRole === "admin";
const isEnterpriseAccount = Boolean(session?.user.enterpriseId || session?.user.accountType === "enterprise");
const refreshEnterpriseUsage = useCallback(async () => {
if (!session) return;
const loader = isEnterpriseAdmin ? loadEnterpriseUsage : loadPersonalUsage;
if (!loader) {
setEnterpriseUsage(null);
setEnterpriseUsageError(null);
return;
}
setEnterpriseUsageLoading(true);
setEnterpriseUsageError(null);
try {
setEnterpriseUsage(await loader());
} catch (error) {
setEnterpriseUsage(null);
setEnterpriseUsageError(error instanceof Error ? error.message : "用量数据暂时不可用");
} finally {
setEnterpriseUsageLoading(false);
}
}, [isEnterpriseAdmin, loadEnterpriseUsage, loadPersonalUsage]);
}, [session, isEnterpriseAdmin, loadEnterpriseUsage, loadPersonalUsage]);
useEffect(() => {
void refreshEnterpriseUsage();
@@ -241,9 +233,6 @@ function TokenUsagePage({
</button>
<strong></strong>
</div>
<span className="management-center-status-pill">
{enterpriseUsageLoading ? "正在同步企业用量" : enterpriseUsageError || "服务器已连接"}
</span>
<button type="button" onClick={refreshEnterpriseUsage}>
<ReloadOutlined />
@@ -252,17 +241,12 @@ function TokenUsagePage({
<UserOutlined />
</button>
<button type="button" className="is-primary" onClick={() => onSelectView?.("settings")}>
<SettingOutlined />
</button>
</header>
{isLowBalance ? (
<div className="management-balance-alert" role="alert">
<WarningOutlined />
<span> {formatCredits(availableBalanceCents)}</span>
<button type="button" onClick={() => onSelectView?.("settings")}></button>
</div>
) : null}