Browse Source

数据标准重构

master
si@aidatagov.com 1 month ago
parent
commit
a8e872f0fe
  1. 99
      vue-fastapi-backend/module_admin/controller/datastd_controller.py
  2. 104
      vue-fastapi-backend/module_admin/dao/datastd_dao.py
  3. 21
      vue-fastapi-backend/module_admin/entity/do/datastd_do.py
  4. 70
      vue-fastapi-backend/module_admin/entity/vo/datastd_vo.py
  5. 211
      vue-fastapi-backend/module_admin/service/datastd_service.py
  6. 4
      vue-fastapi-frontend/src/api/datastd/stdcode.js
  7. 518
      vue-fastapi-frontend/src/views/datastd/stdcode/codeItem.vue
  8. 118
      vue-fastapi-frontend/src/views/datastd/stdcode/index.vue

99
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,DataStdCodeItemModel, DataStdCodePageQueryModel, DataStdCodeItemPageQueryModel, DeleteDataStdModel
from module_admin.entity.vo.datastd_vo import DataStdCodeModel, DataStdCodePageQueryModel, DeleteDataStdModel
from module_admin.service.datastd_service import DataStdService
from module_admin.service.login_service import LoginService
from utils.log_util import logger
@ -29,24 +29,7 @@ async def get_std_code_list(
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'))]
)
@ -100,61 +83,55 @@ async def 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(
@datastdController.post('/stdcode/codeWithItems', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:codeWithItems:add'))])
@Log(title='标准代码与代码项管理', business_type=BusinessType.INSERT)
async def add_std_code_with_items(
request: Request,
add_std_code_item: DataStdCodeItemModel,
code: DataStdCodeModel, # 接收标准代码对象
code_item_list: list[DataStdCodeModel] = [], # 接收代码项列表,默认空列表
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(
# 设置标准代码的创建和更新时间
code.create_by = current_user.user.user_name
code.create_time = datetime.now()
code.update_by = current_user.user.user_name
code.update_time = datetime.now()
code.sys_name='公司级' if 'company'==code.code_type else code.sys_name
# 传递给服务层,处理标准代码和代码项的添加
result = await DataStdService.add_std_code_with_items_services(request, query_db, code, code_item_list)
# 返回响应
logger.info(result.message)
return ResponseUtil.success(msg=result.message)
@datastdController.put('/stdcode/codeWithItems', dependencies=[Depends(CheckUserInterfaceAuth('datastd:stdcode:codeWithItems:add'))])
@Log(title='标准代码与代码项管理', business_type=BusinessType.INSERT)
async def edit_std_code_with_items(
request: Request,
edit_std_code_item: DataStdCodeItemModel,
code: DataStdCodeModel, # 接收标准代码对象
code_item_list: list[DataStdCodeModel], # 接收代码项列表
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)
# 设置标准代码的创建和更新时间
code.sys_name='公司级' if 'company'==code.code_type else code.sys_name
code.update_by = current_user.user.user_name
code.update_time = datetime.now()
# 传递给服务层,处理标准代码和代码项的添加
result = await DataStdService.edit_std_code_with_items_services(request, query_db, code, code_item_list)
# 返回响应
logger.info(result.message)
return ResponseUtil.success(msg=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)

104
vue-fastapi-backend/module_admin/dao/datastd_dao.py

@ -1,7 +1,7 @@
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 module_admin.entity.do.datastd_do import DataStdCode
from module_admin.entity.vo.datastd_vo import DataStdCodeModel
from utils.page_util import PageUtil
@ -30,6 +30,12 @@ class DataStdDao:
if query_object.code_type:
filters.append(DataStdCode.code_type==query_object.code_type)
if query_object.class_id:
filters.append(DataStdCode.class_id==query_object.class_id)
if query_object.class_id=='codeItem' and not query_object.parent_id:
filters.append(1==2)
if query_object.parent_id:
filters.append(DataStdCode.parent_id==query_object.parent_id)
# 构建查询语句
query = (
select(DataStdCode)
@ -44,42 +50,9 @@ class DataStdDao:
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):
async def get_data_code_list_by_info(cls, db: AsyncSession, query_object: DataStdCodeModel):
List = (
await db.execute(
select(DataStdCode)
@ -87,24 +60,30 @@ class DataStdDao:
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
DataStdCode.code_type == query_object.code_type if query_object.code_type else True,
DataStdCode.parent_id == query_object.parent_id if query_object.parent_id else True,
DataStdCode.class_id == query_object.class_id if query_object.class_id else True
)
)
).scalars().all()
return List
@classmethod
async def get_data_code_item_list(cls, db: AsyncSession, query_object: DataStdCodeItemModel):
async def get_data_code_by_info(cls, db: AsyncSession, query_object: DataStdCodeModel):
List = (
await db.execute(
select(DataStdCodeItem)
select(DataStdCode)
.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,
DataStdCode.code_name == query_object.code_name if query_object.code_name else True,
DataStdCode.code_num == query_object.code_num if query_object.code_num 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,
DataStdCode.parent_id == query_object.parent_id if query_object.parent_id else True,
DataStdCode.class_id == query_object.class_id if query_object.class_id else True
)
)
).scalars().all()
).scalars().first()
return List
@classmethod
async def get_std_code_by_id(cls, db: AsyncSession, Id: str):
col = (
@ -115,16 +94,6 @@ class DataStdDao:
).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):
@ -134,22 +103,11 @@ class DataStdDao:
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):
@ -158,6 +116,18 @@ class DataStdDao:
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()
async def check_code_num_exists(cls, query_db: AsyncSession, code_num: str) -> bool:
"""
检查标准代码或代码项的code_num是否已经存在
"""
# 查询标准代码表中是否存在相同的code_num
result = await query_db.execute(select(DataStdCodeModel).filter(DataStdCodeModel.code_num == code_num))
existing_code = result.scalar_one_or_none()
# 如果不存在,则检查代码项表中是否存在相同的code_num
if not existing_code:
result = await query_db.execute(select(DataStdCodeModel).filter(DataStdCodeModel.code_num == code_num))
existing_code_item = result.scalar_one_or_none()
return existing_code_item is not None
return True

