diff --git a/vue-fastapi-backend/module_admin/dao/data_ast_content_dao.py b/vue-fastapi-backend/module_admin/dao/data_ast_content_dao.py
index 423d591..4b522f3 100644
--- a/vue-fastapi-backend/module_admin/dao/data_ast_content_dao.py
+++ b/vue-fastapi-backend/module_admin/dao/data_ast_content_dao.py
@@ -9,6 +9,7 @@ from module_admin.entity.do.user_do import SysUser
 from module_admin.entity.vo.data_ast_content_vo import DataCatalogPageQueryModel, DeleteDataCatalogModel,DataCatalogChild,DataAstBookmarkRelaRequest,DataAstIndxRequest,DataAstIndxResponse
 from utils.page_util import PageUtil
 from utils.log_util import logger
+from exceptions.exception import ServiceException
 
 
 class DataCatalogDAO:
@@ -176,7 +177,33 @@ class DataCatalogDAO:
         )
         return data_ast_list
 
-
+    @classmethod
+    async def check_duplicate_catalog(cls, db: AsyncSession, catalog1: dict, exclude_content_onum: int = None):
+        """
+        校验同一父节点下是否已存在相同名称的目录(可排除指定 content_onum)
+    
+        :param db: ORM 对象
+        :param catalog1: 主目录对象(DataAstContent)
+        :param exclude_content_onum: 可选,编辑时排除自己
+        :return: 如果存在重复目录,抛出 ServiceException
+        """
+        query = select(DataAstContent).where(
+            and_(
+                DataAstContent.supr_content_onum == catalog1.get("supr_content_onum"),
+                DataAstContent.content_name == catalog1.get("content_name")
+            )
+        )
+    
+        if exclude_content_onum:
+            query = query.where(DataAstContent.content_onum != exclude_content_onum)
+    
+        result = await db.execute(query)
+        exist_catalog = result.scalars().first()
+        if exist_catalog:
+            raise ServiceException(
+                message=f"同一父节点下已存在名称为“{catalog1.get('content_name')}”的目录"
+            )
+    
     @classmethod
     async def add_catalog_dao(cls, db: AsyncSession, catalog1: dict, catalog2: dict):
         """
@@ -233,17 +260,19 @@ class DataCatalogDAO:
         await db.execute(stmt)
 
 
+
+            
     @classmethod
     async def edit_catalog_child_dao(cls, db: AsyncSession, catalog: dict):
         """
-        编辑目录数据库操作
-
+        编辑目录数据库操作(子节点先删除再新增)
+    
         :param db: orm对象
