mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2026-06-23 05:56:51 +08:00
✨ 添加 Cookie 组件 (#633)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import SubscribeManager from './features/subsribeConfigManager/SubscribeManager'
|
||||
import WeightConfig from './features/weightConfig/WeightManager';
|
||||
import Home from './pages/Home';
|
||||
import Unauthed from './pages/Unauthed';
|
||||
import CookieManager from './features/cookieManager/CookieManager';
|
||||
|
||||
function App() {
|
||||
const dispatch = useAppDispatch();
|
||||
@@ -46,6 +47,14 @@ function App() {
|
||||
path: 'weight',
|
||||
element: <WeightConfig />,
|
||||
},
|
||||
{
|
||||
path: 'cookie',
|
||||
element: <CookieManager />,
|
||||
},
|
||||
{
|
||||
path: 'cookie/:siteName',
|
||||
element: <CookieManager />,
|
||||
},
|
||||
],
|
||||
},
|
||||
], { basename: '/bison' });
|
||||
|
||||
@@ -17,6 +17,7 @@ import globalConfReducer from '../features/globalConf/globalConfSlice';
|
||||
import { subscribeApi } from '../features/subsribeConfigManager/subscribeConfigSlice';
|
||||
import { targetNameApi } from '../features/targetName/targetNameSlice';
|
||||
import { weightApi } from '../features/weightConfig/weightConfigSlice';
|
||||
import { cookieApi, cookieTargetApi } from '../features/cookieManager/cookieConfigSlice';
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
auth: authReducer,
|
||||
@@ -24,6 +25,8 @@ const rootReducer = combineReducers({
|
||||
[subscribeApi.reducerPath]: subscribeApi.reducer,
|
||||
[weightApi.reducerPath]: weightApi.reducer,
|
||||
[targetNameApi.reducerPath]: targetNameApi.reducer,
|
||||
[cookieApi.reducerPath]: cookieApi.reducer,
|
||||
[cookieTargetApi.reducerPath]: cookieTargetApi.reducer,
|
||||
});
|
||||
|
||||
const persistConfig = {
|
||||
@@ -43,7 +46,10 @@ export const store = configureStore({
|
||||
})
|
||||
.concat(subscribeApi.middleware)
|
||||
.concat(weightApi.middleware)
|
||||
.concat(targetNameApi.middleware),
|
||||
.concat(targetNameApi.middleware)
|
||||
.concat(cookieApi.middleware)
|
||||
.concat(cookieTargetApi.middleware),
|
||||
|
||||
});
|
||||
|
||||
export const persistor = persistStore(store);
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import React, { useState } from 'react';
|
||||
import { Form, Input, Modal } from '@arco-design/web-react';
|
||||
import { useNewCookieMutation } from './cookieConfigSlice';
|
||||
import { useAppDispatch } from '../../app/hooks';
|
||||
import validateCookie from './cookieValidateReq';
|
||||
|
||||
interface CookieAddModalProps {
|
||||
visible: boolean;
|
||||
setVisible: (arg0: boolean) => void;
|
||||
siteName: string;
|
||||
}
|
||||
|
||||
function CookieAddModal({ visible, setVisible, siteName }: CookieAddModalProps) {
|
||||
const FormItem = Form.Item;
|
||||
const [content, setContent] = useState<string>('');
|
||||
const [confirmLoading, setConfirmLoading] = useState(false);
|
||||
const [newCookie] = useNewCookieMutation();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const onSubmit = () => {
|
||||
const postPromise: ReturnType<typeof newCookie> = newCookie({ siteName, content });
|
||||
setConfirmLoading(true);
|
||||
postPromise.then(() => {
|
||||
setConfirmLoading(false);
|
||||
setVisible(false);
|
||||
setContent('');
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="添加 Cookie"
|
||||
visible={visible}
|
||||
onCancel={() => setVisible(false)}
|
||||
confirmLoading={confirmLoading}
|
||||
onOk={onSubmit}
|
||||
style={{ maxWidth: '90vw' }}
|
||||
>
|
||||
|
||||
<Form autoComplete="off">
|
||||
<FormItem label="站点" required>
|
||||
<Input placeholder="Please enter site name" value={siteName} disabled />
|
||||
</FormItem>
|
||||
<FormItem
|
||||
label="Cookie"
|
||||
required
|
||||
field="content"
|
||||
hasFeedback
|
||||
rules={[
|
||||
{
|
||||
validator: (value, callback) => new Promise<void>((resolve) => {
|
||||
dispatch(validateCookie(siteName, value))
|
||||
.then((res) => {
|
||||
if (res) {
|
||||
callback();
|
||||
} else {
|
||||
callback('Cookie 格式错误');
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}),
|
||||
},
|
||||
]}
|
||||
|
||||
>
|
||||
<Input.TextArea
|
||||
placeholder="请输入 Cookie"
|
||||
value={content}
|
||||
onChange={setContent}
|
||||
/>
|
||||
</FormItem>
|
||||
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
|
||||
export default CookieAddModal;
|
||||
@@ -0,0 +1,128 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Button, Empty, Form, Input, Modal, Space, Table,
|
||||
} from '@arco-design/web-react';
|
||||
import { useDeleteCookieTargetMutation, useGetCookieTargetsQuery } from './cookieConfigSlice';
|
||||
import { Cookie, CookieTarget } from '../../utils/type';
|
||||
import CookieTargetModal from '../cookieTargetManager/CookieTargetModal';
|
||||
|
||||
interface CookieEditModalProps {
|
||||
visible: boolean;
|
||||
setVisible: (arg0: boolean) => void;
|
||||
cookie: Cookie | null
|
||||
}
|
||||
|
||||
function CookieEditModal({ visible, setVisible, cookie }: CookieEditModalProps) {
|
||||
if (!cookie) {
|
||||
return <Empty />;
|
||||
}
|
||||
const FormItem = Form.Item;
|
||||
// const [confirmLoading, setConfirmLoading] = useState(false);
|
||||
const [deleteCookieTarget] = useDeleteCookieTargetMutation();
|
||||
// 获取 Cookie Target
|
||||
const { data: cookieTargets } = useGetCookieTargetsQuery({ cookieId: cookie.id });
|
||||
|
||||
// 添加 Cookie Target
|
||||
const [showAddCookieTargetModal, setShowAddCookieTargetModal] = useState(false);
|
||||
const handleAddCookieTarget = () => () => {
|
||||
setShowAddCookieTargetModal(true);
|
||||
};
|
||||
|
||||
// 删除 Cookie Target
|
||||
const handleDelete = (record: CookieTarget) => () => {
|
||||
deleteCookieTarget({
|
||||
cookieId: record.cookie_id,
|
||||
target: record.target.target,
|
||||
platformName: record.target.platform_name,
|
||||
});
|
||||
};
|
||||
const columns = [
|
||||
{
|
||||
title: '平台名称',
|
||||
dataIndex: 'target.platform_name',
|
||||
},
|
||||
{
|
||||
title: '订阅名称',
|
||||
dataIndex: 'target.target_name',
|
||||
|
||||
},
|
||||
{
|
||||
title: 'Cookie ID',
|
||||
dataIndex: 'cookie_id',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
dataIndex: 'op',
|
||||
render: (_: null, record: CookieTarget) => (
|
||||
<Space size="small">
|
||||
<Button type="text" status="danger" onClick={handleDelete(record)}>删除</Button>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
title="编辑 Cookie"
|
||||
visible={visible}
|
||||
onCancel={() => setVisible(false)}
|
||||
// confirmLoading={confirmLoading}
|
||||
onOk={() => setVisible(false)}
|
||||
style={{ maxWidth: '90vw', minWidth: '50vw' }}
|
||||
>
|
||||
<Form autoComplete="off">
|
||||
<FormItem label="Cookie ID">
|
||||
<Input disabled value={cookie.id.toString()} />
|
||||
</FormItem>
|
||||
<FormItem label="Cookie 名称">
|
||||
<Input value={cookie.cookie_name} disabled />
|
||||
</FormItem>
|
||||
<FormItem label="所属站点">
|
||||
<Input value={cookie.site_name} disabled />
|
||||
</FormItem>
|
||||
<FormItem label="内容">
|
||||
<Input.TextArea
|
||||
value={cookie.content}
|
||||
disabled
|
||||
/>
|
||||
</FormItem>
|
||||
|
||||
<FormItem label="标签">
|
||||
<Input.TextArea
|
||||
value={JSON.stringify(cookie.tags)}
|
||||
disabled
|
||||
/>
|
||||
</FormItem>
|
||||
|
||||
<FormItem label="最后使用时间">
|
||||
<Input value={cookie.last_usage.toString()} disabled />
|
||||
</FormItem>
|
||||
<FormItem label="状态">
|
||||
<Input value={cookie.status} disabled />
|
||||
</FormItem>
|
||||
<FormItem label="冷却时间(毫秒)">
|
||||
<Input value={cookie.cd_milliseconds.toString()} disabled />
|
||||
</FormItem>
|
||||
|
||||
</Form>
|
||||
|
||||
<Button type="primary" onClick={handleAddCookieTarget()}>关联 Cookie</Button>
|
||||
<Table
|
||||
columns={columns}
|
||||
data={cookieTargets}
|
||||
rowKey={(record: CookieTarget) => `${record.target.platform_name}-${record.target.target}`}
|
||||
scroll={{ x: true }}
|
||||
/>
|
||||
</Modal>
|
||||
|
||||
<CookieTargetModal
|
||||
cookie={cookie}
|
||||
visible={showAddCookieTargetModal}
|
||||
setVisible={setShowAddCookieTargetModal}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default CookieEditModal;
|
||||
@@ -0,0 +1,13 @@
|
||||
.list-actions-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
transition: all 0.1s;
|
||||
}
|
||||
|
||||
.list-actions-icon:hover {
|
||||
background-color: var(--color-fill-3);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
Button,
|
||||
Table, TableColumnProps, Typography, Space, Popconfirm,
|
||||
} from '@arco-design/web-react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useGetCookiesQuery, useDeleteCookieMutation } from './cookieConfigSlice';
|
||||
import './CookieManager.css';
|
||||
import { Cookie } from '../../utils/type';
|
||||
import CookieAddModal from './CookieAddModal';
|
||||
import CookieEditModal from './CookieEditModal';
|
||||
|
||||
export default function CookieManager() {
|
||||
const { siteName } = useParams();
|
||||
const { data: cookieDict } = useGetCookiesQuery();
|
||||
const cookiesList = cookieDict ? Object.values(cookieDict) : [];
|
||||
|
||||
// 添加cookie
|
||||
const [showAddModal, setShowAddModal] = React.useState(false);
|
||||
const handleAddCookie = () => () => {
|
||||
setShowAddModal(true);
|
||||
};
|
||||
|
||||
// 删除cookie
|
||||
const [deleteCookie] = useDeleteCookieMutation();
|
||||
const handleDelCookie = (cookieId: string) => () => {
|
||||
deleteCookie({
|
||||
cookieId,
|
||||
});
|
||||
};
|
||||
|
||||
// 编辑cookie
|
||||
const [showEditModal, setShowEditModal] = React.useState(false);
|
||||
const [editCookie, setEditCookie] = React.useState<Cookie | null>(null);
|
||||
const handleEditCookie = (cookie: Cookie) => () => {
|
||||
setEditCookie(cookie);
|
||||
setShowEditModal(true);
|
||||
};
|
||||
|
||||
let data = [];
|
||||
if (siteName) {
|
||||
data = cookiesList.filter((tSite) => tSite.site_name === siteName);
|
||||
}
|
||||
|
||||
const columns: TableColumnProps[] = [
|
||||
{
|
||||
title: 'ID',
|
||||
dataIndex: 'id',
|
||||
},
|
||||
{
|
||||
title: 'Cookie 名称',
|
||||
dataIndex: 'cookie_name',
|
||||
},
|
||||
{
|
||||
title: '所属站点',
|
||||
dataIndex: 'site_name',
|
||||
},
|
||||
{
|
||||
title: '最后使用时间',
|
||||
dataIndex: 'last_usage',
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
},
|
||||
{
|
||||
title: 'CD',
|
||||
dataIndex: 'cd_milliseconds',
|
||||
}, {
|
||||
title: '操作',
|
||||
dataIndex: 'op',
|
||||
render: (_: null, record: Cookie) => (
|
||||
<Space size="small">
|
||||
<Popconfirm
|
||||
title={`确定删除 Cookie ${record.cookie_name} ?`}
|
||||
onOk={handleDelCookie(record.id.toString())}
|
||||
>
|
||||
<span className="list-actions-icon">
|
||||
{/* <IconDelete /> */}
|
||||
<Button type="text" status="danger">删除</Button>
|
||||
</span>
|
||||
</Popconfirm>
|
||||
<Button type="text" onClick={handleEditCookie(record)}>编辑</Button>
|
||||
</Space>
|
||||
),
|
||||
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
|
||||
<Typography.Title heading={4} style={{ margin: '15px' }}>Cookie 管理</Typography.Title>
|
||||
|
||||
<Button
|
||||
style={{ width: '90px', margin: '20px 10px' }}
|
||||
type="primary"
|
||||
onClick={handleAddCookie()}
|
||||
>
|
||||
添加
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Table columns={columns} data={data} />
|
||||
<CookieAddModal visible={showAddModal} setVisible={setShowAddModal} siteName={siteName || ''} />
|
||||
<CookieEditModal visible={showEditModal} setVisible={setShowEditModal} cookie={editCookie} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
import { createApi } from '@reduxjs/toolkit/query/react';
|
||||
import {
|
||||
StatusResp, Cookie, NewCookieParam,
|
||||
DelCookieParam, CookieTarget, NewCookieTargetParam, DelCookieTargetParam,
|
||||
} from '../../utils/type';
|
||||
import { baseQueryWithAuth } from '../auth/authQuery';
|
||||
|
||||
export const cookieApi = createApi({
|
||||
reducerPath: 'cookie',
|
||||
baseQuery: baseQueryWithAuth,
|
||||
tagTypes: ['Cookie'],
|
||||
endpoints: (builder) => ({
|
||||
getCookies: builder.query<Cookie, void>({
|
||||
query: () => '/cookie',
|
||||
providesTags: ['Cookie'],
|
||||
}),
|
||||
newCookie: builder.mutation<StatusResp, NewCookieParam>({
|
||||
query: ({ siteName, content }) => ({
|
||||
method: 'POST',
|
||||
url: `/cookie?site_name=${siteName}&content=${content}`,
|
||||
}),
|
||||
invalidatesTags: ['Cookie'],
|
||||
}),
|
||||
deleteCookie: builder.mutation<StatusResp, DelCookieParam>({
|
||||
query: ({ cookieId }) => ({
|
||||
method: 'DELETE',
|
||||
url: `/cookie/${cookieId}`,
|
||||
}),
|
||||
invalidatesTags: ['Cookie'],
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const {
|
||||
useGetCookiesQuery, useNewCookieMutation, useDeleteCookieMutation,
|
||||
} = cookieApi;
|
||||
|
||||
export const cookieTargetApi = createApi({
|
||||
reducerPath: 'cookieTarget',
|
||||
baseQuery: baseQueryWithAuth,
|
||||
tagTypes: ['CookieTarget'],
|
||||
endpoints: (builder) => ({
|
||||
getCookieTargets: builder.query<CookieTarget[], { cookieId: number }>({
|
||||
query: ({ cookieId }) => `/cookie_target?cookie_id=${cookieId}`,
|
||||
providesTags: ['CookieTarget'],
|
||||
}),
|
||||
newCookieTarget: builder.mutation<StatusResp, NewCookieTargetParam>({
|
||||
query: ({ platformName, target, cookieId }) => ({
|
||||
method: 'POST',
|
||||
url: `/cookie_target?platform_name=${platformName}&target=${encodeURIComponent(target)}&cookie_id=${cookieId}`,
|
||||
}),
|
||||
invalidatesTags: ['CookieTarget'],
|
||||
}),
|
||||
deleteCookieTarget: builder.mutation<StatusResp, DelCookieTargetParam>({
|
||||
query: ({ platformName, target, cookieId }) => ({
|
||||
method: 'DELETE',
|
||||
url: `/cookie_target?platform_name=${platformName}&target=${encodeURIComponent(target)}&cookie_id=${cookieId}`,
|
||||
}),
|
||||
invalidatesTags: ['CookieTarget'],
|
||||
}),
|
||||
}),
|
||||
});
|
||||
|
||||
export const {
|
||||
useGetCookieTargetsQuery, useNewCookieTargetMutation, useDeleteCookieTargetMutation,
|
||||
} = cookieTargetApi;
|
||||
@@ -0,0 +1,20 @@
|
||||
import { AppThunk } from '../../app/store';
|
||||
import { baseUrl } from '../../utils/urls';
|
||||
|
||||
// eslint-disable-next-line
|
||||
export const validCookie =
|
||||
(siteName: string, content: string): AppThunk<Promise<string>> => async (_, getState) => {
|
||||
const url = `${baseUrl}cookie/validate?site_name=${siteName}&content=${content}`;
|
||||
const state = getState();
|
||||
const authToken = state.auth.token;
|
||||
const res = await fetch(url, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${authToken}`,
|
||||
},
|
||||
method: 'POST',
|
||||
});
|
||||
const resObj = await res.json();
|
||||
return resObj.ok;
|
||||
};
|
||||
|
||||
export default validCookie;
|
||||
@@ -0,0 +1,109 @@
|
||||
import React
|
||||
from 'react';
|
||||
import {
|
||||
Empty, Form, Modal, Select,
|
||||
} from '@arco-design/web-react';
|
||||
import { Cookie, SubscribeConfig, SubscribeGroupDetail } from '../../utils/type';
|
||||
import { useNewCookieTargetMutation } from '../cookieManager/cookieConfigSlice';
|
||||
import { useGetSubsQuery } from '../subsribeConfigManager/subscribeConfigSlice';
|
||||
import { useAppSelector } from '../../app/hooks';
|
||||
import { selectPlatformConf } from '../globalConf/globalConfSlice';
|
||||
|
||||
interface SubscribeModalProp {
|
||||
cookie:Cookie| null
|
||||
visible: boolean;
|
||||
setVisible: (arg0: boolean) => void;
|
||||
}
|
||||
|
||||
export default function CookieTargetModal({
|
||||
cookie, visible, setVisible,
|
||||
}: SubscribeModalProp) {
|
||||
if (!cookie) {
|
||||
return <Empty />;
|
||||
}
|
||||
const [newCookieTarget] = useNewCookieTargetMutation();
|
||||
const FormItem = Form.Item;
|
||||
|
||||
// 筛选出当前Cookie支持的平台
|
||||
const platformConf = useAppSelector(selectPlatformConf);
|
||||
const platformThatSiteSupport = Object.values(platformConf).reduce((p, c) => {
|
||||
if (c.siteName in p) {
|
||||
p[c.siteName].push(c.platformName);
|
||||
} else {
|
||||
p[c.siteName] = [c.platformName];
|
||||
}
|
||||
return p;
|
||||
}, {} as Record<string, string[]>);
|
||||
const supportedPlatform = platformThatSiteSupport[cookie.site_name];
|
||||
|
||||
const { data: subs } = useGetSubsQuery();
|
||||
const pureSubs:SubscribeConfig[] = subs ? Object.values(subs)
|
||||
.reduce((
|
||||
pv:Array<SubscribeConfig>,
|
||||
cv:SubscribeGroupDetail,
|
||||
) => pv.concat(cv.subscribes), []) : [];
|
||||
const filteredSubs = pureSubs.filter((sub) => supportedPlatform.includes(sub.platformName));
|
||||
const [index, setIndex] = React.useState(-1);
|
||||
|
||||
const handleSubmit = (idx:number) => {
|
||||
const postPromise: ReturnType<typeof newCookieTarget> = newCookieTarget({
|
||||
cookieId: cookie.id,
|
||||
platformName: filteredSubs[idx].platformName,
|
||||
target: filteredSubs[idx].target,
|
||||
});
|
||||
postPromise.then(() => {
|
||||
setVisible(false);
|
||||
});
|
||||
};
|
||||
const { Option } = Select;
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title="关联 Cookie"
|
||||
visible={visible}
|
||||
onCancel={() => setVisible(false)}
|
||||
onOk={() => handleSubmit(index)}
|
||||
>
|
||||
|
||||
<Form>
|
||||
<FormItem label="平台">
|
||||
|
||||
<Select
|
||||
placeholder="选择要关联的平台"
|
||||
style={{ width: '100%' }}
|
||||
onChange={setIndex}
|
||||
>
|
||||
{supportedPlatform.length
|
||||
&& supportedPlatform.map((sub, idx) => (
|
||||
<Option
|
||||
key={JSON.stringify(sub)}
|
||||
value={idx}
|
||||
>
|
||||
{sub}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
|
||||
</FormItem>
|
||||
<FormItem label="订阅目标" required>
|
||||
<Select
|
||||
placeholder="选择要关联的订阅目标"
|
||||
style={{ width: '100%' }}
|
||||
onChange={setIndex}
|
||||
>
|
||||
{filteredSubs.length
|
||||
&& filteredSubs.map((sub, idx) => (
|
||||
<Option
|
||||
key={JSON.stringify(sub)}
|
||||
value={idx}
|
||||
>
|
||||
{sub.targetName}
|
||||
</Option>
|
||||
))}
|
||||
</Select>
|
||||
</FormItem>
|
||||
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { globalConfUrl } from '../../utils/urls';
|
||||
const initialState = {
|
||||
loaded: false,
|
||||
platformConf: {},
|
||||
siteConf: {},
|
||||
} as GlobalConf;
|
||||
|
||||
export const loadGlobalConf = createAsyncThunk(
|
||||
@@ -24,6 +25,7 @@ export const globalConfSlice = createSlice({
|
||||
builder
|
||||
.addCase(loadGlobalConf.fulfilled, (state, payload) => {
|
||||
state.platformConf = payload.payload.platformConf;
|
||||
state.siteConf = payload.payload.siteConf;
|
||||
state.loaded = true;
|
||||
});
|
||||
},
|
||||
@@ -33,3 +35,4 @@ export default globalConfSlice.reducer;
|
||||
|
||||
export const selectGlobalConfLoaded = (state: RootState) => state.globalConf.loaded;
|
||||
export const selectPlatformConf = (state: RootState) => state.globalConf.platformConf;
|
||||
export const selectSiteConf = (state: RootState) => state.globalConf.siteConf;
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
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 {
|
||||
IconRobot, IconDashboard, IconIdcard,
|
||||
} from '@arco-design/web-react/icon';
|
||||
import './Home.css';
|
||||
// import SubscribeManager from '../features/subsribeConfigManager/SubscribeManager';
|
||||
import {
|
||||
Link, Navigate, Outlet, useLocation, useNavigate,
|
||||
} from 'react-router-dom';
|
||||
import { useAppSelector } from '../app/hooks';
|
||||
import { selectIsLogin } from '../features/auth/authSlice';
|
||||
import { selectSiteConf } from '../features/globalConf/globalConfSlice';
|
||||
|
||||
export default function Home() {
|
||||
const location = useLocation();
|
||||
@@ -23,6 +25,12 @@ export default function Home() {
|
||||
if (path !== '/home/groups' && !path.startsWith('/home/groups/') && path !== '/home/weight') {
|
||||
navigate('/home/groups');
|
||||
}
|
||||
if (path === '/home/cookie') {
|
||||
navigate('/home/cookie');
|
||||
}
|
||||
if (path.startsWith('/home/cookie/')) {
|
||||
navigate(path);
|
||||
}
|
||||
}, [path]);
|
||||
|
||||
let currentKey = '';
|
||||
@@ -30,6 +38,8 @@ export default function Home() {
|
||||
currentKey = 'groups';
|
||||
} else if (path.startsWith('/home/groups/')) {
|
||||
currentKey = 'subs';
|
||||
} else if (path.startsWith('/home/cookie/')) {
|
||||
currentKey = path.substring(6);
|
||||
}
|
||||
|
||||
const [selectedTab, changeSelectTab] = useState(currentKey);
|
||||
@@ -40,6 +50,10 @@ export default function Home() {
|
||||
navigate('/home/groups');
|
||||
} else if (tab === 'weight') {
|
||||
navigate('/home/weight');
|
||||
} else if (tab === 'cookie') {
|
||||
navigate('/home/cookie');
|
||||
} else if (tab.startsWith('cookie/')) {
|
||||
navigate(`/home/${tab}`);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -80,7 +94,22 @@ export default function Home() {
|
||||
</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
);
|
||||
} else if (path.startsWith('/home/cookie')) {
|
||||
breadcrumbContent = (
|
||||
<Breadcrumb style={{ margin: '16px 0' }}>
|
||||
<Breadcrumb.Item>
|
||||
<Link to="/home/cookie">
|
||||
<IconIdcard />
|
||||
Cookie 管理
|
||||
</Link>
|
||||
</Breadcrumb.Item>
|
||||
</Breadcrumb>
|
||||
);
|
||||
}
|
||||
const MenuItem = Menu.Item;
|
||||
const { SubMenu } = Menu;
|
||||
const siteConf = useAppSelector(selectSiteConf);
|
||||
|
||||
return (
|
||||
<Layout className="layout-collapse-demo">
|
||||
<Layout.Header>
|
||||
@@ -95,12 +124,29 @@ export default function Home() {
|
||||
>
|
||||
<Menu
|
||||
defaultSelectedKeys={[selectedTab]}
|
||||
onClickMenuItem={(key) => { handleTabSelect(key); }}
|
||||
onClickMenuItem={(key) => {
|
||||
handleTabSelect(key);
|
||||
}}
|
||||
>
|
||||
<Menu.Item key="groups">
|
||||
<IconRobot />
|
||||
订阅管理
|
||||
</Menu.Item>
|
||||
<SubMenu
|
||||
key="cookie"
|
||||
title={(
|
||||
<>
|
||||
<IconIdcard />
|
||||
Cookie 管理
|
||||
</>
|
||||
)}
|
||||
>
|
||||
{Object.values(siteConf).filter((site) => site.enable_cookie).map((site) => (
|
||||
<MenuItem key={`cookie/${site.name}`}>
|
||||
{site.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</SubMenu>
|
||||
<Menu.Item key="weight">
|
||||
<IconDashboard />
|
||||
调度权重
|
||||
@@ -109,7 +155,7 @@ export default function Home() {
|
||||
</Layout.Sider>
|
||||
<Layout.Content style={{ padding: '0 1em' }}>
|
||||
<Layout style={{ height: '100%' }}>
|
||||
{ breadcrumbContent }
|
||||
{breadcrumbContent}
|
||||
<Layout.Content style={{ margin: '0.5em', padding: '2em' }}>
|
||||
<Outlet />
|
||||
</Layout.Content>
|
||||
|
||||
@@ -4,8 +4,10 @@ export interface TokenResp {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface GlobalConf {
|
||||
platformConf: AllPlatformConf;
|
||||
siteConf: AllSiteConf;
|
||||
loaded: boolean;
|
||||
}
|
||||
|
||||
@@ -13,6 +15,10 @@ export interface AllPlatformConf {
|
||||
[idx: string]: PlatformConfig;
|
||||
}
|
||||
|
||||
export interface AllSiteConf {
|
||||
[idx: string]: SiteConfig;
|
||||
}
|
||||
|
||||
export interface CategoryConfig {
|
||||
[idx: number]: string;
|
||||
}
|
||||
@@ -22,9 +28,15 @@ export interface PlatformConfig {
|
||||
categories: CategoryConfig;
|
||||
enabledTag: boolean;
|
||||
platformName: string;
|
||||
siteName: string;
|
||||
hasTarget: boolean;
|
||||
}
|
||||
|
||||
export interface SiteConfig {
|
||||
name: string;
|
||||
enable_cookie: string;
|
||||
}
|
||||
|
||||
export interface SubscribeConfig {
|
||||
platformName: string;
|
||||
target: string;
|
||||
@@ -69,3 +81,48 @@ export interface PlatformWeightConfigResp {
|
||||
platform_name: string;
|
||||
weight: WeightConfig;
|
||||
}
|
||||
|
||||
export interface Target {
|
||||
platform_name: string;
|
||||
target_name: string;
|
||||
target: string;
|
||||
}
|
||||
|
||||
export interface Cookie {
|
||||
id: number;
|
||||
site_name: string;
|
||||
content: string;
|
||||
cookie_name: string;
|
||||
last_usage: Date;
|
||||
status: string;
|
||||
cd_milliseconds: number;
|
||||
is_universal: boolean;
|
||||
is_anonymous: boolean;
|
||||
tags: { [key: string]: string };
|
||||
}
|
||||
|
||||
export interface CookieTarget {
|
||||
target: Target;
|
||||
cookie_id: number;
|
||||
}
|
||||
|
||||
export interface NewCookieParam {
|
||||
siteName: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export interface DelCookieParam {
|
||||
cookieId: string;
|
||||
}
|
||||
|
||||
export interface NewCookieTargetParam {
|
||||
platformName: string;
|
||||
target: string;
|
||||
cookieId: number;
|
||||
}
|
||||
|
||||
export interface DelCookieTargetParam {
|
||||
platformName: string;
|
||||
target: string;
|
||||
cookieId: number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user