blob: f063c09ceef821ca22c769eabc704c7893baae5a [file] [log] [blame]
223011339e292152025-06-08 00:34:37 +08001import React, { useState, useEffect } from "react";
whtb1e79592025-06-07 16:03:09 +08002import { useNavigate } from "react-router-dom";
223011339e292152025-06-08 00:34:37 +08003import { API_BASE_URL } from "./config";
whtb1e79592025-06-07 16:03:09 +08004
5// 示例数据
6const initialConfig = {
7 FarmNumber: 3,
8 FakeTime: 3,
9 BegVote: 3,
10 CheatTime: 5,
11};
12
whtb1e79592025-06-07 16:03:09 +080013export default function AdminPage() {
14 const navigate = useNavigate();
15 const [config, setConfig] = useState(initialConfig);
223011339e292152025-06-08 00:34:37 +080016 // state for users fetched from backend
17 const [cheatUsers, setCheatUsers] = useState([]);
18 const [suspiciousUsers, setSuspiciousUsers] = useState([]);
19
20 // helper to get admin userId from cookie
21 const getUserIdFromCookie = () => {
22 const match = document.cookie.match('(^|;)\\s*userId=([^;]+)');
23 return match ? match[2] : null;
24 };
25
26 // fetch cheat users list from backend
27 const fetchCheatUsers = async () => {
28 const adminId = getUserIdFromCookie();
29 if (!adminId) return;
30 try {
31 const res = await fetch(`${API_BASE_URL}/api/admin/cheat-users?userid=${adminId}`);
32 if (!res.ok) throw new Error('获取作弊用户失败');
33 const data = await res.json();
34 setCheatUsers(data);
35 } catch (err) {
36 console.error(err);
37 }
38 };
39
40 // fetch suspicious users list from backend
41 const fetchSuspiciousUsers = async () => {
42 const adminId = getUserIdFromCookie();
43 if (!adminId) return;
44 try {
45 const res = await fetch(`${API_BASE_URL}/api/admin/suspicious-users?userid=${adminId}`);
46 if (!res.ok) throw new Error('获取可疑用户失败');
47 const data = await res.json();
48 setSuspiciousUsers(data);
49 } catch (err) {
50 console.error(err);
51 }
52 };
whtb1e79592025-06-07 16:03:09 +080053
whtb1e79592025-06-07 16:03:09 +080054 const handleBan = (user) => {
223011339e292152025-06-08 00:34:37 +080055 const adminId = getUserIdFromCookie();
56 if (!adminId) {
57 alert('无法获取用户ID');
58 return;
59 }
60 fetch(`${API_BASE_URL}/api/admin/ban-user`, {
61 method: 'POST',
62 headers: { 'Content-Type': 'application/json' },
63 body: JSON.stringify({ userid: user.userid }),
64 })
65 .then((res) => { if (!res.ok) throw new Error('Network response was not ok'); return res.json(); })
66 .then(() => {
67 // 重新获取用户列表,触发页面重新渲染
68 fetchSuspiciousUsers();
69 fetchCheatUsers();
70 })
71 .catch((err) => console.error('封禁用户失败:', err));
72 }
73
74 // 解封作弊用户
75 const handleUnban = (user) => {
76 const adminId = getUserIdFromCookie();
77 if (!adminId) {
78 alert('无法获取用户ID');
79 return;
80 }
81 fetch(`${API_BASE_URL}/api/admin/unban-user`, {
82 method: 'POST',
83 headers: { 'Content-Type': 'application/json' },
84 body: JSON.stringify({ userid: user.userid }),
85 })
86 .then((res) => { if (!res.ok) throw new Error('Network response was not ok'); return res.json(); })
87 .then(() => {
88 // 重新获取用户列表,触发页面重新渲染
89 fetchCheatUsers();
90 fetchSuspiciousUsers();
91 })
92 .catch((err) => console.error('解封用户失败:', err));
whtb1e79592025-06-07 16:03:09 +080093 };
94
223011339e292152025-06-08 00:34:37 +080095 // 初始化时向后端请求系统参数及用户列表
96 useEffect(() => {
97 const match = document.cookie.match('(^|;)\\s*userId=([^;]+)');
98 const userId = match ? match[2] : null;
99 // console.log("User ID from cookie:", userId);
100 if (userId) {
101 // fetch config
102 fetch(`${API_BASE_URL}/api/admin/config?userid=${userId}`)
103 .then((res) => {
104 if (!res.ok) throw new Error('Network response was not ok');
105 return res.json();
106 })
107 .then((data) => {
108 // console.log("Fetched system config:", data);
109 setConfig(data);
110 })
111 .catch((err) => console.error('获取系统参数失败:', err));
112
113 // 初始获取用户列表
114 fetchCheatUsers();
115 fetchSuspiciousUsers();
116 }
117 }, []);
118
whtb1e79592025-06-07 16:03:09 +0800119 return (
120 <div style={{ padding: 40, maxWidth: 900, margin: "0 auto" }}>
121 <h1 style={{ textAlign: "center", marginBottom: 32 }}>管理员页面</h1>
122 {/* 参数设置 */}
223011339e292152025-06-08 00:34:37 +0800123 <div style={{ marginBottom: 32, padding: 18, background: "#f7faff", borderRadius: 12, display: "flex", gap: 24, alignItems: "center", justifyContent: "space-between" }}>
whtb1e79592025-06-07 16:03:09 +0800124 <b>系统参数:</b>
wht2bf8f802025-06-08 15:52:18 +0800125 <span>FarmNumber: {config.FarmNumber}</span>
126 <span>FakeTime: {config.FakeTime}</span>
127 <span>BegVote: {config.BegVote}</span>
128 <span>CheatTime: {config.CheatTime}</span>
whtb1e79592025-06-07 16:03:09 +0800129 </div>
130 {/* 作弊用户 */}
131 <div style={{ marginBottom: 32 }}>
132 <h2 style={{ color: "#e53935" }}>作弊用户</h2>
133 <table style={{ width: "100%", background: "#fff", borderRadius: 10, boxShadow: "0 2px 8px #e0e7ff", marginBottom: 18 }}>
134 <thead>
135 <tr style={{ background: "#f5f5f5" }}>
223011339e292152025-06-08 00:34:37 +0800136 {/* <th>user_id</th> */}
whtb1e79592025-06-07 16:03:09 +0800137 <th>email</th>
138 <th>username</th>
139 <th>account_status</th>
140 <th>操作</th>
141 </tr>
142 </thead>
143 <tbody>
144 {cheatUsers.map((u) => (
223011339e292152025-06-08 00:34:37 +0800145 <tr key={u.userid}>
146 {/* <td>{u.userid}</td> */}
whtb1e79592025-06-07 16:03:09 +0800147 <td>{u.email}</td>
148 <td>{u.username}</td>
223011339e292152025-06-08 00:34:37 +0800149 <td style={{ color: "#e53935" }}>
wht2bf8f802025-06-08 15:52:18 +0800150 {"封禁"}
whtb1e79592025-06-07 16:03:09 +0800151 </td>
152 <td>
153 <button
223011339e292152025-06-08 00:34:37 +0800154 style={{ background: "#13F31E", color: "#fff", border: "none", borderRadius: 6, padding: "4px 14px", cursor: "pointer" }}
155 onClick={() => handleUnban(u)}
whtb1e79592025-06-07 16:03:09 +0800156 >
223011339e292152025-06-08 00:34:37 +0800157 解封
whtb1e79592025-06-07 16:03:09 +0800158 </button>
159 </td>
160 </tr>
161 ))}
162 </tbody>
163 </table>
164 </div>
165 {/* 可疑用户 */}
166 <div style={{ marginBottom: 32 }}>
167 <h2 style={{ color: "#ff9800" }}>可疑用户</h2>
168 <table style={{ width: "100%", background: "#fff", borderRadius: 10, boxShadow: "0 2px 8px #e0e7ff" }}>
169 <thead>
170 <tr style={{ background: "#f5f5f5" }}>
223011339e292152025-06-08 00:34:37 +0800171 {/* <th>user_id</th> */}
whtb1e79592025-06-07 16:03:09 +0800172 <th>email</th>
173 <th>username</th>
174 <th>account_status</th>
175 <th>操作</th>
176 </tr>
177 </thead>
178 <tbody>
179 {suspiciousUsers.map((u) => (
180 <tr key={u.user_id}>
223011339e292152025-06-08 00:34:37 +0800181 {/* <td>{u.user_id}</td> */}
whtb1e79592025-06-07 16:03:09 +0800182 <td>{u.email}</td>
183 <td>{u.username}</td>
184 <td style={{ color: u.account_status === 1 ? "#e53935" : "#43a047" }}>
185 {u.account_status === 1 ? "封禁" : "正常"}
186 </td>
187 <td>
188 <button
189 style={{ background: "#e53935", color: "#fff", border: "none", borderRadius: 6, padding: "4px 14px", cursor: "pointer" }}
190 onClick={() => handleBan(u)}
191 >
192 封禁
193 </button>
194 </td>
195 </tr>
196 ))}
197 </tbody>
198 </table>
199 </div>
200 {/* 跳转按钮 */}
201 <div style={{ display: "flex", gap: 24, justifyContent: "center" }}>
202 <button
203 style={{ background: "#1976d2", color: "#fff", border: "none", borderRadius: 8, padding: "10px 28px", fontWeight: 600, fontSize: 16, cursor: "pointer" }}
204 onClick={() => navigate("/appeal-review")}
205 >
206 用户申诉
207 </button>
208 <button
209 style={{ background: "#43a047", color: "#fff", border: "none", borderRadius: 8, padding: "10px 28px", fontWeight: 600, fontSize: 16, cursor: "pointer" }}
210 onClick={() => navigate("/migration-review")}
211 >
212 用户迁移
213 </button>
wht2bf8f802025-06-08 15:52:18 +0800214 <button
215 style={{ background: "#ff9800", color: "#fff", border: "none", borderRadius: 8, padding: "10px 28px", fontWeight: 600, fontSize: 16, cursor: "pointer" }}
216 onClick={() => navigate("/seed-promotion")}
217 >
218 促销管理
219 </button>
whtb1e79592025-06-07 16:03:09 +0800220 </div>
221 </div>
222 );
223}