feat: 修改分支

This commit is contained in:
李如威 2025-09-17 18:17:40 +08:00
parent edfdbfd8f9
commit acba77a8da
5 changed files with 48 additions and 153 deletions

View File

@ -14,6 +14,7 @@ from fastapi import FastAPI, Depends, HTTPException
from models.schemas.system import InitStatusResponse, InitConfigRequest, BaseResponse, TableResponse from models.schemas.system import InitStatusResponse, InitConfigRequest, BaseResponse, TableResponse
from models.schemas.user import LoginRequest, LoginResponse from models.schemas.user import LoginRequest, LoginResponse
from models.schemas.client import ClientRequest from models.schemas.client import ClientRequest
from models.schemas.work import WorkRequest
from core.config import load_init_config, save_init_config from core.config import load_init_config, save_init_config
from core.db import init_tortoise, close_tortoise from core.db import init_tortoise, close_tortoise
from core.logger import logger from core.logger import logger
@ -77,131 +78,6 @@ async def is_init():
return init_status return init_status
async def _create_demo_records(app: FastAPI):
"""创建测试用的"""
if await DB.Work.exists():
return
async with in_transaction():
work = DB.Work(
uuid=uuid.uuid4().hex,
creator_id=1,
work_title="pai-beta",
work_desc="大白智护beta环境",
)
await work.save()
work_content = DB.WorkContent(
user_id=work.creator_id,
work_id=work.id,
content=[
{
"type": "git",
"title": "同步前端仓库",
"description": "clone 分支 pai-beta-build",
"uuid": uuid.uuid4().hex,
"detail": {
"host": "58.214.239.10",
"user": "dgx07",
"password": "f=bHt/.7kRo:KIXq",
"port": 6378,
"sudo": True,
"git_path": "/data/wrok-flow/dbpai-web",
"git_user": "liruwei",
"git_password": "Wsad.8246",
"git_url": "https://tencentgit.dabby.com.cn/dbpai/dbpai-web.git",
"git_branch": "pai-beta-build",
"git_clone_type": "http/https",
"git_clone_depth": 1,
},
},
{
"type": "git",
"title": "同步后端仓库",
"description": "clone 分支 v3.4.2",
"uuid": uuid.uuid4().hex,
"detail": {
"host": "58.214.239.10",
"user": "dgx07",
"password": "f=bHt/.7kRo:KIXq",
"port": 6378,
"sudo": True,
"git_path": "/data/wrok-flow/dbpai-server",
"git_user": "liruwei",
"git_password": "Wsad.8246",
"git_url": "https://tencentgit.dabby.com.cn/dbpai/dbpai-server.git",
"git_branch": "v3.4.2",
"git_clone_type": "http/https",
"git_clone_depth": 1,
},
},
{
"type": "git",
"title": "同步项目集合仓库",
"description": "clone 分支 v3.4.2",
"uuid": uuid.uuid4().hex,
"detail": {
"host": "58.214.239.10",
"user": "dgx07",
"password": "f=bHt/.7kRo:KIXq",
"port": 6378,
"sudo": True,
"git_path": "/data/wrok-flow/dbpai-jenkins",
"git_user": "liruwei",
"git_password": "Wsad.8246",
"git_url": "https://tencentgit.dabby.com.cn/dbpai/dbpai-jenkins.git",
"git_branch": "v3.4.2",
"git_clone_type": "http/https",
"git_clone_depth": 1,
},
},
{
"type": "cmd",
"title": "更新项目集合仓库",
"description": "更新 server/ html/ 内容",
"uuid": uuid.uuid4().hex,
"detail": {
"host": "58.214.239.10",
"user": "dgx07",
"password": "f=bHt/.7kRo:KIXq",
"port": 6378,
"sudo": True,
"cmd": ("cd /data/wrok-flow/dbpai-jenkins" " && rm -fr ./server" " && cp -r ../dbpai-server ./server" " && rm -fr ./html" " && cp -r ../dbpai-web/dist ./html" " && git add ." ' && git commit -m "build"' " && git push"),
},
},
{
"type": "cmd",
"title": "部署",
"description": "重新运行 pai-beta 分支 v3.4.2",
"uuid": uuid.uuid4().hex,
"detail": {
"host": "58.214.239.10",
"user": "dgx07",
"password": "f=bHt/.7kRo:KIXq",
"port": 6378,
"sudo": True,
"cmd": ("cd /data/PAI/dbpai-beta/dbpai-jenkins;" " git stash;" " git pull origin v3.4.2;" " git stash pop;" " docker-compose restart;"),
},
},
{
"type": "status",
"title": "健康监测",
"description": "检测服务是否成功运行",
"uuid": uuid.uuid4().hex,
"detail": {
"host": "58.214.239.10",
"user": "dgx07",
"password": "f=bHt/.7kRo:KIXq",
"port": 6378,
"sudo": True,
"status_url": "http://localhost:1336/api/system/license_info",
},
},
],
)
await work_content.save()
logger.debug("创建")
@asynccontextmanager @asynccontextmanager
async def lifespan(app: FastAPI): async def lifespan(app: FastAPI):
tasks = {} tasks = {}
@ -220,8 +96,6 @@ async def lifespan(app: FastAPI):
# 读取上一次登录状态 # 读取上一次登录状态
await load_session_from_file(app) await load_session_from_file(app)
await _create_demo_records(app)
yield yield
for _, v in tasks.items(): for _, v in tasks.items():
@ -416,7 +290,21 @@ def create_app():
return TableResponse(data=res, total=len(res)) return TableResponse(data=res, total=len(res))
@app.put("/api/flows", tags=["Flow"], description="任务修改", response_model=BaseResponse) @app.put("/api/flows", tags=["Flow"], description="任务修改", response_model=BaseResponse)
async def update_flow(work_uuid: int, body: ClientRequest, user: DB.User = Depends(get_current_user)): async def update_flow(work_uuid: str, body: WorkRequest, user: DB.User = Depends(get_current_user)):
work = await DB.Work.filter(uuid=work_uuid).first()
if not work:
return BaseResponse(success=False, message="Not Found")
work_content = await DB.WorkContent.filter(work_id=work.id).first()
if not work_content:
work_content = DB.WorkContent(
user_id=work.creator_id,
content=body.content,
is_deleted=0,
work_id=work.id,
)
work_content.content = body.content
work_content.update_time = datetime.datetime.now()
await work_content.save()
return BaseResponse() return BaseResponse()
@app.get("/api/flows/detail", tags=["Flow"], description="任务详情", response_model=BaseResponse) @app.get("/api/flows/detail", tags=["Flow"], description="任务详情", response_model=BaseResponse)

