Browse Source

接口优化

cuiHe 2 months ago
parent
commit
2fd15e4999

+ 53 - 33
backend/app/api/v1/module_business/vardict/controller.py

@@ -43,38 +43,6 @@ async def get_vardict_list_controller(
     )
     )
     log.info("查询变量信息列表成功")
     log.info("查询变量信息列表成功")
     return SuccessResponse(data=result_dict, msg="查询变量信息列表成功")
     return SuccessResponse(data=result_dict, msg="查询变量信息列表成功")
-@BizVarDictRouter.get("/list_alarms", summary="查询变量信息列表", description="查询变量信息列表")
-async def get_vardict_list_alarms_controller(
-    page: PaginationQueryParam = Depends(),
-    search: BizVarDictQueryParam = Depends(),
-    auth: AuthSchema = Depends(AuthPermission(["module_business:vardict:query"]))
-) -> JSONResponse:
-    """查询变量信息列表接口(数据库分页)"""
-    result_dict = await BizVarDictService.page_vardict_service(
-        auth=auth,
-        page_no=page.page_no if page.page_no is not None else 1,
-        page_size=page.page_size if page.page_size is not None else 10,
-        search=search,
-        order_by=[{'mec_type':'asc'}]
-    )
-    #请求采集接口获取状态信息
-    async with httpx.AsyncClient() as client:
-        response = await client.get(
-            url=settings.COLLECT_DATA_FULL,
-            params={},
-            timeout=2
-        )
-        if response.status_code == 200:
-            json_data = response.json()
-            if json_data['code'] == 200 and json_data['data']:
-                for item in result_dict['items']:
-                    item['value'] = False
-                    crane_no = item['crane_no']
-                    alarm = json_data.get('data').get(crane_no).get('data').get('alarm').get(item['var_code'])
-                    if alarm:
-                        item['value'] = alarm.get('value')
-    log.info("查询变量信息列表成功")
-    return SuccessResponse(data=result_dict, msg="查询变量信息列表成功")
 
 
 @BizVarDictRouter.post("/create", summary="创建变量信息", description="创建变量信息")
 @BizVarDictRouter.post("/create", summary="创建变量信息", description="创建变量信息")
 async def create_vardict_controller(
 async def create_vardict_controller(
@@ -161,6 +129,58 @@ async def export_vardict_template_controller() -> StreamingResponse:
         headers={'Content-Disposition': 'attachment; filename=biz_var_dict_template.xlsx'}
         headers={'Content-Disposition': 'attachment; filename=biz_var_dict_template.xlsx'}
     )
     )
 
 
+@BizVarDictRouter.get("/list_alarms", summary="查询变量信息列表", description="查询变量信息列表")
+async def get_vardict_list_alarms_controller(
+    search: BizVarDictQueryParam = Depends(),
+    auth: AuthSchema = Depends(AuthPermission(["module_business:vardict:query"]))
+) -> JSONResponse:
+    """查询变量信息列表接口(数据库分页)"""
+    result_dict = await BizVarDictService.vardict_alarms_list(auth=auth,crane_no=search.crane_no)
+    #请求采集接口获取状态信息
+    async with httpx.AsyncClient() as client:
+        response = await client.get(
+            url=settings.COLLECT_DATA_FULL,
+            params={},
+            timeout=2
+        )
+        if response.status_code == 200:
+            json_data = response.json()
+            if json_data['code'] == 200 and json_data['data']:
+                for item in result_dict:
+                    item['value'] = False
+                    crane_no = item['crane_no']
+                    alarm = json_data.get('data').get(crane_no).get('data').get('alarm').get(item['var_code'])
+                    if alarm:
+                        item['value'] = alarm.get('value')
+    log.info("查询变量信息列表成功")
+    return SuccessResponse(data=result_dict, msg="查询变量信息列表成功")
+
+@BizVarDictRouter.get("/list_analog", summary="查询变量信息列表", description="查询变量信息列表")
+async def get_vardict_list_analog_controller(
+    search: BizVarDictQueryParam = Depends(),
+    auth: AuthSchema = Depends(AuthPermission(["module_business:vardict:query"]))
+) -> JSONResponse:
+    """查询变量信息列表接口(数据库分页)"""
+    result_dict = await BizVarDictService.vardict_analog_list(auth=auth,crane_no=search.crane_no)
+    #请求采集接口获取状态信息
+    async with httpx.AsyncClient() as client:
+        response = await client.get(
+            url=settings.COLLECT_DATA_FULL,
+            params={},
+            timeout=2
+        )
+        if response.status_code == 200:
+            json_data = response.json()
+            if json_data['code'] == 200 and json_data['data']:
+                for item in result_dict:
+                    item['value'] = False
+                    crane_no = item['crane_no']
+                    analog = json_data.get('data').get(crane_no).get('data').get('analog').get(item['var_code'])
+                    if analog:
+                        item['value'] = analog.get('value')
+    log.info("查询变量信息列表成功")
+    return SuccessResponse(data=result_dict, msg="查询变量信息列表成功")
+
 @BizVarDictRouter.get("/varDictMecGroup/{crane_no}", summary="获取变量信息分组数据", description="获取变量信息分组数据")
 @BizVarDictRouter.get("/varDictMecGroup/{crane_no}", summary="获取变量信息分组数据", description="获取变量信息分组数据")
 async def get_vardict_mec_group_controller(
 async def get_vardict_mec_group_controller(
     crane_no: str = Path(..., description="crane_no"),
     crane_no: str = Path(..., description="crane_no"),
@@ -188,7 +208,7 @@ async def get_vardict_mec_group_controller(
                 json_digital = json_data.get('data').get(crane_no).get('data').get('digital')
                 json_digital = json_data.get('data').get(crane_no).get('data').get('digital')
                 for var_dict in result_dict:
                 for var_dict in result_dict:
                     for key,inner_dict in var_dict.items():
                     for key,inner_dict in var_dict.items():
-                        if key != 'mec_type' and key != 'alarm_varList' and key != 'varList_simple':
+                        if key != 'mec_type' and key != 'alarm_varList' and key != 'mecVarList_simple':
                             for item in inner_dict:
                             for item in inner_dict:
                                 if key == 'digital_varList':
                                 if key == 'digital_varList':
                                     item['value'] = json_digital.get(item.get('var_code')).get('value')
                                     item['value'] = json_digital.get(item.get('var_code')).get('value')

+ 12 - 7
backend/app/api/v1/module_business/vardict/schema.py

@@ -34,6 +34,7 @@ class BizVarDictCreateSchema(BaseModel):
     diagnosis_id: str | None = Field(default=None, description='关联诊断专家')
     diagnosis_id: str | None = Field(default=None, description='关联诊断专家')
     status: str = Field(default="1", description='是否启用')
     status: str = Field(default="1", description='是否启用')
     description: str | None = Field(default=None, max_length=255, description='备注/描述')
     description: str | None = Field(default=None, max_length=255, description='备注/描述')
+    crane_name: str | None = Field(default=None, max_length=255, description='行车名')
 
 
 
 
 class BizVarDictUpdateSchema(BizVarDictCreateSchema):
 class BizVarDictUpdateSchema(BizVarDictCreateSchema):
@@ -82,8 +83,6 @@ class BizVarDictQueryParam:
         updated_id: int | None = Query(None, description="更新人ID"),
         updated_id: int | None = Query(None, description="更新人ID"),
         created_time: list[DateTimeStr] | None = Query(None, description="创建时间范围", examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
         created_time: list[DateTimeStr] | None = Query(None, description="创建时间范围", examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
         updated_time: list[DateTimeStr] | None = Query(None, description="更新时间范围", examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
         updated_time: list[DateTimeStr] | None = Query(None, description="更新时间范围", examples=["2025-01-01 00:00:00", "2025-12-31 23:59:59"]),
-        # 新增:场景区分参数,默认 False(代表后台内部请求),True 代表前端接口请求
-        is_api_request: bool | None = Query(False, description="是否为前端接口请求(用于切换 switch_type 查询方式)")
 
 
     ) -> None:
     ) -> None:
         
         
@@ -97,10 +96,7 @@ class BizVarDictQueryParam:
         self.mec_type = mec_type
         self.mec_type = mec_type
         # 精确查询字段
         # 精确查询字段
         self.data_type = data_type
         self.data_type = data_type
-        if is_api_request:
-            self.switch_type = (">=", switch_type)
-        else:
-            self.switch_type = switch_type
+        self.switch_type = switch_type
         # 模糊查询字段
         # 模糊查询字段
         self.addr = ("like", addr)
         self.addr = ("like", addr)
         # 精确查询字段
         # 精确查询字段
@@ -147,10 +143,19 @@ class BizVarDictQueryParam:
 
 
 class VarDictMecGroupSchema(BaseModel):
 class VarDictMecGroupSchema(BaseModel):
     """
     """
-    行车信息页面数据模型
+    行车信息机构分组数据模型
     """
     """
     mec_type: str = Field(default=..., description='所属机构')
     mec_type: str = Field(default=..., description='所属机构')
     alarm_varList: list[BizVarDictOutSchema] | None = Field(default=None, description='报警变量数据')
     alarm_varList: list[BizVarDictOutSchema] | None = Field(default=None, description='报警变量数据')
     digital_varList: list[BizVarDictOutSchema] | None = Field(default=None, description='开关量变量数据')
     digital_varList: list[BizVarDictOutSchema] | None = Field(default=None, description='开关量变量数据')
     analog_varList: list[BizVarDictOutSchema] | None = Field(default=None, description='模拟量变量数据')
     analog_varList: list[BizVarDictOutSchema] | None = Field(default=None, description='模拟量变量数据')
+    mecVarList_simple: list[BizVarDictOutSchema] | None = Field(default=None, description='变量数据')
+
+class VarDictSchema(BaseModel):
+    """
+    行车信息数据模型
+    """
+    alarm_varList: list[BizVarDictOutSchema] | None = Field(default=None, description='报警变量数据')
+    digital_varList: list[BizVarDictOutSchema] | None = Field(default=None, description='开关量变量数据')
+    analog_varList: list[BizVarDictOutSchema] | None = Field(default=None, description='模拟量变量数据')
     varList_simple: list[BizVarDictOutSchema] | None = Field(default=None, description='变量数据')
     varList_simple: list[BizVarDictOutSchema] | None = Field(default=None, description='变量数据')

+ 60 - 4
backend/app/api/v1/module_business/vardict/service.py

@@ -2,6 +2,8 @@
 
 
 import io
 import io
 import json
 import json
+from typing import Any
+
 from fastapi import UploadFile
 from fastapi import UploadFile
 import pandas as pd
 import pandas as pd
 from redis.asyncio.client import Redis
 from redis.asyncio.client import Redis
@@ -67,6 +69,60 @@ class BizVarDictService:
             item['crane_name'] = crane_model.crane_name
             item['crane_name'] = crane_model.crane_name
             item['gateway_name'] = gateway_model.gateway_name if gateway_model else ""
             item['gateway_name'] = gateway_model.gateway_name if gateway_model else ""
         return result
         return result
+
+    @classmethod
+    async def vardict_alarms_list(cls, auth: AuthSchema, crane_no: str = None) -> list[dict]:
+
+        sql_parts = [
+            """SELECT a.*,b.crane_name 
+            FROM biz_var_dict as a 
+            LEFT JOIN biz_crane as b ON a.crane_no = b.crane_no 
+            WHERE a.`status` = :status AND b.`status` = :status AND a.switch_type >= 2"""
+        ]
+
+        business_params: dict[str, Any] = {"status": 1}
+
+        if crane_no and isinstance(crane_no, str) and crane_no.strip():
+            valid_crane_no = crane_no.strip()
+            sql_parts.append(f"AND a.crane_no = :crane_no")
+            business_params["crane_no"] = valid_crane_no
+
+        sql_parts.append("ORDER BY b.`order` asc,a.mec_type asc,a.var_sort asc")
+        final_sql = " ".join(sql_parts)
+
+        try:
+            obj_list = await BizVarDictCRUD(auth).list_sql(final_sql, business_params)
+
+            return [BizVarDictOutSchema.model_validate(obj).model_dump() for obj in obj_list]
+        except Exception as e:
+            raise CustomException(msg=f"查询变量字典报警列表失败:{str(e)}")
+
+    @classmethod
+    async def vardict_analog_list(cls, auth: AuthSchema, crane_no: str = None) -> list[dict]:
+
+        sql_parts = [
+            """SELECT a.*,b.crane_name 
+            FROM biz_var_dict as a 
+            LEFT JOIN biz_crane as b ON a.crane_no = b.crane_no 
+            WHERE a.`status` = :status AND b.`status` = :status AND a.data_type >= 2"""
+        ]
+
+        business_params: dict[str, Any] = {"status": 1}
+
+        if crane_no and isinstance(crane_no, str) and crane_no.strip():
+            valid_crane_no = crane_no.strip()
+            sql_parts.append(f"AND a.crane_no = :crane_no")
+            business_params["crane_no"] = valid_crane_no
+
+        sql_parts.append("ORDER BY b.`order` asc,a.mec_type asc,a.var_sort asc")
+        final_sql = " ".join(sql_parts)
+
+        try:
+            obj_list = await BizVarDictCRUD(auth).list_sql(final_sql, business_params)
+
+            return [BizVarDictOutSchema.model_validate(obj).model_dump() for obj in obj_list]
+        except Exception as e:
+            raise CustomException(msg=f"查询变量字典报警列表失败:{str(e)}")
     
     
     @classmethod
     @classmethod
     async def create_vardict_service(cls, auth: AuthSchema, data: BizVarDictCreateSchema,redis: Redis) -> dict:
     async def create_vardict_service(cls, auth: AuthSchema, data: BizVarDictCreateSchema,redis: Redis) -> dict:
@@ -325,7 +381,7 @@ class BizVarDictService:
             option_list=option_list
             option_list=option_list
         )
         )
     @classmethod
     @classmethod
-    async def get_vardict_group_service(cls,auth: AuthSchema, redis: Redis,crane_no: str):
+    async def get_vardict_group_service(cls, auth: AuthSchema,redis: Redis,crane_no: str):
         """
         """
         从缓存获取变量分组数据列表信息service
         从缓存获取变量分组数据列表信息service
 
 
@@ -399,17 +455,17 @@ class BizVarDictService:
                             mec_list = await BizMecCRUD(auth).list(search={'crane_no':crane_no,'status':'1'},order_by=[{'sort':'asc'}])
                             mec_list = await BizMecCRUD(auth).list(search={'crane_no':crane_no,'status':'1'},order_by=[{'sort':'asc'}])
                             for mec in mec_list:
                             for mec in mec_list:
                                 # 获取分组数据
                                 # 获取分组数据
-                                varDicts = await BizVarDictCRUD(auth).list(
+                                mecVarDicts = await BizVarDictCRUD(auth).list(
                                     search={'crane_no': crane_no, 'mec_type': mec.mec_type, 'status': '1'},
                                     search={'crane_no': crane_no, 'mec_type': mec.mec_type, 'status': '1'},
                                     order_by=[{'var_sort': 'asc'}])
                                     order_by=[{'var_sort': 'asc'}])
-                                if not varDicts:
+                                if not mecVarDicts:
                                     continue
                                     continue
                                 alarmVarList = await BizVarDictCRUD(auth).list(search={'crane_no': crane_no,'mec_type':mec.mec_type, 'switch_type': ('>=','2'), 'status': '1'},order_by=[{'var_sort': 'asc'}])
                                 alarmVarList = await BizVarDictCRUD(auth).list(search={'crane_no': crane_no,'mec_type':mec.mec_type, 'switch_type': ('>=','2'), 'status': '1'},order_by=[{'var_sort': 'asc'}])
                                 digitalVarList = await BizVarDictCRUD(auth).list(search={'crane_no':crane_no,'mec_type':mec.mec_type,'data_type':'1','status':'1'},order_by=[{'var_sort':'asc'}])
                                 digitalVarList = await BizVarDictCRUD(auth).list(search={'crane_no':crane_no,'mec_type':mec.mec_type,'data_type':'1','status':'1'},order_by=[{'var_sort':'asc'}])
                                 analogVarList = await BizVarDictCRUD(auth).list(search={'crane_no': crane_no,'mec_type':mec.mec_type, 'data_type': ('!=', '1'), 'status': '1'},order_by=[{'var_sort': 'asc'}])
                                 analogVarList = await BizVarDictCRUD(auth).list(search={'crane_no': crane_no,'mec_type':mec.mec_type, 'data_type': ('!=', '1'), 'status': '1'},order_by=[{'var_sort': 'asc'}])
                                 varDictMecGroupSchema.append(
                                 varDictMecGroupSchema.append(
                                     VarDictMecGroupSchema(mec_type=mec.mec_type,
                                     VarDictMecGroupSchema(mec_type=mec.mec_type,
-                                                          varList_simple=varDicts,
+                                                          mecVarList_simple=mecVarDicts,
                                                           digital_varList=digitalVarList,
                                                           digital_varList=digitalVarList,
                                                           analog_varList=analogVarList,
                                                           analog_varList=analogVarList,
                                                           alarm_varList=alarmVarList))
                                                           alarm_varList=alarmVarList))

+ 103 - 1
backend/app/core/base_crud.py

@@ -5,7 +5,7 @@ from typing import TypeVar, Sequence, Generic, Dict, Any, List, Optional, Type,
 from sqlalchemy.sql.elements import ColumnElement
 from sqlalchemy.sql.elements import ColumnElement
 from sqlalchemy.orm import selectinload
 from sqlalchemy.orm import selectinload
 from sqlalchemy.engine import Result
 from sqlalchemy.engine import Result
-from sqlalchemy import asc, func, select, delete, Select, desc, update
+from sqlalchemy import asc, func, select, delete, Select, desc, update, text
 from sqlalchemy import inspect as sa_inspect
 from sqlalchemy import inspect as sa_inspect
 
 
 from app.core.base_model import MappedBase
 from app.core.base_model import MappedBase
@@ -93,6 +93,40 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
         except Exception as e:
         except Exception as e:
             raise CustomException(msg=f"列表查询失败: {str(e)}")
             raise CustomException(msg=f"列表查询失败: {str(e)}")
 
 
+    async def list_sql(self, sql:str,params: Optional[Dict[str, Any]] = None) -> List[Dict]:
+        """
+        根据条件获取对象列表
+
+        参数:
+        - search (Optional[Dict]): 查询条件,格式为 {'id': value, 'name': value}
+        - order_by (Optional[List[Dict[str, str]]]): 排序字段,格式为 [{'id': 'asc'}, {'name': 'desc'}]
+        - preload (Optional[List[Union[str, Any]]]): 预加载关系,支持关系名字符串或SQLAlchemy loader option
+
+        返回:
+        - Sequence[ModelType]: 对象列表
+
+        异常:
+        - CustomException: 查询失败时抛出异常
+        """
+        try:
+            business_params = params.copy() if params else {}
+
+            filtered_sql, permission_params = await self.__filter_permissions_sql(sql)
+
+            final_params = business_params
+            if permission_params:
+                final_params.update(permission_params)
+
+            result = await self.execute_raw_sql(
+                sql=filtered_sql,
+                params=final_params,  # 传入权限参数,绑定current_user_id
+                fetch_one=False,
+                scalar=False
+            )
+            return result
+        except Exception as e:
+            raise CustomException(msg=f"列表查询失败: {str(e)}")
+
     async def tree_list(self, search: Optional[Dict] = None, order_by: Optional[List[Dict[str, str]]] = None, children_attr: str = 'children', preload: Optional[List[Union[str, Any]]] = None) -> Sequence[ModelType]:
     async def tree_list(self, search: Optional[Dict] = None, order_by: Optional[List[Dict[str, str]]] = None, children_attr: str = 'children', preload: Optional[List[Union[str, Any]]] = None) -> Sequence[ModelType]:
         """
         """
         获取树形结构数据列表
         获取树形结构数据列表
@@ -315,6 +349,63 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
         except Exception as e:
         except Exception as e:
             raise CustomException(msg=f"清空失败: {str(e)}")
             raise CustomException(msg=f"清空失败: {str(e)}")
 
 
+    async def execute_raw_sql(
+            self,
+            sql: str,
+            params: Optional[Dict[str, Any]] = None,
+            fetch_one: bool = False,
+            scalar: bool = False
+    ) -> Optional[Union[Dict, List[Dict], Any, Sequence[Any]]]:
+        try:
+            # ---------------------- 1. 严格校验输入:避免空SQL、非字符串等错误 ----------------------
+            # 校验SQL是否为非空字符串
+            if not isinstance(sql, str) or len(sql.strip()) == 0:
+                raise CustomException(msg="传入的原始SQL不能为空且必须为字符串类型")
+
+            # 初始化最终SQL(仅对字符串操作,规避TextClause错误)
+            final_sql = sql.strip()
+            # 初始化最终参数:兜底空字典,避免None报错
+            final_params = params.copy() if (params and isinstance(params, Dict)) else {}
+
+            # ---------------------- 3. 核心:执行SQL(仅包装一次TextClause,不进行后续字符串操作) ----------------------
+            # 包装为TextClause(SQLAlchemy执行原始SQL必需,仅执行此步骤,无额外操作)
+            raw_sql_clause = text(final_sql)
+
+            # 执行SQL:传入上层已合并(业务+权限)的参数,确保所有占位符绑定完成
+            db_result: Result = await self.auth.db.execute(raw_sql_clause, final_params)
+
+            # ---------------------- 4. 处理结果:格式统一,兼容上层list_sql的返回需求 ----------------------
+            # 处理SELECT查询(返回字典/字典列表,兼容Sequence[ModelType])
+            if final_sql.upper().startswith("SELECT"):
+                # 标量结果(单个值,如COUNT(*))
+                if scalar:
+                    return db_result.scalar() if fetch_one else db_result.scalars().all()
+
+                # 完整行结果:转换为字典列表,避免字段名丢失,兜底空列表
+                row_mappings = db_result.mappings().all()
+                result_list = [dict(row) for row in row_mappings] if row_mappings else []
+
+                # 单条/多条结果返回,确保返回序列类型
+                if fetch_one:
+                    return result_list[0] if len(result_list) > 0 else None
+                else:
+                    return result_list
+
+            # 处理DML操作(INSERT/UPDATE/DELETE):刷新会话,返回None
+            await self.auth.db.flush()
+            return None
+
+        # ---------------------- 5. 异常捕获:补充上下文,方便排查上层拼接后的问题 ----------------------
+        except CustomException as ce:
+            raise ce
+        except Exception as e:
+            error_msg = (
+                f"执行原始SQL失败:{str(e)}"
+                f"\n  执行的SQL(上层已拼接权限):{final_sql[:500]}..."
+                f"\n  传入的参数(业务+权限):{final_params}"
+            )
+            raise CustomException(msg=error_msg)
+
     async def set(self, ids: List[int], **kwargs) -> None:
     async def set(self, ids: List[int], **kwargs) -> None:
         """
         """
         批量更新对象
         批量更新对象
@@ -365,6 +456,17 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
         )
         )
         return await filter.filter_query(sql)
         return await filter.filter_query(sql)
 
 
