Skip to content

Commit a26273c

Browse files
committed
feat: trigger init
1 parent bec3dbb commit a26273c

7 files changed

Lines changed: 227 additions & 2 deletions

File tree

apps/maxkb/urls/web.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
path(admin_api_prefix, include("knowledge.urls")),
4242
path(admin_api_prefix, include("system_manage.urls")),
4343
path(admin_api_prefix, include("application.urls")),
44+
path(admin_api_prefix, include("trigger.urls")),
4445
path(admin_api_prefix, include("oss.urls")),
4546
path(chat_api_prefix, include("oss.urls")),
4647
path(chat_api_prefix, include("chat.urls")),
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# coding=utf-8
2+
"""
3+
@project: MaxKB
4+
@Author:niu
5+
@file: trigger.py
6+
@date:2026/1/14 11:48
7+
@desc:
8+
"""
9+
import asyncio
10+
import hashlib
11+
import json
12+
import os
13+
import pickle
14+
import re
15+
import tempfile
16+
import zipfile
17+
from functools import reduce
18+
from typing import Dict, List
19+
20+
import requests
21+
import uuid_utils.compat as uuid
22+
from django.core import validators
23+
from django.db import models, transaction
24+
from django.db.models import QuerySet, Q
25+
from django.http import HttpResponse
26+
from django.utils import timezone
27+
from django.utils.translation import gettext_lazy as _
28+
from langchain_mcp_adapters.client import MultiServerMCPClient
29+
from rest_framework import serializers, status
30+
from rest_framework.utils.formatting import lazy_format
31+
32+
from application.flow.common import Workflow
33+
from application.models.application import Application, ApplicationTypeChoices, \
34+
ApplicationFolder, ApplicationVersion, ApplicationKnowledgeMapping
35+
from application.models.application_access_token import ApplicationAccessToken
36+
from application.serializers.common import update_resource_mapping_by_application
37+
from common import result
38+
from common.cache_data.application_access_token_cache import del_application_access_token
39+
from common.database_model_manage.database_model_manage import DatabaseModelManage
40+
from common.db.search import native_search, native_page_search
41+
from common.exception.app_exception import AppApiException
42+
from common.field.common import UploadedFileField
43+
from common.utils.common import get_file_content, restricted_loads, generate_uuid, _remove_empty_lines, \
44+
bytes_to_uploaded_file
45+
from common.utils.logger import maxkb_logger
46+
from knowledge.models import Knowledge, KnowledgeScope
47+
from knowledge.serializers.knowledge import KnowledgeSerializer, KnowledgeModelSerializer
48+
from maxkb.conf import PROJECT_DIR
49+
from models_provider.models import Model
50+
from models_provider.tools import get_model_instance_by_model_workspace_id
51+
from system_manage.models import WorkspaceUserResourcePermission, AuthTargetType
52+
from system_manage.models.resource_mapping import ResourceMapping
53+
from system_manage.serializers.resource_mapping_serializers import ResourceMappingSerializer
54+
from system_manage.serializers.user_resource_permission import UserResourcePermissionSerializer
55+
from tools.models import Tool, ToolScope
56+
from tools.serializers.tool import ToolExportModelSerializer
57+
from trigger.models import TriggerTypeChoices, Trigger
58+
from users.models import User
59+
from users.serializers.user import is_workspace_manage
60+
61+
62+
63+
class TriggerTaskCreateRequest(serializers.Serializer):
64+
pass
65+
66+
class TriggerCreateRequest(serializers.Serializer):
67+
name = serializers.CharField(required=True, label=_('trigger name'))
68+
desc = serializers.CharField(required=False, allow_null=True, allow_blank=True, label=_('trigger description'))
69+
trigger_type = serializers.ChoiceField(choices=TriggerTypeChoices)
70+
trigger_setting = serializers.DictField(required=True, label=_("trigger setting"))
71+
meta = models.JSONField(required=False, allow_null=True, allow_blank=True, default=dict)
72+
is_active = serializers.BooleanField(required=False, label=_('Is active'))
73+
trigger_task = serializers
74+
75+
76+
77+
class TriggerResponse(serializers.ModelSerializer):
78+
class Meta:
79+
model = Trigger
80+
fields = "__all__"
81+
82+
class TriggerSerializer(serializers.Serializer):
83+
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
84+
user_id = serializers.UUIDField(required=True, label=_("User ID"))
85+
86+
@transaction.atomic
87+
def insert(self, instance, with_valid=True):
88+
if with_valid:
89+
self.is_valid(raise_exception=True)
90+
TriggerCreateRequest(data=instance).is_valid(raise_exception=True)
91+
92+
trigger_model = Trigger(
93+
id=uuid.uuid7(),
94+
name=instance.get('name'),
95+
workspace_id=self.data.get('workspace_id'),
96+
desc=instance.get('desc'),
97+
trigger_type=instance.get('trigger_type'),
98+
trigger_setting=instance.get('trigger_setting'),
99+
meta=instance.get('meta', {}),
100+
is_active=False,
101+
user_id=self.data.get('user_id'),
102+
)
103+
trigger_model.save()
104+
105+
106+
107+
return TriggerResponse(trigger_model).data
108+
109+
class TriggerOperateSerializer(serializers.Serializer):
110+
trigger_id = serializers.UUIDField(required=True, label=_('trigger id'))
111+
user_id = serializers.UUIDField(required=True, label=_("User ID"))
112+
workspace_id = serializers.CharField(required=True, label=_('workspace id'))
113+
114+
def is_valid(self, *, raise_exception=False):
115+
super().is_valid(raise_exception=True)
116+
workspace_id = self.data.get('workspace_id')
117+
query_set = QuerySet(Trigger).filter(id=self.data.get('trigger_id'))
118+
if workspace_id:
119+
query_set = query_set.filter(workspace_id=workspace_id)
120+
if not query_set.exists():
121+
raise AppApiException(500, _('Trigger id does not exist'))
122+
123+
124+
125+

