feat: AI沙箱流式对话+引导学习+静态服务优化

- 后端: AI沙箱流式对话(SSE), reasoning_content 回退支持
- 前端: 沙箱页流式渲染, 引导学习面板, 默认场景/Starter兜底
- 优化: 前端改用静态文件服务器(node server.js)替代next dev, CSS永不丢失
- 修复: 通用模型默认改为可用模型, predev不再删.next缓存
This commit is contained in:
yuzhiran-dev
2026-05-27 18:26:30 +08:00
parent 0b66d752ce
commit 417fb266d4
14 changed files with 947 additions and 203 deletions
+4 -4
View File
@@ -28,8 +28,8 @@ interface Order {
const PLANS = [
{ id: 'FREE', nameKey: 'planFree' as const, price: 0, period: '', popular: false, features: ['featureSandboxFree', 'featureModelsFree', 'featurePromptsFree', 'featureCoursesFree', 'featureAdsFree'] as const },
{ id: 'MONTHLY', nameKey: 'planMonthly' as const, price: 29.9, period: 'perMonth', popular: true, features: ['featureSandboxPro', 'featureModelsPro', 'featurePromptsPro', 'featureCoursesPro', 'featureAdsPro'] as const },
{ id: 'YEARLY', nameKey: 'planYearly' as const, price: 199, period: 'perYear', popular: false, features: ['featureSandboxUnlimited', 'featureModelsPremium', 'featurePromptsPremium', 'featureCoursesPremium', 'featureAdsPremium'] as const },
{ id: 'MONTHLY', nameKey: 'planMonthly' as const, price: 49.9, period: 'perMonth', popular: true, features: ['featureSandboxPro', 'featureModelsPro', 'featurePromptsPro', 'featureCoursesPro', 'featureAdsPro'] as const },
{ id: 'YEARLY', nameKey: 'planYearly' as const, price: 299, period: 'perYear', popular: false, features: ['featureSandboxUnlimited', 'featureModelsPremium', 'featurePromptsPremium', 'featureCoursesPremium', 'featureAdsPremium'] as const },
];
const FEATURE_LABELS = ['featureSandbox', 'featureModels', 'featurePrompts', 'featureCourses', 'featureAds'] as const;
@@ -72,7 +72,7 @@ export default function MemberPage() {
const tradeType = useJsapi ? 'JSAPI' : 'NATIVE';
const body: Record<string, any> = {
amount: planType === 'MONTHLY' ? 29.9 : 199,
amount: planType === 'MONTHLY' ? 49.9 : 299,
planType, payChannel: 'wxpay', tradeType,
};
if (useJsapi && openid) body.openid = openid;
@@ -147,7 +147,7 @@ export default function MemberPage() {
<h3 className="text-lg font-semibold text-foreground mb-1">{t.member[plan.nameKey]}</h3>
<div className="mb-4">
{plan.price > 0 ? (
<span className="text-3xl font-bold text-foreground">{plan.price === 29.9 ? t.member.priceMonthly : t.member.priceYearly}<span className="text-sm font-normal text-muted-foreground">{t.member[plan.period]}</span></span>
<span className="text-3xl font-bold text-foreground">{plan.price === 49.9 ? t.member.priceMonthly : t.member.priceYearly}<span className="text-sm font-normal text-muted-foreground">{t.member[plan.period]}</span></span>
) : (
<span className="text-2xl font-bold text-foreground">¥0</span>
)}