21
vue-fastapi-backend/module_admin/entity/do/datastd_do.py

@ -18,24 +18,9 @@ class DataStdCode(Base):
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_name = Column(String(50), default=None, comment='归属系统')
sys_id = Column(Integer, default=None, comment='归属系统Id')
class_id = Column(String(10), default=None, comment='代码类型(code:代码 codeItem:代码项)')
parent_id = Column(String(50), 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='代码含义')

70
vue-fastapi-backend/module_admin/entity/vo/datastd_vo.py

@ -18,34 +18,21 @@ class DataStdCodeModel(BaseModel):
"""
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[int] = None
id: Optional[str] = Field(default=None, description='标准代码主键')
code_num: Optional[str] = Field(default=None, description='标准代码编号')
code_name: Optional[str] = Field(default=None, description='标准代码名称')
code_type: Optional[str] = Field(default=None, description='标准代码类型')
code_status: Optional[str] = Field(default=None, description='标准代码状态')
sys_name: Optional[str] = Field(default=None, description='系统名称')
sys_id: Optional[int] = Field(default=None, description='系统ID')
parent_id: Optional[str] = Field(default=None, description='父级ID')
class_id: Optional[str] = Field(default=None, description='类目ID')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
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
@ -55,13 +42,7 @@ 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):
"""
@ -69,27 +50,4 @@ 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()

211
vue-fastapi-backend/module_admin/service/datastd_service.py

