feat: bugs
This commit is contained in:
parent
1e71b19ef6
commit
edfdbfd8f9
|
|
@ -37,3 +37,6 @@ frontend/.eslintcache
|
||||||
*.pid.lock
|
*.pid.lock
|
||||||
docker-compose.override.yml
|
docker-compose.override.yml
|
||||||
|
|
||||||
|
# ---- 自定义 ---
|
||||||
|
.login.json
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import uvicorn
|
import uvicorn
|
||||||
import uuid
|
import uuid
|
||||||
import time
|
import time
|
||||||
|
|
@ -39,6 +40,29 @@ def clear_session():
|
||||||
logger.info(f"清理过期 now: {now} session: {expired_keys}")
|
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:
|
def get_current_user(token: str = Depends(oauth2_scheme)) -> DB.User | None:
|
||||||
if not token or token not in sessions:
|
if not token or token not in sessions:
|
||||||
raise HTTPException(status_code=401, detail="用户未登陆")
|
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.add_job(clear_session, "interval", seconds=30, misfire_grace_time=10)
|
||||||
scheduler.start()
|
scheduler.start()
|
||||||
logger.info("初始化定时器")
|
logger.info("初始化定时器")
|
||||||
|
# 读取上一次登录状态
|
||||||
|
await load_session_from_file(app)
|
||||||
|
|
||||||
await _create_demo_records(app)
|
await _create_demo_records(app)
|
||||||
|
|
||||||
|
|
@ -207,6 +233,9 @@ async def lifespan(app: FastAPI):
|
||||||
await close_tortoise()
|
await close_tortoise()
|
||||||
logger.info("关闭数据库")
|
logger.info("关闭数据库")
|
||||||
|
|
||||||
|
save_session_to_file(app)
|
||||||
|
logger.info("保存上一次登录信息")
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
def create_app():
|
||||||
app = FastAPI(title="Workflow API", version="1.0.0", lifespan=lifespan)
|
app = FastAPI(title="Workflow API", version="1.0.0", lifespan=lifespan)
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import '@xyflow/react/dist/style.css';
|
||||||
import { flowDetail } from "../../api/flow";
|
import { flowDetail } from "../../api/flow";
|
||||||
import EditNode from "./components/EditNode";
|
import EditNode from "./components/EditNode";
|
||||||
import CustomNode from "./components/CustomNode";
|
import CustomNode from "./components/CustomNode";
|
||||||
|
import { ProForm, ProFormText, ProFormTextArea } from "@ant-design/pro-components";
|
||||||
|
|
||||||
const COLORS = {
|
const COLORS = {
|
||||||
first: "#89A8B2",
|
first: "#89A8B2",
|
||||||
|
|
@ -55,6 +56,7 @@ const FlowDetail = () => {
|
||||||
const { modal, message } = App.useApp();
|
const { modal, message } = App.useApp();
|
||||||
const { work_uuid } = useParams()
|
const { work_uuid } = useParams()
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const formRef = useRef(null);
|
||||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||||
const [record, setRecord] = useState({});
|
const [record, setRecord] = useState({});
|
||||||
|
|
@ -103,6 +105,7 @@ const FlowDetail = () => {
|
||||||
let startIndex = 1;
|
let startIndex = 1;
|
||||||
if (res?.success) {
|
if (res?.success) {
|
||||||
setRecord(res.data);
|
setRecord(res.data);
|
||||||
|
formRef?.current?.setFieldsValue(res?.data || {});
|
||||||
const tempEdges = [];
|
const tempEdges = [];
|
||||||
const tempNodes = [{
|
const tempNodes = [{
|
||||||
id: '1',
|
id: '1',
|
||||||
|
|
@ -145,14 +148,28 @@ const FlowDetail = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const onSave = async () => {
|
const onSave = async () => {
|
||||||
modal.confirm({
|
try {
|
||||||
title: "保存",
|
await formRef.current.validateFields();
|
||||||
content: "确认保存修改内容?",
|
modal.confirm({
|
||||||
onOk: async () => {
|
title: "保存",
|
||||||
|
content: "确认保存修改内容?",
|
||||||
return true;
|
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(() => {
|
useEffect(() => {
|
||||||
|
|
@ -190,7 +207,9 @@ const FlowDetail = () => {
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
<Col span={6}>
|
<Col span={6}>
|
||||||
<RightCard onCreate={onAdd} />
|
<ProForm formRef={formRef} submitter={false} layout='horizontal'>
|
||||||
|
<RightCard onCreate={onAdd} />
|
||||||
|
</ProForm>
|
||||||
<EditNode ref={editRef} onFinish={onEdit} />
|
<EditNode ref={editRef} onFinish={onEdit} />
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
@ -199,22 +218,29 @@ const FlowDetail = () => {
|
||||||
|
|
||||||
const RightCard = ({ onCreate }) => {
|
const RightCard = ({ onCreate }) => {
|
||||||
const nodes = [{ title: 'Git' }, { title: "Cmd" }, { title: "Status" }];
|
const nodes = [{ title: 'Git' }, { title: "Cmd" }, { title: "Status" }];
|
||||||
return <Card title="节点" className="flow-detail-right">
|
return <>
|
||||||
{nodes?.map((e, i) =>
|
<Card title="节点" className="flow-detail-right">
|
||||||
<div
|
{nodes?.map((e, i) =>
|
||||||
key={e.title}
|
<div
|
||||||
className="node"
|
key={e.title}
|
||||||
style={{ backgroundColor: COLORS[e.title.toLowerCase()] }}
|
className="node"
|
||||||
onClick={() => {
|
style={{ backgroundColor: COLORS[e.title.toLowerCase()] }}
|
||||||
onCreate && onCreate(e.title.toLowerCase());
|
onClick={() => {
|
||||||
}}
|
onCreate && onCreate(e.title.toLowerCase());
|
||||||
>
|
}}
|
||||||
<Typography.Text>
|
>
|
||||||
{e.title}
|
<Typography.Text>
|
||||||
</Typography.Text>
|
{e.title}
|
||||||
</div>
|
</Typography.Text>
|
||||||
)}
|
</div>
|
||||||
</Card>
|
)}
|
||||||
|
</Card>
|
||||||
|
<Card title="基础信息" className="flow-detail-right" style={{ marginTop: 16 }}>
|
||||||
|
<ProFormText label="" placeholder="请输入标题" name='work_title' rules={[{ required: true }]} />
|
||||||
|
<ProFormTextArea label="" placeholder="请输入描述" name='work_desc' rules={[{ required: true }]} />
|
||||||
|
</Card>
|
||||||
|
|
||||||
|
</>
|
||||||
}
|
}
|
||||||
|
|
||||||
const ControlButtons = ({ onLoad }) => {
|
const ControlButtons = ({ onLoad }) => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue