新增路由管理

Change-Id: I8139fd09f135c42944f60ca473ee208e69549dc2
diff --git a/Merge/front/src/components/CreatePost.jsx b/Merge/front/src/components/CreatePost.jsx
index 9817ac0..1d2f306 100644
--- a/Merge/front/src/components/CreatePost.jsx
+++ b/Merge/front/src/components/CreatePost.jsx
@@ -1,5 +1,3 @@
-// src/components/CreatePost.jsx
-
 import React, { useState, useEffect } from 'react'
 import { useNavigate, useParams } from 'react-router-dom'
 import UploadPage from './UploadPage'
@@ -8,6 +6,7 @@
   updatePost, 
   fetchPost as fetchPostDetail 
 } from '../api/posts_wzy'
+import { getUserInfo } from '../utils/auth'
 import '../style/CreatePost.css'
 
 export default function CreatePost() {
@@ -36,6 +35,10 @@
     { id: 3, name: '我染上了拼豆' },
   ]
 
+  // 获取当前登录用户id
+  const user = getUserInfo()
+  const currentUserId = user?.id
+
   // 编辑模式:拉取原帖数据填入
   useEffect(() => {
     if (!isEdit) return
@@ -68,6 +71,10 @@
       setError('标题和正文必填')
       return
     }
+    if (!currentUserId) {
+      setError('未获取到用户ID,请重新登录')
+      return
+    }
     setError(null)
     try {
       if (isEdit) {
@@ -81,7 +88,7 @@
         alert('更新成功!')
       } else {
         await createPost({
-          user_id: 1,
+          user_id: currentUserId,
           topic_id: topicId || undefined,
           title: title.trim(),
           content: content.trim(),
diff --git a/Merge/front/src/components/Header.jsx b/Merge/front/src/components/Header.jsx
index 3b21c98..96ae6ac 100644
--- a/Merge/front/src/components/Header.jsx
+++ b/Merge/front/src/components/Header.jsx
@@ -1,13 +1,21 @@
+// src/components/Header.jsx
 import React from 'react'
 import { useNavigate } from 'react-router-dom'
 import { User } from 'lucide-react'
-import '../App.css' // 或者单独的 Header.css
+import { getUserInfo } from '../utils/auth'
+import '../App.css'
 
 export default function Header() {
   const navigate = useNavigate()
+  const user = getUserInfo() || {}
+  const userId = user.id
+  // 假设后端返回的 user 对象里有个 nickname 字段,否则 fallback 到 “小红薯”
+  const displayName = user.nickname || user.username || '小红薯'
 
   const handleUserClick = () => {
-    navigate('/user/1') // 或者使用实际的用户ID
+    if (userId) {
+      navigate(`/user/${userId}`)
+    }
   }
 
   return (
@@ -16,16 +24,19 @@
         <div className="logo">小红书</div>
         <h1 className="header-title">创作服务平台</h1>
       </div>
-      <div 
+      <div
         className="header-right"
         onClick={handleUserClick}
-        style={{ cursor: 'pointer' }}
+        style={{ cursor: userId ? 'pointer' : 'default' }}
       >
         <div className="user-info">
           <User size={16} />
-          <span>小红薯1</span>
+          <span>
+            {displayName}
+            {userId ? userId : ''}
+          </span>
         </div>
       </div>
     </header>
   )
-}
\ No newline at end of file
+}
diff --git a/Merge/front/src/components/NotebookPage.jsx b/Merge/front/src/components/NotebookPage.jsx
index 25264ec..4214213 100644
--- a/Merge/front/src/components/NotebookPage.jsx
+++ b/Merge/front/src/components/NotebookPage.jsx
@@ -3,6 +3,7 @@
 import React, { useState, useEffect } from 'react'
 import { useNavigate } from 'react-router-dom'
 import { fetchPosts, deletePost } from '../api/posts_wzy'
+import { getUserInfo } from '../utils/auth'   // ← 导入 getUserInfo
 import '../style/NotebookPage.css'
 
 export default function NotebookPage() {
@@ -11,13 +12,20 @@
   const [loading, setLoading] = useState(true)
   const [error, setError]     = useState(null)
 
-  // TODO: 替换成真实用户 ID
-  const currentUserId = 2
+  // 从 auth 获取当前用户信息
+  const userInfo = getUserInfo()
+  const currentUserId = userInfo?.id
 
   useEffect(() => {
+    if (!currentUserId) {
+      setError('未获取到用户信息,无法加载帖子。')
+      setLoading(false)
+      return
+    }
+
     async function load() {
       try {
-        // GET /posts?user_id=1
+        // GET /posts?user_id=currentUserId
         const list = await fetchPosts(currentUserId)
         setPosts(list)
       } catch (e) {
@@ -27,7 +35,7 @@
       }
     }
     load()
-  }, [])
+  }, [currentUserId])
 
   async function handleDelete(id) {
     if (!window.confirm('确定要删除该帖子吗?')) return
@@ -41,7 +49,6 @@
   }
 
   function handleEdit(id) {
-    // 假设你在路由里挂载了 /posts/edit/:postId
     navigate(`/posts/edit/${id}`)
   }
 
diff --git a/Merge/front/src/components/RequireAuth.jsx b/Merge/front/src/components/RequireAuth.jsx
new file mode 100644
index 0000000..e217e4f
--- /dev/null
+++ b/Merge/front/src/components/RequireAuth.jsx
@@ -0,0 +1,13 @@
+// src/components/RequireAuth.jsx
+import React from 'react'
+import { Navigate, useLocation } from 'react-router-dom'
+import { isLoggedIn } from '../utils/auth'
+
+export function RequireAuth({ children }) {
+  const location = useLocation()
+  if (!isLoggedIn()) {
+    // 未登录跳到 /login,并保存当前尝试访问的地址
+    return <Navigate to="/login" replace state={{ from: location }} />
+  }
+  return children
+}
diff --git a/Merge/front/src/components/RequireRole.jsx b/Merge/front/src/components/RequireRole.jsx
new file mode 100644
index 0000000..75a4c28
--- /dev/null
+++ b/Merge/front/src/components/RequireRole.jsx
@@ -0,0 +1,17 @@
+// src/components/RequireRole.jsx
+import React from 'react'
+import { Navigate } from 'react-router-dom'
+import { getUserInfo, isLoggedIn } from '../utils/auth'
+
+export function RequireRole({ role, children }) {
+  if (!isLoggedIn()) {
+    // 未登录
+    return <Navigate to="/login" replace />
+  }
+  const user = getUserInfo()
+  if (user.role !== role) {
+    // 角色不匹配,回首页
+    return <Navigate to="/" replace />
+  }
+  return children
+}