完成性能日志和事务日志功能
Change-Id: Iec30043bc5b954a29fa0d8d18a84c1feed2a1696
diff --git a/Merge/front/src/components/Admin.js b/Merge/front/src/components/Admin.js
index da11100..2d97495 100644
--- a/Merge/front/src/components/Admin.js
+++ b/Merge/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 '../api/posts_trm';
export default function Admin() {
const ADMIN_USER_ID = 2;
diff --git a/Merge/front/src/components/LogsDashboard.js b/Merge/front/src/components/LogsDashboard.js
index 1bd6cb7..22047e2 100644
--- a/Merge/front/src/components/LogsDashboard.js
+++ b/Merge/front/src/components/LogsDashboard.js
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
+import { NavLink, Outlet } from 'react-router-dom';
import '../style/Admin.css';
function LogsDashboard() {
@@ -19,25 +20,17 @@
return (
<div className="admin-container">
<h2>运行日志 & 性能 Dashboard</h2>
- <section className="dashboard-stats">
- <pre>{JSON.stringify(stats, null, 2)}</pre>
- </section>
- <section className="dashboard-logs">
- <table className="admin-table">
- <thead>
- <tr><th>时间</th><th>级别</th><th>消息</th></tr>
- </thead>
- <tbody>
- {logs.map((log, i) => (
- <tr key={i}>
- <td>{new Date(log.time).toLocaleString()}</td>
- <td>{log.level}</td>
- <td>{log.message}</td>
- </tr>
- ))}
- </tbody>
- </table>
- </section>
+ <nav className="dashboard-nav">
+ <NavLink to="transactions" className={({ isActive }) => isActive ? 'active' : ''}>
+ 事务日志
+ </NavLink>
+ <NavLink to="performance" className={({ isActive }) => isActive ? 'active' : ''}>
+ 性能日志
+ </NavLink>
+ </nav>
+
+ {/* nested routes will render here */}
+ <Outlet />
</div>
);
}
diff --git a/Merge/front/src/components/PerformanceLogs.js b/Merge/front/src/components/PerformanceLogs.js
new file mode 100644
index 0000000..bb1c244
--- /dev/null
+++ b/Merge/front/src/components/PerformanceLogs.js
@@ -0,0 +1,44 @@
+import React, { useState, useEffect } from 'react';
+import {
+ ResponsiveContainer, LineChart, Line,
+ XAxis, YAxis, Tooltip, CartesianGrid, Legend
+} from 'recharts';
+import { fetchSysCost } from '../api/posts_trm';
+
+function PerformanceLogs({ userId }) {
+ const [data, setData] = useState([]);
+
+ useEffect(() => {
+ fetchSysCost(userId)
+ .then(list => setData(list))
+ .catch(err => console.error('fetchSysCost error:', err));
+ }, [userId]);
+
+ return (
+ <section className="dashboard-performance">
+ <ResponsiveContainer width="100%" height={400}>
+ <LineChart
+ data={data}
+ margin={{ top: 20, right: 30, left: 20, bottom: 5 }}
+ >
+ <CartesianGrid strokeDasharray="3 3" />
+ <XAxis dataKey="record_time" />
+ <YAxis
+ domain={[0, 'auto']}
+ label={{ value: '时间 (s)', angle: -90, position: 'insideLeft' }}
+ tickFormatter={val => (val / 1000).toFixed(2)}
+ />
+ <Tooltip formatter={val => (typeof val === 'number' ? (val/1000).toFixed(2) + 's' : val)} />
+ <Legend />
+ <Line type="monotone" dataKey="elapsed_time" stroke="#8884d8" name="响应时间" />
+ <Line type="monotone" dataKey="cpu_user" stroke="#82ca9d" name="CPU 用户时间" />
+ <Line type="monotone" dataKey="cpu_system" stroke="#ffc658" name="CPU 系统时间" />
+ <Line type="monotone" dataKey="memory_rss" stroke="#ff7300" name="内存 RSS" />
+ {/* 如需更多指标,可再添其他 <Line /> */}
+ </LineChart>
+ </ResponsiveContainer>
+ </section>
+ );
+}
+
+export default PerformanceLogs;
diff --git a/Merge/front/src/components/SuperAdmin.js b/Merge/front/src/components/SuperAdmin.js
index 817b708..f24e5d4 100644
--- a/Merge/front/src/components/SuperAdmin.js
+++ b/Merge/front/src/components/SuperAdmin.js
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react';
import { NavLink, Outlet } from 'react-router-dom';
import { Spin } from 'antd';
-import { fetchUserList } from '../api/posts';
+import { fetchUserList } from '../api/posts_trm';
import '../style/SuperAdmin.css';
export default function SuperAdmin() {
diff --git a/Merge/front/src/components/TransactionLogs.js b/Merge/front/src/components/TransactionLogs.js
new file mode 100644
index 0000000..9df8f67
--- /dev/null
+++ b/Merge/front/src/components/TransactionLogs.js
@@ -0,0 +1,50 @@
+import React, { useState, useEffect } from 'react';
+import { fetchRecordLog } from '../api/posts_trm';
+
+function TransactionLogs({ userId }) {
+ const [records, setRecords] = useState([]);
+
+ useEffect(() => {
+ fetchRecordLog(userId)
+ .then(data => setRecords(data))
+ .catch(err => console.error('fetchRecordLog error:', err));
+ }, [userId]);
+
+ return (
+ <section className="dashboard-logs">
+ <table className="admin-table">
+ <thead>
+ <tr>
+ <th>ID</th>
+ <th>用户ID</th>
+ <th>类型</th>
+ <th>内容</th>
+ <th>IP</th>
+ <th>创建时间</th>
+ </tr>
+ </thead>
+ <tbody>
+ {records.length > 0
+ ? records.map((r, i) => (
+ <tr key={i}>
+ <td>{r.id}</td>
+ <td>{r.user_id}</td>
+ <td>{r.type}</td>
+ <td>{r.content}</td>
+ <td>{r.ip}</td>
+ <td>{new Date(r.created_at).toLocaleString()}</td>
+ </tr>
+ ))
+ : (
+ <tr>
+ <td colSpan="6" style={{ textAlign: 'center' }}>暂无数据</td>
+ </tr>
+ )
+ }
+ </tbody>
+ </table>
+ </section>
+ );
+}
+
+export default TransactionLogs;
diff --git a/Merge/front/src/components/UserManagement.js b/Merge/front/src/components/UserManagement.js
index 4bd05c5..a48f8cf 100644
--- a/Merge/front/src/components/UserManagement.js
+++ b/Merge/front/src/components/UserManagement.js
@@ -1,7 +1,7 @@
import React, { useState, useEffect } from 'react';
import '../style/Admin.css';
import { Select, message, Table } from 'antd';
-import { fetchUserList, giveUser, giveAdmin, giveSuperAdmin } from '../api/posts';
+import { fetchUserList, giveUser, giveAdmin, giveSuperAdmin } from '../api/posts_trm';
const { Option } = Select;
const ROLE_LIST = ['用户', '管理员', '超级管理员'];