diff --git a/vue-fastapi-backend/module_admin/controller/datastd_controller.py b/vue-fastapi-backend/module_admin/controller/datastd_controller.py new file mode 100644 index 0000000..cf7d04e --- /dev/null +++ b/vue-fastapi-backend/module_admin/controller/datastd_controller.py @@ -0,0 +1,160 @@ +from datetime import datetime +from fastapi import APIRouter, Depends, Request +from sqlalchemy.ext.asyncio import AsyncSession +from config.enums import BusinessType +from config.get_db import get_db +from module_admin.entity.vo.user_vo import CurrentUserModel +from module_admin.annotation.log_annotation import Log +from module_admin.aspect.interface_auth import CheckUserInterfaceAuth +from module_admin.entity.vo.datastd_vo import DataStdCodeModel,DataStdCodeItemModel, DataStdCodePageQueryModel, DataStdCodeItemPageQueryModel, DeleteDataStdModel +from module_admin.service.datastd_service import DataStdService +from module_admin.service.login_service import LoginService +from utils.log_util import logger +from utils.page_util import PageResponseModel +from utils.response_util import ResponseUtil +import uuid + +datastdController = APIRouter(prefix='/datastd', dependencies=[Depends(LoginService.get_current_user)]) + + +#标准代码相关API +@datastdController.get( + '/stdcode/code/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:code:list'))] +) +async def get_std_code_list( + request: Request, + code_page_query: DataStdCodePageQueryModel = Depends(DataStdCodePageQueryModel.as_query), + query_db: AsyncSession = Depends(get_db), +): + code_page_query_result = await DataStdService.get_std_code_list_services(query_db, code_page_query, is_page=True) + logger.info('获取列配置列表成功') + return ResponseUtil.success(model_content=code_page_query_result) +@datastdController.get('/stdcode/codeItem/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:codeItem:list'))] +) +async def get_std_code_item_list( + request: Request, + codeItem_page_query: DataStdCodeItemPageQueryModel = Depends(DataStdCodeItemPageQueryModel.as_query), + query_db: AsyncSession = Depends(get_db), +): + codeItem_page_query_result = await DataStdService.get_std_code_item_list_services(query_db, codeItem_page_query, is_page=True) + logger.info('获取代码项列表成功') + return ResponseUtil.success(model_content=codeItem_page_query_result) +@datastdController.get( + '/stdcode/codeItem/{id}', response_model=DataStdCodeItemModel, dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:codeItem:list'))] +) +async def query_detail_codeItem(request: Request, id: str, query_db: AsyncSession = Depends(get_db)): + config_detail_result = await DataStdService.code_item_detail_services(query_db, id) + logger.info(f'获取config_id为{id}的信息成功') + + return ResponseUtil.success(data=config_detail_result) +@datastdController.get( + '/stdcode/code/{id}', response_model=DataStdCodeModel, dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:code:list'))] +) +async def query_detail_code(request: Request, id: str, query_db: AsyncSession = Depends(get_db)): + config_detail_result = await DataStdService.code_detail_services(query_db, id) + logger.info(f'获取config_id为{id}的信息成功') + + return ResponseUtil.success(data=config_detail_result) +@datastdController.post('/stdcode/code', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:code:add'))]) +@Log(title='代码管理', business_type=BusinessType.INSERT) +async def add_std_code( + request: Request, + add_std_code: DataStdCodeModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), +): + + add_std_code.create_by = current_user.user.user_name + add_std_code.create_time = datetime.now() + add_std_code.update_by = current_user.user.user_name + add_std_code.update_time = datetime.now() + add_std_code_result = await DataStdService.add_std_code_services(request, query_db, add_std_code) + logger.info(add_std_code_result.message) + return ResponseUtil.success(msg=add_std_code_result.message) + + +@datastdController.put('/stdcode/code', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:code:edit'))]) +@Log(title='代码管理', business_type=BusinessType.UPDATE) +async def edit_std_code( + request: Request, + edit_std_code: DataStdCodeModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), +): + edit_std_code.update_by = current_user.user.user_name + edit_std_code.update_time = datetime.now() + edit_std_code_result = await DataStdService.edit_std_code_services(request, query_db, edit_std_code) + logger.info(edit_std_code_result.message) + return ResponseUtil.success(msg=edit_std_code_result.message) + + +@datastdController.delete('/stdcode/code/{ids}', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:code:remove'))]) +@Log(title='代码管理', business_type=BusinessType.DELETE) +async def delete_std_code( + request: Request, + ids: str, + query_db: AsyncSession = Depends(get_db), +): + delete_std_code = DeleteDataStdModel(ids =ids) + delete_std_code_result = await DataStdService.delete_std_code_services(request, query_db, delete_std_code) + logger.info(delete_std_code_result.message) + return ResponseUtil.success(msg=delete_std_code_result.message) + + +@datastdController.post('/stdcode/codeItem', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:codeItem:add'))]) +@Log(title='代码项管理', business_type=BusinessType.INSERT) +async def add_std_code_item( + request: Request, + add_std_code_item: DataStdCodeItemModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), +): + add_std_code_item.create_by = current_user.user.user_name + add_std_code_item.create_time = datetime.now() + add_std_code_item.update_by = current_user.user.user_name + add_std_code_item.update_time = datetime.now() + add_std_code_item_result = await DataStdService.add_std_code_item_services(request, query_db, add_std_code_item) + logger.info(add_std_code_item_result.message) + return ResponseUtil.success(msg=add_std_code_item_result.message) + + +@datastdController.put('/stdcode/codeItem', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:codeItem:edit'))]) +@Log(title='代码项管理', business_type=BusinessType.UPDATE) +async def edit_std_code_item( + request: Request, + edit_std_code_item: DataStdCodeItemModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), +): + edit_std_code_item.update_by = current_user.user.user_name + edit_std_code_item.update_time = datetime.now() + edit_std_code_item_result = await DataStdService.edit_std_code_item_services(request, query_db, edit_std_code_item) + logger.info(edit_std_code_item_result.message) + return ResponseUtil.success(msg=edit_std_code_item_result.message) + + +@datastdController.delete('/stdcode/codeItem/{ids}', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:codeItem:remove'))]) +@Log(title='代码项管理', business_type=BusinessType.DELETE) +async def delete_std_code_item( + request: Request, + ids: str, + query_db: AsyncSession = Depends(get_db), +): + delete_std_code_item = DeleteDataStdModel(ids=ids) + delete_std_code_item_result = await DataStdService.delete_std_code_item_services(request, query_db, delete_std_code_item) + logger.info(delete_std_code_item_result.message) + return ResponseUtil.success(msg=delete_std_code_item_result.message) + + +@datastdController.get('/stdcode/codeItem/{id}', response_model=DataStdCodeItemModel, dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:codeItem:query'))]) +async def query_std_code_item_detail( + request: Request, + id: int, + query_db: AsyncSession = Depends(get_db), +): + codeItem_detail_result = await DataStdService.get_std_code_item_by_id_services(query_db, id) + logger.info(f'获取id为{id}的代码项信息成功') + return ResponseUtil.success(data=codeItem_detail_result) + + + diff --git a/vue-fastapi-backend/module_admin/dao/datastd_dao.py b/vue-fastapi-backend/module_admin/dao/datastd_dao.py new file mode 100644 index 0000000..e408483 --- /dev/null +++ b/vue-fastapi-backend/module_admin/dao/datastd_dao.py @@ -0,0 +1,163 @@ +from sqlalchemy import delete, select, update, desc +from sqlalchemy.ext.asyncio import AsyncSession +from module_admin.entity.do.datastd_do import DataStdCode, DataStdCodeItem +from module_admin.entity.vo.datastd_vo import DataStdCodeModel,DataStdCodeItemModel +from utils.page_util import PageUtil + + +class DataStdDao: + """ + 数据标准模块 + """ + + @classmethod + async def get_std_code_list(cls, db: AsyncSession, query_object: DataStdCodeModel, is_page: bool = False): + """ + 获取 DataStdCode 的列表信息,支持模糊查询和分页 + :param db: ORM对象 + :param query_object: 查询参数对象 + :param is_page: 是否开启分页 + :return: 列表信息 + """ + # 构建查询条件 + filters = [] + if query_object.code_name: + filters.append(DataStdCode.code_name.like(f"%{query_object.code_name}%")) + if query_object.code_status: + filters.append(DataStdCode.code_status==query_object.code_status) + if query_object.sys_id: + filters.append(DataStdCode.sys_id==query_object.sys_id) + if query_object.code_type: + filters.append(DataStdCode.code_type==query_object.code_type) + + # 构建查询语句 + query = ( + select(DataStdCode) + .where(*filters) + .order_by(desc(DataStdCode.create_time)) # 按创建时间降序排序 + ) + + # 分页处理 + col_list = await PageUtil.paginate( + db, query, query_object.page_num, query_object.page_size, is_page + ) + return col_list + + + @classmethod + async def get_std_code_item_list(cls, db: AsyncSession, query_object: DataStdCodeItemModel, is_page: bool = False): + """ + 获取 DataStdCodeItem 的列表信息,支持模糊查询和分页 + :param db: ORM对象 + :param query_object: 查询参数对象 + :param is_page: 是否开启分页 + :return: 列表信息 + """ + # 构建查询条件 + filters = [] + if query_object.code_name: + filters.append(DataStdCodeItem.code_name.like(f"%{query_object.code_name}%") or DataStdCodeItem.code_num.like(f"%{query_object.code_name}%")) + if query_object.code_status: + filters.append(DataStdCodeItem.code_status==query_object.code_status) + if query_object.code_mean: + filters.append(DataStdCodeItem.code_mean==query_object.code_mean) + if query_object.parent_id: + filters.append(DataStdCodeItem.parent_id==query_object.parent_id) + else : + filters.append(1==2) + # 构建查询语句 + query = ( + select(DataStdCodeItem) + .where(*filters) + .order_by(desc(DataStdCodeItem.create_time)) # 按创建时间降序排序 + ) + + # 分页处理 + col_list = await PageUtil.paginate( + db, query, query_object.page_num, query_object.page_size, is_page + ) + return col_list + + @classmethod + async def get_data_code_list(cls, db: AsyncSession, query_object: DataStdCodeModel): + List = ( + await db.execute( + select(DataStdCode) + .where( + DataStdCode.code_name == query_object.code_name if query_object.code_name else True, + DataStdCode.code_status == query_object.code_status if query_object.code_status else True, + DataStdCode.sys_id == query_object.sys_id if query_object.sys_id else True, + DataStdCode.code_type == query_object.code_type if query_object.code_type else True + ) + ) + ).scalars().all() + return List + @classmethod + async def get_data_code_item_list(cls, db: AsyncSession, query_object: DataStdCodeItemModel): + List = ( + await db.execute( + select(DataStdCodeItem) + .where( + DataStdCodeItem.code_name == query_object.code_name if query_object.code_name else True, + DataStdCodeItem.code_status == query_object.code_status if query_object.code_status else True, + ) + ) + ).scalars().all() + return List + + @classmethod + async def get_std_code_by_id(cls, db: AsyncSession, Id: str): + col = ( + await db.execute( + select(DataStdCode) + .where(DataStdCode.Id == Id) + ) + ).scalars().first() + return col + + @classmethod + async def get_std_code_item_by_id(cls, db: AsyncSession, Id: str): + col = ( + await db.execute( + select(DataStdCodeItem) + .where(DataStdCodeItem.Id == Id) + ) + ).scalars().first() + return col + + + @classmethod + async def add_std_code(cls, db: AsyncSession,model:DataStdCodeModel): + col = DataStdCode( + **model.model_dump() + ) + db.add(col) + await db.flush() + return col + @classmethod + async def add_std_code_item(cls, db: AsyncSession,model:DataStdCodeItemModel): + col = DataStdCodeItem( + **model.model_dump() + ) + db.add(col) + await db.flush() + return col + + @classmethod + async def delete_std_code(cls, db: AsyncSession, Id: str): + await db.execute(delete(DataStdCode).where(DataStdCode.id == Id)) + + @classmethod + async def delete_std_code_Item(cls, db: AsyncSession, Id: str): + await db.execute(delete(DataStdCodeItem).where(DataStdCodeItem.id == Id)) + + @classmethod + async def update_std_code(cls, db: AsyncSession, update_data: DataStdCodeModel): + + await db.execute(update(DataStdCode), [update_data]) + await db.flush() + + @classmethod + async def update_std_code_Item(cls, db: AsyncSession, update_data: DataStdCodeItemModel): + await db.execute(update(DataStdCodeItem), [update_data]) + await db.flush() diff --git a/vue-fastapi-backend/module_admin/entity/do/datastd_do.py b/vue-fastapi-backend/module_admin/entity/do/datastd_do.py new file mode 100644 index 0000000..32d38de --- /dev/null +++ b/vue-fastapi-backend/module_admin/entity/do/datastd_do.py @@ -0,0 +1,41 @@ +from sqlalchemy import Column, Integer, String, DateTime, Boolean +from config.database import Base + +# 数据标准模块相关表 + +class DataStdCode(Base): + """ + 标准代码表 (Standard Code Table) + """ + __tablename__ = 't_datastd_code' + + id = Column(String(50), primary_key=True, comment='标准代码Id') + create_by = Column(String(20), default='', comment='创建者') + create_time = Column(DateTime, nullable=True, default=None, comment='创建时间') + update_by = Column(String(20), default='', comment='更新者') + update_time = Column(DateTime, nullable=True, default=None, comment='更新时间') + code_num = Column(String(50), default=None, comment='标准代码编号') + code_name = Column(String(50), default=None, comment='标准代码值') + code_type = Column(String(10), default=None, comment='标准代码类型(sys:系统级 company:公司级)') + code_status = Column(String(1), default=None, comment='代码状态(0:有效 1:无效)') + sys_name = Column(String(500), default=None, comment='归属系统') + sys_id = Column(Integer, default=None, comment='归属系统Id') + + +class DataStdCodeItem(Base): + """ + 标准代码项表 (Standard Code Item Table) + """ + __tablename__ = 't_datastd_code_item' + + id = Column(String(50), primary_key=True, comment='标准代码Id') + create_by = Column(String(20), default='', comment='创建者') + create_time = Column(DateTime, nullable=True, default=None, comment='创建时间') + update_by = Column(String(20), default='', comment='更新者') + update_time = Column(DateTime, nullable=True, default=None, comment='更新时间') + code_num = Column(String(50), default=None, comment='代码值') + code_name = Column(String(50), default=None, comment='代码值名称') + parent_id = Column(String(10), default=None, comment='代码id') + code_status = Column(String(1), default=None, comment='代码状态(0:有效 1:无效)') + code_mean = Column(String(500), default=None, comment='代码含义') + diff --git a/vue-fastapi-backend/module_admin/entity/vo/datastd_vo.py b/vue-fastapi-backend/module_admin/entity/vo/datastd_vo.py new file mode 100644 index 0000000..625440d --- /dev/null +++ b/vue-fastapi-backend/module_admin/entity/vo/datastd_vo.py @@ -0,0 +1,95 @@ +from pydantic import BaseModel +from typing import Union, Optional, List +from datetime import datetime +from module_admin.annotation.pydantic_annotation import as_query +from pydantic import BaseModel, ConfigDict, Field +from pydantic.alias_generators import to_camel +from pydantic_validation_decorator import NotBlank, Size + + +class CrudDataStdModel(BaseModel): + is_success: bool + message: str + + +class DataStdCodeModel(BaseModel): + """ + 标准代码表对应Pydantic模型 (Standard Code Table Pydantic Model) + """ + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) + + id: Optional[str] = None + create_by: Optional[str] = None + create_time: Optional[datetime] = None + update_by: Optional[str] = None # Updater + update_time: Optional[datetime] = None + code_num: Optional[str] = None + code_name: Optional[str] = None + code_type: Optional[str] = None + code_status: Optional[str] = None + sys_name: Optional[str] = None + sys_id: Optional[str] = None + +class DataStdCodeItemModel(BaseModel): + """ + 标准代码项表对应Pydantic模型 (Standard Code Item Table Pydantic Model) + """ + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) + + id: Optional[str] = None + create_by: Optional[str] = None + create_time: Optional[datetime] = None + update_by: Optional[str] = None + update_time: Optional[datetime] = None + code_num: Optional[str] = None + code_name: Optional[str] = None + parent_id: Optional[str] = None + code_status: Optional[str] = None + code_mean: Optional[str] = None + + +@as_query +class DataStdCodePageQueryModel(DataStdCodeModel): + """ + 元数据任务分页查询模型 + """ + page_num: int = Field(default=1, description='当前页码') + page_size: int = Field(default=10, description='每页记录数') +@as_query +class DataStdCodeItemPageQueryModel(DataStdCodeItemModel): + """ + 元数据任务分页查询模型 + """ + page_num: int = Field(default=1, description='当前页码') + page_size: int = Field(default=10, description='每页记录数') + +class DeleteDataStdModel(BaseModel): + """ + 删除参数配置模型 + """ + model_config = ConfigDict(alias_generator=to_camel) + ids: str = Field(description='需要删除的参数主键') +# class MetaSecurityApiModel(BaseModel): +# """ +# 数据源行控制表对应Pydantic模型 +# """ +# model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) +# dbRId: Optional[int] = None +# username: Optional[str] = Field(default=None, description='用户名称') +# password: Optional[str] = Field(default=None, description='用户密码') +# sqlStr: Optional[str] = Field(default=None, description='sql') + +# @NotBlank(field_name='username', message='用户名称不能为空') +# @Size(field_name='username', min_length=0, max_length=100, message='用户名称长度不能超过100个字符') +# def get_username(self): +# return self.username +# @NotBlank(field_name='password', message='用户密码不能为空') +# def get_password(self): +# return self.password +# @NotBlank(field_name='sqlStr', message='sql不能为空') +# def get_sqlStr(self): +# return self.username +# def validate_fields(self): +# self.get_username() +# self.get_password() +# self.get_sqlStr() diff --git a/vue-fastapi-backend/module_admin/service/datastd_service.py b/vue-fastapi-backend/module_admin/service/datastd_service.py new file mode 100644 index 0000000..2227339 --- /dev/null +++ b/vue-fastapi-backend/module_admin/service/datastd_service.py @@ -0,0 +1,249 @@ +from fastapi import Request +from sqlalchemy.ext.asyncio import AsyncSession +from exceptions.exception import ServiceException +from module_admin.dao.datastd_dao import DataStdDao +from module_admin.entity.vo.common_vo import CrudResponseModel +from module_admin.entity.vo.datastd_vo import DataStdCodeModel, DataStdCodeItemModel,DeleteDataStdModel +from utils.common_util import CamelCaseUtil +import uuid +class DataStdService: + """ + 数据源标准服务层 + """ + + @classmethod + async def get_std_code_list_services( + cls, query_db: AsyncSession, query_object: DataStdCodeModel, is_page: bool = False + ): + """ + 获取列配置列表信息service + + :param query_db: orm对象 + :param query_object: 查询参数对象 + :param is_page: 是否开启分页 + :return: 列配置列表信息对象 + """ + col_list_result = await DataStdDao.get_std_code_list(query_db, query_object, is_page) + return col_list_result + + @classmethod + async def get_std_code_item_list_services( + cls, query_db: AsyncSession, query_object: DataStdCodeItemModel, is_page: bool = False + ): + """ + 获取行配置列表信息service + + :param query_db: orm对象 + :param query_object: 查询参数对象 + :param is_page: 是否开启分页 + :return: 行配置列表信息对象 + """ + row_list_result = await DataStdDao.get_std_code_item_list(query_db, query_object, is_page) + return row_list_result + + @classmethod + async def get_std_code_by_id_services(cls, query_db: AsyncSession, id: str): + """ + 获取列配置详细信息service + + :param query_db: orm对象 + :param id: 列配置ID + :return: 列配置详细信息对象 + """ + col = await DataStdDao.get_std_code_by_id(query_db, id) + if col: + result = DataStdCodeModel(**CamelCaseUtil.transform_result(col)) + else: + result = DataStdCodeModel(**dict()) + return result + + @classmethod + async def get_std_code_item_by_id_services(cls, query_db: AsyncSession, id: str): + """ + 获取行配置详细信息service + + :param query_db: orm对象 + :param id: 行配置ID + :return: 行配置详细信息对象 + """ + row = await DataStdDao.get_std_code_item_by_id(query_db, id) + if row: + result = DataStdCodeItemModel(**CamelCaseUtil.transform_result(row)) + else: + result = DataStdCodeItemModel(**dict()) + return result + + @classmethod + async def add_std_code_services(cls, request: Request, query_db: AsyncSession, page_object: DataStdCodeModel): + """ + 新增列配置服务 + + :param request: Request对象 + :param query_db: orm对象 + :param page_object: 新增的列配置对象 + :return: 新增列配置校验结果 + """ + try: + # 创建新的 page_object 实例,避免修改原始对象 + new_page_object = DataStdCodeModel(**page_object.model_dump(by_alias=True)) + new_page_object.id = str(uuid.uuid4()) + # 调用 DAO 方法插入数据 + await DataStdDao.add_std_code(query_db, new_page_object) + await query_db.commit() + return CrudResponseModel(is_success=True, message='新增标准代码成功') + except Exception as e: + await query_db.rollback() + raise e + @classmethod + async def add_std_code_item_services(cls, request: Request, query_db: AsyncSession, page_object: DataStdCodeItemModel): + """ + 新增列配置服务 + + :param request: Request对象 + :param query_db: orm对象 + :param page_object: 新增的列配置对象 + :return: 新增列配置校验结果 + """ + try: + # 创建新的 page_object 实例,避免修改原始对象 + new_page_object = DataStdCodeItemModel(**page_object.model_dump(by_alias=True)) + new_page_object.id = str(uuid.uuid4()) + # 调用 DAO 方法插入数据 + await DataStdDao.add_std_code_item(query_db, new_page_object) + await query_db.commit() + return CrudResponseModel(is_success=True, message='新增标准代码项成功') + except Exception as e: + await query_db.rollback() + raise e + + + @classmethod + async def code_detail_services(cls, query_db: AsyncSession, col: str): + """ + 获取参数配置详细信息service + + :param query_db: orm对象 + :param config_id: 参数配置id + :return: 参数配置id对应的信息 + """ + config = await DataStdDao.get_std_code_by_id(query_db, col) + if config: + result = DataStdCodeModel(**CamelCaseUtil.transform_result(config)) + else: + result = DataStdCodeModel(**dict()) + + return result + @classmethod + async def code_item_detail_services(cls, query_db: AsyncSession, row_id: str): + """ + 获取参数配置详细信息service + + :param query_db: orm对象 + :param config_id: 参数配置id + :return: 参数配置id对应的信息 + """ + config = await DataStdDao.get_std_code_item_by_id(query_db, row_id) + if config: + result = DataStdCodeItemModel(**CamelCaseUtil.transform_result(config)) + else: + result = DataStdCodeItemModel(**dict()) + + return result + @classmethod + async def edit_std_code_services(cls, request: Request, query_db: AsyncSession, page_object: DataStdCodeModel): + """ + 编辑列配置服务 + + :param request: Request对象 + :param query_db: orm对象 + :param page_object: 编辑的列配置对象 + :return: 编辑列配置校验结果 + """ + edit_col = page_object.model_dump(exclude_unset=True) + col_info = await cls.get_std_code_by_id_services(query_db, page_object.id) + + if col_info: + try: + await DataStdDao.update_std_code(query_db, edit_col) + await query_db.commit() + return CrudResponseModel(is_success=True, message='编辑标准代码成功') + except Exception as e: + await query_db.rollback() + raise e + else: + raise ServiceException(message=f'标准代码{page_object.id}不存在') + + @classmethod + async def edit_std_code_item_services(cls, request: Request, query_db: AsyncSession, page_object: DataStdCodeItemModel): + """ + 编辑行配置服务 + :param request: Request对象 + :param query_db: orm对象 + :param page_object: 编辑的行配置对象 + :return: 编辑行配置校验结果 + """ + edit_row = page_object.model_dump(exclude_unset=True) + row_info = await cls.get_std_code_item_by_id_services(query_db, page_object.id) + if row_info: + try: + await DataStdDao.update_std_code_Item(query_db, edit_row) + await query_db.commit() + return CrudResponseModel(is_success=True, message='编辑标准代码项配置成功') + except Exception as e: + await query_db.rollback() + raise e + else: + raise ServiceException(message=f'标准代码项{page_object.id}不存在') + + @classmethod + async def delete_std_code_services(cls, request: Request, query_db: AsyncSession, page_object: DeleteDataStdModel): + """ + 删除列配置服务 + :param request: Request对象 + :param query_db: orm对象 + :param page_object: 删除列配置对象 + :return: 删除列配置校验结果 + """ + if page_object.ids: + col_id_list = page_object.ids.split(',') + try: + for col_id in col_id_list: + col_info = await cls.get_std_code_by_id_services(query_db, col_id) + if col_info: + # 校验不能删除的系统内置列 + await DataStdDao.delete_std_code(query_db, col_id) + await query_db.commit() + + + return CrudResponseModel(is_success=True, message='删除列配置成功') + except Exception as e: + await query_db.rollback() + raise e + else: + raise ServiceException(message='传入列配置ID为空') + + @classmethod + async def delete_std_code_item_services(cls, request: Request, query_db: AsyncSession, page_object: DeleteDataStdModel): + """ + 删除行配置服务 + + :param request: Request对象 + :param query_db: orm对象 + :param page_object: 删除行配置对象 + :return: 删除行配置校验结果 + """ + if page_object.ids: + row_id_list = page_object.ids.split(',') + try: + for row_id in row_id_list: + row_info = await cls.get_std_code_item_by_id_services(query_db, row_id) + if row_info: + await DataStdDao.delete_std_code_Item(query_db, row_id) + await query_db.commit() + return CrudResponseModel(is_success=True, message='删除行配置成功') + except Exception as e: + await query_db.rollback() + raise e + else: + raise ServiceException(message='传入行配置ID为空') + diff --git a/vue-fastapi-backend/module_admin/service/metasecurity_service.py b/vue-fastapi-backend/module_admin/service/metasecurity_service.py index 71714e2..ac9c18f 100644 --- a/vue-fastapi-backend/module_admin/service/metasecurity_service.py +++ b/vue-fastapi-backend/module_admin/service/metasecurity_service.py @@ -587,29 +587,8 @@ async def generate_sql(tablesRowCol:dict, table_columns:dict): if where_conditions: sql_queries[table_name] += " WHERE " + where_conditions return sql_queries - -# async def replace_table_with_subquery(ctrSqlDict, oldStrSql): -# # 遍历 ctrSqlDict 并替换 SQL 查询中的表名 -# for table_name, subquery in ctrSqlDict.items(): -# # 创建一个正则表达式,匹配原始 SQL 中的表名(注意大小写问题,正则会忽略大小写) -# # 匹配类似 "模式名.tab1" 或 "tab1" 的表名 -# table_name_pattern = r'\b(?:[a-zA-Z_][a-zA-Z0-9_]*\.)?' + re.escape(table_name) + r'\b' - -# # 替换原始 SQL 中的表名为对应的子查询 -# def add_alias(match): -# # 子查询替换后,检查是否有 AS 关键字 -# replaced = f"({subquery})" -# # 检查是否已经有 AS -# if ' AS ' not in match.group(0).upper(): -# # 如果没有 AS 关键字,则添加一个默认别名 -# alias = table_name # 你可以根据需求设置别名格式,这里使用表名作为别名 -# replaced += f" AS {alias}" -# return replaced - -# oldStrSql = re.sub(table_name_pattern, add_alias, oldStrSql, flags=re.IGNORECASE) - -# return oldStrSql async def replace_table_with_subquery(ctrSqlDict, oldStrSql): + table_alias_map = {} # 存储表名和别名的映射 for table_name, subquery in ctrSqlDict.items(): # 构建正则表达式,匹配表名及可能的别名 pattern = ( @@ -623,17 +602,22 @@ async def replace_table_with_subquery(ctrSqlDict, oldStrSql): original_table = match.group(1) # 原始表名(可能含模式名) alias_part = match.group(2) # 别名部分(含空格、AS 或直接别名) alias_name = match.group(3) # 别名名称(无 AS 前缀) - # 处理表名后直接跟着 SQL 关键字的情况 - following_text = alias_name.upper() - sql_keywords = {"LIMIT", "WHERE", "ORDER", "GROUP", "HAVING", "JOIN", "ON", "USING", "UNION", - "EXCEPT", "INTERSECT", "FETCH", "OFFSET"} - if alias_name and following_text.split()[0] not in sql_keywords: - # 已存在别名,且别名后没有紧跟 SQL 关键字,保留原别名 - replaced = f"({subquery}) {alias_part}" + if original_table not in table_alias_map: + # 处理表名后直接跟着 SQL 关键字的情况 + sql_keywords = {"LIMIT", "WHERE", "ORDER", "GROUP", "HAVING", "JOIN", "ON", "USING", "UNION", + "EXCEPT", "INTERSECT", "FETCH", "OFFSET"} + if alias_name and alias_name.upper().split()[0] not in sql_keywords: + # 已存在别名,且别名后没有紧跟 SQL 关键字,保留原别名 + replaced = f"({subquery}) {alias_part}" + table_alias_map[original_table] = alias_part + else: + # 无别名时,或者别名无效(如 LIMIT),添加默认别名 + alias = original_table.split('.')[-1] + replaced = f"({subquery}) AS {alias}{alias_part}" + table_alias_map[original_table] = alias else: - # 无别名时,或者别名无效(如 LIMIT),添加默认别名 - alias = original_table.split('.')[-1] - replaced = f"({subquery}) AS {alias}{alias_part}" + alias = table_alias_map[original_table] + replaced = f"{alias}" # 使用别名 return replaced # 执行替换(忽略大小写) oldStrSql = re.sub(pattern, replace, oldStrSql, flags=re.IGNORECASE) diff --git a/vue-fastapi-backend/server.py b/vue-fastapi-backend/server.py index 9853789..e0ba955 100644 --- a/vue-fastapi-backend/server.py +++ b/vue-fastapi-backend/server.py @@ -26,6 +26,7 @@ from module_admin.controller.aichat_controller import aichatController from module_admin.controller.metatask_controller import metataskController from module_admin.controller.meta_controller import metaController from module_admin.controller.metasecurity_controller import metaSecurityController +from module_admin.controller.datastd_controller import datastdController from module_admin.controller.approval_controller import approvalController from module_admin.controller.data_ast_content_controller import dataCatalogController from sub_applications.handle import handle_sub_applications @@ -88,6 +89,7 @@ controller_list = [ {'router': aichatController, 'tags': ['智能问答模块']}, {'router': metaController, 'tags': ['元数据信息模块']}, {'router': approvalController, 'tags': ['审批模块']}, + {'router': datastdController, 'tags': ['数据标准模块']}, {'router': dataCatalogController, 'tags': ['系统管理-数据目录管理']}, ] diff --git a/vue-fastapi-frontend/src/api/datastd/stdcode.js b/vue-fastapi-frontend/src/api/datastd/stdcode.js new file mode 100644 index 0000000..377e93e --- /dev/null +++ b/vue-fastapi-frontend/src/api/datastd/stdcode.js @@ -0,0 +1,108 @@ +import request from '@/utils/request' +import { parseStrEmpty } from "@/utils/ruoyi"; + +// 查询标准代码列表 +export function listStdCode(query) { + return request({ + url: '/default-api/datastd/stdcode/code/list', + method: 'get', + params: query + }) +} + +// 查询标准代码项列表 +export function listStdCodeItem(query) { + return request({ + url: '/default-api/datastd/stdcode/codeItem/list', + method: 'get', + params: query + }) +} + +// 查询标准代码详情 +export function getStdCode(colId) { + return request({ + url: '/default-api/datastd/stdcode/code/' + parseStrEmpty(colId), + method: 'get' + }) +} + +// 查询标准代码项详情 +export function getStdCodeItem(rowId) { + return request({ + url: '/default-api/datastd/stdcode/codeItem/' + parseStrEmpty(rowId), + method: 'get' + }) +} + +// 新增标准代码 +export function addStdCode(data) { + return request({ + url: '/default-api/datastd/stdcode/code', + method: 'post', + data: data + }) +} + +// 新增标准代码项 +export function addStdCodeItem(data) { + return request({ + url: '/default-api/datastd/stdcode/codeItem', + method: 'post', + data: data + }) +} + +// 修改标准代码 +export function updateStdCode(data) { + return request({ + url: '/default-api/datastd/stdcode/code', + method: 'put', + data: data + }) +} + +// 修改标准代码项 +export function updateStdCodeItem(data) { + return request({ + url: '/default-api/datastd/stdcode/codeItem', + method: 'put', + data: data + }) +} + +// 删除标准代码 +export function deleteStdCode(colId) { + return request({ + url: '/default-api/datastd/stdcode/code/' + colId, + method: 'delete' + }) +} + +// 删除标准代码项 +export function deleteStdCodeItem(rowId) { + return request({ + url: '/default-api/datastd/stdcode/codeItem/' + rowId, + method: 'delete' + }) +} + +// 批量删除标准代码 +export function deleteStdCodes(colIds) { + return request({ + url: '/default-api/datastd/stdcode/code/' + colIds, + method: 'delete' + }) +} + +// 批量删除标准代码项 +export function deleteStdCodeItems(rowIds) { + return request({ + url: '/default-api/datastd/stdcode/codeItem/' + rowIds, + method: 'delete' + }) +} + + + + diff --git a/vue-fastapi-frontend/src/views/datastd/stdcode/index.vue b/vue-fastapi-frontend/src/views/datastd/stdcode/index.vue new file mode 100644 index 0000000..44d0fbb --- /dev/null +++ b/vue-fastapi-frontend/src/views/datastd/stdcode/index.vue @@ -0,0 +1,319 @@ + + + + + + + + + + + + + {{ data.name }} + + + + + + + + + + + + + + + + 搜索 + 重置 + + + + + + 新增 + + + 修改 + + + 删除 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 取消 + 确定 + + + + + + + +