Implement workflow sharing feature with new API endpoints and helper

Co-authored-by: jxxghp <jxxghp@163.com>
This commit is contained in:
Cursor Agent
2025-07-08 15:26:16 +00:00
parent bbffb1420b
commit a2fd3a8d90
2 changed files with 197 additions and 28 deletions

167
WORKFLOW_SHARE_README.md Normal file
View File

@@ -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等字段

View File

@@ -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="工作流不存在")
# 停止工作流