View File

@ -0,0 +1,6 @@
from pydantic import BaseModel
class WorkRequest(BaseModel):
work_title: str
work_desc: str
content: list

View File

@ -16,6 +16,10 @@ export const flowDetail = async (id) => {
return request("/api/flows/detail?work_uuid=" + id, "GET") return request("/api/flows/detail?work_uuid=" + id, "GET")
} }
export const flowUpdate = async (id, data = {}) => {
return request("/api/flows?work_uuid=" + id, "PUT", data)
}

View File

@ -14,7 +14,7 @@ import {
ReactFlowProvider, ReactFlowProvider,
} from '@xyflow/react'; } from '@xyflow/react';
import '@xyflow/react/dist/style.css'; import '@xyflow/react/dist/style.css';
import { flowDetail } from "../../api/flow"; import { flowDetail, flowUpdate } 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"; import { ProForm, ProFormText, ProFormTextArea } from "@ant-design/pro-components";
@ -101,41 +101,27 @@ const FlowDetail = () => {
try { try {
const res = await flowDetail(work_uuid); const res = await flowDetail(work_uuid);
const { data: { content: { content: infoList } } } = res; const { data: { content: { content: infoList } } } = res;
let startX = 0;
let startIndex = 1;
if (res?.success) { if (res?.success) {
setRecord(res.data); setRecord(res.data);
formRef?.current?.setFieldsValue(res?.data || {}); formRef?.current?.setFieldsValue(res?.data || {});
const tempEdges = []; const tempEdges = [];
const tempNodes = [{ const tempNodes = [];
id: '1',
position: { x: startX, y: 0 },
sourcePosition: 'right',
type: 'first',
data: { label: '开始', style: { backgroundColor: COLORS['first'] }, position: POSITION['first'] },
}]
infoList.forEach((e, i) => { infoList.forEach((e, i) => {
tempNodes.push({ tempNodes.push({
id: e.uuid, id: e.uuid,
position: { x: startX + 200, y: 0 }, position: e.position,
sourcePosition: 'right', sourcePosition: 'right',
targetPosition: 'left', targetPosition: 'left',
type: e.type, type: e.type,
data: { label: e.title, style: { backgroundColor: COLORS[e.type] }, position: POSITION[e.type] }, data: { label: e.title, style: { backgroundColor: COLORS[e.type] }, position: POSITION[e.type] },
detail: e detail: e
}) })
if (e.edge) {
const sourceNode = tempNodes[startIndex - 1]; tempEdges.push({
const targetNode = tempNodes[startIndex]; ...e.edge,
tempEdges.push({ id: tempEdges.length + 1 + ""
id: `${sourceNode.id}-${targetNode.id}`, });
source: sourceNode.id, }
target: targetNode.id
})
startX += 200;
startIndex += 1;
}); });
setNodes(tempNodes); setNodes(tempNodes);
@ -155,7 +141,7 @@ const FlowDetail = () => {
content: "确认保存修改内容?", content: "确认保存修改内容?",
onOk: async () => { onOk: async () => {
const content = []; const content = [];
nodes.filter(e => e.type != 'first').forEach(e => { nodes.forEach(e => {
const edge = edges.find(obj => obj.target === e.id); const edge = edges.find(obj => obj.target === e.id);
content.push({ content.push({
...e.detail, ...e.detail,
@ -163,7 +149,15 @@ const FlowDetail = () => {
edge: edge ? { source: edge.source, target: edge.target } : undefined edge: edge ? { source: edge.source, target: edge.target } : undefined
}) })
}); });
console.log(content); const res = await flowUpdate(record.uuid, {
content,
...formRef.current.getFieldsValue()
})
if (res?.success) {
message.success("保持成功");
} else {
message.error(res.message);
}
return true; return true;
} }
}); });

View File

@ -43,6 +43,9 @@ const EditNode = forwardRef(({ onFinish }, ref) => {
<ProFormSelect label="节点" rules={[{ required: true }]} name={["detail", "client"]} options={clients} request={onRequest} width='md' /> <ProFormSelect label="节点" rules={[{ required: true }]} name={["detail", "client"]} options={clients} request={onRequest} width='md' />
<ProFormText name='title' rules={[{ required: true }]} label='标题' fieldProps={{ maxLength: 20 }} width='md' /> <ProFormText name='title' rules={[{ required: true }]} label='标题' fieldProps={{ maxLength: 20 }} width='md' />
<ProFormText fieldProps={{ maxLength: 50 }} name='description' label='描述' width="md" /> <ProFormText fieldProps={{ maxLength: 50 }} name='description' label='描述' width="md" />
<div style={{ display: 'none'}}>
<ProFormText name='type' label='描述'/>
</div>
</ProFormGroup> </ProFormGroup>
{record?.type === 'git' && <> {record?.type === 'git' && <>
<Divider orientation="left">Git</Divider> <Divider orientation="left">Git</Divider>