apps/trigger/urls.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,13 @@
66
@date:2026/1/9 16:15
77
@desc:
88
"""
9+
from django.urls import path
10+
11+
from . import views
12+
13+
app_name = "trigger"
14+
15+
urlpatterns = [
16+
path('workspace/<str:workspace_id>/trigger', views.TriggerView.as_view(), name='trigger'),
17+
path('workspace/<str:workspace_id>/trigger/<int:current_page>/<int:page_size>', views.TriggerView.as_view(), name='trigger_page'),
18+
]

apps/trigger/views/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
@date:2026/1/9 16:15
77
@desc:
88
"""
9+
from .trigger import *

apps/trigger/views/trigger.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# coding=utf-8
2+
"""
3+
@project: MaxKB
4+
@Author:niu
5+
@file: trigger.py
6+
@date:2026/1/14 11:44
7+
@desc:
8+
"""
9+
from django.db.models import QuerySet
10+
from django.http import HttpResponse
11+
from django.utils.translation import gettext_lazy as _
12+
from drf_spectacular.utils import extend_schema
13+
from rest_framework.parsers import MultiPartParser
14+
from rest_framework.request import Request
15+
from rest_framework.views import APIView
16+
17+
from application.api.application_api import ApplicationCreateAPI, ApplicationQueryAPI, ApplicationImportAPI, \
18+
ApplicationExportAPI, ApplicationOperateAPI, ApplicationEditAPI, TextToSpeechAPI, SpeechToTextAPI, PlayDemoTextAPI
19+
from application.models import Application
20+
from application.serializers.application import ApplicationSerializer, Query, ApplicationOperateSerializer
21+
from common import result
22+
from common.auth import TokenAuth
23+
from common.auth.authentication import has_permissions, get_is_permissions
24+
from common.constants.permission_constants import PermissionConstants, RoleConstants, ViewPermission, CompareConstants
25+
from common.log.log import log
26+
from tools.api.tool import GetInternalToolAPI
27+
from trigger.serializers.trigger import TriggerSerializer
28+
29+
30+
class TriggerApi(APIView):
31+
authentication_classes = [TokenAuth]
32+
33+
@extend_schema(
34+
methods=['POST'],
35+
description=_('Create trigger'),
36+
summary=_('Create trigger'),
37+
operation_id=_('Create trigger'), # type: ignore
38+
parameters=ApplicationCreateAPI.get_parameters(),
39+
request=ApplicationCreateAPI.get_request(),
40+
responses=ApplicationCreateAPI.get_response(),
41+
tags=[_('Trigger')] # type: ignore
42+
)
43+
44+
45+
def post(self, request: Request, workspace_id: str):
46+
return result.success(TriggerSerializer(
47+
data={'workspace_id': workspace_id,'user_id': request.user.id}).insert(request.data))
48+
49+
50+
51+
52+

