Procházet zdrojové kódy

Merge remote-tracking branch 'origin_shh/1.1.3-master' into 1.1.3-master

liangxunge před 1 měsícem
rodič
revize
6353dcecc8

+ 2 - 2
api/controllers/console/datasets/datasets_document.py

@@ -858,7 +858,7 @@ class DocumentStatusApi(DocumentResource):
                     continue
                 #     本人 本人
                 if dataset.edit_auth == 1:
-                    if current_user != dataset.created_by:
+                    if current_user.id != dataset.created_by:
                         document.enable_applicant = current_user.id
                         document.check_status = 1
                         db.session.commit()
@@ -902,7 +902,7 @@ class DocumentStatusApi(DocumentResource):
                 if not document.enabled:
                     continue
                 if dataset.edit_auth == 1:
-                    if current_user != dataset.created_by:
+                    if current_user.id != dataset.created_by:
                         document.enable_applicant = current_user.id
                         db.session.commit()
                         return {"result": "该操作需要提交所有者审核后生效,请确认是否提交"}, 200

+ 2 - 1
api/controllers/console/tag/tags.py

@@ -25,7 +25,8 @@ class TagListApi(Resource):
     def get(self):
         tag_type = request.args.get("type", type=str, default="")
         keyword = request.args.get("keyword", default=None, type=str)
-        tags = TagService.get_tags(tag_type, current_user.current_tenant_id, keyword)
+        label_map = request.args.get("label_map", default=None, type=str)
+        tags = TagService.get_tags(tag_type, current_user.current_tenant_id, keyword, label_map)
 
         return tags, 200
 

+ 1 - 1
api/services/app_service.py

@@ -203,7 +203,7 @@ class AppService:
         app.created_by = account.id
         app.dept_id =account.dept_id
         app.updated_by = account.id
-
+        app.edit_auth = 1
         db.session.add(app)
         db.session.flush()
 

+ 15 - 14
api/services/dataset_service.py