@ -3,9 +3,11 @@ 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 module_admin.entity.vo.datastd_vo import DataStdCodeModel,DeleteDataStdModel
from utils.common_util import CamelCaseUtil
import uuid
from config.constant import CommonConstant
class DataStdService:
"""
数据源标准服务层
@ -26,20 +28,6 @@ class DataStdService:
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):
@ -57,21 +45,6 @@ class DataStdService:
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):
@ -86,36 +59,13 @@ class DataStdService:
try:
# 创建新的 page_object 实例,避免修改原始对象
new_page_object = DataStdCodeModel(**page_object.model_dump(by_alias=True))
new_page_object.id = str(uuid.uuid4())
new_page_object.code_status="0"
# 调用 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
@ -135,22 +85,6 @@ class DataStdService:
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):
"""
编辑列配置服务
@ -166,7 +100,6 @@ class DataStdService:
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()
@ -174,27 +107,6 @@ class DataStdService:
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):
@ -224,27 +136,102 @@ class DataStdService:
raise ServiceException(message='传入列配置ID为空')
@classmethod
async def delete_std_code_item_services(cls, request: Request, query_db: AsyncSession, page_object: DeleteDataStdModel):
async def add_std_code_with_items_services(cls, request, query_db: AsyncSession, code: DataStdCodeModel, code_item_list: list[DataStdCodeModel]):
"""
新增标准代码和对应的代码项
"""
try:
# 先校验标准代码是否唯一
if not await cls.check_code_unique_services(query_db, code):
raise ServiceException(message=f'新增代码{code.code_name}失败,{code.code_num}代码已存在')
else:
# 保存标准代码
code.id=str(uuid.uuid4())
await cls.add_std_code_services(request, query_db, code)
# 为每个代码项设置parent_id,并进行校验
for code_item in code_item_list:
# 校验同一个父级下,code是否已存在
code_item.parent_id = code.id
if not await cls.check_code_unique_services(query_db, code_item):
raise ServiceException(message=f"父级代码{code.code_num}下的代码项{code_item.code_num}已存在")
# 将parent_id设为code的ID
code_item.id=str(uuid.uuid4())
code_item.create_by=code.create_by
code_item.create_time=code.create_time
code_item.update_by=code.update_by
code_item.update_time=code.update_time
await cls.add_std_code_services(request, query_db, code_item)
# 提交事务
await query_db.commit()
return CrudResponseModel(is_success=True, message='标准代码和代码项新增成功')
except Exception as e:
await query_db.rollback()
raise ServiceException(message=f"新增标准代码失败: {str(e)}")
@classmethod
async def edit_std_code_with_items_services(cls, request, query_db: AsyncSession, code: DataStdCodeModel, code_item_list: list[DataStdCodeModel]):
"""
删除行配置服务
:param request: Request对象
:param query_db: orm对象
:param page_object: 删除行配置对象
:return: 删除行配置校验结果
修改标准代码和对应的代码项如果code_item.id为0则执行新增操作否则执行更新操作
"""
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为空')
try:
# 校验标准代码是否存在并且唯一
if not await cls.check_code_unique_services(query_db, code):
raise ServiceException(message=f'修改代码{code.code_name}失败,{code.code_num}代码不存在或已存在')
# 更新标准代码
await cls.edit_std_code_services(request, query_db, code)
# 为每个代码项设置parent_id,并进行校验
for code_item in code_item_list:
code_item.parent_id = code.id
if code_item.id :
# 校验同一个父级下,code_num是否已存在
if not await cls.check_code_unique_services(query_db, code_item):
raise ServiceException(message=f"父级代码{code.code_num}下的代码项{code_item.code_num}已存在")
# 更新代码项的相关信息
code_item.update_time = code.update_time
code_item.update_by = code.update_by
await cls.edit_std_code_services(request, query_db, code_item) # 执行更新操作
else: # 如果code_item的id不为0,表示是修改操作
# 校验同一个父级下,code_num是否已存在
existing_code_item = await cls.check_code_unique_services(query_db,code_item)
if existing_code_item:
raise ServiceException(message=f"父级代码{code.code_num}下的代码项{code_item.code_num}已存在")
# 生成新的UUID,并新增代码项
code_item.id = str(uuid.uuid4()) # 新生成的UUID
code_item.create_time = code.update_time
code_item.create_by = code.create_by
code_item.update_time = code.update_time
code_item.update_by = code.update_by
await cls.add_std_code_services(request, query_db, code_item) # 执行新增操作
# 提交事务
await query_db.commit()
return CrudResponseModel(is_success=True, message='标准代码和代码项修改成功')
except Exception as e:
await query_db.rollback()
raise ServiceException(message=f"修改标准代码失败: {str(e)}")
@classmethod
async def check_code_unique_services(cls, query_db: AsyncSession, page_object: DataStdCodeModel):
"""
校验字典类型称是否唯一service
:param query_db: orm对象
:param page_object: 字典类型对象
:return: 校验结果
"""
id = -1 if page_object.id is None else page_object.id
codemodel=DataStdCodeModel()
codemodel.code_num=page_object.code_num
codemodel.class_id=page_object.class_id
codemodel.parent_id=page_object.parent_id
codemodel.code_type=page_object.code_type
dict_type = await DataStdDao.get_data_code_by_info(query_db, codemodel
)
if dict_type and dict_type.id != id:
return CommonConstant.NOT_UNIQUE
return CommonConstant.UNIQUE