-        :param catalog: 需要更新的目录字典
-        :return:
+        :param catalog: 需要更新的目录字典(包含 children 列表)
         """
         content_onum = catalog['content_onum']
-
+    
+        # ---------- 更新主目录 ----------
         stmt = (
             update(DataAstContent)
             .where(DataAstContent.content_onum == content_onum)
@@ -256,35 +285,25 @@ class DataCatalogDAO:
                 leaf_node_flag=catalog['leaf_node_flag'],
                 upd_prsn=catalog['upd_prsn'],
                 upd_time=datetime.now()
-        ) )
-
+            )
+        )
         await db.execute(stmt)
-
-        # 处理子关系
+    
+        # ---------- 删除原有子关系 ----------
+        delete_stmt = (
+            delete(DataAstContentRela)
+            .where(DataAstContentRela.content_onum == content_onum)
+        )
+        await db.execute(delete_stmt)
+    
+        # ---------- 新增子关系 ----------
         for child in catalog.get('children', []):
-            rela_onum = child.get('rela_onum')
-            if rela_onum:
-                st = (
-                    update(DataAstContentRela)
-                    .where(DataAstContentRela.rela_onum == rela_onum)
-                    .values(
-                        content_onum=child.get('content_onum'),
-                        ast_onum=child.get('ast_onum'),
-                        rela_type=child.get('rela_type'),
-                        rela_eff_begn_date=child.get('rela_eff_begn_date'),
-                        rela_eff_end_date=child.get('rela_eff_end_date'),
-                        upd_prsn=child.get('upd_prsn'))
-                    )
-
-                await db.execute(st)
-                await cls.update_leaf_node_flag(db)
-            else:
-                child['content_onum'] = content_onum
-                db_child = DataAstContentRela(**child)
-                db.add(db_child)
-                await db.flush()
-                await cls.update_leaf_node_flag(db)
-            
+            child['content_onum'] = content_onum
+            db_child = DataAstContentRela(**child)
+            db.add(db_child)
+    
+        # 更新叶子节点状态
+        await cls.update_leaf_node_flag(db)
 
 
 
diff --git a/vue-fastapi-backend/module_admin/service/data_ast_content_service.py b/vue-fastapi-backend/module_admin/service/data_ast_content_service.py
index c102a84..c7d4282 100644
--- a/vue-fastapi-backend/module_admin/service/data_ast_content_service.py
+++ b/vue-fastapi-backend/module_admin/service/data_ast_content_service.py
@@ -156,10 +156,14 @@ class DataCatalogService:
                 child["rela_eff_end_date"] = datetime(year=2999, month=12, day=31, hour=0, minute=0, second=0).strftime("%Y-%m-%d %H:%M:%S"), # 设置默认值,2999-12-31
                 child["upd_prsn"] = request.upd_prsn,
                 child["rela_status"] = "1"
-            
+            await DataCatalogDAO.check_duplicate_catalog(query_db, catalog_data1)
             new_catalog = await DataCatalogDAO.add_catalog_dao(query_db, catalog_data1, catalog_data2)
             await query_db.commit()
             return CrudResponseModel(is_success=True, message='新增成功', data=new_catalog)
+        except ServiceException as e:
+            await query_db.rollback()
+            # 直接抛出,不再重新包装,保留 DAO 层信息
+            raise e
         except Exception as e:
             await query_db.rollback()
             raise ServiceException(message=f"创建目录时发生错误: {str(e)}")
@@ -224,9 +228,14 @@ class DataCatalogService:
                 
                 child["upd_prsn"] = request.upd_prsn
                 child["rela_status"] = "1"
+            await DataCatalogDAO.check_duplicate_catalog(query_db, catalog_data, exclude_content_onum=request.content_onum)
             await DataCatalogDAO.edit_catalog_child_dao(query_db, catalog_data)
             await query_db.commit()
             return CrudResponseModel(is_success=True, message='更新成功')
+        except ServiceException as e:
+            await query_db.rollback()
+            # 直接抛出,不再重新包装,保留 DAO 层信息
+            raise e        
         except Exception as e:
             await query_db.rollback()
             raise ServiceException(message=f"更新目录时发生错误: {str(e)}")
diff --git a/vue-fastapi-frontend/src/api/meta/metaInfo.js b/vue-fastapi-frontend/src/api/meta/metaInfo.js
index 08dfa28..3457112 100644
--- a/vue-fastapi-frontend/src/api/meta/metaInfo.js
+++ b/vue-fastapi-frontend/src/api/meta/metaInfo.js
@@ -17,6 +17,15 @@ export function runBloodAnalysis(query) {
     headers: {dashUserName:query.userName,dashPassword:query.password}
   })
 }
+export function runBloodAnalysisBySql(query) {
+  return request({
+    url: '/blood-analysis-api/bloodAnalysis/sql/analysis',
+    method: 'post',
+    data: query,
+    headers: {dashUserName:query.userName,dashPassword:query.password}
+  })
+}
+
 // 查询参数列表
 export function getMetaDataList(query) {
   return request({
diff --git a/vue-fastapi-frontend/src/components/codemirror/SQLCodeMirrorSqlFlow.vue b/vue-fastapi-frontend/src/components/codemirror/SQLCodeMirrorSqlFlow.vue
new file mode 100644
index 0000000..7ddb735
--- /dev/null
+++ b/vue-fastapi-frontend/src/components/codemirror/SQLCodeMirrorSqlFlow.vue
@@ -0,0 +1,78 @@
+
+