合并JWL,WZY,TRM代码

Change-Id: Ifb4fcad3c06733e1e005e7d8d9403e3561010fb4
diff --git a/TRM/front/src/api/posts.js b/TRM/front/src/api/posts.js
index a42e781..012cd00 100644
--- a/TRM/front/src/api/posts.js
+++ b/TRM/front/src/api/posts.js
@@ -13,7 +13,16 @@
     body: JSON.stringify({ userid: userId })
   })
   if (!res.ok) throw new Error(`fetchPosts: ${res.status}`)
-  return res.json()
+  
+  const json = await res.json()
+  console.log('fetchPosts response:', json)         // debug: inspect shape
+  
+  // normalize: if it's already an array use it; else pull array out of known keys
+  const list = Array.isArray(json)
+    ? json
+    : json.data || json.posts || []
+  
+  return list
 }
 
 /**
@@ -59,4 +68,50 @@
   })
   if (!res.ok) throw new Error(`fetchPost: ${res.status}`)
   return res.json()
+}
+
+/**
+ * 获取超级管理员用户列表
+ * POST /sgetuserlist
+ * @param {number|string} userId 平台管理员的用户 ID
+ * @returns Promise<[ {id, name, role}, … ]>
+ */
+export async function fetchUserList(userId) {
+  const res = await fetch(`${BASE}/sgetuserlist`, {
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    body: JSON.stringify({ userid: userId })
+  })
+  if (!res.ok) throw new Error(`fetchUserList: ${res.status}`)
+  return res.json()
+}
+
+export async function giveAdmin(userId, targetId) {
+  const res = await fetch(`${BASE}/sgiveadmin`, {
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    body: JSON.stringify({ userid: userId, targetid: targetId })
+  })
+  if (!res.ok) throw new Error(`giveAdmin: ${res.status}`)
+  return res.json()
+}
+
+export async function giveSuperAdmin(userId, targetId) {
+  const res = await fetch(`${BASE}/sgivesuperadmin`, {
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    body: JSON.stringify({ userid: userId, targetid: targetId })
+  })
+  if (!res.ok) throw new Error(`giveSuperAdmin: ${res.status}`)
+  return res.json()
+}
+
+export async function giveUser(userId, targetId) {
+  const res = await fetch(`${BASE}/sgiveuser`, {
+    method: 'POST',
+    headers: { 'Content-Type': 'application/json' },
+    body: JSON.stringify({ userid: userId, targetid: targetId })
+  })
+  if (!res.ok) throw new Error(`giveUser: ${res.status}`)
+  return res.json()
 }
\ No newline at end of file
diff --git a/TRM/front/src/components/Admin.js b/TRM/front/src/components/Admin.js
index 75253b8..6d278d5 100644
--- a/TRM/front/src/components/Admin.js
+++ b/TRM/front/src/components/Admin.js
@@ -2,7 +2,7 @@
 import React, { useState, useEffect, useMemo, useCallback } from 'react';
 import { Layout, Tabs, Input, List, Card, Button, Tag, Spin, Typography, Divider } from 'antd';
 import '../style/Admin.css';