+    async def __filter_permissions_sql(self, sql: str) -> Select:
+        """
+        过滤数据权限(仅用于Select)。
+        """
+        filter = Permission(
+            model=self.model,
+            auth=self.auth
+        )
+        return await filter.filter_query_sql(sql)
+
+
     async def __build_conditions(self, **kwargs) -> List[ColumnElement]:
     async def __build_conditions(self, **kwargs) -> List[ColumnElement]:
         """
         """
         构建查询条件
         构建查询条件

+ 150 - 2
backend/app/core/permission.py

@@ -1,6 +1,8 @@
 # -*- coding: utf-8 -*-
 # -*- coding: utf-8 -*-
 
 
-from typing import Any
+from typing import Any, Optional, Dict, Set
+
+from pluggy import Result
 from sqlalchemy.sql.elements import ColumnElement
 from sqlalchemy.sql.elements import ColumnElement
 from sqlalchemy import select
 from sqlalchemy import select
 from app.api.v1.module_system.user.model import UserModel
 from app.api.v1.module_system.user.model import UserModel
@@ -156,4 +158,150 @@ class Permission:
         created_id_attr = getattr(self.model, "created_id", None)
         created_id_attr = getattr(self.model, "created_id", None)
         if created_id_attr is not None:
         if created_id_attr is not None:
             return created_id_attr == self.auth.user.id
             return created_id_attr == self.auth.user.id
