diff --git a/.gitignore b/.gitignore index a8e3e1a..ee9abab 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ frontend/.eslintcache *.pid.lock docker-compose.override.yml +# ---- 自定义 --- +.login.json + diff --git a/backend/app/main.py b/backend/app/main.py index c3d9bbe..e75895a 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -1,6 +1,7 @@ import asyncio import datetime import json +import os import uvicorn import uuid import time @@ -39,6 +40,29 @@ def clear_session(): logger.info(f"清理过期 now: {now} session: {expired_keys}") +def save_session_to_file(app:FastAPI): + if sessions: + login_json = {} + for k, v in sessions.items(): + login_json[k] = [v[0], v[1].id] + logger.debug(login_json) + with open(".login.json", "w", encoding="utf-8") as f: + json.dump(login_json, f, indent=4, ensure_ascii=False) + + +async def load_session_from_file(app:FastAPI): + if os.path.exists(".login.json"): + with open('.login.json', 'r', encoding='utf-8') as f: + login_json = json.load(f) + if login_json: + users = await DB.User.filter(is_deleted=0).all() + for k, v in login_json.items(): + u = next((u for u in users if u.id == v[1]), None) + if u: + sessions[k] = v[0], u + logger.debug(sessions) + + def get_current_user(token: str = Depends(oauth2_scheme)) -> DB.User | None: if not token or token not in sessions: raise HTTPException(status_code=401, detail="用户未登陆") @@ -193,6 +217,8 @@ async def lifespan(app: FastAPI): scheduler.add_job(clear_session, "interval", seconds=30, misfire_grace_time=10) scheduler.start() logger.info("初始化定时器") + # 读取上一次登录状态 + await load_session_from_file(app) await _create_demo_records(app) @@ -207,6 +233,9 @@ async def lifespan(app: FastAPI): await close_tortoise() logger.info("关闭数据库") + save_session_to_file(app) + logger.info("保存上一次登录信息") + def create_app(): app = FastAPI(title="Workflow API", version="1.0.0", lifespan=lifespan) diff --git a/frontend/src/pages/Flow/Detail.jsx b/frontend/src/pages/Flow/Detail.jsx index 3ee14b8..e506a06 100644 --- a/frontend/src/pages/Flow/Detail.jsx +++ b/frontend/src/pages/Flow/Detail.jsx @@ -17,6 +17,7 @@ import '@xyflow/react/dist/style.css'; import { flowDetail } from "../../api/flow"; import EditNode from "./components/EditNode"; import CustomNode from "./components/CustomNode"; +import { ProForm, ProFormText, ProFormTextArea } from "@ant-design/pro-components"; const COLORS = { first: "#89A8B2", @@ -55,6 +56,7 @@ const FlowDetail = () => { const { modal, message } = App.useApp(); const { work_uuid } = useParams() const navigate = useNavigate(); + const formRef = useRef(null); const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const [record, setRecord] = useState({}); @@ -103,6 +105,7 @@ const FlowDetail = () => { let startIndex = 1; if (res?.success) { setRecord(res.data); + formRef?.current?.setFieldsValue(res?.data || {}); const tempEdges = []; const tempNodes = [{ id: '1', @@ -145,14 +148,28 @@ const FlowDetail = () => { } } const onSave = async () => { - modal.confirm({ - title: "保存", - content: "确认保存修改内容?", - onOk: async () => { - - return true; - } - }); + try { + await formRef.current.validateFields(); + modal.confirm({ + title: "保存", + content: "确认保存修改内容?", + onOk: async () => { + const content = []; + nodes.filter(e => e.type != 'first').forEach(e => { + const edge = edges.find(obj => obj.target === e.id); + content.push({ + ...e.detail, + position: e.position, + edge: edge ? { source: edge.source, target: edge.target } : undefined + }) + }); + console.log(content); + return true; + } + }); + } catch (error) { + message.warning("请检查基础信息"); + } } useEffect(() => { @@ -190,7 +207,9 @@ const FlowDetail = () => {