diff --git a/vue-fastapi-backend/module_admin/controller/datastd_controller.py b/vue-fastapi-backend/module_admin/controller/datastd_controller.py index 2bcd8c2..173597d 100644 --- a/vue-fastapi-backend/module_admin/controller/datastd_controller.py +++ b/vue-fastapi-backend/module_admin/controller/datastd_controller.py @@ -6,7 +6,7 @@ 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, DataStdCodePageQueryModel, DeleteDataStdModel +from module_admin.entity.vo.datastd_vo import DataStdCodeModel, DataStdCodePageQueryModel, DeleteDataStdModel,DataStdDictModel,DataStdDictPageQueryModel from module_admin.service.datastd_service import DataStdService from module_admin.service.login_service import LoginService from utils.log_util import logger @@ -138,6 +138,72 @@ async def edit_std_code_with_items( + # ----------------------------------------------------------------数据字典---------------------------------------------------------------------------------------------------- + + +@datastdController.get( + '/stddict/dict/list', response_model=PageResponseModel, dependencies=[Depends(CheckUserInterfaceAuth('datastd:stddict:dict:list'))] +) +async def get_std_dict_list( + request: Request, + dict_page_query: DataStdDictPageQueryModel = Depends(DataStdDictPageQueryModel.as_query), + query_db: AsyncSession = Depends(get_db), +): + dict_page_query_result = await DataStdService.get_std_dict_list_services(query_db, dict_page_query, is_page=True) + logger.info('获取列配置列表成功') + return ResponseUtil.success(model_content=dict_page_query_result) +@datastdController.get( + '/stddict/dict/{id}', response_model=DataStdDictModel, dependencies=[Depends(CheckUserInterfaceAuth('datastd:stddict:dict:list'))] +) +async def query_detail_dict(request: Request, id: str, query_db: AsyncSession = Depends(get_db)): + config_detail_result = await DataStdService.dict_detail_services(query_db, id) + logger.info(f'获取config_id为{id}的信息成功') + + return ResponseUtil.success(data=config_detail_result) +@datastdController.post('/stddict/dict', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stddict:dict:add'))]) +@Log(title='代码管理', business_type=BusinessType.INSERT) +async def add_std_dict( + request: Request, + add_std_dict: DataStdDictModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), +): + + add_std_dict.create_by = current_user.user.user_name + add_std_dict.create_time = datetime.now() + add_std_dict.update_by = current_user.user.user_name + add_std_dict.update_time = datetime.now() + add_std_dict_result = await DataStdService.add_std_dict_services(request, query_db, add_std_dict) + logger.info(add_std_dict_result.message) + return ResponseUtil.success(msg=add_std_dict_result.message) + + +@datastdController.put('/stddict/dict', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stddict:dict:edit'))]) +@Log(title='代码管理', business_type=BusinessType.UPDATE) +async def edit_std_dict( + request: Request, + edit_std_dict: DataStdDictModel, + query_db: AsyncSession = Depends(get_db), + current_user: CurrentUserModel = Depends(LoginService.get_current_user), +): + edit_std_dict.update_by = current_user.user.user_name + edit_std_dict.update_time = datetime.now() + edit_std_dict_result = await DataStdService.edit_std_dict_services(request, query_db, edit_std_dict) + logger.info(edit_std_dict_result.message) + return ResponseUtil.success(msg=edit_std_dict_result.message) + + +@datastdController.delete('/stddict/dict/{ids}', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stddict:dict:remove'))]) +@Log(title='代码管理', business_type=BusinessType.DELETE) +async def delete_std_dict( + request: Request, + ids: str, + query_db: AsyncSession = Depends(get_db), +): + delete_std_dict = DeleteDataStdModel(ids =ids) + delete_std_dict_result = await DataStdService.delete_std_dict_services(request, query_db, delete_std_dict) + logger.info(delete_std_dict_result.message) + return ResponseUtil.success(msg=delete_std_dict_result.message) diff --git a/vue-fastapi-backend/module_admin/dao/datastd_dao.py b/vue-fastapi-backend/module_admin/dao/datastd_dao.py index 9876c8f..219fa90 100644 --- a/vue-fastapi-backend/module_admin/dao/datastd_dao.py +++ b/vue-fastapi-backend/module_admin/dao/datastd_dao.py @@ -1,15 +1,14 @@ from sqlalchemy import delete, select, update, desc,or_ from sqlalchemy.ext.asyncio import AsyncSession -from module_admin.entity.do.datastd_do import DataStdCode -from module_admin.entity.vo.datastd_vo import DataStdCodeModel +from module_admin.entity.do.datastd_do import DataStdCode,DataStdDict +from module_admin.entity.vo.datastd_vo import DataStdCodeModel,DataStdDictModel from utils.page_util import PageUtil from sqlalchemy.orm import aliased class DataStdDao: - """ - 数据标准模块 - """ + + # ----------------------------------------------------------------数据标准模块---------------------------------------------------------------------------------------------------- @classmethod async def get_std_code_list(cls, db: AsyncSession, query_object: DataStdCodeModel, is_page: bool = False): @@ -172,8 +171,89 @@ class DataStdDao: # 如果不存在,则检查代码项表中是否存在相同的code_num if not existing_code: - result = await query_db.execute(select(DataStdCodeModel).filter(DataStdCodeModel.code_num == code_num)) + result = await query_db.execute(select(DataStdCode).filter(DataStdCodeModel.code_num == code_num)) existing_code_item = result.scalar_one_or_none() return existing_code_item is not None - return True \ No newline at end of file + return True + # ----------------------------------------------------------------数据字典---------------------------------------------------------------------------------------------------- + @classmethod + async def get_std_dict_list(cls, db: AsyncSession, query_object: DataStdDictModel, is_page: bool = False): + """ + 获取 DataStdDict 的列表信息,支持模糊查询和分页 + :param db: ORM对象 + :param query_object: 查询参数对象 + :param is_page: 是否开启分页 + :return: 列表信息 + """ + # 构建查询条件 + filters = [] + if query_object.dict_name: + filters.append(DataStdDict.dict_name.like(f"%{query_object.dict_name}%")) + if query_object.dict_code: + filters.append(DataStdDict.dict_code.like(f"%{query_object.dict_code}%")) + if query_object.dict_level: + filters.append(DataStdDict.dict_level == query_object.dict_level) + if query_object.sys_id: + filters.append(DataStdDict.sys_id == query_object.sys_id) + if query_object.dict_type: + filters.append(DataStdDict.dict_type == query_object.dict_type) + if query_object.dict_status: + filters.append(DataStdDict.dict_status == query_object.dict_status) + + # 构建查询语句 + query = ( + select(DataStdDict) + .where(*filters) + .order_by(desc(DataStdDict.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 add_std_dict(cls, db: AsyncSession,model:DataStdDictModel): + col = DataStdDict( + **model.model_dump() + ) + db.add(col) + await db.flush() + return col + + @classmethod + async def delete_std_dict(cls, db: AsyncSession, Id: str): + await db.execute(delete(DataStdDict).where(DataStdDict.id == Id)) + + @classmethod + async def update_std_dict(cls, db: AsyncSession, update_data: DataStdDictModel): + + await db.execute(update(DataStdDict), [update_data]) + await db.flush() + + @classmethod + async def get_std_dict_by_id(cls, db: AsyncSession, Id: str): + col = ( + await db.execute( + select(DataStdDict) + .where(DataStdDict.id == Id) + ) + ).scalars().first() + return col + @classmethod + async def get_data_dict_by_info(cls, db: AsyncSession, query_object: DataStdDictModel): + List = ( + await db.execute( + select(DataStdDict) + .where( + DataStdDict.dict_name == query_object.dict_name if query_object.dict_name else True, + DataStdDict.dict_num == query_object.dict_num if query_object.dict_num else True, + DataStdDict.dict_status == query_object.dict_status if query_object.dict_status else True, + DataStdDict.sys_id == query_object.sys_id if query_object.sys_id else True, + DataStdDict.dict_type == query_object.dict_type if query_object.dict_type else True, + ) + ) + ).scalars().first() + return List \ No newline at end of file diff --git a/vue-fastapi-backend/module_admin/entity/do/datastd_do.py b/vue-fastapi-backend/module_admin/entity/do/datastd_do.py index 72541f7..4bfbe5e 100644 --- a/vue-fastapi-backend/module_admin/entity/do/datastd_do.py +++ b/vue-fastapi-backend/module_admin/entity/do/datastd_do.py @@ -1,4 +1,4 @@ -from sqlalchemy import Column, Integer, String, DateTime, Boolean +from sqlalchemy import Column, Integer, String, DateTime, Boolean,BigInteger from config.database import Base # 数据标准模块相关表 @@ -25,3 +25,32 @@ class DataStdCode(Base): code_map_id = Column(String(50), default=None,comment='标准代码Id') code_map_num = Column(String(50), default=None, comment='标准代码编号') code_map_name = Column(String(200), default=None, comment='标准代码值') + + +class DataStdDict(Base): + """ + 标准字典表 (Standard Code Table) + """ + __tablename__ = 't_datastd_dict' # 表名为 t_datastd_dict + + 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='更新时间') + dict_num = Column(String(50), default=None, comment='字典编号') + dict_code = Column(String(50), default=None, comment='字典英文名') + dict_name = Column(String(200), default=None, comment='字典中文名') + dict_level = Column(String(10), default=None, comment='字典归属(sys:系统级 company:公司级)') + dict_type = Column(String(1), default=None, comment='字典类型(0:基础数据 1:指标数据)') + sys_name = Column(String(50), default=None, comment='归属系统') + sys_id = Column(Integer, default=None, comment='归属系统Id') + dict_menu = Column(String(200), default=None, comment='字典业务定义') + data_type = Column(String(20), default=None, comment='数据类型') + std_code = Column(String(50), default=None, comment='数据标准编号') + std_name = Column(String(50), default=None, comment='数据标准名称') + dict_status = Column(String(1), default=None, comment='字典状态(1:有效 0:无效)') + buss_dept_id = Column(BigInteger, default=None, comment='业务认责部门') + tech_dept_id = Column(BigInteger, default=None, comment='技术认责部门') + buss_user = Column(String(20), default=None, comment='业务认责人员') + tech_user = Column(String(20), 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 index 1b748e5..1f2a0a7 100644 --- a/vue-fastapi-backend/module_admin/entity/vo/datastd_vo.py +++ b/vue-fastapi-backend/module_admin/entity/vo/datastd_vo.py @@ -53,3 +53,37 @@ class DeleteDataStdModel(BaseModel): model_config = ConfigDict(alias_generator=to_camel) ids: str = Field(description='需要删除的参数主键') +class DataStdDictModel(BaseModel): + """ + 标准字典表对应Pydantic模型 (Standard Dictionary Table Pydantic Model) + """ + model_config = ConfigDict(alias_generator=to_camel, from_attributes=True) + + id: Optional[str] = Field(default=None, description='标准字典主键') + create_by: Optional[str] = Field(default='', description='创建者') + create_time: Optional[datetime] = Field(default=None, description='创建时间') + update_by: Optional[str] = Field(default='', description='更新者') + update_time: Optional[datetime] = Field(default=None, description='更新时间') + dict_num: Optional[str] = Field(default=None, description='字典编号') + dict_code: Optional[str] = Field(default=None, description='字典英文名') + dict_name: Optional[str] = Field(default=None, description='字典中文名') + dict_level: Optional[str] = Field(default=None, description='字典归属(sys:系统级 company:公司级)') + dict_type: Optional[str] = Field(default=None, description='字典类型(0:基础数据 1:指标数据)') + sys_name: Optional[str] = Field(default=None, description='归属系统') + sys_id: Optional[int] = Field(default=None, description='归属系统Id') + dict_menu: Optional[str] = Field(default=None, description='字典业务定义') + data_type: Optional[str] = Field(default=None, description='数据类型') + std_code: Optional[str] = Field(default=None, description='数据标准编号') + std_name: Optional[str] = Field(default=None, description='数据标准名称') + dict_status: Optional[str] = Field(default=None, description='字典状态(1:有效 0:无效)') + buss_dept_id: Optional[int] = Field(default=None, description='业务认责部门') + tech_dept_id: Optional[int] = Field(default=None, description='技术认责部门') + buss_user: Optional[str] = Field(default=None, description='业务认责人员') + tech_user: Optional[str] = Field(default=None, description='技术认责人员') +@as_query +class DataStdDictPageQueryModel(DataStdDictModel): + """ + 元数据任务分页查询模型 + """ + page_num: int = Field(default=1, description='当前页码') + page_size: int = Field(default=10, description='每页记录数') \ No newline at end of file diff --git a/vue-fastapi-backend/module_admin/service/datastd_service.py b/vue-fastapi-backend/module_admin/service/datastd_service.py index 256033d..b04b3cc 100644 --- a/vue-fastapi-backend/module_admin/service/datastd_service.py +++ b/vue-fastapi-backend/module_admin/service/datastd_service.py @@ -3,7 +3,7 @@ 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,DeleteDataStdModel +from module_admin.entity.vo.datastd_vo import DataStdCodeModel,DeleteDataStdModel,DataStdDictModel from utils.common_util import CamelCaseUtil import uuid from config.constant import CommonConstant @@ -246,4 +246,149 @@ class DataStdService: ) if dict_type and dict_type.id != id: return CommonConstant.NOT_UNIQUE - return CommonConstant.UNIQUE \ No newline at end of file + return CommonConstant.UNIQUE + # ----------------------------------------------------------------数据字典---------------------------------------------------------------------------------------------------- + + @classmethod + async def get_std_dict_list_services( + cls, query_db: AsyncSession, query_object: DataStdDictModel, is_page: bool = False + ): + """ + 获取列配置列表信息service + + :param query_db: orm对象 + :param query_object: 查询参数对象 + :param is_page: 是否开启分页 + :return: 列配置列表信息对象 + """ + col_list_result = await DataStdDao.get_std_dict_list(query_db, query_object, is_page) + return col_list_result + + + @classmethod + async def get_std_dict_by_id_services(cls, query_db: AsyncSession, id: str): + """ + 获取列配置详细信息service + + :param query_db: orm对象 + :param id: 列配置ID + :return: 列配置详细信息对象 + """ + col = await DataStdDao.get_std_dict_by_id(query_db, id) + if col: + result = DataStdDictModel(**CamelCaseUtil.transform_result(col)) + else: + result = DataStdDictModel(**dict()) + return result + + + @classmethod + async def add_std_dict_services(cls, request: Request, query_db: AsyncSession, page_object: DataStdDictModel): + """ + 新增列配置服务 + + :param request: Request对象 + :param query_db: orm对象 + :param page_object: 新增的列配置对象 + :return: 新增列配置校验结果 + """ + try: + if not await cls.check_dict_unique_services(query_db, page_object): + raise ServiceException(message=f"数据字典{page_object.dict_num}已存在") + # 创建新的 page_object 实例,避免修改原始对象 + new_page_object = DataStdDictModel(**page_object.model_dump(by_alias=True)) + new_page_object.dict_status="0" + new_page_object.id=str(uuid.uuid4()) + # 调用 DAO 方法插入数据 + await DataStdDao.add_std_dict(query_db, new_page_object) + return CrudResponseModel(is_success=True, message='新增数据字典成功') + except Exception as e: + await query_db.rollback() + raise e + + + @classmethod + async def dict_detail_services(cls, query_db: AsyncSession, col: str): + """ + 获取参数配置详细信息service + + :param query_db: orm对象 + :param config_id: 参数配置id + :return: 参数配置id对应的信息 + """ + config = await DataStdDao.get_std_dict_by_id(query_db, col) + if config: + result = DataStdDictModel(**CamelCaseUtil.transform_result(config)) + else: + result = DataStdDictModel(**dict()) + + return result + @classmethod + async def edit_std_dict_services(cls, request: Request, query_db: AsyncSession, page_object: DataStdDictModel): + """ + 编辑列配置服务 + + :param request: Request对象 + :param query_db: orm对象 + :param page_object: 编辑的列配置对象 + :return: 编辑列配置校验结果 + """ + if not await cls.check_dict_unique_services(query_db, page_object): + raise ServiceException(message=f"数据字典编号:{page_object.dict_num}已存在") + edit_col = page_object.model_dump(exclude_unset=True) + col_info = await cls.get_std_dict_by_id_services(query_db, page_object.id) + if col_info: + try: + await DataStdDao.update_std_dict(query_db, edit_col) + 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_dict_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_dict_by_id_services(query_db, col_id) + if col_info: + # 校验不能删除的系统内置列 + await DataStdDao.delete_std_dict(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 check_dict_unique_services(cls, query_db: AsyncSession, page_object: DataStdDictModel): + """ + 校验字典类型称是否唯一service + + :param query_db: orm对象 + :param page_object: 字典类型对象 + :return: 校验结果 + """ + id ='-1' if page_object.id is None else page_object.id + codemodel=DataStdDictModel() + codemodel.dict_num=page_object.dict_num + + dict_type = await DataStdDao.get_data_dict_by_info(query_db, codemodel + ) + if dict_type and dict_type.id != id: + return CommonConstant.NOT_UNIQUE + return CommonConstant.UNIQUE \ No newline at end of file diff --git a/vue-fastapi-frontend/src/api/datastd/stdcode.js b/vue-fastapi-frontend/src/api/datastd/std.js similarity index 69% rename from vue-fastapi-frontend/src/api/datastd/stdcode.js rename to vue-fastapi-frontend/src/api/datastd/std.js index f117e0c..dc8d968 100644 --- a/vue-fastapi-frontend/src/api/datastd/stdcode.js +++ b/vue-fastapi-frontend/src/api/datastd/std.js @@ -116,6 +116,62 @@ export function deleteStdCodeItems(rowIds) { }) } +// ------------------------------------------------------------数据词典----------------------------------------------------------------- +export function listStdDict(query) { + return request({ + url: '/default-api/datastd/stddict/dict/list', + method: 'get', + params: query + }) +} + + + +// 查询标准代码详情 +export function getStdDict(colId) { + return request({ + url: '/default-api/datastd/stddict/dict/' + parseStrEmpty(colId), + method: 'get' + }) +} + + +// 新增标准代码 +export function addStdDict(data) { + return request({ + url: '/default-api/datastd/stddict/dict', + method: 'post', + data: data + }) +} + +// 修改标准代码 +export function updateStdDict(data) { + return request({ + url: '/default-api/datastd/stddict/dict', + method: 'put', + data: data + }) +} + + +// 删除标准代码 +export function deleteStdDict(colId) { + return request({ + url: '/default-api/datastd/stddict/dict/' + colId, + method: 'delete' + }) +} + + + +// 批量删除标准代码 +export function deleteStdDicts(colIds) { + return request({ + url: '/default-api/datastd/stddict/dict/' + colIds, + method: 'delete' + }) +} diff --git a/vue-fastapi-frontend/src/views/datastd/stdcode/codeItem.vue b/vue-fastapi-frontend/src/views/datastd/stdcode/codeItem.vue index 59ba8a6..8099674 100644 --- a/vue-fastapi-frontend/src/views/datastd/stdcode/codeItem.vue +++ b/vue-fastapi-frontend/src/views/datastd/stdcode/codeItem.vue @@ -197,7 +197,7 @@ diff --git a/vue-fastapi-frontend/src/views/datastd/stddict/codeItem.vue b/vue-fastapi-frontend/src/views/datastd/stddict/codeItem.vue new file mode 100644 index 0000000..59ba8a6 --- /dev/null +++ b/vue-fastapi-frontend/src/views/datastd/stddict/codeItem.vue @@ -0,0 +1,446 @@ + + + + + diff --git a/vue-fastapi-frontend/src/views/datastd/stddict/codeItemCommon.vue b/vue-fastapi-frontend/src/views/datastd/stddict/codeItemCommon.vue new file mode 100644 index 0000000..d1e8ee3 --- /dev/null +++ b/vue-fastapi-frontend/src/views/datastd/stddict/codeItemCommon.vue @@ -0,0 +1,222 @@ + + + + + + + diff --git a/vue-fastapi-frontend/src/views/datastd/stddict/index.vue b/vue-fastapi-frontend/src/views/datastd/stddict/index.vue new file mode 100644 index 0000000..8714ab7 --- /dev/null +++ b/vue-fastapi-frontend/src/views/datastd/stddict/index.vue @@ -0,0 +1,277 @@ + + + + +