diff --git a/.umirc.ts b/.umirc.ts index 9568f1c1..f280dac4 100644 --- a/.umirc.ts +++ b/.umirc.ts @@ -1,20 +1,15 @@ -import { defineConfig } from 'umi'; +import { defineConfig } from '@umijs/max'; const CompressionPlugin = require('compression-webpack-plugin'); export default defineConfig({ hash: true, - layout: false, + antd: {}, outputPath: 'static/dist', - nodeModulesTransform: { - type: 'none', + fastRefresh: true, + favicons: ['/images/favicon.svg'], + mfsu: { + strategy: 'eager', }, - fastRefresh: {}, - esbuild: {}, - webpack5: {}, - dynamicImport: { - loading: '@/components/pageLoading', - }, - favicon: '/images/favicon.svg', proxy: { '/api/public': { target: 'http://127.0.0.1:5400/', @@ -26,7 +21,7 @@ export default defineConfig({ ws: true, }, }, - chainWebpack: (config) => { + chainWebpack: ((config: any) => { config.plugin('compression-webpack-plugin').use( new CompressionPlugin({ algorithm: 'gzip', @@ -35,13 +30,13 @@ export default defineConfig({ minRatio: 0.6, }), ); - }, + }) as any, externals: { react: 'window.React', 'react-dom': 'window.ReactDOM', }, - scripts: [ - 'https://gw.alipayobjects.com/os/lib/react/16.13.1/umd/react.production.min.js', - 'https://gw.alipayobjects.com/os/lib/react-dom/16.13.1/umd/react-dom.production.min.js', + headScripts: [ + 'https://gw.alipayobjects.com/os/lib/react/18.2.0/umd/react.production.min.js', + 'https://gw.alipayobjects.com/os/lib/react-dom/18.2.0/umd/react-dom.production.min.js', ], }); diff --git a/back/api/script.ts b/back/api/script.ts index 257a2f13..4273459e 100644 --- a/back/api/script.ts +++ b/back/api/script.ts @@ -115,8 +115,11 @@ export default (app: Router) => { if (!originFilename) { originFilename = filename; } - const originFilePath = `${path}${originFilename.replace(/\//g, '')}`; - const filePath = `${path}${filename.replace(/\//g, '')}`; + const originFilePath = join( + path, + `${originFilename.replace(/\//g, '')}`, + ); + const filePath = join(path, `${filename.replace(/\//g, '')}`); if (fs.existsSync(originFilePath)) { fs.copyFileSync( originFilePath, diff --git a/back/loaders/initTask.ts b/back/loaders/initTask.ts index 987c129a..3b9c8301 100644 --- a/back/loaders/initTask.ts +++ b/back/loaders/initTask.ts @@ -13,7 +13,7 @@ export default async () => { // 生成内置token let tokenCommand = `ts-node-transpile-only ${config.rootPath}/back/token.ts`; - const tokenFile = `${config.rootPath}/static/build/token.js`; + const tokenFile = `${config.rootPath}static/build/token.js`; if (await fileExist(tokenFile)) { tokenCommand = `node ${tokenFile}`; } diff --git a/package.json b/package.json index 71f9e640..2c2da8c6 100644 --- a/package.json +++ b/package.json @@ -2,16 +2,16 @@ "private": true, "scripts": { "start": "concurrently -n w: npm:start:*", - "start:front": "umi dev", + "start:front": "max dev", "start:back": "nodemon", "start:public": "ts-node back/public.ts", - "build:front": "umi build", + "build:front": "max build", "build:back": "tsc -p tsconfig.back.json", "panel": "npm run build:back && node static/build/app.js", "schedule": "npm run build:back && node static/build/schedule.js", "public": "npm run build:back && node static/build/public.js", "prettier": "prettier --write '**/*.{js,jsx,tsx,ts,less,md,json}'", - "postinstall": "umi generate tmp 2>/dev/null || true", + "postinstall": "max setup 2>/dev/null || true", "test": "umi-test", "test:coverage": "umi-test --coverage" }, @@ -28,9 +28,26 @@ }, "pnpm": { "peerDependencyRules": { + "ignoreMissing": [ + "react", + "react-dom", + "antd", + "dva", + "postcss", + "webpack", + "eslint", + "stylelint", + "redux", + "@babel/core", + "monaco-editor", + "rc-field-form", + "@types/lodash.merge", + "rollup" + ], "allowedVersions": { - "react": "17", - "react-dom": "17" + "react": "18", + "react-dom": "18", + "dva-core": "2" } } }, @@ -86,16 +103,14 @@ "@types/node-schedule": "^1.3.2", "@types/nodemailer": "^6.4.4", "@types/qrcode.react": "^1.0.2", - "@types/react": "^17.0.39", - "@types/react-dom": "^17.0.13", + "@types/react": "^18.0.20", + "@types/react-dom": "^18.0.6", "@types/serve-handler": "^6.1.1", "@types/sockjs": "^0.3.33", "@types/sockjs-client": "^1.5.1", "@types/uuid": "^8.3.4", - "@umijs/plugin-antd": "^0.15.0", - "@umijs/plugin-esbuild": "^1.4.1", + "@umijs/max": "^4.0.21", "@umijs/ssr-darkreader": "^4.9.45", - "@umijs/test": "^3.5.21", "ansi-to-react": "^6.1.6", "antd": "^4.20.5", "antd-img-crop": "^4.2.3", @@ -107,19 +122,19 @@ "prettier": "^2.5.1", "qiniu": "^7.4.0", "qrcode.react": "^1.0.1", + "query-string": "^7.1.1", "rc-tween-one": "^3.0.6", - "react": "17.x", + "react": "18.x", "react-codemirror2": "^7.2.1", "react-diff-viewer": "^3.1.1", "react-dnd": "^14.0.2", "react-dnd-html5-backend": "^14.0.0", - "react-dom": "17.x", + "react-dom": "18.x", "react-split-pane": "^0.1.92", "sockjs-client": "^1.6.0", "ts-node": "^10.6.0", "tslib": "^2.4.0", "typescript": "^4.6.2", - "umi": "^3.5.21", "umi-request": "^1.4.0", "vh-check": "^2.0.5", "webpack": "^5.70.0", diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 6c013d86..812914d1 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect, useState, useRef } from 'react'; import ProLayout, { PageLoading } from '@ant-design/pro-layout'; import * as DarkReader from '@umijs/ssr-darkreader'; import defaultProps from './defaultProps'; -import { Link, history } from 'umi'; +import { Link, history, Outlet, useLocation } from '@umijs/max'; import { LogoutOutlined, MenuFoldOutlined, @@ -21,7 +21,18 @@ import SockJS from 'sockjs-client'; import * as Sentry from '@sentry/react'; import { init } from '../utils/init'; -export default function (props: any) { +export interface SharedContext { + headerStyle: React.CSSProperties; + isPhone: boolean; + theme: 'vs' | 'vs-dark'; + user: any; + reloadUser: (needLoading?: boolean) => void; + reloadTheme: () => void; + socketMessage: any; +} + +export default function () { + const location = useLocation(); const ctx = useCtx(); const { theme, reloadTheme } = useTheme(); const [user, setUser] = useState({}); @@ -73,7 +84,7 @@ export default function (props: any) { .then(({ code, data }) => { if (code === 200 && data.username) { setUser(data); - if (props.location.pathname === '/') { + if (location.pathname === '/') { history.push('/crontab'); } } else { @@ -94,7 +105,7 @@ export default function (props: any) { if (systemInfo && systemInfo.isInitialized && !user) { getUser(); } - }, [props.location.pathname]); + }, [location.pathname]); useEffect(() => { if (!systemInfo) { @@ -138,7 +149,9 @@ export default function (props: any) { useEffect(() => { if (!user || !user.username) return; ws.current = new SockJS( - `${location.origin}/api/ws?token=${localStorage.getItem(config.authKey)}`, + `${window.location.origin}/api/ws?token=${localStorage.getItem( + config.authKey, + )}`, ); ws.current.onmessage = (e: any) => { @@ -183,30 +196,27 @@ export default function (props: any) { }; }, []); - if ( - ['/login', '/initialization', '/error'].includes(props.location.pathname) - ) { + if (['/login', '/initialization', '/error'].includes(location.pathname)) { document.title = `${ - (config.documentTitleMap as any)[props.location.pathname] + (config.documentTitleMap as any)[location.pathname] } - 控制面板`; - if ( - systemInfo?.isInitialized && - props.location.pathname === '/initialization' - ) { + if (systemInfo?.isInitialized && location.pathname === '/initialization') { history.push('/crontab'); } - if (systemInfo || props.location.pathname === '/error') { - return React.Children.map(props.children, (child) => { - return React.cloneElement(child, { - ...ctx, - theme, - user, - reloadUser, - reloadTheme, - ws: ws.current, - }); - }); + if (systemInfo || location.pathname === '/error') { + return ( + + ); } } @@ -227,7 +237,7 @@ export default function (props: any) { ) : ( } @@ -320,16 +330,16 @@ export default function (props: any) { )} {...defaultProps} > - {React.Children.map(props.children, (child) => { - return React.cloneElement(child, { + ); } diff --git a/src/components/pageLoading.tsx b/src/loading.tsx similarity index 100% rename from src/components/pageLoading.tsx rename to src/loading.tsx diff --git a/src/pages/config/index.tsx b/src/pages/config/index.tsx index 002a2419..72670fbf 100644 --- a/src/pages/config/index.tsx +++ b/src/pages/config/index.tsx @@ -11,8 +11,11 @@ import { PageContainer } from '@ant-design/pro-layout'; import { request } from '@/utils/http'; import Editor from '@monaco-editor/react'; import { Controlled as CodeMirror } from 'react-codemirror2'; +import { useOutletContext } from '@umijs/max'; +import { SharedContext } from '@/layouts'; -const Config = ({ headerStyle, isPhone, theme }: any) => { +const Config = () => { + const { headerStyle, isPhone, theme } = useOutletContext(); const [value, setValue] = useState(''); const [loading, setLoading] = useState(true); const [title, setTitle] = useState('config.sh'); diff --git a/src/pages/crontab/index.tsx b/src/pages/crontab/index.tsx index bc259209..80f905ba 100644 --- a/src/pages/crontab/index.tsx +++ b/src/pages/crontab/index.tsx @@ -44,12 +44,13 @@ import CronDetailModal from './detail'; import cron_parser from 'cron-parser'; import { diffTime } from '@/utils/date'; import { getTableScroll } from '@/utils/index'; -import { history } from 'umi'; +import { history, useOutletContext } from '@umijs/max'; import './index.less'; import ViewCreateModal from './viewCreateModal'; import ViewManageModal from './viewManageModal'; import pagination from 'antd/lib/pagination'; import { FilterValue, SorterResult } from 'antd/lib/table/interface'; +import { SharedContext } from '@/layouts'; const { Text, Paragraph } = Typography; const { Search } = Input; @@ -81,7 +82,8 @@ enum OperationPath { 'unpin', } -const Crontab = ({ headerStyle, isPhone, theme }: any) => { +const Crontab = () => { + const { headerStyle, isPhone, theme } = useOutletContext(); const columns: any = [ { title: '名称', @@ -199,10 +201,10 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { > {record.last_execution_time ? new Date(record.last_execution_time * 1000) - .toLocaleString(language, { - hour12: false, - }) - .replace(' 24:', ' 00:') + .toLocaleString(language, { + hour12: false, + }) + .replace(' 24:', ' 00:') : '-'} ); @@ -411,9 +413,16 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { const getCrons = () => { setLoading(true); const { page, size, sorter, filters } = pageConf; - let url = `${config.apiPrefix}crons?searchValue=${searchText}&page=${page}&size=${size}&filters=${JSON.stringify(filters)}`; + let url = `${ + config.apiPrefix + }crons?searchValue=${searchText}&page=${page}&size=${size}&filters=${JSON.stringify( + filters, + )}`; if (sorter && sorter.field) { - url += `&sorter=${JSON.stringify({ field: sorter.field, type: sorter.order === 'ascend' ? 'ASC' : 'DESC' })}`; + url += `&sorter=${JSON.stringify({ + field: sorter.field, + type: sorter.order === 'ascend' ? 'ASC' : 'DESC', + })}`; } if (viewConf) { url += `&queryString=${JSON.stringify({ @@ -577,7 +586,8 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { onOk() { request .put( - `${config.apiPrefix}crons/${record.isDisabled === 1 ? 'enable' : 'disable' + `${config.apiPrefix}crons/${ + record.isDisabled === 1 ? 'enable' : 'disable' }`, { data: [record.id], @@ -622,7 +632,8 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { onOk() { request .put( - `${config.apiPrefix}crons/${record.isPinned === 1 ? 'unpin' : 'pin' + `${config.apiPrefix}crons/${ + record.isPinned === 1 ? 'unpin' : 'pin' }`, { data: [record.id], @@ -828,7 +839,12 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { sorter: SorterResult | SorterResult[], ) => { const { current, pageSize } = pagination; - setPageConf({ page: current as number, size: pageSize as number, sorter, filters }); + setPageConf({ + page: current as number, + size: pageSize as number, + sorter, + filters, + }); localStorage.setItem('pageSize', String(pageSize)); }; @@ -865,7 +881,7 @@ const Crontab = ({ headerStyle, isPhone, theme }: any) => { page: 1, size: parseInt(localStorage.getItem('pageSize') || '20'), sorter: {}, - filters: {} + filters: {}, }); setTimeout(() => { setTableScrollHeight(getTableScroll()); diff --git a/src/pages/dependence/index.tsx b/src/pages/dependence/index.tsx index aab8e262..0bebfb05 100644 --- a/src/pages/dependence/index.tsx +++ b/src/pages/dependence/index.tsx @@ -29,6 +29,8 @@ import { HTML5Backend } from 'react-dnd-html5-backend'; import './index.less'; import { getTableScroll } from '@/utils/index'; import DependenceLogModal from './logModal'; +import { useOutletContext } from '@umijs/max'; +import { SharedContext } from '@/layouts'; const { Text } = Typography; const { Search } = Input; @@ -48,7 +50,9 @@ enum StatusColor { 'error', } -const Dependence = ({ headerStyle, isPhone, socketMessage }: any) => { +const Dependence = () => { + const { headerStyle, isPhone, socketMessage } = + useOutletContext(); const columns: any = [ { title: '序号', diff --git a/src/pages/dependence/modal.tsx b/src/pages/dependence/modal.tsx index 7547958a..6cd089d8 100644 --- a/src/pages/dependence/modal.tsx +++ b/src/pages/dependence/modal.tsx @@ -101,7 +101,9 @@ const DependenceModal = ({ > diff --git a/src/pages/diff/index.less b/src/pages/diff/index.less index 9c6682b0..e6f5f3c2 100644 --- a/src/pages/diff/index.less +++ b/src/pages/diff/index.less @@ -17,4 +17,8 @@ .ant-form-item { margin-bottom: 8px; } + + + section { + height: calc(100% - 40px) !important; + } } diff --git a/src/pages/diff/index.tsx b/src/pages/diff/index.tsx index 8993f6a3..a07e6b8a 100644 --- a/src/pages/diff/index.tsx +++ b/src/pages/diff/index.tsx @@ -6,10 +6,13 @@ import { request } from '@/utils/http'; import './index.less'; import { DiffEditor } from '@monaco-editor/react'; import ReactDiffViewer from 'react-diff-viewer'; +import { useOutletContext } from '@umijs/max'; +import { SharedContext } from '@/layouts'; const { Option } = Select; -const Diff = ({ headerStyle, isPhone, theme }: any) => { +const Diff = () => { + const { headerStyle, isPhone, theme } = useOutletContext(); const [origin, setOrigin] = useState('config.sample.sh'); const [current, setCurrent] = useState('config.sh'); const [originValue, setOriginValue] = useState(''); @@ -95,7 +98,9 @@ const Diff = ({ headerStyle, isPhone, theme }: any) => { @@ -104,7 +109,9 @@ const Diff = ({ headerStyle, isPhone, theme }: any) => { diff --git a/src/pages/env/index.tsx b/src/pages/env/index.tsx index 84bc0d07..47a669c7 100644 --- a/src/pages/env/index.tsx +++ b/src/pages/env/index.tsx @@ -26,6 +26,8 @@ import { DndProvider, useDrag, useDrop } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import './index.less'; import { exportJson, getTableScroll } from '@/utils/index'; +import { useOutletContext } from '@umijs/max'; +import { SharedContext } from '@/layouts'; const { Text, Paragraph } = Typography; const { Search } = Input; @@ -96,7 +98,8 @@ const DragableBodyRow = ({ ); }; -const Env = ({ headerStyle, isPhone, theme }: any) => { +const Env = () => { + const { headerStyle, isPhone, theme } = useOutletContext(); const columns: any = [ { title: '序号', diff --git a/src/pages/error/index.tsx b/src/pages/error/index.tsx index c1af55a7..bb4d9d64 100644 --- a/src/pages/error/index.tsx +++ b/src/pages/error/index.tsx @@ -3,11 +3,13 @@ import config from '@/utils/config'; import { request } from '@/utils/http'; import Terminal, { ColorMode, LineType } from '../../components/terminal'; import { PageLoading } from '@ant-design/pro-layout'; -import { history } from 'umi'; +import { history, useOutletContext } from '@umijs/max'; import Ansi from 'ansi-to-react'; import './index.less'; +import { SharedContext } from '@/layouts'; -const Error = ({ user, theme }: any) => { +const Error = () => { + const { user, theme } = useOutletContext(); const [loading, setLoading] = useState(false); const [data, setData] = useState('暂无日志'); diff --git a/src/pages/initialization/index.tsx b/src/pages/initialization/index.tsx index a91d020c..87916ba1 100644 --- a/src/pages/initialization/index.tsx +++ b/src/pages/initialization/index.tsx @@ -10,7 +10,7 @@ import { Select, } from 'antd'; import config from '@/utils/config'; -import { history } from 'umi'; +import { history } from '@umijs/max'; import styles from './index.less'; import { request } from '@/utils/http'; @@ -116,7 +116,9 @@ const Initialization = () => { {config.notificationModes .filter((x) => x.value !== 'closed') .map((x) => ( - + ))} diff --git a/src/pages/log/index.module.less b/src/pages/log/index.module.less index 5f3e2c8d..8f6e003d 100644 --- a/src/pages/log/index.module.less +++ b/src/pages/log/index.module.less @@ -6,8 +6,7 @@ overflow: hidden; position: relative; background-color: @component-background; - height: calc(100vh - 128px); - height: calc(100vh - var(--vh-offset, 0px) - 128px); + height: 100%; display: flex; flex-direction: column; } diff --git a/src/pages/log/index.tsx b/src/pages/log/index.tsx index c216e1b3..92327785 100644 --- a/src/pages/log/index.tsx +++ b/src/pages/log/index.tsx @@ -7,6 +7,8 @@ import { request } from '@/utils/http'; import styles from './index.module.less'; import { Controlled as CodeMirror } from 'react-codemirror2'; import SplitPane from 'react-split-pane'; +import { useOutletContext } from '@umijs/max'; +import { SharedContext } from '@/layouts'; function getFilterData(keyword: string, data: any) { const expandedKeys: string[] = []; @@ -36,7 +38,8 @@ function getFilterData(keyword: string, data: any) { return { tree: data, expandedKeys }; } -const Log = ({ headerStyle, isPhone, theme }: any) => { +const Log = () => { + const { headerStyle, isPhone, theme } = useOutletContext(); const [title, setTitle] = useState('请选择日志文件'); const [value, setValue] = useState('请选择日志文件'); const [select, setSelect] = useState(); diff --git a/src/pages/login/index.tsx b/src/pages/login/index.tsx index 58d31207..9f8fe06a 100644 --- a/src/pages/login/index.tsx +++ b/src/pages/login/index.tsx @@ -9,16 +9,18 @@ import { Statistic, } from 'antd'; import config from '@/utils/config'; -import { history, Link } from 'umi'; +import { history, useOutletContext } from '@umijs/max'; import styles from './index.less'; import { request } from '@/utils/http'; import { useTheme } from '@/utils/hooks'; import { MobileOutlined } from '@ant-design/icons'; +import { SharedContext } from '@/layouts'; const FormItem = Form.Item; const { Countdown } = Statistic; -const Login = ({ reloadUser }: any) => { +const Login = () => { + const { reloadUser } = useOutletContext(); const [loading, setLoading] = useState(false); const [waitTime, setWaitTime] = useState(); const { theme } = useTheme(); diff --git a/src/pages/script/editNameModal.tsx b/src/pages/script/editNameModal.tsx index 7986241c..04f3648e 100644 --- a/src/pages/script/editNameModal.tsx +++ b/src/pages/script/editNameModal.tsx @@ -36,7 +36,7 @@ const EditScriptNameModal = ({ const handleOk = async (values: any) => { setLoading(true); - const { path = '', filename: inputFilename, directory } = values; + const { path = '', filename: inputFilename, directory = '' } = values; const formData = new FormData(); formData.append('file', file as any); formData.append('filename', inputFilename); @@ -50,11 +50,11 @@ const EditScriptNameModal = ({ .then(({ code, data }) => { if (code === 200) { message.success(directory ? '新建文件夹成功' : '新建文件成功'); - const key = path ? `${values.path}/` : ''; + const key = path ? `${path}/` : ''; const filename = file ? file.name : inputFilename; handleCancel({ filename, - path: values.path, + path, key: `${key}${filename}`, }); } else { diff --git a/src/pages/script/index.module.less b/src/pages/script/index.module.less index 5f3e2c8d..8f6e003d 100644 --- a/src/pages/script/index.module.less +++ b/src/pages/script/index.module.less @@ -6,8 +6,7 @@ overflow: hidden; position: relative; background-color: @component-background; - height: calc(100vh - 128px); - height: calc(100vh - var(--vh-offset, 0px) - 128px); + height: 100%; display: flex; flex-direction: column; } diff --git a/src/pages/script/index.tsx b/src/pages/script/index.tsx index c007d591..e9bc1689 100644 --- a/src/pages/script/index.tsx +++ b/src/pages/script/index.tsx @@ -33,7 +33,10 @@ import { } from '@ant-design/icons'; import EditScriptNameModal from './editNameModal'; import debounce from 'lodash/debounce'; -import { history } from 'umi'; +import { history, useOutletContext, useLocation } from '@umijs/max'; +import { parse } from 'query-string'; +import { depthFirstSearch } from '@/utils'; +import { SharedContext } from '@/layouts'; const { Text } = Typography; @@ -72,7 +75,9 @@ const LangMap: any = { '.ts': 'typescript', }; -const Script = ({ headerStyle, isPhone, theme, socketMessage }: any) => { +const Script = () => { + const { headerStyle, isPhone, theme, socketMessage } = + useOutletContext(); const [title, setTitle] = useState('请选择脚本文件'); const [value, setValue] = useState('请选择脚本文件'); const [select, setSelect] = useState(); @@ -111,7 +116,7 @@ const Script = ({ headerStyle, isPhone, theme, socketMessage }: any) => { }; const initGetScript = () => { - const { p, s } = history.location.query as any; + const { p, s } = parse(history.location.search); if (s) { const vkey = `${p}/${s}`; const obj = { @@ -313,20 +318,17 @@ const Script = ({ headerStyle, isPhone, theme, socketMessage }: any) => { }, ) => { if (filename) { - const newData = [...data]; + let newData = [...data]; const _file = { title: filename, key, parent: path }; if (path) { - // TODO: 更新左侧树数据 - const parentNodeIndex = newData.findIndex((x) => x.key === path); - if (parentNodeIndex !== -1) { - const parentNode = newData[parentNodeIndex]; - if (parentNode.children && parentNode.children.length > 0) { - parentNode.children.unshift(_file); - } else { - parentNode.children = [_file]; - } - newData.splice(parentNodeIndex, 1, { ...parentNode }); - } + newData = depthFirstSearch(newData, (c) => c.key === path, _file); + const keys = path.split('/'); + const sKeys: string[] = []; + keys.reduce((p, c) => { + sKeys.push(p); + return `${p}/${c}`; + }); + setExpandedKeys([...expandedKeys, ...sKeys, path]); } else { newData.unshift(_file); } @@ -360,10 +362,6 @@ const Script = ({ headerStyle, isPhone, theme, socketMessage }: any) => { const word = searchValue || ''; const { tree } = getFilterData(word.toLocaleLowerCase(), data); setFilterData(tree); - setSelect(''); - setCurrentNode(null); - setTitle('请选择脚本文件'); - setValue('请选择脚本文件'); }, [data]); useEffect(() => { diff --git a/src/pages/setting/appModal.tsx b/src/pages/setting/appModal.tsx index 1fff2b0e..0b12d7f1 100644 --- a/src/pages/setting/appModal.tsx +++ b/src/pages/setting/appModal.tsx @@ -91,7 +91,11 @@ const AppModal = ({ style={{ width: '100%' }} > {config.scopes.map((x) => { - return {x.name}; + return ( + + {x.name} + + ); })} diff --git a/src/pages/setting/index.tsx b/src/pages/setting/index.tsx index 9109ff24..b138331c 100644 --- a/src/pages/setting/index.tsx +++ b/src/pages/setting/index.tsx @@ -29,6 +29,8 @@ import LoginLog from './loginLog'; import NotificationSetting from './notification'; import CheckUpdate from './checkUpdate'; import About from './about'; +import { useOutletContext } from '@umijs/max'; +import { SharedContext } from '@/layouts'; const { Text } = Typography; const optionsWithDisabled = [ @@ -37,14 +39,9 @@ const optionsWithDisabled = [ { label: '跟随系统', value: 'auto' }, ]; -const Setting = ({ - headerStyle, - isPhone, - user, - reloadUser, - reloadTheme, - socketMessage, -}: any) => { +const Setting = () => { + const { headerStyle, isPhone, user, reloadUser, reloadTheme, socketMessage } = + useOutletContext(); const columns = [ { title: '名称', diff --git a/src/pages/setting/notification.tsx b/src/pages/setting/notification.tsx index 289b804d..ed5d7816 100644 --- a/src/pages/setting/notification.tsx +++ b/src/pages/setting/notification.tsx @@ -64,6 +64,7 @@ const NotificationSetting = ({ data }: any) => { {fields.map((x) => ( { +const Subscription = () => { + const { headerStyle, isPhone, socketMessage } = + useOutletContext(); + const columns: any = [ { title: '名称', diff --git a/src/utils/http.ts b/src/utils/http.ts index dc1c2929..18ed28d6 100644 --- a/src/utils/http.ts +++ b/src/utils/http.ts @@ -1,7 +1,7 @@ import { extend } from 'umi-request'; import { message } from 'antd'; import config from './config'; -import { history } from 'umi'; +import { history } from '@umijs/max'; message.config({ duration: 1.5, diff --git a/src/utils/index.ts b/src/utils/index.ts index c09a8984..6c4b509b 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -241,3 +241,31 @@ export function exportJson(name: string, data: string) { createA.download = name; automaticClick(createA); } + +export function depthFirstSearch< + T extends Record & { children?: T[] }, +>(children: T[], condition: (column: T) => boolean, item: T) { + const c = [...children]; + const keys = []; + + (function find(cls: T[] | undefined) { + if (!cls) return; + for (let i = 0; i < cls?.length; i++) { + if (condition(cls[i])) { + if (cls[i].children) { + cls[i].children!.unshift(item); + } else { + cls[i].children = [item]; + } + return; + } + if (cls[i].children) { + keys.push(cls[i].key); + find(cls[i].children); + } + } + })(c); + + console.log(keys); + return c; +}