Skip to content

Commit 3b8dcea

Browse files
committed
feat: trigger task record
1 parent df5487b commit 3b8dcea

File tree

12 files changed

+357
-122
lines changed

12 files changed

+357
-122
lines changed

apps/trigger/migrations/0001_initial.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# Generated by Django 5.2.8 on 2026-01-22 03:09
1+
# Generated by Django 5.2.9 on 2026-01-23 09:47
22

3+
import common.encoder.encoder
34
import django.db.models.deletion
45
import uuid_utils.compat
56
from django.db import migrations, models
@@ -40,14 +41,34 @@ class Migration(migrations.Migration):
4041
('update_time', models.DateTimeField(auto_now=True, db_index=True, verbose_name='修改时间')),
4142
('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键id')),
4243
('source_type', models.CharField(choices=[('APPLICATION', 'Application'), ('TOOL', 'Tool')], default='APPLICATION', max_length=256, verbose_name='触发器任务类型')),
43-
('source_id', models.UUIDField(blank=True, null=True, verbose_name='资源id')),
44+
('source_id', models.UUIDField(verbose_name='资源id')),
4445
('is_active', models.BooleanField(db_index=True, default=True)),
4546
('parameter', models.JSONField(default=list)),
4647
('meta', models.JSONField(default=dict)),
4748
('trigger', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='trigger.trigger')),
4849
],
4950
options={
5051
'db_table': 'event_trigger_task',
52+
'unique_together': {('trigger', 'source_id', 'source_type')},
53+
},
54+
),
55+
migrations.CreateModel(
56+
name='TaskRecord',
57+
fields=[
58+
('create_time', models.DateTimeField(auto_now_add=True, db_index=True, verbose_name='创建时间')),
59+
('update_time', models.DateTimeField(auto_now=True, db_index=True, verbose_name='修改时间')),
60+
('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键id')),
61+
('source_type', models.CharField(choices=[('APPLICATION', 'Application'), ('TOOL', 'Tool')], default='APPLICATION', max_length=256, verbose_name='触发器任务类型')),
62+
('source_id', models.UUIDField(verbose_name='资源id')),
63+
('task_record_id', models.UUIDField(verbose_name='任务记录id')),
64+
('meta', models.JSONField(default=dict, encoder=common.encoder.encoder.SystemEncoder)),
65+
('state', models.CharField(choices=[('PENDING', 'Pending'), ('STARTED', 'Started'), ('SUCCESS', 'Success'), ('FAILURE', 'Failure'), ('REVOKE', 'Revoke'), ('REVOKED', 'Revoked')], default='STARTED', max_length=20, verbose_name='状态')),
66+
('run_time', models.FloatField(default=0, verbose_name='运行时长')),
67+
('trigger', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='trigger.trigger')),
68+
('trigger_task', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='trigger.triggertask')),
69+
],
70+
options={
71+
'db_table': 'event_trigger_task_record',
5172
},
5273
),
5374
]

apps/trigger/migrations/0002_taskrecord.py

Lines changed: 0 additions & 32 deletions
This file was deleted.

apps/trigger/migrations/0003_alter_taskrecord_task_record_id.py

Lines changed: 0 additions & 18 deletions
This file was deleted.

apps/trigger/migrations/0004_alter_triggertask_unique_together.py

Lines changed: 0 additions & 17 deletions
This file was deleted.

apps/trigger/models/trigger.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class TriggerTask(AppModelMixin):
4848
source_type = models.CharField(verbose_name="触发器任务类型", choices=TriggerTaskTypeChoices.choices,
4949
default=TriggerTaskTypeChoices.APPLICATION, max_length=256
5050
)
51-
source_id = models.UUIDField(verbose_name="资源id", blank=True, null=True)
51+
source_id = models.UUIDField(verbose_name="资源id")
5252
is_active = models.BooleanField(default=True, db_index=True)
5353
parameter = models.JSONField(default=list)
5454
meta = models.JSONField(default=dict)
@@ -60,10 +60,15 @@ class Meta:
6060