-        return None
+        return None
+
+    async def filter_query_sql(self, sql: str) -> (str, Optional[Dict[str, Any]]):
+        """
+        异步过滤**原始SQL字符串**,拼接完整权限条件(无逻辑省略)
+        Args:
+            sql: 原始SQL字符串(如"SELECT * FROM biz_var_dict")
+        Returns:
+            拼接权限条件后的完整SQL字符串、权限参数字典(防SQL注入,可直接传入execute_raw_sql)
+        """
+        # 1. 获取完整的权限SQL条件和参数(无省略,包含所有角色/部门逻辑)
+        permission_condition, permission_params = await self.__permission_condition_sql()
+
+        # 2. 无权限条件,直接返回原始SQL和空参数(保持原有逻辑)
+        if not permission_condition:
+            return sql.strip(), None
+
+        # 3. 清理原始SQL,保证拼接语法正确(移除末尾分号、多余空格)
+        cleaned_sql = sql.strip().rstrip("; \n\t")  # 处理多种空白字符和分号
+
+        # 4. 智能判断原始SQL是否包含WHERE子句,进行拼接(兼容所有场景)
+        if "WHERE" in cleaned_sql.upper():
+            # 已有WHERE,用AND拼接权限条件(保留原有查询条件)
+            final_sql = f"{cleaned_sql} AND {permission_condition}"
+        else:
+            # 无WHERE,直接添加WHERE和权限条件
+            final_sql = f"{cleaned_sql} WHERE {permission_condition}"
+
+        # 5. 返回拼接后的完整SQL和权限参数(后续执行可直接使用)
+        return final_sql, permission_params
+    async def __permission_condition_sql(self) -> (Optional[str], Optional[Dict[str, Any]]):
+        """
+        应用数据范围权限隔离(完整逻辑,无任何省略)
+        基于角色的五种数据权限范围过滤,返回原始SQL条件字符串和参数(防注入)
+        Returns:
+            权限条件字符串(如"created_id = :current_user_id AND dept_id IN (:accessible_dept_ids)")
+            权限参数字典(如{"current_user_id": 100, "accessible_dept_ids": [1,2,3]})
+        """
+        # 初始化返回结果(权限SQL条件、权限参数)
+        permission_sql: Optional[str] = None
+        permission_params: Dict[str, Any] = {}
+
+        # --------------- 原有逻辑:前置判断(无任何省略)---------------
+        # 1. 未登录用户,不限制数据权限
+        if not self.auth.user:
+            return permission_sql, permission_params
+
+        # 2. 关闭数据权限检查,不限制数据权限
+        if not self.auth.check_data_scope:
+            return permission_sql, permission_params
+
+        # 3. 模型无created_id字段,无法进行权限过滤,不限制
+        if not hasattr(self.model, "created_id"):
+            return permission_sql, permission_params
+
+        # 4. 超级管理员,拥有全部数据权限,不限制
+        if self.auth.user.is_superuser:
+            return permission_sql, permission_params
+
+        # --------------- 原有逻辑:获取用户角色与数据范围(无任何省略)---------------
+        current_user_id = self.auth.user.id
+        roles = getattr(self.auth.user, "roles", []) or []
+
+        # 5. 无角色用户,仅能查看自己创建的数据(基础权限)
+        if not roles:
+            permission_sql = "created_id = :current_user_id"
+            permission_params["current_user_id"] = current_user_id
+            return permission_sql, permission_params
+
+        # 6. 收集所有角色的权限范围和自定义部门ID
+        data_scopes: Set[int] = set()
+        custom_dept_ids: Set[int] = set()
+
+        for role in roles:
+            data_scopes.add(role.data_scope)
+            # 收集自定义权限(DATA_SCOPE_CUSTOM=5)关联的部门ID
+            if role.data_scope == self.DATA_SCOPE_CUSTOM and hasattr(role, 'depts') and role.depts:
+                for dept in role.depts:
+                    custom_dept_ids.add(dept.id)
+
+        # 7. 全部数据权限(最高优先级),不限制数据权限
+        if self.DATA_SCOPE_ALL in data_scopes:
+            return None, None
+
+        # --------------- 收集可访问的部门ID---------------
+        accessible_dept_ids: Set[int] = set()
+        user_dept_id = getattr(self.auth.user, "dept_id", None)
+
+        # 8. 处理自定义数据权限(DATA_SCOPE_CUSTOM=5)
+        if self.DATA_SCOPE_CUSTOM in data_scopes:
+            accessible_dept_ids.update(custom_dept_ids)
+
+        # 9. 处理本部门数据权限(DATA_SCOPE_DEPT=3)
+        if self.DATA_SCOPE_DEPT in data_scopes:
+            if user_dept_id is not None:
+                accessible_dept_ids.add(user_dept_id)
+
+        # 10. 处理本部门及以下数据权限(DATA_SCOPE_DEPT_AND_CHILD=4)
+        if self.DATA_SCOPE_DEPT_AND_CHILD in data_scopes:
+            if user_dept_id is not None:
+                try:
+                    # 完整查询所有部门,递归获取子部门ID(无省略)
+                    dept_sql = select(DeptModel)
+                    dept_result = await self.auth.db.execute(dept_sql)
+                    dept_objs = dept_result.scalars().all()
+                    id_map = get_child_id_map(dept_objs)
+                    # 递归获取当前部门及所有子部门ID(包含自身)
+                    dept_with_children_ids = get_child_recursion(id=user_dept_id, id_map=id_map)
+
+                    # 合并到可访问部门ID集合
+                    accessible_dept_ids.update(dept_with_children_ids)
+                except Exception:
+                    # 查询失败降级:仅保留本部门ID(与原有逻辑一致)
+                    accessible_dept_ids.add(user_dept_id)
+
+        # --------------- 原有逻辑:构建部门权限过滤条件(无任何省略)---------------
+        if accessible_dept_ids:
+            # 转换部门ID集合为列表(方便SQL IN条件使用)
+            accessible_dept_list = list(accessible_dept_ids)
+
+            # 优先使用模型的created_by关联(关联UserModel.dept_id,性能更优)
+            creator_rel = getattr(self.model, "created_by", None)
+            if creator_rel is not None and hasattr(UserModel, 'dept_id'):
+                # 构建部门权限SQL条件(参数化,防注入)
+                permission_sql = "created_by_dept_id IN (:accessible_dept_ids)"
+                permission_params["accessible_dept_ids"] = accessible_dept_list
+
+                # 补充:同时保留创建人ID条件(可选,根据你的业务需求调整)
+                permission_sql = f"created_id = :current_user_id AND {permission_sql}"
+                permission_params["current_user_id"] = current_user_id
+            else:
+                # 降级方案:无created_by关联,仅能查看自己创建的数据
+                permission_sql = "created_id = :current_user_id"
+                permission_params["current_user_id"] = current_user_id
+
+            return permission_sql, permission_params
+
+        # --------------- 原有逻辑:处理仅本人数据权限(DATA_SCOPE_SELF=2)---------------
+        if self.DATA_SCOPE_SELF in data_scopes:
+            permission_sql = "created_id = :current_user_id"
+            permission_params["current_user_id"] = current_user_id
+            return permission_sql, permission_params
+
+        # --------------- 原有逻辑:默认情况(无有效权限范围,仅能查看自己数据)---------------
+        permission_sql = "created_id = :current_user_id"
+        permission_params["current_user_id"] = current_user_id
+        return permission_sql, permission_params

