diff --git a/apps/common/constants/permission_constants.py b/apps/common/constants/permission_constants.py index 67a84312f..184ed3f66 100644 --- a/apps/common/constants/permission_constants.py +++ b/apps/common/constants/permission_constants.py @@ -146,6 +146,14 @@ class PermissionConstants(Enum): TOOL_EXPORT = Permission(group=Group.TOOL, operate=Operate.USE, role_list=[RoleConstants.ADMIN, RoleConstants.USER]) + KNOWLEDGE_MODULE_CREATE = Permission(group=Group.KNOWLEDGE, operate=Operate.CREATE, role_list=[RoleConstants.ADMIN, + RoleConstants.USER]) + KNOWLEDGE_MODULE_READ = Permission(group=Group.KNOWLEDGE, operate=Operate.READ, role_list=[RoleConstants.ADMIN, + RoleConstants.USER]) + KNOWLEDGE_MODULE_EDIT = Permission(group=Group.KNOWLEDGE, operate=Operate.EDIT, role_list=[RoleConstants.ADMIN, + RoleConstants.USER]) + KNOWLEDGE_MODULE_DELETE = Permission(group=Group.KNOWLEDGE, operate=Operate.DELETE, role_list=[RoleConstants.ADMIN, + RoleConstants.USER]) def get_workspace_application_permission(self): return lambda r, kwargs: Permission(group=self.value.group, operate=self.value.operate, resource_path= diff --git a/apps/knowledge/migrations/0001_initial.py b/apps/knowledge/migrations/0001_initial.py new file mode 100644 index 000000000..5dd16abcf --- /dev/null +++ b/apps/knowledge/migrations/0001_initial.py @@ -0,0 +1,79 @@ +# Generated by Django 5.2 on 2025-04-25 06:42 + +import django.db.models.deletion +import knowledge.models.knowledge +import mptt.fields +import uuid_utils.compat +from django.db import migrations, models + +from knowledge.models import KnowledgeModule + + +def insert_default_data(apps, schema_editor): + # 创建一个根模块(没有父节点) + KnowledgeModule.objects.create(id='root', name='根目录', user_id='f0dd8f71-e4ee-11ee-8c84-a8a1595801ab') + + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('models_provider', '0001_initial'), + ('users', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='File', + fields=[ + ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, verbose_name='修改时间')), + ('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键id')), + ('file_name', models.CharField(default='', max_length=256, verbose_name='文件名称')), + ('loid', models.IntegerField(verbose_name='loid')), + ('meta', models.JSONField(default=dict, verbose_name='文件关联数据')), + ], + options={ + 'db_table': 'file', + }, + ), + migrations.CreateModel( + name='Knowledge', + fields=[ + ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, verbose_name='修改时间')), + ('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键id')), + ('name', models.CharField(max_length=150, verbose_name='知识库名称')), + ('desc', models.CharField(max_length=256, verbose_name='描述')), + ('type', models.IntegerField(choices=[(0, '通用类型'), (1, 'web站点类型'), (2, '飞书类型'), (3, '语雀类型')], default=0, verbose_name='类型')), + ('meta', models.JSONField(default=dict, verbose_name='元数据')), + ('embedding_mode', models.ForeignKey(default=knowledge.models.knowledge.default_model, on_delete=django.db.models.deletion.DO_NOTHING, to='models_provider.model', verbose_name='向量模型')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to='users.user', verbose_name='所属用户')), + ], + options={ + 'db_table': 'knowledge', + }, + ), + migrations.CreateModel( + name='KnowledgeModule', + fields=[ + ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, verbose_name='修改时间')), + ('id', models.CharField(editable=False, max_length=64, primary_key=True, serialize=False, verbose_name='主键id')), + ('name', models.CharField(max_length=64, verbose_name='文件夹名称')), + ('workspace_id', models.CharField(db_index=True, default='default', max_length=64, verbose_name='工作空间id')), + ('lft', models.PositiveIntegerField(editable=False)), + ('rght', models.PositiveIntegerField(editable=False)), + ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), + ('level', models.PositiveIntegerField(editable=False)), + ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='knowledge.knowledgemodule')), + ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.user', verbose_name='用户id')), + ], + options={ + 'db_table': 'knowledge_module', + }, + ), + migrations.RunPython(insert_default_data), + ] diff --git a/apps/knowledge/models/__init__.py b/apps/knowledge/models/__init__.py index e69de29bb..4a43fce73 100644 --- a/apps/knowledge/models/__init__.py +++ b/apps/knowledge/models/__init__.py @@ -0,0 +1 @@ +from .knowledge import * diff --git a/apps/knowledge/models/knowledge.py b/apps/knowledge/models/knowledge.py index 5fc9d2d77..49b586033 100644 --- a/apps/knowledge/models/knowledge.py +++ b/apps/knowledge/models/knowledge.py @@ -2,6 +2,8 @@ import uuid_utils.compat as uuid from django.db import models from django.db.models.signals import pre_delete from django.dispatch import receiver +from mptt.fields import TreeForeignKey +from mptt.models import MPTTModel from common.db.sql_execute import select_one from common.mixins.app_model_mixin import AppModelMixin @@ -9,7 +11,7 @@ from models_provider.models import Model from users.models import User -class KnowledgeType(models.TextChoices): +class KnowledgeType(models.IntegerChoices): base = 0, '通用类型' web = 1, 'web站点类型' lark = 2, '飞书类型' @@ -21,7 +23,21 @@ def default_model(): return uuid.UUID('42f63a3d-427e-11ef-b3ec-a8a1595801ab') -class DataSet(AppModelMixin): +class KnowledgeModule(MPTTModel, AppModelMixin): + id = models.CharField(primary_key=True, max_length=64, editable=False, verbose_name="主键id") + name = models.CharField(max_length=64, verbose_name="文件夹名称") + user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户id") + workspace_id = models.CharField(max_length=64, verbose_name="工作空间id", default="default", db_index=True) + parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children') + + class Meta: + db_table = "knowledge_module" + + class MPTTMeta: + order_insertion_by = ['name'] + + +class Knowledge(AppModelMixin): id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id") name = models.CharField(max_length=150, verbose_name="知识库名称") desc = models.CharField(max_length=256, verbose_name="描述") diff --git a/apps/maxkb/settings/base.py b/apps/maxkb/settings/base.py index 24fe69d92..c6a75353c 100644 --- a/apps/maxkb/settings/base.py +++ b/apps/maxkb/settings/base.py @@ -40,6 +40,7 @@ INSTALLED_APPS = [ 'drf_spectacular_sidecar', 'users.apps.UsersConfig', 'tools.apps.ToolConfig', + 'knowledge.apps.KnowledgeConfig', 'common', 'system_manage', 'models_provider', diff --git a/apps/modules/serializers/module.py b/apps/modules/serializers/module.py index 44764fadb..026fffb71 100644 --- a/apps/modules/serializers/module.py +++ b/apps/modules/serializers/module.py @@ -6,6 +6,7 @@ from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from common.constants.permission_constants import Group +from knowledge.models import KnowledgeModule from modules.api.module import ModuleCreateRequest from tools.models import ToolModule from tools.serializers.tool_module import ToolModuleTreeSerializer @@ -18,8 +19,7 @@ def get_module_type(source): # todo app module return None elif source == Group.KNOWLEDGE.name: - # todo knowledge module - return None + return KnowledgeModule else: return None diff --git a/apps/tools/migrations/0001_initial.py b/apps/tools/migrations/0001_initial.py index e28dbfcc6..dff684212 100644 --- a/apps/tools/migrations/0001_initial.py +++ b/apps/tools/migrations/0001_initial.py @@ -24,13 +24,13 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ToolModule', fields=[ + ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, verbose_name='修改时间')), ('id', models.CharField(editable=False, max_length=64, primary_key=True, serialize=False, verbose_name='主键id')), ('name', models.CharField(max_length=64, verbose_name='文件夹名称')), ('workspace_id', models.CharField(db_index=True, default='default', max_length=64, verbose_name='工作空间id')), - ('create_time', models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')), - ('update_time', models.DateTimeField(auto_now=True, null=True, verbose_name='修改时间')), ('lft', models.PositiveIntegerField(editable=False)), ('rght', models.PositiveIntegerField(editable=False)), ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)), @@ -49,6 +49,8 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Tool', fields=[ + ('create_time', models.DateTimeField(auto_now_add=True, verbose_name='创建时间')), + ('update_time', models.DateTimeField(auto_now=True, verbose_name='修改时间')), ('id', models.UUIDField(default=uuid_utils.compat.uuid7, editable=False, primary_key=True, serialize=False, verbose_name='主键id')), @@ -68,8 +70,6 @@ class Migration(migrations.Migration): ('template_id', models.UUIDField(default=None, null=True, verbose_name='模版id')), ('workspace_id', models.CharField(default='default', max_length=64, verbose_name='工作空间id', db_index=True)), ('init_params', models.CharField(max_length=102400, null=True, verbose_name='初始化参数')), - ('create_time', models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')), - ('update_time', models.DateTimeField(auto_now=True, null=True, verbose_name='修改时间')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='users.user', verbose_name='用户id')), ('module', diff --git a/apps/tools/models/__init__.py b/apps/tools/models/__init__.py index c7f6bcfcb..4d360990d 100644 --- a/apps/tools/models/__init__.py +++ b/apps/tools/models/__init__.py @@ -1,4 +1,3 @@ # -*- coding: utf-8 -*- from .tool import * -from .tool_module import * diff --git a/apps/tools/models/tool.py b/apps/tools/models/tool.py index 69641ddf7..22b0d451c 100644 --- a/apps/tools/models/tool.py +++ b/apps/tools/models/tool.py @@ -1,8 +1,24 @@ import uuid_utils.compat as uuid from django.db import models +from mptt.fields import TreeForeignKey +from mptt.models import MPTTModel +from common.mixins.app_model_mixin import AppModelMixin from users.models import User -from .tool_module import ToolModule + + +class ToolModule(MPTTModel, AppModelMixin): + id = models.CharField(primary_key=True, max_length=64, editable=False, verbose_name="主键id") + name = models.CharField(max_length=64, verbose_name="文件夹名称") + user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户id") + workspace_id = models.CharField(max_length=64, verbose_name="工作空间id", default="default", db_index=True) + parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children') + + class Meta: + db_table = "tool_module" + + class MPTTMeta: + order_insertion_by = ['name'] class ToolScope(models.TextChoices): @@ -15,7 +31,7 @@ class ToolType(models.TextChoices): CUSTOM = "CUSTOM", "自定义" -class Tool(models.Model): +class Tool(AppModelMixin): id = models.UUIDField(primary_key=True, max_length=128, default=uuid.uuid7, editable=False, verbose_name="主键id") user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户id") name = models.CharField(max_length=64, verbose_name="工具名称") @@ -33,8 +49,6 @@ class Tool(models.Model): module = models.ForeignKey(ToolModule, on_delete=models.CASCADE, verbose_name="模块id", default='root') workspace_id = models.CharField(max_length=64, verbose_name="工作空间id", default="default", db_index=True) init_params = models.CharField(max_length=102400, verbose_name="初始化参数", null=True) - create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True, null=True) - update_time = models.DateTimeField(verbose_name="修改时间", auto_now=True, null=True) class Meta: - db_table = "tool" + db_table = "tool" \ No newline at end of file diff --git a/apps/tools/models/tool_module.py b/apps/tools/models/tool_module.py deleted file mode 100644 index 2e61d4dd0..000000000 --- a/apps/tools/models/tool_module.py +++ /dev/null @@ -1,21 +0,0 @@ -from django.db import models -from mptt.fields import TreeForeignKey -from mptt.models import MPTTModel - -from users.models import User - - -class ToolModule(MPTTModel): - id = models.CharField(primary_key=True, max_length=64, editable=False, verbose_name="主键id") - name = models.CharField(max_length=64, verbose_name="文件夹名称") - user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户id") - workspace_id = models.CharField(max_length=64, verbose_name="工作空间id", default="default", db_index=True) - parent = TreeForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, related_name='children') - create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True, null=True) - update_time = models.DateTimeField(verbose_name="修改时间", auto_now=True, null=True) - - class Meta: - db_table = "tool_module" - - class MPTTMeta: - order_insertion_by = ['name']