From 89787a187dd73bd71ae1768ee4b1a18ec2bd11cf Mon Sep 17 00:00:00 2001
From: felinae98 <731499577@qq.com>
Date: Fri, 7 Oct 2022 00:57:12 +0800
Subject: [PATCH] update
---
admin-frontend/.eslintrc.json | 6 +-
admin-frontend/src/App.tsx | 5 +
admin-frontend/src/app/store.ts | 5 +-
.../SubscribeManager.tsx | 52 +++-
.../subsribeConfigManager/SubscribeModal.tsx | 241 ++++++++++++++++++
.../src/features/targetName/targetNameReq.ts | 15 ++
.../features/targetName/targetNameSlice.ts | 14 +
.../features/weightConfig/WeightManager.tsx | 54 ++--
admin-frontend/src/pages/Home.css | 8 +
admin-frontend/src/pages/Home.tsx | 42 ++-
10 files changed, 392 insertions(+), 50 deletions(-)
create mode 100644 admin-frontend/src/features/subsribeConfigManager/SubscribeModal.tsx
create mode 100644 admin-frontend/src/features/targetName/targetNameReq.ts
create mode 100644 admin-frontend/src/features/targetName/targetNameSlice.ts
diff --git a/admin-frontend/.eslintrc.json b/admin-frontend/.eslintrc.json
index 4a244e9..ce2ac20 100644
--- a/admin-frontend/.eslintrc.json
+++ b/admin-frontend/.eslintrc.json
@@ -6,6 +6,8 @@
},
"extends": [
"plugin:react/recommended",
+ "plugin:@typescript-eslint/recommended",
+ "plugin:@typescript-eslint/eslint-recommended",
"airbnb"
],
"parser": "@typescript-eslint/parser",
@@ -25,7 +27,9 @@
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": ["error"],
"import/extensions": ["error", "ignorePackages", {"ts": "never", "tsx": "never"}],
- "no-param-reassign": ["error", { "props": false }]
+ "no-param-reassign": ["error", { "props": false }],
+ "no-unused-vars": "off",
+ "@typescript-eslint/no-unused-vars": ["error"]
},
"settings": {
"import/resolver": {
diff --git a/admin-frontend/src/App.tsx b/admin-frontend/src/App.tsx
index a292b7f..10ccaf6 100644
--- a/admin-frontend/src/App.tsx
+++ b/admin-frontend/src/App.tsx
@@ -6,6 +6,7 @@ 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 WeightConfig from './features/weightConfig/WeightManager';
import Home from './pages/Home';
import Unauthed from './pages/Unauthed';
@@ -41,6 +42,10 @@ function App() {
path: 'groups/:groupNumber',
element: ,
},
+ {
+ path: 'weight',
+ element: ,
+ },
],
},
], { basename: '/bison' });
diff --git a/admin-frontend/src/app/store.ts b/admin-frontend/src/app/store.ts
index 09e59fc..abfe3ff 100644
--- a/admin-frontend/src/app/store.ts
+++ b/admin-frontend/src/app/store.ts
@@ -15,6 +15,7 @@ import storage from 'redux-persist/lib/storage';
import authReducer from '../features/auth/authSlice';
import globalConfReducer from '../features/globalConf/globalConfSlice';
import { subscribeApi } from '../features/subsribeConfigManager/subscribeConfigSlice';
+import { targetNameApi } from '../features/targetName/targetNameSlice';
import { weightApi } from '../features/weightConfig/weightConfigSlice';
const rootReducer = combineReducers({
@@ -22,6 +23,7 @@ const rootReducer = combineReducers({
globalConf: globalConfReducer,
[subscribeApi.reducerPath]: subscribeApi.reducer,
[weightApi.reducerPath]: weightApi.reducer,
+ [targetNameApi.reducerPath]: targetNameApi.reducer,
});
const persistConfig = {
@@ -40,7 +42,8 @@ export const store = configureStore({
},
})
.concat(subscribeApi.middleware)
- .concat(weightApi.middleware),
+ .concat(weightApi.middleware)
+ .concat(targetNameApi.middleware),
});
export const persistor = persistStore(store);
diff --git a/admin-frontend/src/features/subsribeConfigManager/SubscribeManager.tsx b/admin-frontend/src/features/subsribeConfigManager/SubscribeManager.tsx
index 03950a4..fbb02d3 100644
--- a/admin-frontend/src/features/subsribeConfigManager/SubscribeManager.tsx
+++ b/admin-frontend/src/features/subsribeConfigManager/SubscribeManager.tsx
@@ -1,18 +1,34 @@
-import React from 'react';
+import React, { useState } from 'react';
import {
- Button, Empty, Space, Table, Tag,
+ Button, Empty, Message, Popconfirm, Space, Table, Tag, Typography,
} from '@arco-design/web-react';
import { useParams } from 'react-router-dom';
-import { useGetSubsQuery } from './subscribeConfigSlice';
+import { useDeleteSubMutation, useGetSubsQuery } from './subscribeConfigSlice';
import { useAppSelector } from '../../app/hooks';
import { selectPlatformConf } from '../globalConf/globalConfSlice';
import { SubscribeConfig } from '../../utils/type';
+import SubscribeModal from './SubscribeModal';
export default function SubscribeManager() {
const { data: subs } = useGetSubsQuery();
+ const [deleteSub, { isLoading: deleteIsLoading }] = useDeleteSubMutation();
const { groupNumber } = useParams();
const platformConf = useAppSelector(selectPlatformConf);
+ const isLoading = deleteIsLoading;
+ const [showModal, setShowModal] = useState(false);
+ const [formInitVal, setFormInitVal] = useState(null as SubscribeConfig | null);
+
+ const handleNewSub = () => {
+ setFormInitVal(null);
+ setShowModal(true);
+ };
+
+ const handleEdit = (sub: SubscribeConfig) => () => {
+ setFormInitVal(sub);
+ setShowModal(true);
+ };
+
const columns = [
{
title: '平台名称',
@@ -59,9 +75,20 @@ export default function SubscribeManager() {
dataIndex: 'op',
render: (_: any, record: SubscribeConfig) => (
-
-
-
+
+
+ {
+ deleteSub({
+ groupNumber: parseInt(groupNumber!, 10),
+ target: record.target,
+ platformName: record.platformName,
+ });
+ }}
+ >
+
+
),
},
@@ -71,14 +98,21 @@ export default function SubscribeManager() {
return (
<>
- {subs[groupNumber].name}
- {groupNumber}
+ {subs[groupNumber].name}
+ {groupNumber}
-
+
`${record.platformName}-${record.target}`}
+ loading={isLoading}
+ />
+
>
);
diff --git a/admin-frontend/src/features/subsribeConfigManager/SubscribeModal.tsx b/admin-frontend/src/features/subsribeConfigManager/SubscribeModal.tsx
new file mode 100644
index 0000000..31e29d6
--- /dev/null
+++ b/admin-frontend/src/features/subsribeConfigManager/SubscribeModal.tsx
@@ -0,0 +1,241 @@
+import React, { useEffect, useState } from 'react';
+import {
+ Form, Input, InputTag, Modal, Select, Space, Tag,
+} from '@arco-design/web-react';
+import useForm from '@arco-design/web-react/es/Form/useForm';
+import { IconInfoCircle } from '@arco-design/web-react/icon';
+import { useAppSelector } from '../../app/hooks';
+import { selectPlatformConf } from '../globalConf/globalConfSlice';
+import { CategoryConfig, SubscribeConfig } from '../../utils/type';
+import getTargetName from '../targetName/targetNameReq';
+import { useUpdateSubMutation, useNewSubMutation } from './subscribeConfigSlice';
+
+function SubscribeTag({
+ value, onChange, disabled,
+}: {
+ value?: string[];
+ onChange?: (arg0: string[]) => void;
+ disabled?: boolean;
+}) {
+ const [valueState, setValueState] = useState(value || []);
+ const handleSetValue = (newVal: string[]) => {
+ setValueState(newVal);
+ if (onChange) {
+ onChange(newVal);
+ }
+ };
+ useEffect(() => {
+ if (value) {
+ setValueState(value);
+ }
+ }, [value]);
+
+ if (disabled) {
+ return 不支持标签;
+ }
+ return (
+
+ { valueState.length === 0 && 全部标签 }
+
+
+ );
+}
+
+SubscribeTag.defaultProps = {
+ value: [],
+ onChange: null,
+ disabled: false,
+};
+
+interface SubscribeModalProp {
+ visible: boolean;
+ setVisible: (arg0: boolean) => void;
+ groupNumber: string;
+ initval?: SubscribeConfig | null;
+}
+
+function SubscribeModal({
+ visible, setVisible, groupNumber, initval,
+}: SubscribeModalProp) {
+ const [form] = useForm();
+ const [confirmLoading, setConfirmLoading] = useState(false);
+ const platformConf = useAppSelector(selectPlatformConf);
+ const [updateSub] = useUpdateSubMutation();
+ const [newSub] = useNewSubMutation();
+
+ const onSubmit = () => {
+ form.validate().then((value: SubscribeConfig) => {
+ const newVal = { ...value };
+ if (typeof newVal.tags !== 'object') {
+ newVal.tags = [];
+ }
+ if (typeof newVal.cats !== 'object') {
+ newVal.cats = [];
+ }
+ if (newVal.target === '') {
+ newVal.target = 'default';
+ }
+ let postPromise: Promise;
+ if (initval) {
+ postPromise = updateSub({
+ groupNumber: parseInt(groupNumber, 10),
+ sub: newVal,
+ });
+ } else {
+ postPromise = newSub({
+ groupNumber: parseInt(groupNumber, 10),
+ sub: newVal,
+ });
+ }
+ setConfirmLoading(true);
+ postPromise.then(() => {
+ setConfirmLoading(false);
+ setVisible(false);
+ form.clearFields();
+ });
+ });
+ };
+
+ const [hasTarget, setHasTarget] = useState(false);
+ const [categories, setCategories] = useState({} as CategoryConfig);
+ const [enableTags, setEnableTags] = useState(false);
+
+ const setPlatformStates = (platform: string) => {
+ setHasTarget(platformConf[platform].hasTarget);
+ setCategories(platformConf[platform].categories);
+ setEnableTags(platformConf[platform].enabledTag);
+ };
+
+ const handlePlatformSelected = (platform: string) => {
+ setPlatformStates(platform);
+ form.setFieldValue('cats', []);
+ if (!platformConf[platform].hasTarget) {
+ getTargetName(platform, 'default').then((res) => {
+ form.setFieldsValue({
+ targetName: res,
+ target: '',
+ });
+ });
+ } else {
+ form.setFieldsValue({
+ targetName: '',
+ target: '',
+ });
+ }
+ };
+
+ useEffect(() => {
+ if (initval) {
+ const { platformName } = initval;
+ setPlatformStates(platformName);
+ form.setFieldsValue(initval);
+ } else {
+ form.clearFields();
+ }
+ }, [initval, form, platformConf]);
+
+ return (
+ setVisible(false)}
+ confirmLoading={confirmLoading}
+ onOk={onSubmit}
+ >
+
+
+
+ new Promise((resolve) => {
+ getTargetName(form.getFieldValue('platformName'), value)
+ .then((res) => {
+ if (res) {
+ form.setFieldsValue({
+ targetName: res,
+ });
+ resolve();
+ } else {
+ form.setFieldsValue({
+ targetName: '',
+ });
+ callback('账号不正确,请重新检查账号');
+ resolve();
+ }
+ })
+ .catch(() => {
+ callback('服务器错误,请稍后再试');
+ resolve();
+ });
+ }),
+ },
+ ]}
+ >
+ }
+ placeholder={hasTarget ? '获取方式见文档' : '此平台不需要账号'}
+ />
+
+
+
+
+ 0,
+ message: '请至少选择一个分类进行订阅',
+ },
+ ]}
+ >
+
+
+
+
+
+
+
+
+ );
+}
+SubscribeModal.defaultProps = {
+ initval: null,
+};
+export default SubscribeModal;
diff --git a/admin-frontend/src/features/targetName/targetNameReq.ts b/admin-frontend/src/features/targetName/targetNameReq.ts
new file mode 100644
index 0000000..538b9a1
--- /dev/null
+++ b/admin-frontend/src/features/targetName/targetNameReq.ts
@@ -0,0 +1,15 @@
+import { RootState, store } from '../../app/store';
+import { baseUrl } from '../../utils/urls';
+
+export default async function getTargetName(platformName: string, target: string) {
+ const url = `${baseUrl}target_name?platformName=${platformName}&target=${target}`;
+ const state = store.getState() as RootState;
+ const authToken = state.auth.token;
+ const res = await fetch(url, {
+ headers: {
+ Authorization: `Bearer ${authToken}`,
+ },
+ });
+ const resObj = await res.json();
+ return resObj.targetName as string;
+}
diff --git a/admin-frontend/src/features/targetName/targetNameSlice.ts b/admin-frontend/src/features/targetName/targetNameSlice.ts
new file mode 100644
index 0000000..cb5a9aa
--- /dev/null
+++ b/admin-frontend/src/features/targetName/targetNameSlice.ts
@@ -0,0 +1,14 @@
+import { createApi } from '@reduxjs/toolkit/query/react';
+import baseQueryWithAuth from '../auth/authQuery';
+
+export const targetNameApi = createApi({
+ reducerPath: 'targetName',
+ baseQuery: baseQueryWithAuth,
+ endpoints: (builder) => ({
+ getTargetName: builder.query<{targetName: string}, {target: string; platformName: string}>({
+ query: () => '/target_name',
+ }),
+ }),
+});
+
+export const { useGetTargetNameQuery } = targetNameApi;
diff --git a/admin-frontend/src/features/weightConfig/WeightManager.tsx b/admin-frontend/src/features/weightConfig/WeightManager.tsx
index 9f4a8b3..fbf6f67 100644
--- a/admin-frontend/src/features/weightConfig/WeightManager.tsx
+++ b/admin-frontend/src/features/weightConfig/WeightManager.tsx
@@ -1,28 +1,32 @@
import React from 'react';
-import { WeightConfig } from '../../utils/type';
-import { useGetWeightQuery, useUpdateWeightMutation } from './weightConfigSlice';
+// import { WeightConfig } from '../../utils/type';
+// import { useGetWeightQuery, useUpdateWeightMutation } from './weightConfigSlice';
+//
+// export default function WeightManager() {
+// const { data: weight } = useGetWeightQuery();
+// const [updateWeight] = useUpdateWeightMutation();
+//
+// const doUpdate = () => {
+// const weightConfig: WeightConfig = {
+// default: 20,
+// time_config: [
+// {
+// start_time: '01:00',
+// end_time: '02:00',
+// weight: 50,
+// },
+// ],
+// };
+// updateWeight({ weight: weightConfig, platform_name: 'weibo', target: '' });
+// };
+// return (
+// <>
+// {weight && JSON.stringify(weight)}
+//
+// >
+// );
+// }
-export default function WeightManager() {
- const { data: weight } = useGetWeightQuery();
- const [updateWeight] = useUpdateWeightMutation();
-
- const doUpdate = () => {
- const weightConfig: WeightConfig = {
- default: 20,
- time_config: [
- {
- start_time: '01:00',
- end_time: '02:00',
- weight: 50,
- },
- ],
- };
- updateWeight({ weight: weightConfig, platform_name: 'weibo', target: '' });
- };
- return (
- <>
- {weight && JSON.stringify(weight)}
-
- >
- );
+export default function WeightConfig() {
+ return 下个版本再写
;
}
diff --git a/admin-frontend/src/pages/Home.css b/admin-frontend/src/pages/Home.css
index 7f8cb90..501573b 100644
--- a/admin-frontend/src/pages/Home.css
+++ b/admin-frontend/src/pages/Home.css
@@ -7,9 +7,17 @@
.layout-collapse-demo .arco-layout-header .logo {
height: 32px;
margin: 12px 8px;
+ width: 150px;
background: var(--color-fill-2);
}
+.layout-collapse-demo .arco-layout-header span {
+ height: 100%;
+ line-height: 100%;
+ font-size: 20px;
+ margin: 0 20px;
+}
+
.layout-collapse-demo .arco-layout-content .arco-layout-footer,
.layout-collapse-demo .arco-layout-content .arco-layout-content {
color: var(--color-white);
diff --git a/admin-frontend/src/pages/Home.tsx b/admin-frontend/src/pages/Home.tsx
index b86073f..b17683d 100644
--- a/admin-frontend/src/pages/Home.tsx
+++ b/admin-frontend/src/pages/Home.tsx
@@ -4,15 +4,15 @@ import { IconRobot, IconDashboard } from '@arco-design/web-react/icon';
import './Home.css';
// import SubscribeManager from '../features/subsribeConfigManager/SubscribeManager';
import {
- Link, Outlet, useLocation, useNavigate,
+ Link, Navigate, Outlet, useLocation, useNavigate,
} from 'react-router-dom';
-
-export function homeLoader() {
-}
+import { useAppSelector } from '../app/hooks';
+import { selectIsLogin } from '../features/auth/authSlice';
export default function Home() {
const location = useLocation();
const navigate = useNavigate();
+ const isLogin = useAppSelector(selectIsLogin);
const path = location.pathname;
useEffect(() => {
@@ -20,13 +20,12 @@ export default function Home() {
navigate('/home/groups');
}
- if (path !== '/home/groups' && !path.startsWith('/home/groups/')) {
- console.log(path);
+ if (path !== '/home/groups' && !path.startsWith('/home/groups/') && path !== '/home/weight') {
navigate('/home/groups');
}
}, [path]);
- let currentKey: string = '';
+ let currentKey = '';
if (path === '/home/groups') {
currentKey = 'groups';
} else if (path.startsWith('/home/groups/')) {
@@ -38,14 +37,18 @@ export default function Home() {
const handleTabSelect = (tab: string) => {
changeSelectTab(tab);
if (tab === 'groups') {
- navigate('/home/navigate');
+ navigate('/home/groups');
} else if (tab === 'weight') {
navigate('/home/weight');
}
};
+ if (!isLogin) {
+ return ;
+ }
+
let breadcrumbContent: ReactNode;
- if (selectedTab === 'groups') {
+ if (path === '/home/groups') {
breadcrumbContent = (
@@ -54,17 +57,26 @@ export default function Home() {
);
- } else if (selectedTab === 'subs') {
+ } else if (path.startsWith('/home/groups/')) {
breadcrumbContent = (
-
- 订阅管理
+
+ 调度权重
- groupman
+ 群管理
+
+
+ );
+ } else if (path === '/home/weight') {
+ breadcrumbContent = (
+
+
+
+ 调度权重
);
@@ -72,7 +84,9 @@ export default function Home() {
return (
-
+
+ Nonebot Bison
+