1
0
forked from erp-dev/erp

feat: query all process nodes for business_object

This commit is contained in:
2025-11-17 16:37:21 +08:00
parent d23db848ec
commit 6fd199a218
9 changed files with 973 additions and 3 deletions

View File

@@ -268,6 +268,37 @@ Authorization: Bearer <access_token>
- **描述**: 获取当前待执行节点(`current_state`)的参数模板。
- **注意**: `current_state` 指的是下一个待执行的节点。如果流程已完成,则返回空。
#### 3.7.5. 获取流程的所有节点
- **GET** `/api/v1/stateflow/business-objects/{id}/process-nodes/`
- **描述**: 获取业务对象所属流程的所有状态节点列表,按顺序排列。
- **响应示例**:
```json
{
"count": 3,
"nodes": [
{
"id": 1,
"state_id": 10,
"state_name": "质检",
"order": 0
},
{
"id": 2,
"state_id": 11,
"state_name": "包装",
"order": 1
},
{
"id": 3,
"state_id": 12,
"state_name": "发货",
"order": 2
}
]
}
```
### 3.8. 参数与日志接口 (Custom Actions)
#### 3.8.1. 获取状态流转记录列表
@@ -737,7 +768,7 @@ token = response.json()['access']
# 创建状态
headers = {'Authorization': f'Bearer {token}'}
response = requests.post(
'http://localhost:8000/api/v1/states/',
'http://localhost:8000/api/v1/stateflow/states/',
json={
'name': '待审核',
'description': '等待审核'
@@ -745,26 +776,50 @@ response = requests.post(
headers=headers
)
state = response.json()
# 获取业务对象的流程节点
business_object_id = 1
response = requests.get(
f'http://localhost:8000/api/v1/stateflow/business-objects/{business_object_id}/process-nodes/',
headers=headers
)
nodes_data = response.json()
print(f"流程共有 {nodes_data['count']} 个节点")
for node in nodes_data['nodes']:
print(f" 节点 {node['order']}: {node['state_name']}")
```
### JavaScript (fetch)
```javascript
// 获取状态列表
const response = await fetch('/api/v1/states/?limit=10&offset=0', {
const response = await fetch('/api/v1/stateflow/states/?limit=10&offset=0', {
headers: {
'Authorization': `Bearer ${token}`
}
});
const data = await response.json();
console.log(data.results);
// 获取业务对象的流程节点
const businessObjectId = 1;
const nodesResponse = await fetch(
`/api/v1/stateflow/business-objects/${businessObjectId}/process-nodes/`,
{
headers: {
'Authorization': `Bearer ${token}`
}
}
);
const nodesData = await nodesResponse.json();
console.log(`流程共有 ${nodesData.count} 个节点:`, nodesData.nodes);
```
### curl
```bash
# 创建流程
curl -X POST "http://localhost:8000/api/v1/processes/" \
curl -X POST "http://localhost:8000/api/v1/stateflow/processes/" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
@@ -775,4 +830,8 @@ curl -X POST "http://localhost:8000/api/v1/processes/" \
{"state_id": 2, "order": 1}
]
}'
# 获取业务对象的流程节点
curl -X GET "http://localhost:8000/api/v1/stateflow/business-objects/1/process-nodes/" \
-H "Authorization: Bearer <token>"
```

View File

@@ -476,3 +476,34 @@ def add_parameters_to_state_log(state_log: 'models.StateFlowRecord', remark: str
StateLogParameterRecord: 创建的参数记录
"""
return create_parameter_record(state_log, remark, **parameters)
def get_process_nodes(business_object: 'models.BusinessObject') -> List[dict]:
"""
获取业务对象所属流程的所有状态节点列表
参数:
business_object: BusinessObject 实例
返回:
节点列表,每个元素包含:
{
'id': ProcessNode ID,
'state': State对象,
'state_id': State ID,
'state_name': State 名称,
'order': 节点顺序号
}
"""
process_nodes = business_object.process.process_nodes.select_related('state').order_by('order', 'id')
return [
{
'id': node.id,
'state': node.state,
'state_id': node.state_id,
'state_name': node.state.name,
'order': node.order,
}
for node in process_nodes
]

View File

@@ -652,3 +652,39 @@ class BusinessObjectAPITestCase(TestCase):
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertFalse(response.data['success'])
self.assertIn('流程没有任何节点', response.data['message'])
def test_get_process_nodes(self):
"""测试获取业务对象所属流程的所有状态节点 API"""
response = self.client.get(
f'/api/v1/stateflow/business-objects/{self.business_object.id}/process-nodes/'
)
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIn('count', response.data)
self.assertIn('nodes', response.data)
# 验证节点数量
self.assertEqual(response.data['count'], 3)
self.assertEqual(len(response.data['nodes']), 3)
# 验证节点内容和顺序
nodes = response.data['nodes']
self.assertEqual(nodes[0]['state_id'], self.state1.id)
self.assertEqual(nodes[0]['state_name'], self.state1.name)
self.assertEqual(nodes[0]['order'], 0)
self.assertEqual(nodes[1]['state_id'], self.state2.id)
self.assertEqual(nodes[1]['state_name'], self.state2.name)
self.assertEqual(nodes[1]['order'], 1)
self.assertEqual(nodes[2]['state_id'], self.state3.id)
self.assertEqual(nodes[2]['state_name'], self.state3.name)
self.assertEqual(nodes[2]['order'], 2)
# 验证每个节点都有必要的字段
for node in nodes:
self.assertIn('id', node)
self.assertIn('state_id', node)
self.assertIn('state_name', node)
self.assertIn('order', node)

View File

@@ -288,3 +288,33 @@ class StateFlowServicesTestCase(TestCase):
self.state3.parameters.add(required_param)
params = services.get_state_parameters(self.state3, required_only=True)
self.assertEqual(len(params), 1)
def test_get_process_nodes(self):
"""测试获取业务对象所属流程的所有状态节点"""
# 获取流程节点
nodes = services.get_process_nodes(self.business_object)
# 验证节点数量
self.assertEqual(len(nodes), 3)
# 验证节点顺序和内容
self.assertEqual(nodes[0]['state_id'], self.state1.id)
self.assertEqual(nodes[0]['state_name'], self.state1.name)
self.assertEqual(nodes[0]['order'], 0)
self.assertEqual(nodes[1]['state_id'], self.state2.id)
self.assertEqual(nodes[1]['state_name'], self.state2.name)
self.assertEqual(nodes[1]['order'], 1)
self.assertEqual(nodes[2]['state_id'], self.state3.id)
self.assertEqual(nodes[2]['state_name'], self.state3.name)
self.assertEqual(nodes[2]['order'], 2)
# 验证每个节点都有必要的字段
for node in nodes:
self.assertIn('id', node)
self.assertIn('state', node)
self.assertIn('state_id', node)
self.assertIn('state_name', node)
self.assertIn('order', node)
self.assertIsInstance(node['state'], models.State)