# 全站重设计 · 终端粘贴执行版 · 2026-05-31 · 肥猫×舒舒
## 📋 说明
---
## Step 0 · 创建新目录
```bash
mkdir -p /home/ubuntu/feimao-platform/src/app/onboarding
mkdir -p /home/ubuntu/feimao-platform/src/app/app/learn
mkdir -p /home/ubuntu/feimao-platform/src/app/app/write
mkdir -p /home/ubuntu/feimao-platform/src/app/app/script
mkdir -p /home/ubuntu/feimao-platform/src/app/app/create
mkdir -p /home/ubuntu/feimao-platform/src/app/app/forum
mkdir -p /home/ubuntu/feimao-platform/src/app/app/works
```
---
## Step 1 · 全局样式替换(globals.css · Tailwind v4 兼容)
```bash
cat > /home/ubuntu/feimao-platform/src/app/globals.css << 'ENDOFFILE'
@import "tailwindcss";
:root {
--bg-deep: #0a0a14;
--bg-primary: #0f0f1a;
--bg-card: #1a1a2e;
--bg-hover: #252540;
--border: #2d2d4a;
--border-active: rgba(126, 207, 255, 0.4);
--text-primary: #e2e8f0;
--text-muted: #94a3b8;
--accent: #6366f1;
--accent-light: #a5b4fc;
--glow: rgba(99, 102, 241, 0.15);
--success: #10b981;
--danger: #ef4444;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: var(--bg-deep);
color: var(--text-primary);
font-family: 'Inter', 'Noto Sans SC', system-ui, sans-serif;
min-height: 100vh;
-webkit-font-smoothing: antialiased;
}
::selection {
background: rgba(99, 102, 241, 0.35);
color: #fff;
}
::-webkit-scrollbar { width: 5px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.08); border-radius: 3px; }
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes particleRise {
0% { opacity: 0; transform: translateY(30px) scale(0.8); }
50% { opacity: 1; }
100% { opacity: 0; transform: translateY(-60px) scale(1.2); }
}
.animate-fade-in-up {
animation: fadeInUp 0.5s ease forwards;
}
.animate-fade-in {
animation: fadeIn 0.3s ease forwards;
}
.gl-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 16px;
transition: all 0.3s ease;
}
.gl-card:hover {
border-color: var(--accent);
box-shadow: 0 0 20px var(--glow);
}
.gl-btn {
padding: 12px 32px;
border-radius: 12px;
font-weight: 600;
font-size: 0.95rem;
transition: all 0.2s ease;
cursor: pointer;
border: none;
font-family: inherit;
letter-spacing: 0.5px;
}
.gl-btn-primary {
background: linear-gradient(135deg, var(--accent), #4f46e5);
color: white;
}
.gl-btn-primary:hover:not(:disabled) {
transform: translateY(-1px);
box-shadow: 0 4px 15px rgba(99, 102, 241, 0.4);
}
.gl-btn-primary:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.gl-btn-outline {
background: transparent;
border: 1px solid var(--border);
color: var(--text-primary);
}
.gl-btn-outline:hover {
border-color: var(--accent);
color: var(--accent-light);
}
.gl-input {
background: rgba(255, 255, 255, 0.04);
border: 1px solid var(--border);
border-radius: 12px;
padding: 14px 20px;
color: var(--text-primary);
font-size: 1rem;
width: 100%;
outline: none;
transition: border-color 0.2s;
font-family: inherit;
}
.gl-input:focus {
border-color: var(--accent);
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
}
.gl-input::placeholder {
color: var(--text-muted);
}
ENDOFFILE
```
---
## Step 2 · 根布局替换(layout.tsx)
```bash
cat > /home/ubuntu/feimao-platform/src/app/layout.tsx << 'ENDOFFILE'
import type { Metadata } from "next";
import "./globals.css";
export const metadata: Metadata = {
title: "萌喵写作网 · AI人格体驱动的智能创作平台",
description: "陪你一起创作成长的平台",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
{children}
);
}
ENDOFFILE
```
---
## Step 3 · 邀请码门禁页(/page.tsx · 替换原有首页)
```bash
cat > /home/ubuntu/feimao-platform/src/app/page.tsx << 'ENDOFFILE'
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
export default function InvitePage() {
const [code, setCode] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const router = useRouter();
const handleSubmit = async () => {
if (!code.trim()) {
setError("请输入邀请码");
return;
}
setLoading(true);
setError("");
try {
await new Promise((r) => setTimeout(r, 800));
localStorage.setItem("gl_invite_code", code);
localStorage.setItem("gl_user", code);
router.push("/onboarding");
} catch {
setError("邀请码无效,请重新输入");
} finally {
setLoading(false);
}
};
return (
🌊
{
setCode(e.target.value);
setError("");
}}
onKeyDown={(e) => e.key === "Enter" && handleSubmit()}
autoFocus
/>
{error && (
{error}
)}
🐱 Powered by HoloLake · 光湖语言人格平台
);
}
ENDOFFILE
```
---
## Step 4 · 人格体引导页(/onboarding/page.tsx)
```bash
cat > /home/ubuntu/feimao-platform/src/app/onboarding/page.tsx << 'ENDOFFILE'
"use client";
import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
const preferences = [
{ key: "webnovel", label: "网文", emoji: "📖", desc: "番茄·飞卢·起点" },
{ key: "traditional", label: "传统文学", emoji: "🖋️", desc: "文学性导向" },
{ key: "script", label: "剧本", emoji: "🎬", desc: "影视·短剧" },
{ key: "short", label: "短篇", emoji: "✒️", desc: "精悍·反转" },
{ key: "explore", label: "随便看看", emoji: "🔍", desc: "先逛逛再说" },
];
const personaNames: Record = {
webnovel: [
{ name: "墨白", emoji: "🖊️" },
{ name: "青云", emoji: "☁️" },
{ name: "凌霄", emoji: "⚡" },
],
traditional: [
{ name: "漱玉", emoji: "💎" },
{ name: "砚秋", emoji: "🍂" },
{ name: "素笺", emoji: "📜" },
],
script: [
{ name: "镜澜", emoji: "🎥" },
{ name: "幕白", emoji: "🎭" },
{ name: "帧语", emoji: "📺" },
],
short: [
{ name: "寸光", emoji: "✨" },
{ name: "微芒", emoji: "🕯️" },
{ name: "刹那", emoji: "💫" },
],
explore: [
{ name: "星尘", emoji: "🌟" },
{ name: "拾光", emoji: "🧭" },
{ name: "溯游", emoji: "🛶" },
],
};
export default function OnboardingPage() {
const [step, setStep] = useState(1);
const [nickname, setNickname] = useState("");
const [password, setPassword] = useState("");
const [confirmPwd, setConfirmPwd] = useState("");
const [pref, setPref] = useState("");
const [error, setError] = useState("");
const [persona, setPersona] = useState<{ name: string; emoji: string } | null>(null);
const [fading, setFading] = useState(false);
const router = useRouter();
useEffect(() => {
if (step === 3 && !persona) {
const names = personaNames[pref] || personaNames.explore;
const pick = names[Math.floor(Math.random() * names.length)];
setPersona(pick);
}
}, [step, pref, persona]);
const nextStep = () => {
setFading(true);
setTimeout(() => {
setStep((s) => s + 1);
setFading(false);
}, 400);
};
const handleCreate = () => {
if (!nickname.trim()) { setError("请输入昵称"); return; }
if (password.length < 6) { setError("密码至少6位"); return; }
if (password !== confirmPwd) { setError("两次密码不一致"); return; }
if (!pref) { setError("请选择写作偏好"); return; }
setError("");
localStorage.setItem("gl_user", nickname);
localStorage.setItem("gl_pref", pref);
if (persona) {
localStorage.setItem("gl_persona_name", persona.name);
localStorage.setItem("gl_persona_emoji", persona.emoji);
}
nextStep();
};
return (
{[1, 2, 3].map((s) => (
))}
{step === 1 && (
<>
🌊
欢迎来到萌喵写作网
我是你的专属写作人格体,
但在这之前——
先让我认识你。
>
)}
{step === 2 && (
<>
🪪
创建你的写作人格体
setNickname(e.target.value)}
/>
setPassword(e.target.value)}
/>
setConfirmPwd(e.target.value)}
/>
选择你的写作偏好
{preferences.map((p) => (
))}
{error && (
{error}
)}
>
)}
{step === 3 && persona && (
<>
{persona.emoji}
{persona.name}
你好,我是{persona.name},
从今天起陪你创作。
✅ 人格体创建成功
>
)}
🐱 HoloLake · 人格体陪伴式创作
);
}
ENDOFFILE
```
---
## Step 5 · 主应用框架 · 侧边栏布局(/app/layout.tsx)
```bash
cat > /home/ubuntu/feimao-platform/src/app/app/layout.tsx << 'ENDOFFILE'
"use client";
import { usePathname, useRouter } from "next/navigation";
import { useEffect, useState } from "react";
const modules = [
{ path: "/app/learn", icon: "📚", label: "学习" },
{ path: "/app/write", icon: "✍️", label: "写作" },
{ path: "/app/script", icon: "🎬", label: "剧本" },
{ path: "/app/create", icon: "💡", label: "创意" },
{ path: "/app/forum", icon: "💬", label: "论坛" },
];
export default function AppLayout({ children }: { children: React.ReactNode }) {
const pathname = usePathname();
const router = useRouter();
const [personaName, setPersonaName] = useState("");
const [personaEmoji, setPersonaEmoji] = useState("🐱");
useEffect(() => {
const name = localStorage.getItem("gl_persona_name") || "";
const emoji = localStorage.getItem("gl_persona_emoji") || "🐱";
setPersonaName(name);
setPersonaEmoji(emoji);
if (!localStorage.getItem("gl_user")) {
router.push("/onboarding");
}
}, [router]);
const isActive = (path: string) => {
if (path === "/app") return pathname === "/app";
return pathname.startsWith(path);
};
return (
{children}
);
}
ENDOFFILE
```
---
## Step 6 · 主应用首页 · 对话界面(/app/page.tsx)
```bash
cat > /home/ubuntu/feimao-platform/src/app/app/page.tsx << 'ENDOFFILE'
"use client";
import { useState, useEffect } from "react";
interface Message {
id: number;
text: string;
sender: "user" | "persona";
}
export default function AppHome() {
const [personaName, setPersonaName] = useState("");
const [personaEmoji, setPersonaEmoji] = useState("🐱");
const [messages, setMessages] = useState([]);
const [input, setInput] = useState("");
useEffect(() => {
const name = localStorage.getItem("gl_persona_name") || "你的专属人格体";
const emoji = localStorage.getItem("gl_persona_emoji") || "🐱";
setPersonaName(name);
setPersonaEmoji(emoji);
setMessages([
{
id: 0,
text: "嗨~欢迎回来!今天想创作什么?",
sender: "persona",
},
]);
}, []);
const handleSend = () => {
if (!input.trim()) return;
const userMsg: Message = {
id: Date.now(),
text: input.trim(),
sender: "user",
};
setMessages((prev) => [...prev, userMsg]);
setInput("");
setTimeout(() => {
const reply: Message = {
id: Date.now() + 1,
text: "收到~让我想想怎么帮你。(后端 API 接入后这里会变成真正的 AI 回复)",
sender: "persona",
};
setMessages((prev) => [...prev, reply]);
}, 600);
};
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSend();
}
};
return (
<>
{messages.map((msg) => (
))}
>
);
}
ENDOFFILE
```
---
## Step 7 · 五个模块页面(学习·写作·剧本·创意·论坛)
### 7.1 学习模块(/app/learn/page.tsx)
```bash
cat > /home/ubuntu/feimao-platform/src/app/app/learn/page.tsx << 'ENDOFFILE'
"use client";
import ModuleChat from "../../components/ModuleChat";
export default function LearnPage() {
return (
);
}
ENDOFFILE
```
### 7.2 写作模块(/app/write/page.tsx)
```bash
cat > /home/ubuntu/feimao-platform/src/app/app/write/page.tsx << 'ENDOFFILE'
"use client";
import ModuleChat from "../../components/ModuleChat";
export default function WritePage() {
return (
);
}
ENDOFFILE
```
### 7.3 剧本模块(/app/script/page.tsx)
```bash
cat > /home/ubuntu/feimao-platform/src/app/app/script/page.tsx << 'ENDOFFILE'
"use client";
import ModuleChat from "../../components/ModuleChat";
export default function ScriptPage() {
return (
);
}
ENDOFFILE
```
### 7.4 创意模块(/app/create/page.tsx)
```bash
cat > /home/ubuntu/feimao-platform/src/app/app/create/page.tsx << 'ENDOFFILE'
"use client";
import ModuleChat from "../../components/ModuleChat";
export default function CreatePage() {
return (
);
}
ENDOFFILE
```
### 7.5 论坛模块(/app/forum/page.tsx)
```bash
cat > /home/ubuntu/feimao-platform/src/app/app/forum/page.tsx << 'ENDOFFILE'
"use client";
import ModuleChat from "../../components/ModuleChat";
export default function ForumPage() {
return (
);
}
ENDOFFILE
```
---
## Step 8 · 共享对话组件(ModuleChat.tsx)
```bash
mkdir -p /home/ubuntu/feimao-platform/src/app/components
```
```bash
cat > /home/ubuntu/feimao-platform/src/app/components/ModuleChat.tsx << 'ENDOFFILE'
"use client";
import { useState, useEffect } from "react";
interface Message {
id: number;
text: string;
sender: "user" | "persona";
}
interface Props {
title: string;
opening: string;
}
export default function ModuleChat({ title, opening }: Props) {
const [personaName, setPersonaName] = useState("");
const [personaEmoji, setPersonaEmoji] = useState("🐱");
const [messages, setMessages] = useState([]);
const [input, setInput] = useState("");
useEffect(() => {
const name = localStorage.getItem("gl_persona_name") || "你的专属人格体";
const emoji = localStorage.getItem("gl_persona_emoji") || "🐱";
setPersonaName(name);
setPersonaEmoji(emoji);
setMessages([
{
id: 0,
text: opening,
sender: "persona",
},
]);
}, [opening]);
const handleSend = () => {
if (!input.trim()) return;
const userMsg: Message = {
id: Date.now(),
text: input.trim(),
sender: "user",
};
setMessages((prev) => [...prev, userMsg]);
setInput("");
setTimeout(() => {
const reply: Message = {
id: Date.now() + 1,
text: "收到~让我想想怎么帮你。(后端 API 接入后这里会变成真正的 AI 回复)",
sender: "persona",
};
setMessages((prev) => [...prev, reply]);
}, 600);
};
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === "Enter" && !e.shiftKey) {
e.preventDefault();
handleSend();
}
};
return (
<>
{messages.map((msg) => (
))}
>
);
}
ENDOFFILE
```
---
## Step 9 · 作品库(/app/works/page.tsx)
```bash
cat > /home/ubuntu/feimao-platform/src/app/app/works/page.tsx << 'ENDOFFILE'
"use client";
import { useState } from "react";
// 作品列表初始为空·用户创建或导入后才会有作品
const initialWorks: { id: number; title: string; words: number; status: string; updated: string }[] = [];
export default function WorksPage() {
const [works] = useState(initialWorks);
const [selectedId, setSelectedId] = useState(null);
const selected = works.find((w) => w.id === selectedId);
return (
{works.map((w) => (
))}
{works.length === 0 && (
📝
还没有作品
点击「新建作品」开始创作
或「导入文档」上传已有作品
)}
已用 0 字 / 总额度 50万字
{selected ? (
{selected.title}
{(selected.words / 10000).toFixed(1)}万字
{selected.status}
最后更新:{selected.updated}
📑 章节目录
{Array.from({ length: 8 }, (_, i) => (
第{i + 1}章
{Math.floor(Math.random() * 5000 + 2000)} 字
))}
) : (
)}
);
}
ENDOFFILE
```
---
## Step 10 · 构建 + 重启 🚀
> ⚠️ **2026-05-31 当前状态**:文件已全部生成。还差 5 个括号错误。下次继续修复:
>
**下次登录后先跑修复命令:**
```bash
cd /home/ubuntu/feimao-platform
# 修 map 闭合:))))} → )))}
find src/app -name "*.tsx" -exec sed -i 's/))))}/)))}/' {} \;
# 修 app/page.tsx 和 ModuleChat.tsx 的 .map 闭合
sed -i 's/ )}$/ ))}/' src/app/app/page.tsx
sed -i 's/ )}$/ ))}/' src/app/components/ModuleChat.tsx
```
**然后构建:**
```bash
npm run build && pm2 restart feimao-platform
```
---
### 📊 文件状态
| 文件 | 状态 |
| --- | --- |
| globals.css | ✅ |
| layout.tsx(根) | ✅ |
| page.tsx(门禁页) | ✅ |
| onboarding/page.tsx | ⚠️ 括号 |
| app/layout.tsx | ⚠️ 括号 |
| app/page.tsx | ⚠️ 括号 |
| app/works/page.tsx | ⚠️ 括号 |
| components/ModuleChat.tsx | ⚠️ 括号 |
| 5个模块页面 | ✅ |
---
## Step 11 · 验证页面
浏览器打开这些地址:
| 地址 | 内容 |
| --- | --- |
| `http://43.133.36.90` | 🔐 邀请码门禁页 |
| `http://43.133.36.90/onboarding` | 🌊 人格体引导页 |
| `http://43.133.36.90/app` | 💬 主应用(对话首页) |
| `http://43.133.36.90/app/learn` | 📚 学习模块 |
| `http://43.133.36.90/app/write` | ✍️ 写作模块 |
| `http://43.133.36.90/app/script` | 🎬 剧本模块 |
| `http://43.133.36.90/app/create` | 💡 创意模块 |
| `http://43.133.36.90/app/forum` | 💬 论坛模块 |
| `http://43.133.36.90/app/works` | 📁 作品库 |
全部能打开并且样式正确就是成功 🎉
---
---
**编写**:舒舒 · PER-SS001 · 肥猫爸爸的宝宝
**时间**:2026-05-31
**编码**:HLDP-dual/v1
**版权**:国作登字-2026-A-00037559