diff --git a/backend/app/config/init2.json b/backend/app/config/init2.json new file mode 100644 index 0000000..353db93 --- /dev/null +++ b/backend/app/config/init2.json @@ -0,0 +1,10 @@ +{ + "is_init": true, + "db_type": "sqlite", + "db_host": "localhost", + "db_port": 3306, + "db_user": "root", + "db_password": "12345", + "db_name": "your_workflow", + "admin_password": "12345" +} \ No newline at end of file diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 460db18..7e694a5 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -6,8 +6,14 @@ CONFIG_PATH = Path(__file__).parent.parent / "config" / "init.json" def _sync_load_config() -> dict: - with CONFIG_PATH.open("r", encoding="utf-8") as f: - return json.load(f) + CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True) + try: + with CONFIG_PATH.open("r", encoding="utf-8") as f: + return json.load(f) + except FileNotFoundError: + default_config = {"is_init": False} + _sync_save_config(default_config) + return default_config def _sync_save_config(config_data: dict): diff --git a/backend/app/main.py b/backend/app/main.py index 8d0211b..2bd63c9 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -95,12 +95,12 @@ async def lifespan(app: FastAPI): init_config = await load_init_config() await init_tortoise(init_config["db_type"], init_config, init_config.get("admin_password")) logger.info("初始化数据库") + # 读取上一次登录状态 + await load_session_from_file(app) # 定时器 scheduler.add_job(clear_session, "interval", seconds=30, misfire_grace_time=10) scheduler.start() logger.info("初始化定时器") - # 读取上一次登录状态 - await load_session_from_file(app) yield @@ -173,6 +173,8 @@ def create_app(): @app.get("/api/current_user", tags=["User"], description="当前用户信息", response_model=LoginResponse) async def current_user(user: DB.User = Depends(get_current_user)): + if not await is_init(): + return LoginResponse(success=False) return LoginResponse(data=user.json(del_columns=["password"])) @app.post("/api/run", tags=["Flow"], description="执行任务", response_model=BaseResponse) diff --git a/frontend/src/api/system.js b/frontend/src/api/system.js index 9f692f8..84dddcb 100644 --- a/frontend/src/api/system.js +++ b/frontend/src/api/system.js @@ -4,3 +4,6 @@ export const isInit = async () => { return request("/api/check_init", "GET") } +export const initSystem = async (data) => { + return request("/api/init_system", "POST", data) +} \ No newline at end of file diff --git a/frontend/src/context/AuthContext.jsx b/frontend/src/context/AuthContext.jsx index 1fb4e6e..b87ca93 100644 --- a/frontend/src/context/AuthContext.jsx +++ b/frontend/src/context/AuthContext.jsx @@ -1,13 +1,15 @@ import { createContext, useContext, useEffect, useState } from "react"; import { login as loginToServer, currentUser } from "../api/user"; +import { isInit } from '../api/system'; const AuthContext = createContext(null); import { useNavigate } from 'react-router-dom'; export function AuthProvider({ children }) { + const navigate = useNavigate(); const token = localStorage.getItem('_token') const [user, setUser] = useState(null); - const navigate = useNavigate(); const [loading, setLoading] = useState(token?.length > 0); + const [systemStatus, setSystemStatus] = useState(-1); const getUserInfoFromToken = async () => { try { @@ -24,6 +26,11 @@ export function AuthProvider({ children }) { setLoading(false); } + const checkSystemStatus = async () => { + const res = await isInit(); + setSystemStatus(res?.data ? 1 : 0); + } + const login = async (username, password) => { const res = await loginToServer(username, password); if (res?.success) { @@ -42,11 +49,22 @@ export function AuthProvider({ children }) { }; useEffect(() => { - token && getUserInfoFromToken(); - }, [token]) + systemStatus === 1 && token && getUserInfoFromToken(); + + if (systemStatus === 0) { + navigate("/init"); + } + else if (!token) { + navigate("/login") + } + }, [token, systemStatus]) + + useEffect(() => { + checkSystemStatus(); + }, []) return ( - + {children} ); diff --git a/frontend/src/pages/InitPage.jsx b/frontend/src/pages/InitPage.jsx index 34b2772..7c33d50 100644 --- a/frontend/src/pages/InitPage.jsx +++ b/frontend/src/pages/InitPage.jsx @@ -1,12 +1,32 @@ -import { ProForm, ProFormSelect, ProFormText } from "@ant-design/pro-components"; -import { Card, Divider } from "antd"; +import { ProForm, ProFormDependency, ProFormDigit, ProFormGroup, ProFormSelect, ProFormText } from "@ant-design/pro-components"; +import { App, Card, Divider } from "antd"; +import { useNavigate } from "react-router-dom"; +import { initSystem } from "../api/system"; +import { useAuth } from "../context/AuthContext"; +import { useEffect } from "react"; const rules = [{required: true}] const InitPage = () => { + const { systemStatus } = useAuth(); + const navigate = useNavigate(); + const { message } = App.useApp(); + useEffect(() => { + if (systemStatus === 1) { + navigate("/login"); + } + }, [systemStatus]) return (
- - - 超级帐号 + + { + const res = await initSystem(values); + if (res?.success) { + message.success("初始化成功"); + navigate("/login"); + } else { + message.error(res.message); + } + }}> + 超级帐号 { label="密码" rules={rules} /> - 数据库配置 + 数据库配置 - + + {({ db_type }) => { + if (db_type === 'mysql') return <> + + + + + + + + + + return null; + + }} +
diff --git a/frontend/src/routes.jsx b/frontend/src/routes.jsx index 41e7705..6a90262 100644 --- a/frontend/src/routes.jsx +++ b/frontend/src/routes.jsx @@ -10,17 +10,25 @@ import FlowDetail from "./pages/Flow/Detail"; import LayoutPage from "./pages/Layout"; import ClientPage from "./pages/Client"; import LogPage from "./pages/Log"; +import InitPage from "./pages/InitPage"; // 受保护的路由:没登录就跳转到登录页 function PrivateRoute() { - const { user, loading } = useAuth(); - return (user || loading) ? : ; + const { user, loading, systemStatus } = useAuth(); + if (systemStatus === 0) { + return + } + if (user || loading || systemStatus != 0) { + return ; + } + return ; } const routes = [ // 登录页公开访问 { path: "/", element: }, { path: "/login", element: }, + { path: "/init", element: }, // 需要登录才能访问的路由 {