+ 1 - 0
frontend/src/api/module_business/crane.ts

@@ -119,6 +119,7 @@ export interface BizCranePageQuery extends PageQuery {
   updated_id?: number;
   updated_id?: number;
   created_time?: string[];
   created_time?: string[];
   updated_time?: string[];
   updated_time?: string[];
+  order_by?: string;
 }
 }
 
 
 // 列表展示项
 // 列表展示项

+ 10 - 2
frontend/src/api/module_business/vardict.ts

@@ -14,13 +14,21 @@ const BizVarDictAPI = {
   },
   },
 
 
   listBizVarDictAlarms(query: BizVarDictPageQuery) {
   listBizVarDictAlarms(query: BizVarDictPageQuery) {
-    return request<ApiResponse<PageResult<BizVarDictTable[]>>>({
+    return request<ApiResponse<BizVarDictTable[]>>({
       url: `${API_PATH}/list_alarms`,
       url: `${API_PATH}/list_alarms`,
       method: "get",
       method: "get",
       params: query,
       params: query,
     });
     });
   },
   },
 
 
+  listBizVarDictAnalog(query: BizVarDictPageQuery) {
+    return request<ApiResponse<BizVarDictTable[]>>({
+      url: `${API_PATH}/list_analog`,
+      method: "get",
+      params: query,
+    });
+  },
+
   // 详情查询
   // 详情查询
   detailBizVarDict(id: number) {
   detailBizVarDict(id: number) {
     return request<ApiResponse<BizVarDictTable>>({
     return request<ApiResponse<BizVarDictTable>>({
@@ -128,7 +136,7 @@ export interface BizVarDictPageQuery extends PageQuery {
   updated_id?: number;
   updated_id?: number;
   created_time?: string[];
   created_time?: string[];
   updated_time?: string[];
   updated_time?: string[];
-  is_api_request?: string;
+  order_by?:string;
 }
 }
 
 
 // 列表展示项
 // 列表展示项

+ 13 - 1
frontend/src/router/index.ts

@@ -96,7 +96,19 @@ export const constantRoutes: RouteRecordRaw[] = [
             name: 'HistoryAlarm',
             name: 'HistoryAlarm',
             meta: { title: '历史报警' },
             meta: { title: '历史报警' },
             component: import("@/views/web/detail/historyAlarm.vue")
             component: import("@/views/web/detail/historyAlarm.vue")
-          }
+          },
+          {
+            path: '/detail/realtimeCurve',
+            name: 'RealtimeCurve',
+            meta: { title: '实时曲线' },
+            component: import("@/views/web/detail/realtimeCurve.vue")
+          },
+          {
+            path: '/detail/historyCurve',
+            name: 'HistoryCurve',
+            meta: { title: '历史曲线' },
+            component: import("@/views/web/detail/HistoryCurve.vue")
+          },
         ]
         ]
       }
       }
     ],
     ],