6161
class TaskRecord(AppModelMixin):
6262
id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id")
63+
64+
trigger = models.ForeignKey(Trigger, on_delete=models.CASCADE)
65+
66+
trigger_task = models.ForeignKey(TriggerTask, on_delete=models.CASCADE)
67+
6368
source_type = models.CharField(verbose_name="触发器任务类型", choices=TriggerTaskTypeChoices.choices,
6469
default=TriggerTaskTypeChoices.APPLICATION, max_length=256)
65-
source_id = models.UUIDField(verbose_name="资源id", blank=True, null=True)
66-
task_record_id = models.UUIDField(verbose_name="任务记录id", blank=True, null=True)
70+
source_id = models.UUIDField(verbose_name="资源id")
71+
task_record_id = models.UUIDField(verbose_name="任务记录id")
6772
meta = models.JSONField(default=dict, encoder=SystemEncoder)
6873
state = models.CharField(verbose_name='状态', max_length=20,
6974
choices=State.choices,

apps/trigger/serializers/trigger_task.py

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,17 @@
66
@date:2026/1/14 16:34
77
@desc:
88
"""
9+
import os
10+
11+
from django.db import models
912
from django.db.models import QuerySet
1013
from django.utils.translation import gettext_lazy as _
1114
from rest_framework import serializers
1215

13-
from trigger.models import TriggerTask
16+
from common.db.search import native_page_search, get_dynamics_model
17+
from common.utils.common import get_file_content
18+
from maxkb.conf import PROJECT_DIR
19+
from trigger.models import TriggerTask, TaskRecord
1420

1521

1622
class TriggerTaskResponse(serializers.ModelSerializer):
@@ -32,3 +38,38 @@ def list(self, with_valid=True):
3238
if with_valid:
3339
self.is_valid(raise_exception=True)
3440
return [TriggerTaskResponse(row).data for row in self.get_query_set()]
41+
42+
43+
class TriggerTaskRecordQuerySerializer(serializers.Serializer):
44+
trigger_id = serializers.CharField(required=True, label=_("Trigger ID"))
45+
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
46+
state = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_('Trigger task'))
47+
name = serializers.CharField(required=False, allow_blank=True, allow_null=True, label=_('Trigger task'))
48+
49+
def get_query_set(self):
50+
trigger_query_set = QuerySet(
51+
model=get_dynamics_model({
52+
'ett.state': models.CharField(),
53+
'sdc.name': models.CharField(),
54+
'ett.workspace_id': models.CharField(),
55+
'ett.trigger_id': models.UUIDField(),
56+
}))
57+
trigger_query_set = trigger_query_set.filter(
58+
**{'ett.trigger_id': self.data.get("trigger_id")})
59+
if self.data.get('state'):
60+
trigger_query_set = trigger_query_set.filter(**{'ett.state': self.data.get('state')})
61+
if self.data.get("name"):
62+
trigger_query_set = trigger_query_set.filter(**{'sdc.name__contains': self.data.get('name')})
63+
return trigger_query_set
64+
65+
def list(self, with_valid=True):
66+
if with_valid:
67+
self.is_valid(raise_exception=True)
68+
return [TriggerTaskResponse(row).data for row in self.get_query_set()]
69+
70+
def page(self, current_page, page_size, with_valid=True):
71+
if with_valid:
72+
self.is_valid(raise_exception=True)
73+
return native_page_search(current_page, page_size, self.get_query_set(), get_file_content(
74+
os.path.join(PROJECT_DIR, "apps", "trigger", "sql", 'get_trigger_task_record_page_list.sql')
75+
))
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
WITH source_data_cte AS (SELECT 'APPLICATION' as source_type,
2+
id,
3+
"name",
4+
"desc",
5+
"user_id",
6+
"workspace_id",
7+
"icon",
8+
"type",
9+
"folder_id"
10+
FROM application
11+
UNION ALL
12+
SELECT 'TOOL' as source_type,
13+
id,
14+
"name",
15+
"desc",
16+
"user_id",
17+
"workspace_id",
18+
"icon",
19+
"tool_type"::text as "type",
20+
"folder_id"
21+
FROM tool)
22+
select ett.*,
23+
sdc.name as source_name,
24+
sdc.icon as source_icon
25+
from event_trigger_task_record ett
26+
left join source_data_cte sdc
27+
on ett.source_id = sdc.id and ett.source_type = sdc.source_type

apps/trigger/urls.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@
1919
name='delete batch'),
2020
path('workspace/<str:workspace_id>/trigger/batch_activate', views.TriggerView.BatchActivate.as_view(),
2121
name='activate batch'),
22-
path('workspace/<str:workspace_id>/trigger/<str:trigger_id>', views.TriggerView.Operate.as_view(), name='trigger operate'),
22+
path('workspace/<str:workspace_id>/trigger/<str:trigger_id>', views.TriggerView.Operate.as_view(),
23+
name='trigger operate'),
2324
path('workspace/<str:workspace_id>/trigger/<int:current_page>/<int:page_size>', views.TriggerView.Page.as_view(),
2425
name='trigger_page'),
2526
path('workspace/<str:workspace_id>/<str:source_type>/<str:source_id>/trigger/<str:trigger_id>',
2627
views.TaskSourceTriggerView.Operate.as_view(), name='task source trigger operate'),
27-
path('workspace/<str:workspace_id>/<str:source_type>/<str:source_id>/trigger', views.TaskSourceTriggerView.as_view(), name='task source trigger'),
28+
path('workspace/<str:workspace_id>/<str:source_type>/<str:source_id>/trigger',
29+
views.TaskSourceTriggerView.as_view(), name='task source trigger'),
30+
path(
31+
'workspace/<str:workspace_id>/trigger/<str:trigger_id>/task_record/<int:current_page>/<int:page_size>',
32+
views.TriggerTaskRecordPageView.as_view(), name='trigger_task_record'),
2833
path('workspace/<str:workspace_id>/task', views.TriggerTaskView.as_view(), name='task'),
2934
path('trigger/v1/webhook/<str:trigger_id>', EventTriggerView.as_view(), name='trigger_webhook')
3035
]

apps/trigger/views/trigger_task.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
from application.api.application_api import ApplicationCreateAPI
1515
from common import result
16-
from trigger.serializers.trigger_task import TriggerTaskQuerySerializer
16+
from trigger.serializers.trigger_task import TriggerTaskQuerySerializer, TriggerTaskRecordQuerySerializer
1717

1818

1919
class TriggerTaskView(APIView):
@@ -30,3 +30,27 @@ class TriggerTaskView(APIView):
3030
def get(self, request: Request, workspace_id: str, trigger_id: str):
3131
return result.success(
3232
TriggerTaskQuerySerializer(data={'workspace_id': workspace_id, 'trigger_id': trigger_id}).list())
33+
34+
35+
class TriggerTaskRecordView(APIView):
36+
pass
37+
38+
39+
class TriggerTaskRecordPageView(APIView):
40+
@extend_schema(
41+
methods=['GET'],
42+
description=_('Get a paginated list of execution records for trigger tasks.'),
43+
summary=_('Get a paginated list of execution records for trigger tasks.'),
44+
operation_id=_('Get a paginated list of execution records for trigger tasks.'), # type: ignore
45+
parameters=ApplicationCreateAPI.get_parameters(),
46+
request=ApplicationCreateAPI.get_request(),
47+
responses=ApplicationCreateAPI.get_response(),
48+
tags=[_('Trigger')] # type: ignore
49+
)
50+
def get(self, request: Request, workspace_id: str, trigger_id: str, current_page: int, page_size: int):
51+
return result.success(
52+
TriggerTaskRecordQuerySerializer(
53+
data={'workspace_id': workspace_id, 'trigger_id': trigger_id,
54+
'state': request.query_params.get('state'),
55+
'name': request.query_params.get('name')})
56+
.page(current_page, page_size))

0 commit comments

Comments
 (0)