Browse Source

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	vue-fastapi-backend/server.py
master
xueyinfei 1 month ago
parent
commit
75f965da6d
  1. 160
      vue-fastapi-backend/module_admin/controller/datastd_controller.py
  2. 163
      vue-fastapi-backend/module_admin/dao/datastd_dao.py
  3. 41
      vue-fastapi-backend/module_admin/entity/do/datastd_do.py
  4. 95
      vue-fastapi-backend/module_admin/entity/vo/datastd_vo.py
  5. 249
      vue-fastapi-backend/module_admin/service/datastd_service.py
  6. 48
      vue-fastapi-backend/module_admin/service/metasecurity_service.py
  7. 2
      vue-fastapi-backend/server.py
  8. 108
      vue-fastapi-frontend/src/api/datastd/stdcode.js
  9. 319
      vue-fastapi-frontend/src/views/datastd/stdcode/index.vue

160
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)

163
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()

41
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='代码含义')

95
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()

249
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为空')

48
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)

2
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': ['系统管理-数据目录管理']},
]

108
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'
})
}

319
vue-fastapi-frontend/src/views/datastd/stdcode/index.vue

@ -0,0 +1,319 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<el-col :span="4" :xs="24">
<div class="head-container">
<el-input
v-model="dbResoursName"
placeholder="请输入代码分类"
clearable
prefix-icon="search"
style="margin-bottom: 20px"
/>
</div>
<div class="head-container">
<el-tree
:data="dbResourceOptions"
:props="defaultProps"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="tree"
node-key="id"
default-expand-all
highlight-current
@node-click="handleNodeClick"
>
<template #default="{ node, data }">
<span class="custom-tree-node">
<!-- <i :class="getIconClass(data)"></i> -->
<span>{{ data.name }}</span>
</span>
</template>
</el-tree>
</div>
</el-col>
<el-col :span="20" :xs="24">
<el-form :model="queryParams" ref="queryRef" :inline="true">
<el-form-item label="标准代码编号" prop="codeNum">
<el-input v-model="queryParams.codeNum" placeholder="请输入标准代码编号" clearable style="width: 220px" />
</el-form-item>
<el-form-item label="标准代码值" prop="codeName">
<el-input v-model="queryParams.codeName" placeholder="请输入标准代码值" clearable style="width: 220px" />
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['meta:metaSecurityCol:add']"
>新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleEdit"
v-hasPermi="['meta:metaSecurityCol:edit']"
>修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleRemove"
v-hasPermi="['meta:metaSecurityCol:remove']"
>删除</el-button>
</el-col>
</el-row>
<!-- 表格展示 -->
<el-table v-loading="loading" :data="tableData" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="标准代码编号" align="center" prop="codeNum" />
<el-table-column label="标准代码值" align="center" prop="codeName" />
<el-table-column label="代码状态" align="center" prop="codeStatus">
<template #default="scope">
<dict-tag :options="metasecurity_ctr" :value="scope.row.codeStatus" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="180">
<template #default="scope">
<el-button @click="handleEdit(scope.row)" type="text" icon="Edit" />
<el-button @click="handleRemove(scope.row)" type="text" icon="Delete" />
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="handlePagination" />
</el-col>
</el-row>
<!-- 添加或编辑标准代码对话框 -->
<el-dialog :title="dialogTitle" v-model="dialogVisible" width="600px">
<el-form :model="form" ref="formRef" label-width="120px" :rules="formRules">
<el-form-item label="标准代码编号" prop="codeNum">
<el-input v-model="form.codeNum" placeholder="请输入标准代码编号" />
</el-form-item>
<el-form-item label="标准代码值" prop="codeName">
<el-input v-model="form.codeName" placeholder="请输入标准代码值" />
</el-form-item>
<el-form-item label="标准代码类型" prop="codeType">
<el-input v-model="form.codeType" placeholder="请输入标准代码类型" />
</el-form-item>
<el-form-item label="代码状态" prop="codeStatus">
<el-select v-model="form.codeStatus" placeholder="请选择代码状态">
<el-option v-for="status in codeStatusOptions" :key="status.value" :label="status.label" :value="status.value" />
</el-select>
</el-form-item>
<el-form-item label="归属系统" prop="sysName">
<el-input v-model="form.sysName" placeholder="请输入归属系统" />
</el-form-item>
<el-form-item label="归属系统Id" prop="sysId">
<el-input v-model="form.sysId" placeholder="请输入归属系统Id" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSave">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, toRefs } from 'vue';
import { listStdCode, addStdCode, getStdCode, updateStdCode, deleteStdCode } from "@/api/datastd/stdcode"; //
import { datasourcetree } from "@/api/meta/metatask";
const { proxy } = getCurrentInstance();
const { metasecurity_ctr } = proxy.useDict("metasecurity_ctr");
const queryParams = ref({
codeNum: '',
codeName: '',
codeType: '',
sysName: '',
sysId: '',
pageNum: 1,
pageSize: 10
});
const single = ref(true);
const multiple = ref(true);
const dbResoursName = ref(undefined);
const defaultProps = {
children: "children",
label: "name"
};
const filterNode = (value, data) => {
if (!value) return true;
return data.name.indexOf(value) !== -1;
};
const handleNodeClick = (data) => {
if (data.id === 99999) {
queryParams.value.dbRID = "";
} else {
queryParams.value.dbRID = data.id;
}
handleQuery();
};
const dbResourceOptions = ref(undefined);
const form = ref({
colId: '',
codeNum: '',
codeName: '',
codeType: '',
codeStatus: '',
sysName: '',
sysId: ''
});
const ids = ref([]);
//
const getList = async () => {
loading.value = true;
const response = await listStdCode(queryParams.value);
tableData.value = response.rows;
total.value = response.total;
loading.value = false;
};
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.colId);
single.value = ids.value.length === 1;
multiple.value = ids.value.length > 0;
}
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
const resetQuery = () => {
queryParams.value = {
codeNum: '',
codeName: '',
codeType: '',
sysName: '',
sysId: '',
pageNum: 1,
pageSize: 10
};
getList();
};
const handleAdd = () => {
dialogTitle.value = "新增标准代码";
form.value = {
colId: '',
codeNum: '',
codeName: '',
codeType: '',
codeStatus: '',
sysName: '',
sysId: '',
};
dialogVisible.value = true;
};
const handleEdit = (row) => {
dialogTitle.value = "编辑标准代码";
getStdCode(row.colId).then(response => {
form.value = response;
dialogVisible.value = true;
});
};
const handleRemove = (row) => {
const idsToDelete = row ? [row.colId] : ids.value;
deleteStdCode(idsToDelete).then(() => {
handleQuery();
});
};
const handleSave = () => {
if (!form.value.codeNum || !form.value.codeName) {
ElMessage.warning("请填写必填项");
return;
}
const saveAction = form.value.colId ? updateStdCode : addStdCode;
saveAction(form.value).then(() => {
dialogVisible.value = false;
handleQuery();
});
};
const handleCancel = () => {
dialogVisible.value = false;
};
const dbResourceOldList = ref([]);
const tableData = ref([]);
const total = ref(0);
const loading = ref(false);
const dialogVisible = ref(false);
const dialogTitle = ref("");
const formRules = reactive({
codeNum: [{ required: true, message: "请输入标准代码编号", trigger: "blur" }],
codeName: [{ required: true, message: "请输入标准代码值", trigger: "blur" }]
});
onMounted(() => {
datasourcetree().then(response => {
dbResourceOldList.value = response.rows;
const childrenList = dbResourceOldList.value.map(element => ({ ...element, parentId: "99999" }));
dbResourceOptions.value = [
{
id: 10000, // ID
name: "公司级代码",
parentId: 0,
children: [] //
},
{
id: 99999,
name: "系统级代码",
parentId: 0,
children: childrenList
},
]; });
getList();
});
</script>
<style scoped>
.app-container {
padding: 20px;
}
.head-container {
margin-bottom: 0px;
}
.custom-tree-node {
display: flex;
align-items: center;
}
.custom-tree-node i {
margin-right: 8px;
}
</style>
Loading…
Cancel
Save