新增管理员页面和用户申诉、迁移审核页面,推荐系统
Change-Id: Ief5646321feb98fadb17da4b4e91caeaacdbacc5
diff --git a/front/src/AdminPage.js b/front/src/AdminPage.js
new file mode 100644
index 0000000..4862449
--- /dev/null
+++ b/front/src/AdminPage.js
@@ -0,0 +1,145 @@
+import React, { useState } from "react";
+import { useNavigate } from "react-router-dom";
+
+// 示例数据
+const initialConfig = {
+ FarmNumber: 3,
+ FakeTime: 3,
+ BegVote: 3,
+ CheatTime: 5,
+};
+
+const cheatUsers = [
+ { user_id: "u001", email: "cheat1@example.com", username: "cheater1", account_status: 1 },
+ { user_id: "u002", email: "cheat2@example.com", username: "cheater2", account_status: 0 },
+];
+
+const suspiciousUsers = [
+ { user_id: "u101", email: "suspect1@example.com", username: "suspect1", account_status: 0 },
+ { user_id: "u102", email: "suspect2@example.com", username: "suspect2", account_status: 0 },
+];
+
+export default function AdminPage() {
+ const navigate = useNavigate();
+ const [config, setConfig] = useState(initialConfig);
+
+ const handleConfigChange = (e) => {
+ const { name, value } = e.target;
+ setConfig({ ...config, [name]: value });
+ };
+
+ const handleBan = (user) => {
+ alert(`已封禁用户:${user.username}`);
+ };
+
+ return (
+ <div style={{ padding: 40, maxWidth: 900, margin: "0 auto" }}>
+ <h1 style={{ textAlign: "center", marginBottom: 32 }}>管理员页面</h1>
+ {/* 参数设置 */}
+ <div style={{ marginBottom: 32, padding: 18, background: "#f7faff", borderRadius: 12, display: "flex", gap: 24, alignItems: "center" }}>
+ <b>系统参数:</b>
+ <label>
+ FarmNumber:
+ <input type="number" name="FarmNumber" value={config.FarmNumber} onChange={handleConfigChange} style={{ width: 60, margin: "0 12px" }} />
+ </label>
+ <label>
+ FakeTime:
+ <input type="number" name="FakeTime" value={config.FakeTime} onChange={handleConfigChange} style={{ width: 60, margin: "0 12px" }} />
+ </label>
+ <label>
+ BegVote:
+ <input type="number" name="BegVote" value={config.BegVote} onChange={handleConfigChange} style={{ width: 60, margin: "0 12px" }} />
+ </label>
+ <label>
+ CheatTime:
+ <input type="number" name="CheatTime" value={config.CheatTime} onChange={handleConfigChange} style={{ width: 60, margin: "0 12px" }} />
+ </label>
+ </div>
+ {/* 作弊用户 */}
+ <div style={{ marginBottom: 32 }}>
+ <h2 style={{ color: "#e53935" }}>作弊用户</h2>
+ <table style={{ width: "100%", background: "#fff", borderRadius: 10, boxShadow: "0 2px 8px #e0e7ff", marginBottom: 18 }}>
+ <thead>
+ <tr style={{ background: "#f5f5f5" }}>
+ <th>user_id</th>
+ <th>email</th>
+ <th>username</th>
+ <th>account_status</th>
+ <th>操作</th>
+ </tr>
+ </thead>
+ <tbody>
+ {cheatUsers.map((u) => (
+ <tr key={u.user_id}>
+ <td>{u.user_id}</td>
+ <td>{u.email}</td>
+ <td>{u.username}</td>
+ <td style={{ color: u.account_status === 1 ? "#e53935" : "#43a047" }}>
+ {u.account_status === 1 ? "封禁" : "正常"}
+ </td>
+ <td>
+ <button
+ style={{ background: "#e53935", color: "#fff", border: "none", borderRadius: 6, padding: "4px 14px", cursor: "pointer" }}
+ onClick={() => handleBan(u)}
+ >
+ 封禁
+ </button>
+ </td>
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ </div>
+ {/* 可疑用户 */}
+ <div style={{ marginBottom: 32 }}>
+ <h2 style={{ color: "#ff9800" }}>可疑用户</h2>
+ <table style={{ width: "100%", background: "#fff", borderRadius: 10, boxShadow: "0 2px 8px #e0e7ff" }}>
+ <thead>
+ <tr style={{ background: "#f5f5f5" }}>
+ <th>user_id</th>
+ <th>email</th>
+ <th>username</th>
+ <th>account_status</th>
+ <th>操作</th>
+ </tr>
+ </thead>
+ <tbody>
+ {suspiciousUsers.map((u) => (
+ <tr key={u.user_id}>
+ <td>{u.user_id}</td>
+ <td>{u.email}</td>
+ <td>{u.username}</td>
+ <td style={{ color: u.account_status === 1 ? "#e53935" : "#43a047" }}>
+ {u.account_status === 1 ? "封禁" : "正常"}
+ </td>
+ <td>
+ <button
+ style={{ background: "#e53935", color: "#fff", border: "none", borderRadius: 6, padding: "4px 14px", cursor: "pointer" }}
+ onClick={() => handleBan(u)}
+ >
+ 封禁
+ </button>
+ </td>
+ </tr>
+ ))}
+ </tbody>
+ </table>
+ </div>
+ {/* 跳转按钮 */}
+ <div style={{ display: "flex", gap: 24, justifyContent: "center" }}>
+ <button
+ style={{ background: "#1976d2", color: "#fff", border: "none", borderRadius: 8, padding: "10px 28px", fontWeight: 600, fontSize: 16, cursor: "pointer" }}
+ onClick={() => navigate("/appeal-review")}
+ >
+ 用户申诉
+ </button>
+ <button
+ style={{ background: "#43a047", color: "#fff", border: "none", borderRadius: 8, padding: "10px 28px", fontWeight: 600, fontSize: 16, cursor: "pointer" }}
+ onClick={() => navigate("/migration-review")}
+ >
+ 用户迁移
+ </button>
+ </div>
+ </div>
+ );
+}
\ No newline at end of file