ui/src/components/app-icon/icons/about.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,31 @@ export default {
2121
])
2222
},
2323
},
24+
'app-trigger': {
25+
iconReader: () => {
26+
return h('i', [
27+
h(
28+
'svg',
29+
{
30+
style: { height: '100%', width: '100%' },
31+
viewBox: '0 0 18 18',
32+
version: '1.1',
33+
xmlns: 'http://www.w3.org/2000/svg',
34+
},
35+
[
36+
h('path', {
37+
d: 'M9.16458 4.44856C9.09375 1.9795 7.06958 0 4.58333 0C2.05208 0 0 2.052 0 4.58314C0 7.06804 1.97708 9.09087 4.44458 9.1642L3.72792 7.37219C3.24691 7.22438 2.81234 6.95463 2.46643 6.58918C2.12052 6.22374 1.87505 5.77501 1.75388 5.28663C1.63271 4.79826 1.63995 4.28684 1.77492 3.80209C1.90988 3.31734 2.16797 2.87575 2.5241 2.52025C2.88022 2.16475 3.32227 1.90743 3.80727 1.77331C4.29227 1.63918 4.80372 1.63281 5.29191 1.75481C5.7801 1.87682 6.22842 2.12305 6.59329 2.46957C6.95816 2.81609 7.22717 3.25111 7.37417 3.73234L9.16458 4.44856Z',
38+
fill: '#3370FF',
39+
}),
40+
h('path', {
41+
d: 'M8.98125 17.1364C9.26292 17.8405 10.2629 17.8326 10.5333 17.1239L12.3442 12.3799L17.1263 10.5329C17.8325 10.26 17.8383 9.26295 17.1354 8.98171L5.35042 4.26774C4.67 3.99567 3.995 4.67106 4.26709 5.35103L8.98125 17.1364Z',
42+
fill: '#3370FF',
43+
}),
44+
],
45+
),
46+
])
47+
},
48+
},
2449
'app-help': {
2550
iconReader: () => {
2651
return h('i', [

ui/src/layout/layout-header/top-about/index.vue

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
<template>
22
<div class="flex align-center">
3-
<el-button round @click="toUrl('https://maxkb.cn/pricing.html')" class="pricing-button mr-8"
3+
<el-button
4+
round
5+
@click="toUrl('https://maxkb.cn/pricing.html')"
6+
class="pricing-button mr-8"
47
v-hasPermission="EditionConst.IS_CE"
58
>
69
<AppIcon iconName="app-pricing" class="mr-8"></AppIcon>
710
{{ $t('common.upgrade') }}
811
</el-button>
12+
<el-tooltip effect="dark" :content="$t('layout.trigger', '触发器')" placement="top" v-if="true">
13+
<AppIcon
14+
iconName="app-trigger"
15+
class="cursor color-secondary mr-8 ml-8"
16+
style="font-size: 20px"
17+
@click=""
18+
></AppIcon>
19+
</el-tooltip>
920
<el-tooltip
1021
effect="dark"
1122
:content="$t('layout.github')"
@@ -49,7 +60,7 @@
4960
</template>
5061
<script setup lang="ts">
5162
import useStore from '@/stores'
52-
import { EditionConst, RoleConst } from '@/utils/permission/data';
63+
import { EditionConst, RoleConst } from '@/utils/permission/data'
5364
const { theme, user } = useStore()
5465
5566
function toUrl(url: string) {

0 commit comments

Comments
 (0)