blob: dac05cb75f6a71053e6279fd3c9211067c5ee7c6 [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
54 const handleConfigChange = (e) => {
55 const { name, value } = e.target;
56 setConfig({ ...config, [name]: value });
57 };
58
59 const handleBan = (user) => {
223011339e292152025-06-08 00:34:37 +080060 const adminId = getUserIdFromCookie();
61 if (!adminId) {
62 alert('无法获取用户ID');
63 return;
64 }
65 fetch(`${API_BASE_URL}/api/admin/ban-user`, {
66 method: 'POST',
67 headers: { 'Content-Type': 'application/json' },
68 body: JSON.stringify({ userid: user.userid }),
69 })
70 .then((res) => { if (!res.ok) throw new Error('Network response was not ok'); return res.json(); })
71 .then(() => {
72 // 重新获取用户列表,触发页面重新渲染
73 fetchSuspiciousUsers();
74 fetchCheatUsers();
75 })
76 .catch((err) => console.error('封禁用户失败:', err));
77 }
78
79 // 解封作弊用户
80 const handleUnban = (user) => {
81 const adminId = getUserIdFromCookie();
82 if (!adminId) {
83 alert('无法获取用户ID');
84 return;
85 }
86 fetch(`${API_BASE_URL}/api/admin/unban-user`, {
87 method: 'POST',
88 headers: { 'Content-Type': 'application/json' },
89 body: JSON.stringify({ userid: user.userid }),
90 })
91 .then((res) => { if (!res.ok) throw new Error('Network response was not ok'); return res.json(); })
92 .then(() => {
93 // 重新获取用户列表,触发页面重新渲染
94 fetchCheatUsers();
95 fetchSuspiciousUsers();
96 })
97 .catch((err) => console.error('解封用户失败:', err));
whtb1e79592025-06-07 16:03:09 +080098 };
99
223011339e292152025-06-08 00:34:37 +0800100 // 保存系统参数到后端
101 const handleSave = () => {
102 const match = document.cookie.match('(^|;)\\s*userId=([^;]+)');
103 const userId = match ? match[2] : null;
104 if (!userId) {
105 alert('无法获取用户ID');
106 return;
107 }
108 fetch(`${API_BASE_URL}/api/save-config`, {
109 method: 'POST',
110 // credentials: 'include',
111 headers: { 'Content-Type': 'application/json' },
112 body: JSON.stringify({ userid: userId, ...config }),
113 })
114 .then((res) => {
115 if (!res.ok) throw new Error('Network response was not ok');
116 return res.json();
117 })
118 .then(() => alert('系统参数已保存'))
119 .catch((err) => console.error('保存系统参数失败:', err));
120 };
121
122 // 初始化时向后端请求系统参数及用户列表
123 useEffect(() => {
124 const match = document.cookie.match('(^|;)\\s*userId=([^;]+)');
125 const userId = match ? match[2] : null;
126 // console.log("User ID from cookie:", userId);
127 if (userId) {
128 // fetch config
129 fetch(`${API_BASE_URL}/api/admin/config?userid=${userId}`)
130 .then((res) => {
131 if (!res.ok) throw new Error('Network response was not ok');
132 return res.json();
133 })
134 .then((data) => {
135 // console.log("Fetched system config:", data);
136 setConfig(data);
137 })
138 .catch((err) => console.error('获取系统参数失败:', err));
139
140 // 初始获取用户列表
141 fetchCheatUsers();
142 fetchSuspiciousUsers();
143 }
144 }, []);
145
whtb1e79592025-06-07 16:03:09 +0800146 return (
147 <div style={{ padding: 40, maxWidth: 900, margin: "0 auto" }}>
148 <h1 style={{ textAlign: "center", marginBottom: 32 }}>管理员页面</h1>
149 {/* 参数设置 */}
223011339e292152025-06-08 00:34:37 +0800150 <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 +0800151 <b>系统参数:</b>
152 <label>
153 FarmNumber:
223011339e292152025-06-08 00:34:37 +0800154 <input type="number" name="FarmNumber" value={config.FarmNumber} onChange={handleConfigChange} disabled style={{ width: 60, margin: "0 12px" }} />
whtb1e79592025-06-07 16:03:09 +0800155 </label>
156 <label>
157 FakeTime:
223011339e292152025-06-08 00:34:37 +0800158 <input type="number" name="FakeTime" value={config.FakeTime} onChange={handleConfigChange} disabled style={{ width: 60, margin: "0 12px" }} />
whtb1e79592025-06-07 16:03:09 +0800159 </label>
160 <label>
161 BegVote:
223011339e292152025-06-08 00:34:37 +0800162 <input type="number" name="BegVote" value={config.BegVote} onChange={handleConfigChange} disabled style={{ width: 60, margin: "0 12px" }} />
whtb1e79592025-06-07 16:03:09 +0800163 </label>
164 <label>
165 CheatTime:
223011339e292152025-06-08 00:34:37 +0800166 <input type="number" name="CheatTime" value={config.CheatTime} onChange={handleConfigChange} disabled style={{ width: 60, margin: "0 12px" }} />
whtb1e79592025-06-07 16:03:09 +0800167 </label>
223011339e292152025-06-08 00:34:37 +0800168 {/* <button
169 onClick={handleSave}
170 style={{
171 background: '#1976d2',
172 color: '#fff',
173 border: 'none',
174 borderRadius: 6,
175 padding: '6px 18px',
176 cursor: 'pointer',
177 writingMode: 'horizontal-tb',
178 whiteSpace: 'nowrap'
179 }}
180 >
181 保存
182 </button> */}
whtb1e79592025-06-07 16:03:09 +0800183 </div>
184 {/* 作弊用户 */}
185 <div style={{ marginBottom: 32 }}>
186 <h2 style={{ color: "#e53935" }}>作弊用户</h2>
187 <table style={{ width: "100%", background: "#fff", borderRadius: 10, boxShadow: "0 2px 8px #e0e7ff", marginBottom: 18 }}>
188 <thead>
189 <tr style={{ background: "#f5f5f5" }}>
223011339e292152025-06-08 00:34:37 +0800190 {/* <th>user_id</th> */}
whtb1e79592025-06-07 16:03:09 +0800191 <th>email</th>
192 <th>username</th>
193 <th>account_status</th>
194 <th>操作</th>
195 </tr>
196 </thead>
197 <tbody>
198 {cheatUsers.map((u) => (
223011339e292152025-06-08 00:34:37 +0800199 <tr key={u.userid}>
200 {/* <td>{u.userid}</td> */}
whtb1e79592025-06-07 16:03:09 +0800201 <td>{u.email}</td>
202 <td>{u.username}</td>
223011339e292152025-06-08 00:34:37 +0800203 <td style={{ color: "#e53935" }}>
204 {"封禁" }
whtb1e79592025-06-07 16:03:09 +0800205 </td>
206 <td>
207 <button
223011339e292152025-06-08 00:34:37 +0800208 style={{ background: "#13F31E", color: "#fff", border: "none", borderRadius: 6, padding: "4px 14px", cursor: "pointer" }}
209 onClick={() => handleUnban(u)}
whtb1e79592025-06-07 16:03:09 +0800210 >
223011339e292152025-06-08 00:34:37 +0800211 解封
whtb1e79592025-06-07 16:03:09 +0800212 </button>
213 </td>
214 </tr>
215 ))}
216 </tbody>
217 </table>
218 </div>
219 {/* 可疑用户 */}
220 <div style={{ marginBottom: 32 }}>
221 <h2 style={{ color: "#ff9800" }}>可疑用户</h2>
222 <table style={{ width: "100%", background: "#fff", borderRadius: 10, boxShadow: "0 2px 8px #e0e7ff" }}>
223 <thead>
224 <tr style={{ background: "#f5f5f5" }}>
223011339e292152025-06-08 00:34:37 +0800225 {/* <th>user_id</th> */}
whtb1e79592025-06-07 16:03:09 +0800226 <th>email</th>
227 <th>username</th>
228 <th>account_status</th>
229 <th>操作</th>
230 </tr>
231 </thead>
232 <tbody>
233 {suspiciousUsers.map((u) => (
234 <tr key={u.user_id}>
223011339e292152025-06-08 00:34:37 +0800235 {/* <td>{u.user_id}</td> */}
whtb1e79592025-06-07 16:03:09 +0800236 <td>{u.email}</td>
237 <td>{u.username}</td>
238 <td style={{ color: u.account_status === 1 ? "#e53935" : "#43a047" }}>
239 {u.account_status === 1 ? "封禁" : "正常"}
240 </td>
241 <td>
242 <button
243 style={{ background: "#e53935", color: "#fff", border: "none", borderRadius: 6, padding: "4px 14px", cursor: "pointer" }}
244 onClick={() => handleBan(u)}
245 >
246 封禁
247 </button>
248 </td>
249 </tr>
250 ))}
251 </tbody>
252 </table>
253 </div>
254 {/* 跳转按钮 */}
255 <div style={{ display: "flex", gap: 24, justifyContent: "center" }}>
256 <button
257 style={{ background: "#1976d2", color: "#fff", border: "none", borderRadius: 8, padding: "10px 28px", fontWeight: 600, fontSize: 16, cursor: "pointer" }}
258 onClick={() => navigate("/appeal-review")}
259 >
260 用户申诉
261 </button>
262 <button
263 style={{ background: "#43a047", color: "#fff", border: "none", borderRadius: 8, padding: "10px 28px", fontWeight: 600, fontSize: 16, cursor: "pointer" }}
264 onClick={() => navigate("/migration-review")}
265 >
266 用户迁移
267 </button>
268 </div>
269 </div>
270 );
271}