4
vue-fastapi-frontend/src/api/datastd/stdcode.js

@ -38,7 +38,7 @@ export function getStdCodeItem(rowId) {
// 新增标准代码
export function addStdCode(data) {
return request({
url: '/default-api/datastd/stdcode/code',
url: '/default-api/datastd/stdcode/codeWithItems',
method: 'post',
data: data
})
@ -56,7 +56,7 @@ export function addStdCodeItem(data) {
// 修改标准代码
export function updateStdCode(data) {
return request({
url: '/default-api/datastd/stdcode/code',
url: '/default-api/datastd/stdcode/codeWithItems',
method: 'put',
data: data
})

518
vue-fastapi-frontend/src/views/datastd/stdcode/codeItem.vue

@ -1,242 +1,391 @@
<template>
<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 :model="form" ref="formRef" label-width="120px" :rules="formRules">
<div class="form-container">
<el-row :gutter="20">
<!-- 标准代码编号 -->
<el-col :span="12">
<el-form-item label="标准代码编号" prop="codeNum">
<el-input v-model="form.codeNum" placeholder="请输入标准代码编号" />
</el-form-item>
</el-col>
<el-form-item>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
<!-- 标准代码名称 -->
<el-col :span="12">
<el-form-item label="标准代码名称" prop="codeName">
<el-input v-model="form.codeName" placeholder="请输入标准代码名称" />
</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" >
<template #default="scope">
<el-link
type="primary"
:underline="true"
@click="handleCodeClick(scope.row)"
style="cursor: pointer"
>
查看关系
</el-link>
</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-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="codeMean">
<el-input v-model="form.codeMean" placeholder="请输入标准代码值" />
</el-col>
</el-row>
<el-row :gutter="20">
<!-- 标准代码类型 -->
<el-col :span="12">
<el-form-item label="标准代码类型" prop="codeType">
<el-select
v-model="form.codeType"
placeholder="请选择标准代码类型"
maxlength="30"
@change="changeCodeType"
>
<el-option
v-for="dict in std_code_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
</el-col>
<!-- 归属系统 -->
<el-col :span="12" v-show="showSys">
<el-form-item label="归属系统" prop="sysId">
<el-select
v-model="form.sysId"
placeholder="请选择归属系统"
maxlength="30"
@change="dataChange"
>
<el-option
v-for="dict in dbResourceOldList"
:key="dict.id"
:label="dict.name"
:value="dict.id"
></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</div>
<!-- 查询表单 -->
<!-- <div class="query-form-container">
<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>
<template #footer>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSave">确定</el-button>
<el-form-item>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</div> -->
</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="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"
@row-dblclick="handleRowDblClick"
border
style="width: 100%"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column
label="代码值"
align="center"
prop="codeNum"
:editable="true"
>
<template #default="scope">
<el-input
v-if="scope.row.isEditing"
v-model="scope.row.codeNum"
size="small"
placeholder="请输入代码值"
@blur="handleBlur(scope.row)"
/>
<span v-else>{{ scope.row.codeNum }}</span>
</template>
</el-dialog>
</el-table-column>
<el-table-column
label="代码名称"
align="center"
prop="codeName"
:editable="true"
>
<template #default="scope">
<el-input
v-if="scope.row.isEditing"
v-model="scope.row.codeName"
size="small"
placeholder="请输入代码名称"
@blur="handleBlur(scope.row)"
/>
<span v-else>{{ scope.row.codeName }}</span>
</template>
</el-table-column>
<el-table-column
label="代码关系"
align="center"
>
<template #default="scope">
<el-link
type="primary"
:underline="true"
@click="handleCodeClick(scope.row)"
style="cursor: pointer"
>
查看关系
</el-link>
</template>
</el-table-column>
</el-table>
</template>
<script setup>
import { ref, reactive, onMounted, toRefs } from 'vue';
import { listStdCodeItem, addStdCodeItem, getStdCodeItem, updateStdCodeItem, deleteStdCodeItem } from "@/api/datastd/stdcode"; //
import { ElLink } from 'element-plus';
import { listStdCode,addStdCode,updateStdCode } from "@/api/datastd/stdcode"; //
const { proxy } = getCurrentInstance();
const { std_code_status,std_code_appr } = proxy.useDict("std_code_status","std_code_appr");
const { std_code_status } = proxy.useDict("std_code_status");
const props = defineProps({
rowData: {
type: Object,
required: true
required: false
},
dbResourceOldList: {
type: Object,
required: false
}
});
const queryParams = ref({
codeNum: '',
parentId: props.rowData.id,
codeName: '',
codeType: '',
sysName: '',
classId: 'codeItem',
sysId: '',
pageNum: 1,
pageSize: 10
pageSize: 100
});
const single = ref(true);
const multiple = ref(true);
const handlePagination = (pageNum, pageSize) => {
queryParams.value.pageNum = pageNum;
queryParams.value.pageSize = pageSize;
handleQuery();
};
const form = ref({
id: '',
id: "",
codeNum: '',
codeName: '',
codeType: 'company',
codeStatus: ''
codeStatus: '',
sysName: '',
classId: 'code',
sysId: undefined
});
const ids = ref([]);
const codeNums = ref([]);
const tableData = ref([]);
const loading = ref(false);
const showSys = ref(false);
const multiple = ref(false);
function dataChange(data) {
// dbResourceOldList name
const selectedItem = props.dbResourceOldList.find(item => item.id === data);
if (selectedItem) {
// name form.value.dbRName
form.value.sysName = selectedItem.name;
} else {
// form.value.dbRName
form.value.sysName = '';
}
}
if (props.rowData.id) {
form.value = { ...props.rowData };
if (form.value.codeType == "sys") {
showSys.value = true;
} else {
showSys.value = false;
}
}
//
const handleRowDblClick = (row) => {
row.isEditing = true;
};
//
const handleBlur = (row) => {
row.isEditing = false;
//
console.log('保存编辑', row);
};
//
const getList = async () => {
loading.value = true;
const response = await listStdCodeItem(queryParams.value);
tableData.value = response.rows;
total.value = response.total;
console.log(queryParams.value,"queryParams.value")
const response = await listStdCode(queryParams.value);
tableData.value = response.rows.map(item => ({ ...item, isEditing: false }));
loading.value = false;
};
const formRules = reactive({
codeNum: [{ required: true, message: "请输入标准代码编号", trigger: "blur" }],
codeName: [{ required: true, message: "请输入标准代码名称", trigger: "blur" }]
});
const handleCodeClick = (row) => {
//
console.log('点击了标准代码名称', row);
};
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.id);
codeNums.value = selection.map(item => item.codeNum);
single.value = ids.value.length !== 1;
multiple.value = !ids.value.length > 0;
}
// const handleSave = async () => {
// // ID
// const params = { code: form.value, code_item_list: tableData.value };
// try {
// let response;
// if (props.rowData.id) {
// // ID updateStdCode
// response = await updateStdCode(params);
// if(response.success){
// proxy.$modal.msgSuccess(response.msg);
// }else{
// proxy.$modal.msgError(response.msg);
// }
// } else {
// // ID addStdCode
// response = await addStdCode(params);
// if(response.success){
// proxy.$modal.msgSuccess(response.msg);
// }else{
// proxy.$modal.msgError(response.msg);
// }
// }
// //
// if (response.success) {
// //
// console.log('');
// } else {
// console.error('');
// }
// } catch (error) {
// console.error(':', error);
// //
// }
// };
const handleSave = async () => {
// ID
const params = { code: form.value, code_item_list: tableData.value };
try {
let response;
if (props.rowData.id) {
// ID updateStdCode
response = await updateStdCode(params);
if (response.success) {
proxy.$modal.msgSuccess(response.msg);
} else {
proxy.$modal.msgError(response.msg);
}
} else {
// ID addStdCode
response = await addStdCode(params);
if (response.success) {
proxy.$modal.msgSuccess(response.msg);
} else {
proxy.$modal.msgError(response.msg);
}
}
// response.success true false
if (response.success) {
//
console.log('操作成功11111');
return true;
} else {
//
console.error('操作失败22222222');
return false;
}
} catch (error) {
console.error('保存时出错:', error);
//
return false; // false
}
};
const handleSelectionChange = (selection) => {
multiple.value = selection.length > 0;
};
//
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
//
const resetQuery = () => {
queryParams.value = {
codeNum: '',
pageNum: 1,
pageSize: 10
pageSize: 100
};
getList();
};
const handleAdd = () => {
dialogTitle.value = "新增标准代码项";
form.value = {
id: '',
codeNum: '',
parentId: props.rowData.id,
codeName: '',
codeMean: '',
codeStatus: '',
};
dialogVisible.value = true;
};
const handleEdit = (row) => {
dialogTitle.value = "编辑标准代码项";
getStdCodeItem(row.id).then(response => {
form.value = response.data;
dialogVisible.value = true;
});
};
const handleRemove = (row) => {
const idsToDelete = row.id ? [row.id] : ids.value;
const codesToDelete = row.codeNum ? [row.codeNum] : codeNums.value;
proxy.$modal.confirm('是否确认删除ID为"' + codesToDelete.toString() + '"的数据项?').then(function () {
return deleteStdCodeItem(idsToDelete.toString());
}).then(() => {
handleQuery();
proxy.$modal.msgSuccess("删除成功");
}).catch(() => {});
};
const handleSave = () => {
console.log(form.value.codeNum,form.value.codeName,"sssssssss")
if (!form.value.codeNum || !form.value.codeName) {
proxy.$modal.msgWarning("请填写必填项");
return;
function changeCodeType(data) {
if (data != "company") {
showSys.value = true;
form.value.sysName = "";
form.value.sysId = undefined;
} else {
showSys.value = false;
form.value.sysName = "公司级";
form.value.sysId = 10000;
}
const saveAction = form.value.id ? updateStdCodeItem : addStdCodeItem;
saveAction(form.value).then(() => {
dialogVisible.value = false;
handleQuery();
});
}
//
const handleAdd = () => {
const newRow = {id:'',classId: 'codeItem',parentId: props.rowData.id,codeNum: '', codeName: '', isEditing: true };
tableData.value.push(newRow);
};
const handleCancel = () => {
dialogVisible.value = false;
//
const handleRemove = () => {
const selectedRows = tableData.value.filter(row => row.isSelected);
tableData.value = tableData.value.filter(row => !row.isSelected);
};
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" }]
defineExpose({
handleSave
});
onMounted(() => {
getList();
});
</script>
@ -246,16 +395,15 @@ onMounted(() => {
padding: 20px;
}
.head-container {
margin-bottom: 0px;
.form-container {
margin-bottom: 20px;
}
.custom-tree-node {
display: flex;
align-items: center;
.query-form-container {
margin-bottom: 20px;
}
.custom-tree-node i {
margin-right: 8px;
.el-table .el-input {
width: 100%;
}
</style>

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

@ -142,57 +142,11 @@
</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="codeType">
<el-select
v-model="form.codeType"
placeholder="请选择标准代码类型"
maxlength="30"
@change="changeCodeType"
>
<el-option
v-for="dict in std_code_status"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="归属系统" prop="sysId" v-show="showSys">
<el-select
v-model="form.sysId"
placeholder="请选择归属系统"
maxlength="30"
@change="dataChange"
>
<el-option
v-for="dict in dbResourceOldList"
:key="dict.id"
:label="dict.name"
:value="dict.id"
></el-option>
</el-select>
</el-form-item>
<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>
<template #footer>
<el-button @click="handleCancel">取消</el-button>
<el-button type="primary" @click="handleSave">确定</el-button>
</template>
</el-dialog>
<!-- 第二个对话框 - 用于查看标准代码详情 -->
<el-dialog :title="dialogTitle2" v-model="dialogVisible2" width="1000px">
<!-- 查看标准代码详情 -->
<el-dialog :title="dialogTitle2" v-model="dialogVisible2" width="1000px">
<!-- 引入第二个页面组件 -->
<code-item :rowData="selectedRow"/>
<code-item ref="editCodeDialog" v-if="dialogVisible2" :rowData="selectedRow" :dbResourceOldList="dbResourceOldList"/>
<template #footer>
<el-button @click="handleCancel2">取消</el-button>
<el-button type="primary" @click="handleSave2">确定</el-button>
@ -217,12 +171,12 @@ const queryParams = ref({
codeName: '',
codeType: '',
sysName: '',
classId:'code',
sysId: '',
pageNum: 1,
pageSize: 10
});
const single = ref(true);
const showSys = ref(false);
const multiple = ref(true);
const dbResoursName = ref(undefined);
const defaultProps = {
@ -233,7 +187,6 @@ const defaultProps = {
const dialogVisible2 = ref(false);
const dialogTitle2 = ref('标准代码');
const selectedRow = ref(null); // codeItem
const formData = ref({}); // codeItem
const handlePagination = (pageNum, pageSize) => {
queryParams.value.pageNum = pageNum;
queryParams.value.pageSize = pageSize;
@ -289,35 +242,12 @@ function handleSelectionChange(selection) {
single.value = ids.value.length !== 1;
multiple.value = !ids.value.length > 0;
}
function changeCodeType(data){
if(data != "company"){
showSys.value=true
form.value.sysName=""
form.value.sysId=undefined
} else {
showSys.value=false
form.value.sysName="公司级"
form.value.sysId=10000
}
}
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
function dataChange(data) {
// dbResourceOldList name
const selectedItem = dbResourceOldList.value.find(item => item.id === data);
if (selectedItem) {
// name form.value.dbRName
form.value.sysName = selectedItem.name;
} else {
// form.value.dbRName
form.value.sysName = '';
}
}
const resetQuery = () => {
queryParams.value = {
codeNum: '',
@ -342,7 +272,8 @@ const handleAdd = () => {
sysName: '',
sysId: '',
};
dialogVisible.value = true;
selectedRow.value={...form.value}
dialogVisible2.value = true;
};
const handleEdit = (row) => {
@ -350,14 +281,9 @@ const handleEdit = (row) => {
dialogTitle.value = "编辑标准代码";
getStdCode(id).then(response => {
form.value = response.data;
if(form.value.codeType=="sys")
{
showSys.value=true
} else{
showSys.value=false
selectedRow.value={...form.value}
}
dialogVisible.value = true;
dialogVisible2.value = true;
});
};
@ -372,17 +298,16 @@ const handleRemove = (row) => {
}).catch(() => {});
};
const handleSave = () => {
if (!form.value.codeNum || !form.value.codeName) {
proxy.$modal.msgWarning("请填写必填项");
return;
}
const handleSave2 =async () => {
const child = proxy.$refs.editCodeDialog;
console.log(Object.getOwnPropertyNames(child)); //
let isSuccess= await child.handleSave()
console.log(isSuccess,"ssssssssssss")
if(isSuccess){
dialogVisible2.value = false;
const saveAction = form.value.id ? updateStdCode : addStdCode;
saveAction(form.value).then(() => {
dialogVisible.value = false;
handleQuery();
});
handleQuery()
}
};
const handleCancel = () => {
@ -397,10 +322,7 @@ 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 => {

Loading…
Cancel
Save