-import { fetchPosts, approvePost, rejectPost } from '../api/posts';
+import { fetchPosts, approvePost, rejectPost } from '../../../../Merge/front/src/api/posts';
 
 export default function Admin() {
   const ADMIN_USER_ID = 3;
diff --git a/TRM/front/src/components/SuperAdmin.js b/TRM/front/src/components/SuperAdmin.js
index 118ab56..169441e 100644
--- a/TRM/front/src/components/SuperAdmin.js
+++ b/TRM/front/src/components/SuperAdmin.js
@@ -1,8 +1,10 @@
 import React from 'react';
 import { NavLink, Outlet } from 'react-router-dom';
-import '../style/SuperAdmin.css';  // 可选:自定义样式
+import '../style/SuperAdmin.css';
 
 export default function SuperAdmin() {
+  const SUPERADMIN_USER_ID = 3;
+
   return (
     <div className="super-admin-container">
       <aside className="super-admin-sidebar">
diff --git a/TRM/front/src/components/UserManagement.js b/TRM/front/src/components/UserManagement.js
index 400884b..4bd05c5 100644
--- a/TRM/front/src/components/UserManagement.js
+++ b/TRM/front/src/components/UserManagement.js
@@ -1,42 +1,74 @@
 import React, { useState, useEffect } from 'react';
 import '../style/Admin.css';
+import { Select, message, Table } from 'antd';
+import { fetchUserList, giveUser, giveAdmin, giveSuperAdmin } from '../api/posts';
 
-function UserManagement() {
+const { Option } = Select;
+const ROLE_LIST = ['用户', '管理员', '超级管理员'];
+
+function UserManagement({ superAdminId }) {
   const [users, setUsers] = useState([]);
 
   useEffect(() => {
-    fetch('/api/users')
-      .then(res => res.json())
-      .then(data => setUsers(data))
-      .catch(console.error);
-  }, []);
+    async function load() {
+      try {
+        const data = superAdminId
+          ? await fetchUserList(superAdminId)
+          : await fetch('/api/users').then(res => res.json());
+        setUsers(data);
+      } catch (e) {
+        console.error(e);
+      }
+    }
+    load();
+  }, [superAdminId]);
 
-  const handleUserAction = (id, action) => {
-    fetch(`/api/users/${id}/${action}`, { method: 'POST' })
-      .then(res => res.ok && setUsers(us => us.filter(u => u.id !== id)))
-      .catch(console.error);
+  // handle role changes
+  const handleRoleChange = async (userId, newRole) => {
+    try {
+      if (newRole === '用户') await giveUser(superAdminId, userId);
+      else if (newRole === '管理员') await giveAdmin(superAdminId, userId);
+      else if (newRole === '超级管理员') await giveSuperAdmin(superAdminId, userId);
+      setUsers(us => us.map(u => u.id === userId ? { ...u, role: newRole } : u));
+      message.success('修改成功');
+    } catch (e) {
+      console.error(e);
+      message.error('修改失败');
+    }
   };
 
+  // define table columns
+  const columns = [
+    { title: '用户名', dataIndex: 'username', key: 'username' },
+    { title: '角色', dataIndex: 'role', key: 'role' },
+    {
+      title: '操作',
+      key: 'action',
+      render: (_, record) => {
+        const orderedRoles = [record.role, ...ROLE_LIST.filter(r => r !== record.role)];
+        return (
+          <Select
+            value={record.role}
+            style={{ width: 120 }}
+            onChange={value => handleRoleChange(record.id, value)}
+          >
+            {orderedRoles.map(r => (
+              <Option key={r} value={r}>{r}</Option>
+            ))}
+          </Select>
+        );
+      },
+    },
+  ];
+
   return (
     <div className="admin-container">
-      <h2>用户管理</h2>
-      <table className="admin-table">
-        <thead>
-          <tr><th>用户名</th><th>角色</th><th>操作</th></tr>
-        </thead>
-        <tbody>
-          {users.map(u => (
-            <tr key={u.id}>
-              <td>{u.username}</td>
-              <td>{u.role}</td>
-              <td>
-                <button onClick={() => handleUserAction(u.id, 'ban')}>封禁</button>
-                <button onClick={() => handleUserAction(u.id, 'promote')}>提升权限</button>
-              </td>
-            </tr>
-          ))}
-        </tbody>
-      </table>
+      <Table
+        dataSource={users}
+        columns={columns}
+        rowKey="id"
+        pagination={false}
+      />
     </div>
   );
 }
diff --git a/TRM/front/src/router/App.js b/TRM/front/src/router/App.js
index b9f9ac1..fd10142 100644
--- a/TRM/front/src/router/App.js
+++ b/TRM/front/src/router/App.js
@@ -20,7 +20,7 @@
       {/* 超级管理员,只用 SuperAdminLayout */}
       <Route path="superadmin" element={<SuperAdmin />}>
         <Route index element={<Navigate to="users" replace />} />
-        <Route path="users" element={<UserManagement />} />
+        <Route path="users" element={<UserManagement superAdminId={3} />} />
         <Route path="dashboard" element={<LogsDashboard />} />
       </Route>
     </Routes>
diff --git a/TRM/front/src/style/Admin.css b/TRM/front/src/style/Admin.css
index e5dff20..4a5bcb7 100644
--- a/TRM/front/src/style/Admin.css
+++ b/TRM/front/src/style/Admin.css
@@ -369,4 +369,21 @@
 .search-input:focus {
   outline: none;
   border-color: #e61515;
+}
+
+/* 小红书品牌红 */
+:root {
+  --xiaohongshu-red: #e2204f;
+}
+
+/* Antd 表格表头背景小红书红,文字白色 */
+.ant-table-thead > tr > th {
+  background-color: var(--xiaohongshu-red) !important;
+  color: #fff;
+}
+
+/* 侧栏前两项文字变小红书红 */
+.ant-layout-sider .ant-menu-item:nth-child(1),
+.ant-layout-sider .ant-menu-item:nth-child(2) {
+  color: var(--xiaohongshu-red) !important;
 }
\ No newline at end of file