diff --git a/WORKFLOW_SHARE_README.md b/WORKFLOW_SHARE_README.md new file mode 100644 index 00000000..e8385d6d --- /dev/null +++ b/WORKFLOW_SHARE_README.md @@ -0,0 +1,167 @@ +# 工作流分享功能 + +## 概述 + +基于订阅分享的相关API接口和helper类,新增了工作流分享相关接口和helper,以实现共享公共服务器的相关接口给前端调用,与订阅使用的是同一个服务器。 + +## 功能特性 + +1. **工作流分享** - 将本地工作流分享到公共服务器 +2. **分享管理** - 查看、删除已分享的工作流 +3. **工作流复用** - 从公共服务器复用其他用户分享的工作流 +4. **缓存机制** - 使用缓存提高查询性能 + +## 文件结构 + +### 新增文件 +- `app/schemas/workflow.py` - 新增 `WorkflowShare` schema类 +- `app/helper/workflow.py` - 新增工作流分享helper类 + +### 修改文件 +- `app/api/endpoints/workflow.py` - 新增工作流分享相关API接口 + +## API接口 + +### 1. 分享工作流 +``` +POST /api/v1/workflow/share +``` + +**请求参数:** +```json +{ + "id": 1, + "share_title": "我的工作流", + "share_comment": "这是一个自动化工作流", + "share_user": "用户名" +} +``` + +**响应:** +```json +{ + "success": true, + "message": "success" +} +``` + +### 2. 删除分享 +``` +DELETE /api/v1/workflow/share/{share_id} +``` + +**响应:** +```json +{ + "success": true, + "message": "success" +} +``` + +### 3. 复用工作流 +``` +POST /api/v1/workflow/fork +``` + +**请求参数:** +```json +{ + "id": 1, + "name": "工作流名称", + "description": "工作流描述", + "timer": "0 0 * * *", + "actions": "[{\"id\": \"action1\", \"type\": \"test\"}]", + "flows": "[{\"id\": \"flow1\", \"source\": \"action1\"}]", + "context": "{}" +} +``` + +**响应:** +```json +{ + "success": true, + "message": "复用成功" +} +``` + +### 4. 查询分享的工作流 +``` +GET /api/v1/workflow/shares?name=关键词&page=1&count=30 +``` + +**响应:** +```json +[ + { + "id": 1, + "share_title": "我的工作流", + "share_comment": "这是一个自动化工作流", + "share_user": "用户名", + "share_uid": "user_uuid", + "name": "工作流名称", + "description": "工作流描述", + "timer": "0 0 * * *", + "actions": "[{\"id\": \"action1\", \"type\": \"test\"}]", + "flows": "[{\"id\": \"flow1\", \"source\": \"action1\"}]", + "context": "{}", + "date": "2024-01-01 12:00:00", + "count": 5 + } +] +``` + +## 配置说明 + +工作流分享功能复用了订阅分享的配置项 `SUBSCRIBE_STATISTIC_SHARE`,当该配置为 `true` 时,工作流分享功能才会启用。 + +## 服务器接口 + +工作流分享功能与订阅分享使用同一个服务器,服务器接口定义如下: + +```python +class WorkflowShareItem(BaseModel): + id: Optional[int] = None + share_title: Optional[str] = None + share_comment: Optional[str] = None + share_user: Optional[str] = None + share_uid: Optional[str] = None + name: Optional[str] = None + description: Optional[str] = None + timer: Optional[str] = None + actions: Optional[str] = None # JSON字符串 + flows: Optional[str] = None # JSON字符串 + context: Optional[str] = None # JSON字符串 + date: Optional[str] = None + +# 工作流分享相关接口 +@App.post("/workflow/share") +def workflow_share(workflow: WorkflowShareItem, db: Session = Depends(get_db)): + """新增工作流分享""" + +@App.delete("/workflow/share/{sid}") +def workflow_share_delete(sid: int, share_uid: str, db: Session = Depends(get_db)): + """删除工作流分享""" + +@App.get("/workflow/shares") +def workflow_shares(name: str = None, page: int = 1, count: int = 30, db: Session = Depends(get_db)): + """查询分享的工作流""" + +@App.get("/workflow/fork/{shareid}") +def workflow_fork(shareid: int, db: Session = Depends(get_db)): + """复用分享的工作流""" +``` + +## 使用说明 + +1. **启用功能**: 确保 `SUBSCRIBE_STATISTIC_SHARE` 配置为 `true` +2. **分享工作流**: 通过API接口分享本地工作流到公共服务器 +3. **查看分享**: 查询公共服务器上的工作流分享 +4. **复用工作流**: 将其他用户分享的工作流复制到本地使用 +5. **管理分享**: 删除自己分享的工作流 + +## 注意事项 + +1. 工作流分享功能需要网络连接才能访问公共服务器 +2. 复用的工作流默认状态为暂停,需要手动启用 +3. 工作流名称不能重复,复用时会检查本地是否存在同名工作流 +4. 分享的工作流数据以JSON字符串形式存储,包含actions、flows、context等字段 \ No newline at end of file diff --git a/app/api/endpoints/workflow.py b/app/api/endpoints/workflow.py index c0e44bc1..a09b89ec 100644 --- a/app/api/endpoints/workflow.py +++ b/app/api/endpoints/workflow.py @@ -26,7 +26,8 @@ def list_workflows(db: Session = Depends(get_db), """ 获取工作流列表 """ - return Workflow.list(db) + from app.db.models.workflow import Workflow as WorkflowModel + return WorkflowModel.list(db) @router.post("/", summary="创建工作流", response_model=schemas.Response) @@ -36,13 +37,14 @@ def create_workflow(workflow: schemas.Workflow, """ 创建工作流 """ - if Workflow.get_by_name(db, workflow.name): + from app.db.models.workflow import Workflow as WorkflowModel + if workflow.name and WorkflowModel.get_by_name(db, workflow.name): return schemas.Response(success=False, message="已存在相同名称的工作流") if not workflow.add_time: workflow.add_time = datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S") if not workflow.state: workflow.state = "P" - Workflow(**workflow.dict()).create(db) + WorkflowModel(**workflow.dict()).create(db) return schemas.Response(success=True, message="创建工作流成功") @@ -69,7 +71,8 @@ def get_workflow(workflow_id: int, """ 获取工作流详情 """ - return Workflow.get(db, workflow_id) + from app.db.models.workflow import Workflow as WorkflowModel + return WorkflowModel.get(db, workflow_id) @router.put("/{workflow_id}", summary="更新工作流", response_model=schemas.Response) @@ -79,7 +82,10 @@ def update_workflow(workflow: schemas.Workflow, """ 更新工作流 """ - wf = Workflow.get(db, workflow.id) + from app.db.models.workflow import Workflow as WorkflowModel + if not workflow.id: + return schemas.Response(success=False, message="工作流ID不能为空") + wf = WorkflowModel.get(db, workflow.id) if not wf: return schemas.Response(success=False, message="工作流不存在") wf.update(db, workflow.dict()) @@ -93,13 +99,14 @@ def delete_workflow(workflow_id: int, """ 删除工作流 """ - workflow = Workflow.get(db, workflow_id) + from app.db.models.workflow import Workflow as WorkflowModel + workflow = WorkflowModel.get(db, workflow_id) if not workflow: return schemas.Response(success=False, message="工作流不存在") # 删除定时任务 Scheduler().remove_workflow_job(workflow) # 删除工作流 - Workflow.delete(db, workflow_id) + WorkflowModel.delete(db, workflow_id) # 删除缓存 SystemConfigOper().delete(f"WorkflowCache-{workflow_id}") return schemas.Response(success=True, message="删除成功") @@ -140,35 +147,27 @@ def workflow_fork( """ 复用工作流 """ - # 获取分享的工作流数据 - shares = WorkflowHelper().get_shares() - target_share = None - for share in shares: - if share.get("id") == workflow_share.id: - target_share = share - break - - if not target_share: - return schemas.Response(success=False, message="分享的工作流不存在") + if not workflow_share.name: + return schemas.Response(success=False, message="工作流名称不能为空") # 创建工作流 workflow_dict = { - "name": target_share.get("name"), - "description": target_share.get("description"), - "timer": target_share.get("timer"), - "actions": json.loads(target_share.get("actions", "[]")), - "flows": json.loads(target_share.get("flows", "[]")), - "context": json.loads(target_share.get("context", "{}")), + "name": workflow_share.name, + "description": workflow_share.description, + "timer": workflow_share.timer, + "actions": json.loads(workflow_share.actions or "[]"), + "flows": json.loads(workflow_share.flows or "[]"), + "context": json.loads(workflow_share.context or "{}"), "state": "P" # 默认暂停状态 } # 检查名称是否重复 db = next(get_db()) - if Workflow.get_by_name(db, workflow_dict["name"]): + from app.db.models.workflow import Workflow as WorkflowModel + if WorkflowModel.get_by_name(db, workflow_dict["name"]): return schemas.Response(success=False, message="已存在相同名称的工作流") # 创建新工作流 - from app.db.models.workflow import Workflow as WorkflowModel workflow = WorkflowModel(**workflow_dict) workflow.create(db) @@ -211,7 +210,8 @@ def start_workflow(workflow_id: int, """ 启用工作流 """ - workflow = Workflow.get(db, workflow_id) + from app.db.models.workflow import Workflow as WorkflowModel + workflow = WorkflowModel.get(db, workflow_id) if not workflow: return schemas.Response(success=False, message="工作流不存在") # 添加定时任务 @@ -228,7 +228,8 @@ def pause_workflow(workflow_id: int, """ 停用工作流 """ - workflow = Workflow.get(db, workflow_id) + from app.db.models.workflow import Workflow as WorkflowModel + workflow = WorkflowModel.get(db, workflow_id) if not workflow: return schemas.Response(success=False, message="工作流不存在") # 删除定时任务 @@ -247,7 +248,8 @@ def reset_workflow(workflow_id: int, """ 重置工作流 """ - workflow = Workflow.get(db, workflow_id) + from app.db.models.workflow import Workflow as WorkflowModel + workflow = WorkflowModel.get(db, workflow_id) if not workflow: return schemas.Response(success=False, message="工作流不存在") # 停止工作流