@@ -253,16 +253,11 @@ class DatasetService:
              WHERE t.type = 'knowledge_category'
          """
         params = {}
-
         if tenant_id:
             sql += " AND d.tenant_id = :tenant_id"
             params["tenant_id"] = tenant_id
-
         sql += " GROUP BY t.name, t.id"
-
-        # 注意这里要用 text(sql)
         result = db.session.execute(text(sql), params).fetchall()
-
         total = sum(row.count for row in result)
         if total == 0:
             return []
@@ -271,7 +266,7 @@ class DatasetService:
         stats = []
         for row in result:
             percentage = (row.count / total) * 100
-            stats.append({"type": row.name, "percentage": round(percentage, 2)})
+            stats.append({"type": row.name,"count": row.count, "percentage": round(percentage, 2)})
 
         return stats
 
@@ -439,6 +434,7 @@ class DatasetService:
         dataset.permission = DatasetPermissionEnum.ALL_TEAM
         dataset.provider = provider
         dataset.dept_id = account.dept_id
+        dataset.edit_auth = 1
         db.session.add(dataset)
         db.session.flush()
 
@@ -715,7 +711,7 @@ class DatasetService:
             logging.debug(f"User {user.id} does not have permission to access dataset {dataset.id}")
             raise NoPermissionError("You do not have permission to access this dataset.")
         if user.current_role != TenantAccountRole.OWNER:
-            if user.current_role != Acc.ADMIN and dataset.created_by != user.id:
+            if user.current_role != TenantAccountRole.ADMIN and dataset.created_by != user.id:
                 logging.debug(f"User {user.id} does not have permission to access dataset {dataset.id}")
                 raise NoPermissionError("You do not have permission to access this dataset.")
 
@@ -834,16 +830,16 @@ class DatasetService:
         # 添加创建人部门过滤
         if creator_dept:
             from sqlalchemy.orm import aliased
-            CreatorAccount = aliased(Account)
-            union_query = union_query.join(CreatorAccount, Dataset.created_by == CreatorAccount.id)
-            union_query = union_query.filter(CreatorAccount.dept_id == literal(str(creator_dept)))
+            creator_account = aliased(Account)
+            union_query = union_query.join(creator_account, Dataset.created_by == creator_account.id)
+            union_query = union_query.filter(creator_account.dept_id == literal(str(creator_dept)))
 
         # 添加创建人过滤
         if creator:
             from sqlalchemy.orm import aliased
-            CreatorAccount = aliased(Account)
-            union_query = union_query.join(CreatorAccount, Dataset.created_by == CreatorAccount.id)
-            union_query = union_query.filter(CreatorAccount.name.ilike(f"%{creator}%"))
+            creator_account = aliased(Account)
+            union_query = union_query.join(creator_account, Dataset.created_by == creator_account.id)
+            union_query = union_query.filter(creator_account.name.ilike(f"%{creator}%"))
 
         # 其它过滤
         if search:
@@ -1627,7 +1623,11 @@ class DocumentService:
         name: str,
         batch: str,
     ):
-        if account.current_role == TenantAccountRole.EDITOR:
+        if dataset.edit_auth==1 and account.id!=dataset.created_by:
+            raise ValueError(
+                "Only the creator can upload documents to this knowledge base."
+            )
+        if account.current_role == TenantAccountRole.EDITOR or account.dept_id!= dataset.dept_id:
             document = Document(
                 tenant_id=dataset.tenant_id,
                 dataset_id=dataset.id,
@@ -1865,6 +1865,7 @@ class DocumentService:
             collection_binding_id=dataset_collection_binding_id,
             retrieval_model=retrieval_model.model_dump() if retrieval_model else None,
             dept_id=account.dept_id,
+            edit_auth=1
         )
 
         db.session.add(dataset)  # type: ignore

+ 40 - 2
api/services/tag_service.py

@@ -6,14 +6,17 @@ from sqlalchemy import func
 from werkzeug.exceptions import NotFound
 
 from extensions.ext_database import db
+from models.account import TenantAccountRole
 from models.dataset import Dataset
-from models.model import App, Tag, TagBinding
+from models.model import App, AppPermissionAll, Tag, TagBinding
+from services.errors.account import NoPermissionError
 from services.errors.tag import TagNameDuplicateError
 
 
 class TagService:
     @staticmethod
-    def get_tags(tag_type: str, current_tenant_id: str, keyword: Optional[str] = None) -> list:
+    def get_tags(tag_type: str, current_tenant_id: str, keyword: Optional[str] = None,
+                 label_map: Optional[str] = None) -> list:
         query = (
             db.session.query(Tag.id, Tag.type, Tag.name, func.count(TagBinding.id).label("binding_count"))
             .outerjoin(TagBinding, Tag.id == TagBinding.tag_id)
@@ -22,10 +25,16 @@ class TagService:
         if keyword:
             query = query.filter(db.and_(Tag.name.ilike(f"%{keyword}%")))
         query = query.group_by(Tag.id, Tag.type, Tag.name)
+        if TagService.str2bool(label_map):
+            query = query.having(func.count(TagBinding.id) >= 1)
         results: list = query.order_by(Tag.created_at.desc()).all()
         return results
 
     @staticmethod
+    def str2bool(v: Optional[str]) -> bool:
+        return str(v).lower() in ("true", "1", "yes")
+
+    @staticmethod
     def get_tag_by_tag_name(tag_type: str, tenant_id: str, tag_name: str) -> Optional[Tag]:
         tag: Optional[Tag] = (
             db.session.query(Tag).filter(Tag.type == tag_type, Tag.tenant_id == tenant_id, Tag.name == tag_name).first()
@@ -145,6 +154,8 @@ class TagService:
 
     @staticmethod
     def save_tag_binding(args):
+        # 1.智能体设置可见授权的编辑权限一致,2.知识库的标签都能设置--修改为随设置权限一致
+        TagService.check_target_edit_auth(args["type"], args["target_id"])
         # check if target exists
         TagService.check_target_exists(args["type"], args["target_id"])
         # save tag binding
@@ -167,6 +178,7 @@ class TagService:
 
     @staticmethod
     def delete_tag_binding(args):
+        TagService.check_target_edit_auth(args["type"], args["target_id"])
         # check if target exists
         TagService.check_target_exists(args["type"], args["target_id"])
         # delete tag binding
@@ -199,3 +211,29 @@ class TagService:
                 raise NotFound("App not found")
         else:
             raise NotFound("Invalid binding type")
+
+    @staticmethod
+    def check_target_edit_auth(type: str, target_id: str):
+        if type in {"knowledge", "knowledge_category"}:
+            dataset = (
+                db.session.query(Dataset)
+                .filter(Dataset.id == target_id)
+                .first()
+            )
+            if (
+                    current_user.current_role not in [TenantAccountRole.ADMIN, TenantAccountRole.OWNER]
+                    and dataset.created_by != current_user.id
+            ):
+                raise NoPermissionError("You do not have permission to operate this dataset.")
+        elif type == "app":
+            app = (
+                db.session.query(AppPermissionAll)
+                .filter(AppPermissionAll.has_read_permission == True,
+                        AppPermissionAll.account_id == current_user.id,
+                        AppPermissionAll.app_id == target_id)
+                .first()
+            )
+            if not app:
+                raise NoPermissionError("You do not have permission to operate this app.")
+        else:
+            raise NotFound("Invalid binding type")

+ 3 - 1
web/app/(commonLayout)/datasets/Statistic.tsx

@@ -53,12 +53,13 @@ const Statistic = () => {
         type: 'pie',
         radius: ['26%', '50%'],
         data: typeData.map((v: any) => {
-          v.value = v.value || 100
+          v.value = v.count || 0
           v.name = v.type
           return v
         }),
         label: {
           formatter: '{b} {d}%',
+          overflow: 'break',
         },
         emphasis: {
           disabled: true,
@@ -131,6 +132,7 @@ const Statistic = () => {
       url: '/tags',
       params: {
         type: 'knowledge',
+        label_map: true,
       },
     },
     fetchStatistic,