mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2025-06-05 11:26:43 +08:00
update frontend
This commit is contained in:
parent
9ec4973fc3
commit
469dc8877b
@ -1,9 +1,11 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { Route, Routes } from 'react-router-dom';
|
||||
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
|
||||
import './App.css';
|
||||
import { useAppDispatch, useAppSelector } from './app/hooks';
|
||||
import Auth from './features/auth/Auth';
|
||||
import { loadGlobalConf, selectGlobalConfLoaded } from './features/globalConf/globalConfSlice';
|
||||
import GroupManager from './features/subsribeConfigManager/GroupManager';
|
||||
import SubscribeManager from './features/subsribeConfigManager/SubscribeManager';
|
||||
import Home from './pages/Home';
|
||||
import Unauthed from './pages/Unauthed';
|
||||
|
||||
@ -17,14 +19,36 @@ function App() {
|
||||
}
|
||||
}, [globalConfLoaded]);
|
||||
|
||||
const router = createBrowserRouter([
|
||||
{
|
||||
path: '/auth/:code',
|
||||
element: <Auth />,
|
||||
},
|
||||
{
|
||||
path: '/unauthed',
|
||||
element: <Unauthed />,
|
||||
},
|
||||
{
|
||||
path: '/home/',
|
||||
element: <Home />,
|
||||
// loader: homeLoader,
|
||||
children: [
|
||||
{
|
||||
path: 'groups',
|
||||
element: <GroupManager />,
|
||||
},
|
||||
{
|
||||
path: 'groups/:groupNumber',
|
||||
element: <SubscribeManager />,
|
||||
},
|
||||
],
|
||||
},
|
||||
], { basename: '/bison' });
|
||||
|
||||
return (
|
||||
globalConfLoaded
|
||||
? (
|
||||
<Routes>
|
||||
<Route path="/auth/:code" element={<Auth />} />
|
||||
<Route path="/unauthed" element={<Unauthed />} />
|
||||
<Route path="/home" element={<Home />} />
|
||||
</Routes>
|
||||
<RouterProvider router={router} />
|
||||
) : <div>loading</div>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Card, Typography, Grid, Button,
|
||||
} from '@arco-design/web-react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useGetSubsQuery } from './subscribeConfigSlice';
|
||||
|
||||
export default function GroupManager() {
|
||||
const { data: subs } = useGetSubsQuery();
|
||||
return (
|
||||
<>
|
||||
<Typography.Title heading={4} style={{ margin: '15px' }}>群管理</Typography.Title>
|
||||
<div>
|
||||
{ subs && (
|
||||
<Grid.Row gutter={20}>
|
||||
{ Object.keys(subs).map(
|
||||
(groupNumber: string) => (
|
||||
<Grid.Col span={6} key={groupNumber}>
|
||||
<Card
|
||||
title={subs[groupNumber].name}
|
||||
actions={[
|
||||
<Link to={`/home/groups/${groupNumber}`}><Button>详情</Button></Link>,
|
||||
<Button type="primary">添加</Button>,
|
||||
]}
|
||||
>
|
||||
<div>{groupNumber}</div>
|
||||
</Card>
|
||||
</Grid.Col>
|
||||
),
|
||||
)}
|
||||
</Grid.Row>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
@ -1,13 +1,87 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Button, Empty, Space, Table, Tag,
|
||||
} from '@arco-design/web-react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useGetSubsQuery } from './subscribeConfigSlice';
|
||||
import { useAppSelector } from '../../app/hooks';
|
||||
import { selectPlatformConf } from '../globalConf/globalConfSlice';
|
||||
import { SubscribeConfig } from '../../utils/type';
|
||||
|
||||
export default function SubscribeManager() {
|
||||
const { data: subs } = useGetSubsQuery();
|
||||
const { groupNumber } = useParams();
|
||||
const platformConf = useAppSelector(selectPlatformConf);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>{ subs && JSON.stringify(subs) }</div>
|
||||
<div>1</div>
|
||||
</>
|
||||
);
|
||||
const columns = [
|
||||
{
|
||||
title: '平台名称',
|
||||
dataIndex: 'platformName',
|
||||
render: (col: any, record: SubscribeConfig) => (
|
||||
<span>{platformConf[record.platformName].name}</span>
|
||||
),
|
||||
},
|
||||
{ title: '帐号名称', dataIndex: 'targetName' },
|
||||
{ title: '订阅帐号', dataIndex: 'target' },
|
||||
{
|
||||
title: '订阅分类',
|
||||
dataIndex: 'cats',
|
||||
render: (col: any, record: SubscribeConfig) => (
|
||||
<span>
|
||||
<Space>
|
||||
{
|
||||
record.cats.map((catNumber: number) => (
|
||||
<Tag>{platformConf[record.platformName].categories[catNumber]}</Tag>
|
||||
))
|
||||
}
|
||||
</Space>
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '订阅标签',
|
||||
dataIndex: 'tags',
|
||||
render: (col: any, record: SubscribeConfig) => (
|
||||
<span>
|
||||
<Space>
|
||||
{
|
||||
record.tags.length === 0 ? <Tag color="green">全部标签</Tag>
|
||||
: record.tags.map((tag: string) => (
|
||||
<Tag color="blue">{tag}</Tag>
|
||||
))
|
||||
}
|
||||
</Space>
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'op',
|
||||
render: (_: any, record: SubscribeConfig) => (
|
||||
<Space>
|
||||
<Button type="text">编辑</Button>
|
||||
<Button type="text" status="success">复制</Button>
|
||||
<Button type="text" status="danger" onClick={() => { console.log(record); }}>删除</Button>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
if (subs && groupNumber) {
|
||||
return (
|
||||
<>
|
||||
<span>
|
||||
{subs[groupNumber].name}
|
||||
{groupNumber}
|
||||
</span>
|
||||
<Button style={{ width: '90px', margin: '20px' }} type="primary">添加</Button>
|
||||
<Table
|
||||
columns={columns}
|
||||
data={subs[groupNumber].subscribes}
|
||||
rowKey={(record: SubscribeConfig) => `${record.platformName}-${record.target}`}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
return <Empty />;
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { Provider } from 'react-redux';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { PersistGate } from 'redux-persist/integration/react';
|
||||
import App from './App';
|
||||
import { persistor, store } from './app/store';
|
||||
@ -16,9 +15,7 @@ root.render(
|
||||
<React.StrictMode>
|
||||
<Provider store={store}>
|
||||
<PersistGate loading={null} persistor={persistor}>
|
||||
<BrowserRouter basename="/bison">
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
<App />
|
||||
</PersistGate>
|
||||
</Provider>
|
||||
</React.StrictMode>,
|
||||
|
44
admin-frontend/src/pages/Home.css
Normal file
44
admin-frontend/src/pages/Home.css
Normal file
@ -0,0 +1,44 @@
|
||||
.layout-collapse-demo {
|
||||
height: 100vh;
|
||||
border: 1px solid var(--color-border);
|
||||
background: var(--color-fill-2);
|
||||
}
|
||||
|
||||
.layout-collapse-demo .arco-layout-header .logo {
|
||||
height: 32px;
|
||||
margin: 12px 8px;
|
||||
background: var(--color-fill-2);
|
||||
}
|
||||
|
||||
.layout-collapse-demo .arco-layout-content .arco-layout-footer,
|
||||
.layout-collapse-demo .arco-layout-content .arco-layout-content {
|
||||
color: var(--color-white);
|
||||
/* text-align: center; */
|
||||
font-stretch: condensed;
|
||||
font-size: 16px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* justify-content: center; */
|
||||
}
|
||||
|
||||
.layout-collapse-demo .arco-layout-footer {
|
||||
color: var(--color-text-2);
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.layout-collapse-demo .arco-layout-content .arco-layout-content {
|
||||
background: var(--color-bg-3);
|
||||
color: var(--color-text-2);
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.layout-collapse-demo .arco-layout-header {
|
||||
height: 64px;
|
||||
line-height: 64px;
|
||||
background: var(--color-bg-3);
|
||||
}
|
@ -1,42 +1,102 @@
|
||||
import React, { ReactNode, useState } from 'react';
|
||||
import React, { ReactNode, useEffect, useState } from 'react';
|
||||
import { Breadcrumb, Layout, Menu } from '@arco-design/web-react';
|
||||
import { IconRobot, IconDashboard } from '@arco-design/web-react/icon';
|
||||
import './Home.css';
|
||||
// import SubscribeManager from '../features/subsribeConfigManager/SubscribeManager';
|
||||
import {
|
||||
Link, Outlet, useLocation, useNavigate,
|
||||
} from 'react-router-dom';
|
||||
|
||||
export function homeLoader() {
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
const [selectedTab, changeSelectTab] = useState('1');
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const path = location.pathname;
|
||||
useEffect(() => {
|
||||
if (path === '/home') {
|
||||
navigate('/home/groups');
|
||||
}
|
||||
|
||||
if (path !== '/home/groups' && !path.startsWith('/home/groups/')) {
|
||||
console.log(path);
|
||||
navigate('/home/groups');
|
||||
}
|
||||
}, [path]);
|
||||
|
||||
let currentKey: string = '';
|
||||
if (path === '/home/groups') {
|
||||
currentKey = 'groups';
|
||||
} else if (path.startsWith('/home/groups/')) {
|
||||
currentKey = 'subs';
|
||||
}
|
||||
|
||||
const [selectedTab, changeSelectTab] = useState(currentKey);
|
||||
|
||||
const handleTabSelect = (tab: string) => {
|
||||
changeSelectTab(tab);
|
||||
if (tab === 'groups') {
|
||||
navigate('/home/navigate');
|
||||
} else if (tab === 'weight') {
|
||||
navigate('/home/weight');
|
||||
}
|
||||
};
|
||||
|
||||
let breadcrumbContent: ReactNode;
|
||||
if (selectedTab === '1') {
|
||||
if (selectedTab === 'groups') {
|
||||
breadcrumbContent = (
|
||||
<Breadcrumb.Item>
|
||||
<IconRobot />
|
||||
订阅管理
|
||||
</Breadcrumb.Item>
|
||||
<Breadcrumb style={{ margin: '16px 0' }}>
|
||||
<Breadcrumb.Item>
|
||||
<IconRobot />
|
||||
订阅管理
|
||||
</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
);
|
||||
} else if (selectedTab === 'subs') {
|
||||
breadcrumbContent = (
|
||||
<Breadcrumb style={{ margin: '16px 0' }}>
|
||||
<Breadcrumb.Item>
|
||||
<Link to="/home/groups">
|
||||
<IconRobot />
|
||||
订阅管理
|
||||
</Link>
|
||||
</Breadcrumb.Item>
|
||||
<Breadcrumb.Item>
|
||||
groupman
|
||||
</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
);
|
||||
}
|
||||
// let content: ReactNode;
|
||||
return (
|
||||
<Layout style={{ height: '100vh' }}>
|
||||
<Layout className="layout-collapse-demo">
|
||||
<Layout.Header>
|
||||
heade
|
||||
<div className="logo" />
|
||||
</Layout.Header>
|
||||
<Layout>
|
||||
<Layout className="layout-collapse-demo">
|
||||
<Layout.Sider>
|
||||
<Menu defaultSelectedKeys={['1']} onClickMenuItem={(key) => { changeSelectTab(key); }}>
|
||||
<Menu.Item key="1">
|
||||
<Menu
|
||||
defaultSelectedKeys={[selectedTab]}
|
||||
onClickMenuItem={(key) => { handleTabSelect(key); }}
|
||||
>
|
||||
<Menu.Item key="groups">
|
||||
<IconRobot />
|
||||
订阅管理
|
||||
</Menu.Item>
|
||||
<Menu.Item key="2">
|
||||
<Menu.Item key="weight">
|
||||
<IconDashboard />
|
||||
调度权重
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
</Layout.Sider>
|
||||
<Layout.Content style={{ padding: '0 24px' }}>
|
||||
<Breadcrumb style={{ margin: '16px 0' }}>
|
||||
<Layout style={{ height: '100%' }}>
|
||||
{ breadcrumbContent }
|
||||
</Breadcrumb>
|
||||
<div>123</div>
|
||||
<Layout.Content style={{ margin: '10px', padding: '40px' }}>
|
||||
<Outlet />
|
||||
</Layout.Content>
|
||||
</Layout>
|
||||
</Layout.Content>
|
||||
</Layout>
|
||||
</Layout>
|
||||
|
@ -99,6 +99,7 @@ async def get_subs_info(jwt_obj: dict):
|
||||
"targetName": sub.target.target_name,
|
||||
"cats": sub.categories,
|
||||
"tags": sub.tags,
|
||||
"target": sub.target.target,
|
||||
},
|
||||
raw_subs,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user