+ 12 - 0
frontend/src/views/web/detail/historyCurve.vue

@@ -0,0 +1,12 @@
+<template>
+    这是历史曲线
+
+  </template>
+  
+  <script setup lang="ts">
+
+  </script>
+  
+  <style lang="less" scoped>
+
+  </style>

+ 5 - 6
frontend/src/views/web/detail/realtimeAlarm.vue

@@ -18,7 +18,7 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import { ref } from 'vue';
 import { ref } from 'vue';
 import { useDictStore } from "@/store";
 import { useDictStore } from "@/store";
-import BizVarDictAPI, { BizVarDictTable,BizVarDictPageQuery,MecDataItem } from '@/api/module_business/vardict'
+import BizVarDictAPI, { BizVarDictTable,BizVarDictPageQuery } from '@/api/module_business/vardict'
 import MqttUtil, { MqttMessageCallback } from '@/utils/mqttUtil';
 import MqttUtil, { MqttMessageCallback } from '@/utils/mqttUtil';
 
 
 const tabHeight = ref('calc(100vh - 70px - 5px - 50px - 10px - 44px)')
 const tabHeight = ref('calc(100vh - 70px - 5px - 50px - 10px - 44px)')
@@ -46,13 +46,13 @@ const mqttConfig = {
 const mqttUtil = new MqttUtil(mqttConfig);
 const mqttUtil = new MqttUtil(mqttConfig);
 
 
 const queryFormVarDictData = reactive<BizVarDictPageQuery>({
 const queryFormVarDictData = reactive<BizVarDictPageQuery>({
-  page_no: 1,
-  page_size: 100,
+  page_no: 0,
+  page_size: 0,
   crane_no: craneInfo.crane_no,
   crane_no: craneInfo.crane_no,
   var_code: undefined,
   var_code: undefined,
   var_name: undefined,
   var_name: undefined,
   mec_type: undefined,
   mec_type: undefined,
-  switch_type: '2',
+  switch_type: undefined,
   gateway_id: undefined,
   gateway_id: undefined,
   var_group: undefined,
   var_group: undefined,
   var_category: undefined,
   var_category: undefined,
@@ -65,7 +65,6 @@ const queryFormVarDictData = reactive<BizVarDictPageQuery>({
   updated_time: undefined,
   updated_time: undefined,
   created_id: undefined,
   created_id: undefined,
   updated_id: undefined,
   updated_id: undefined,
-  is_api_request: 'True',
 });
 });
 const allData = ref<BizVarDictTable[]>([]);
 const allData = ref<BizVarDictTable[]>([]);
 
 
@@ -74,7 +73,7 @@ const filteredData = computed(() => {
 });
 });
 const getData = async () => {
 const getData = async () => {
   const response = await BizVarDictAPI.listBizVarDictAlarms(queryFormVarDictData);
   const response = await BizVarDictAPI.listBizVarDictAlarms(queryFormVarDictData);
-  allData.value = response.data.data.items
+  allData.value = response.data.data
   tab_loading.value = false
   tab_loading.value = false
 }
 }
 
 

+ 315 - 0
frontend/src/views/web/detail/realtimeCurve.vue

@@ -0,0 +1,315 @@
+<template>
+    <div class="realtime-curve-container">
+      <!-- ECharts 容器 -->
+      <div ref="chartRef" class="chart-box"></div>
+    </div>
+  </template>
+  
+  <script setup lang="ts">
+  // 补全所有必要导入,并严格指定类型
+  import { ref, reactive, onMounted, onUnmounted, watch } from 'vue';
+  import * as echarts from 'echarts';
+  import type { ECharts, EChartsOption, YAxisOption, SeriesOption } from 'echarts';
+  import BizVarDictAPI, { BizVarDictTable, BizVarDictPageQuery } from '@/api/module_business/vardict';
+  import MqttUtil, { MqttMessageCallback } from '@/utils/mqttUtil';
+  
+  // ========== 严格 TS 类型定义 ==========
+  /** MQTT 消息 payload 数据项类型 */
+  interface MqttPayloadItem {
+    var_code: string;
+    value: number | string;
+    [key: string]: unknown; // 兼容其他字段
+  }
+  
+  /** MQTT 消息 payload 类型 */
+  interface MqttPayload {
+    data: MqttPayloadItem[];
+    [key: string]: unknown;
+  }
+  
+  /** 曲线数据结构类型 */
+  interface CurveDataItem {
+    xData: string[]; // X轴:时间戳字符串
+    yData: number[]; // Y轴:数值
+  }
+  
+  /** 曲线数据映射类型 */
+  type CurveDataMap = Record<string, CurveDataItem>;
+  
+  // ========== 业务配置 ==========
+  const craneInfo = JSON.parse(localStorage.getItem('craneInfo') || '{}') as Record<string, string>;
+  const loading = ref<boolean>(true);
+  // 严格指定查询参数类型,避免 undefined 隐式类型
+  const queryFormVarDictData = reactive<BizVarDictPageQuery>({
+    page_no: 0,
+    page_size: 0,
+    crane_no: craneInfo.crane_no || '', // 兜底空字符串,避免 TS 报错
+    var_code: undefined,
+    var_name: undefined,
+    mec_type: undefined,
+    switch_type: undefined,
+    gateway_id: undefined,
+    var_group: undefined,
+    var_category: undefined,
+    is_top_show: undefined,
+    is_save: undefined,
+    is_overview_top_show: undefined,
+    is_home_page_show: undefined,
+    status: undefined,
+    created_time: undefined,
+    updated_time: undefined,
+    created_id: undefined,
+    updated_id: undefined,
+  });
+  
+  // MQTT 配置(TS 类型约束)
+  const mqttConfig = {
+    wsUrl: import.meta.env.VITE_APP_WS_ENDPOINT || 'ws://127.0.0.1:9001',
+    topics: [`cdc/${craneInfo.crane_no || ''}/analog/batch/#`], // 兜底空字符串
+  };
+  const mqttUtil = new MqttUtil(mqttConfig);
+  
+  // ========== 核心数据(严格 TS 类型) ==========
+  const allData = ref<BizVarDictTable[]>([]);
+  const chartRef = ref<HTMLDivElement | null>(null);
+  let chartInstance: ECharts | null = null;
+  const curveData = ref<CurveDataMap>({});
+  const MAX_DATA_LEN = 30; // 最大数据点数量
+  
+  // ========== 解决 ECharts 报错核心:规范 Y 轴/系列配置 ==========
+  const initECharts = (): void => {
+    if (!chartRef.value) return;
+    
+    // 销毁旧实例,避免重复创建
+    if (chartInstance) {
+      chartInstance.dispose();
+    }
+  
+    // 初始化 ECharts 实例(指定 DOM 类型)
+    chartInstance = echarts.init(chartRef.value);
+    
+    // 基础配置:无标题、图例置顶(规避 getAxesOnZeroOf 报错的核心:Y轴先初始化单轴,后续动态更新)
+    const baseOption: EChartsOption = {
+      title: { show: false }, // 隐藏标题
+      legend: {
+        top: 0, // 图例置顶
+        left: 'center',
+        textStyle: { fontSize: 12 },
+        type: 'scroll', // 图例过多时滚动,避免溢出
+      },
+      tooltip: {
+        trigger: 'axis',
+        axisPointer: { type: 'line' }, // 改用 line 类型,避免 shadow 兼容性问题
+        formatter: (params: echarts.EChartOption.TooltipFormatterParams) => {
+          if (!Array.isArray(params) || params.length === 0) return '';
+          const timeStr = new Date(params[0].name).toLocaleTimeString();
+          return params.reduce((res, param) => {
+            const value = param.value as number;
+            return `${res}${param.seriesName}: ${value.toFixed(2)}<br/>`;
+          }, `${timeStr}<br/>`);
+        },
+      },
+      grid: {
+        left: '10%',
+        right: '10%',
+        bottom: '15%',
+        top: '15%',
+        containLabel: true,
+      },
+      xAxis: {
+        type: 'category',
+        data: [],
+        axisLabel: {
+          formatter: (value: string) => new Date(value).toLocaleTimeString(),
+        },
+        boundaryGap: false, // 取消边界间隙,曲线更连续
+      },
+      // 初始单 Y 轴(解决 getAxesOnZeroOf 报错),后续按变量值域分组分配区间
+      yAxis: {
+        type: 'value',
+        axisLine: { show: true },
+        splitLine: { show: true },
+      },
+      series: [], // 动态生成系列
+    };
+  
+    chartInstance.setOption(baseOption);
+    
+    // 监听窗口大小变化
+    window.addEventListener('resize', handleResize);
+  };
+  
+  /** 窗口大小变化处理 */
+  const handleResize = (): void => {
+    chartInstance?.resize();
+  };
+  
+  /** 初始化曲线数据 */
+  const initCurveData = (): void => {
+    if (!allData.value.length) return;
+  
+    // 初始化每个变量的曲线数据
+    curveData.value = allData.value.reduce((map, item) => {
+      map[item.var_code] = { xData: [], yData: [] };
+      return map;
+    }, {} as CurveDataMap);
+  
+    // 初始化系列配置(曲线不交叉核心:按变量值域分配不同区间)
+    updateEChartsSeries();
+  };
+  
+  /** 更新 ECharts 系列配置(规避曲线交叉:值域分段) */
+  const updateEChartsSeries = (): void => {
+    if (!chartInstance || !allData.value.length) return;
+  
+    // 为每个变量分配独立值域区间(避免交叉)
+    const seriesList: SeriesOption[] = allData.value.map((item, index) => {
+      // 按索引分配值域区间(如第1个变量[0-100],第2个[100-200],以此类推)
+      const valueRange = index * 100;
+  
+      return {
+        name: item.var_name || item.var_code,
+        type: 'line',
+        data: curveData.value[item.var_code]?.yData || [],
+        symbol: 'none',
+        smooth: true,
+        lineStyle: { width: 2 },
+        // 值域映射:将原始值映射到独立区间,避免交叉
+        encode: { y: 0 },
+        // 自定义数值转换(核心:曲线不交叉)
+        transform: [
+          {
+            type: 'ecSimpleTransform:custom',
+            config: {
+              callback: (params: { value: number }) => {
+                // 原始值 + 区间偏移量,保证每条曲线值域不重叠
+                return { value: params.value + valueRange };
+              },
+            },
+          },
+        ],
+      };
+    });
+  
+    // 更新系列配置(避免直接修改 Y 轴导致 getAxesOnZeroOf 报错)
+    chartInstance.setOption({
+      series: seriesList,
+    });
+  };
+  
+  /** 更新曲线数据(严格 TS 类型) */
+  const updateCurveData = (varCode: string, value: number): void => {
+    if (!curveData.value[varCode]) return;
+  
+    const now = new Date().toISOString();
+    const curveItem = curveData.value[varCode];
+  
+    // 添加新数据
+    curveItem.xData.push(now);
+    curveItem.yData.push(Number(value));
+  
+    // 限制数据长度
+    if (curveItem.xData.length > MAX_DATA_LEN) {
+      curveItem.xData.shift();
+      curveItem.yData.shift();
+    }
+  
+    // 更新 ECharts(仅更新数据,不修改轴配置,规避报错)
+    if (chartInstance) {
+      const seriesOption = chartInstance.getOption().series as SeriesOption[];
+      const targetSeriesIndex = allData.value.findIndex(item => item.var_code === varCode);
+      
+      if (targetSeriesIndex > -1) {
+        chartInstance.setOption({
+          xAxis: { data: curveItem.xData },
+          series: [
+            {
+              index: targetSeriesIndex,
+              data: curveItem.yData,
+            },
+          ],
+        });
+      }
+    }
+  };
+  
+  // ========== 数据获取 & MQTT 处理(严格 TS 类型) ==========
+  const getData = async (): Promise<void> => {
+    try {
+      const response = await BizVarDictAPI.listBizVarDictAnalog(queryFormVarDictData);
+      allData.value = response.data.data || [];
+      initCurveData();
+    } catch (error) {
+      console.error('获取变量数据失败:', error);
+    } finally {
+      loading.value = false;
+    }
+  };
+  
+  /** MQTT 消息处理(严格 TS 类型,兼容 analog/alarm 后缀) */
+  const handleMqttMessage: MqttMessageCallback = (topic: string, payload: MqttPayload): void => {
+    const topicLevels = topic.split('/');
+    if (topicLevels.length < 4 || !payload.data) return;
+  
+    const suffix = topicLevels[2];
+    // 兼容 analog(实时数据)和 alarm(告警数据)
+    if (['analog', 'alarm'].includes(suffix)) {
+      payload.data.forEach((payloadItem) => {
+        const { var_code, value } = payloadItem;
+        if (!var_code || value === undefined) return;
+  
+        // 更新 allData 中的值
+        const targetItem = allData.value.find(item => item.var_code === var_code);
+        if (targetItem) {
+          targetItem.value = Number(value);
+        }
+  
+        // 更新曲线数据(仅处理数值类型)
+        const numValue = Number(value);
+        if (!isNaN(numValue)) {
+          updateCurveData(var_code, numValue);
+        }
+      });
+    }
+  };
+  
+  // ========== 生命周期(严格 TS 规范) ==========
+  onMounted(async (): Promise<void> => {
+    initECharts();
+    await getData();
+    mqttUtil.initConnect(handleMqttMessage);
+  });
+  
+  onUnmounted((): void => {
+    mqttUtil.releaseResources();
+    window.removeEventListener('resize', handleResize);
+    // 销毁 ECharts 实例,避免内存泄漏
+    if (chartInstance) {
+      chartInstance.dispose();
+      chartInstance = null;
+    }
+  });
+  
+  // 深度监听 allData 变化
+  watch(
+    allData,
+    () => {
+      if (!loading.value) {
+        initCurveData();
+      }
+    },
+    { deep: true }
+  );
+  </script>
+  
+  <style lang="less" scoped>
+  .realtime-curve-container {
+    width: 100%;
+    height: 100vh;
+  
+    .chart-box {
+      width: 100%;
+      height: 100%;
+    }
+  }
+  </style>

+ 6 - 5
frontend/src/views/web/overview/index.vue

@@ -127,16 +127,17 @@ const queryFormCraneData = reactive<BizCranePageQuery>({
   updated_time: undefined,
   updated_time: undefined,
   created_id: undefined,
   created_id: undefined,
   updated_id: undefined,
   updated_id: undefined,
+  order_by: 'order,asc;',
 });
 });
 
 
 const queryFormVarDictData = reactive<BizVarDictPageQuery>({
 const queryFormVarDictData = reactive<BizVarDictPageQuery>({
-  page_no: 1,
-  page_size: 100,
+  page_no: 0,
+  page_size: 0,
   crane_no: undefined,
   crane_no: undefined,
   var_code: undefined,
   var_code: undefined,
   var_name: undefined,
   var_name: undefined,
   mec_type: undefined,
   mec_type: undefined,
-  switch_type: '2',
+  switch_type: undefined,
   gateway_id: undefined,
   gateway_id: undefined,
   var_group: undefined,
   var_group: undefined,
   var_category: undefined,
   var_category: undefined,
@@ -149,7 +150,7 @@ const queryFormVarDictData = reactive<BizVarDictPageQuery>({
   updated_time: undefined,
   updated_time: undefined,
   created_id: undefined,
   created_id: undefined,
   updated_id: undefined,
   updated_id: undefined,
-  is_api_request: 'True',
+  order_by: undefined,
 });
 });
 
 
 // 操作按钮点击事件
 // 操作按钮点击事件
@@ -176,7 +177,7 @@ const getVarDictData = async () => {
   try {
   try {
     alarm_loading.value = true;
     alarm_loading.value = true;
     const response = await BizVarDictAPI.listBizVarDictAlarms(queryFormVarDictData);
     const response = await BizVarDictAPI.listBizVarDictAlarms(queryFormVarDictData);
-    varDictData.value = response.data.data.items;
+    varDictData.value = response.data.data;
   } finally {
   } finally {
     alarm_loading.value = false
     alarm_loading.value = false
   }
   }