mirror of
https://github.com/suyiiyii/nonebot-bison.git
synced 2025-06-04 02:26:11 +08:00
✨ 添加 Cookie 界面
This commit is contained in:
parent
54c9020c36
commit
db4b848e3f
@ -17,6 +17,7 @@ import globalConfReducer from '../features/globalConf/globalConfSlice';
|
|||||||
import { subscribeApi } from '../features/subsribeConfigManager/subscribeConfigSlice';
|
import { subscribeApi } from '../features/subsribeConfigManager/subscribeConfigSlice';
|
||||||
import { targetNameApi } from '../features/targetName/targetNameSlice';
|
import { targetNameApi } from '../features/targetName/targetNameSlice';
|
||||||
import { weightApi } from '../features/weightConfig/weightConfigSlice';
|
import { weightApi } from '../features/weightConfig/weightConfigSlice';
|
||||||
|
import { cookieApi } from '../features/cookieManager/cookieConfigSlice';
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
auth: authReducer,
|
auth: authReducer,
|
||||||
@ -24,6 +25,7 @@ const rootReducer = combineReducers({
|
|||||||
[subscribeApi.reducerPath]: subscribeApi.reducer,
|
[subscribeApi.reducerPath]: subscribeApi.reducer,
|
||||||
[weightApi.reducerPath]: weightApi.reducer,
|
[weightApi.reducerPath]: weightApi.reducer,
|
||||||
[targetNameApi.reducerPath]: targetNameApi.reducer,
|
[targetNameApi.reducerPath]: targetNameApi.reducer,
|
||||||
|
[cookieApi.reducerPath]: cookieApi.reducer,
|
||||||
});
|
});
|
||||||
|
|
||||||
const persistConfig = {
|
const persistConfig = {
|
||||||
@ -43,7 +45,8 @@ export const store = configureStore({
|
|||||||
})
|
})
|
||||||
.concat(subscribeApi.middleware)
|
.concat(subscribeApi.middleware)
|
||||||
.concat(weightApi.middleware)
|
.concat(weightApi.middleware)
|
||||||
.concat(targetNameApi.middleware),
|
.concat(targetNameApi.middleware)
|
||||||
|
.concat(cookieApi.middleware),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const persistor = persistStore(store);
|
export const persistor = persistStore(store);
|
||||||
|
42
admin-frontend/src/features/cookieManager/CookieModal.tsx
Normal file
42
admin-frontend/src/features/cookieManager/CookieModal.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { Form, Input, Modal } from '@arco-design/web-react';
|
||||||
|
|
||||||
|
interface CookieModalProps {
|
||||||
|
visible: boolean;
|
||||||
|
setVisible: (arg0: boolean) => void;
|
||||||
|
siteName: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function CookieModal({ visible, setVisible, siteName }: CookieModalProps) {
|
||||||
|
const FormItem = Form.Item;
|
||||||
|
const [content, setContent] = useState<string>('');
|
||||||
|
// const [confirmLoading, setConfirmLoading] = useState(false);
|
||||||
|
const [confirmLoading] = useState(false);
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title="添加 Cookie"
|
||||||
|
visible={visible}
|
||||||
|
onCancel={() => setVisible(false)}
|
||||||
|
confirmLoading={confirmLoading}
|
||||||
|
onOk={() => setVisible(false)}
|
||||||
|
style={{ maxWidth: '90vw' }}
|
||||||
|
>
|
||||||
|
|
||||||
|
<Form autoComplete="off">
|
||||||
|
<FormItem label="Site Name" required>
|
||||||
|
<Input placeholder="Please enter site name" value={siteName} disabled />
|
||||||
|
</FormItem>
|
||||||
|
<FormItem label="Content" required>
|
||||||
|
<Input.TextArea
|
||||||
|
placeholder="Please enter content"
|
||||||
|
value={content}
|
||||||
|
onChange={setContent}
|
||||||
|
/>
|
||||||
|
</FormItem>
|
||||||
|
|
||||||
|
</Form>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CookieModal;
|
@ -0,0 +1,35 @@
|
|||||||
|
import { createApi } from '@reduxjs/toolkit/query/react';
|
||||||
|
import {
|
||||||
|
StatusResp, Cookie, NewCookieParam, DelCookieParam,
|
||||||
|
} 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: ({ siteName, cookieId }) => ({
|
||||||
|
method: 'DELETE',
|
||||||
|
url: `/cookie/${cookieId}?site_name=${siteName}`,
|
||||||
|
}),
|
||||||
|
invalidatesTags: ['Cookie'],
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {
|
||||||
|
useGetCookiesQuery, useNewCookieMutation, useDeleteCookieMutation,
|
||||||
|
} = cookieApi;
|
@ -1,5 +1,86 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import {
|
||||||
|
Button,
|
||||||
|
Card, Descriptions, Grid, List, Popover, Typography,
|
||||||
|
} from '@arco-design/web-react';
|
||||||
|
import { selectSiteConf } from '../globalConf/globalConfSlice';
|
||||||
|
import { useAppSelector } from '../../app/hooks';
|
||||||
|
import { Cookie, SiteConfig } from '../../utils/type';
|
||||||
|
import { useGetCookiesQuery } from './cookieConfigSlice';
|
||||||
|
import CookieModal from './CookieModal';
|
||||||
|
|
||||||
|
interface CookieSite {
|
||||||
|
site: SiteConfig;
|
||||||
|
cookies: Cookie[];
|
||||||
|
}
|
||||||
|
|
||||||
export default function CookieManager() {
|
export default function CookieManager() {
|
||||||
return <div>下个版本再写啦啦啦啦</div>;
|
const siteConf = useAppSelector(selectSiteConf);
|
||||||
|
const { data: cookieDict } = useGetCookiesQuery();
|
||||||
|
const cookiesList = cookieDict ? Object.values(cookieDict) : [];
|
||||||
|
const cookieSite = Object.values(siteConf).filter((site) => site.enable_cookie);
|
||||||
|
const cookieSiteList: CookieSite[] = cookieSite.map((site) => ({
|
||||||
|
site,
|
||||||
|
cookies: cookiesList.filter((cookie) => cookie.site_name === site.name),
|
||||||
|
}));
|
||||||
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
const [siteName, setSiteName] = useState('');
|
||||||
|
|
||||||
|
const handleAddCookie = (newSiteName: string) => () => {
|
||||||
|
console.log(newSiteName);
|
||||||
|
setSiteName(newSiteName);
|
||||||
|
setShowModal(true);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Typography.Title heading={4} style={{ margin: '15px' }}>Cookie 管理</Typography.Title>
|
||||||
|
|
||||||
|
<Grid.Row gutter={20}>
|
||||||
|
{cookieSiteList && cookieSiteList.map(({ cookies, site }) => (
|
||||||
|
<Grid.Col xs={24} sm={12} md={8} lg={6} key={site.name} style={{ margin: '1em 0' }}>
|
||||||
|
<Card
|
||||||
|
title={site.name}
|
||||||
|
extra={(
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={handleAddCookie(site.name)}
|
||||||
|
>
|
||||||
|
添加
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
|
||||||
|
{cookies.map((cookie) => (
|
||||||
|
<List>
|
||||||
|
|
||||||
|
<Popover
|
||||||
|
key={cookie.id}
|
||||||
|
title={cookie.friendly_name}
|
||||||
|
content={(
|
||||||
|
<Descriptions
|
||||||
|
column={1}
|
||||||
|
title="Cookie 详情"
|
||||||
|
data={Object.entries(cookie).map((entry) => ({
|
||||||
|
label: entry[0].toString(),
|
||||||
|
value: entry[1].toString(),
|
||||||
|
}))}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<List.Item key={cookie.id}>
|
||||||
|
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
|
||||||
|
{cookie.friendly_name}
|
||||||
|
<Button type="primary" status="danger">删除</Button>
|
||||||
|
</div>
|
||||||
|
</List.Item>
|
||||||
|
</Popover>
|
||||||
|
</List>
|
||||||
|
))}
|
||||||
|
</Card>
|
||||||
|
</Grid.Col>
|
||||||
|
))}
|
||||||
|
</Grid.Row>
|
||||||
|
<CookieModal visible={showModal} setVisible={setShowModal} siteName={siteName} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import { globalConfUrl } from '../../utils/urls';
|
|||||||
const initialState = {
|
const initialState = {
|
||||||
loaded: false,
|
loaded: false,
|
||||||
platformConf: {},
|
platformConf: {},
|
||||||
|
siteConf: {},
|
||||||
} as GlobalConf;
|
} as GlobalConf;
|
||||||
|
|
||||||
export const loadGlobalConf = createAsyncThunk(
|
export const loadGlobalConf = createAsyncThunk(
|
||||||
@ -24,6 +25,7 @@ export const globalConfSlice = createSlice({
|
|||||||
builder
|
builder
|
||||||
.addCase(loadGlobalConf.fulfilled, (state, payload) => {
|
.addCase(loadGlobalConf.fulfilled, (state, payload) => {
|
||||||
state.platformConf = payload.payload.platformConf;
|
state.platformConf = payload.payload.platformConf;
|
||||||
|
state.siteConf = payload.payload.siteConf;
|
||||||
state.loaded = true;
|
state.loaded = true;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -33,3 +35,4 @@ export default globalConfSlice.reducer;
|
|||||||
|
|
||||||
export const selectGlobalConfLoaded = (state: RootState) => state.globalConf.loaded;
|
export const selectGlobalConfLoaded = (state: RootState) => state.globalConf.loaded;
|
||||||
export const selectPlatformConf = (state: RootState) => state.globalConf.platformConf;
|
export const selectPlatformConf = (state: RootState) => state.globalConf.platformConf;
|
||||||
|
export const selectSiteConf = (state: RootState) => state.globalConf.siteConf;
|
||||||
|
@ -6,6 +6,7 @@ export interface TokenResp {
|
|||||||
}
|
}
|
||||||
export interface GlobalConf {
|
export interface GlobalConf {
|
||||||
platformConf: AllPlatformConf;
|
platformConf: AllPlatformConf;
|
||||||
|
siteConf: AllSiteConf;
|
||||||
loaded: boolean;
|
loaded: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13,6 +14,10 @@ export interface AllPlatformConf {
|
|||||||
[idx: string]: PlatformConfig;
|
[idx: string]: PlatformConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AllSiteConf {
|
||||||
|
[idx: string]: SiteConfig;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CategoryConfig {
|
export interface CategoryConfig {
|
||||||
[idx: number]: string;
|
[idx: number]: string;
|
||||||
}
|
}
|
||||||
@ -25,6 +30,11 @@ export interface PlatformConfig {
|
|||||||
hasTarget: boolean;
|
hasTarget: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SiteConfig {
|
||||||
|
name: string
|
||||||
|
enable_cookie: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface SubscribeConfig {
|
export interface SubscribeConfig {
|
||||||
platformName: string;
|
platformName: string;
|
||||||
target: string;
|
target: string;
|
||||||
@ -69,3 +79,36 @@ export interface PlatformWeightConfigResp {
|
|||||||
platform_name: string;
|
platform_name: string;
|
||||||
weight: WeightConfig;
|
weight: WeightConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Target {
|
||||||
|
platform_name: string;
|
||||||
|
target_name: string;
|
||||||
|
target: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Cookie {
|
||||||
|
id: number;
|
||||||
|
site_name: string;
|
||||||
|
friendly_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;
|
||||||
|
cookieId: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NewCookieParam {
|
||||||
|
siteName: string
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DelCookieParam {
|
||||||
|
siteName: string
|
||||||
|
cookieId: string
|
||||||
|
}
|
||||||
|
@ -210,10 +210,11 @@ async def update_weigth_config(platformName: str, target: str, weight_config: We
|
|||||||
|
|
||||||
|
|
||||||
@router.get("/cookie", dependencies=[Depends(check_is_superuser)])
|
@router.get("/cookie", dependencies=[Depends(check_is_superuser)])
|
||||||
async def get_cookie(site_name: str = None, target: str = None) -> list[Cookie]:
|
async def get_cookie(site_name: str | None = None, target: str | None = None) -> list[Cookie]:
|
||||||
cookies_in_db = await config.get_cookie(site_name, is_anonymous=False)
|
cookies_in_db = await config.get_cookie(site_name, is_anonymous=False)
|
||||||
client_mgr = cast(CookieClientManager, site_manager[site_name].client_mgr)
|
# client_mgr = cast(CookieClientManager, site_manager[site_name].client_mgr)
|
||||||
friendly_names = [await client_mgr.get_cookie_friendly_name(x) for x in cookies_in_db]
|
# friendly_names = [await client_mgr.get_cookie_friendly_name(x) for x in cookies_in_db]
|
||||||
|
friendly_names = [x.content[:10] for x in cookies_in_db]
|
||||||
return [
|
return [
|
||||||
Cookie(
|
Cookie(
|
||||||
id=cookies_in_db[i].id,
|
id=cookies_in_db[i].id,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user