Browse Source

元数据上传

master
xueyinfei 3 days ago
parent
commit
2f71cf8e04
  1. 26
      vue-fastapi-backend/module_admin/controller/meta_controller.py
  2. 12
      vue-fastapi-backend/module_admin/dao/datastd_dao.py
  3. 21
      vue-fastapi-backend/module_admin/dao/meta_dao.py
  4. 2
      vue-fastapi-backend/module_admin/entity/do/meta_do.py
  5. 47
      vue-fastapi-backend/module_admin/service/approval_service.py
  6. 270
      vue-fastapi-backend/module_admin/service/meta_service.py
  7. 110
      vue-fastapi-frontend/src/views/meta/metaInfo/index.vue
  8. 345
      vue-fastapi-frontend/src/views/system/flow/index.vue

26
vue-fastapi-backend/module_admin/controller/meta_controller.py

@ -1,12 +1,14 @@
from fastapi import APIRouter, Depends, Request
from fastapi import APIRouter, Depends, Request, UploadFile, File
from sqlalchemy.ext.asyncio import AsyncSession
from config.get_db import get_db
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.login_service import LoginService
from utils.response_util import ResponseUtil
from utils.common_util import bytes2file_response
from module_admin.service.meta_service import MetaService
from module_admin.entity.vo.meta_vo import MetaPageObject, MetaColObject, SuppleModel, MetaBusinessRelShipObject, MetaProcQueryObject
from module_admin.entity.vo.meta_vo import MetaPageObject, MetaColObject, SuppleModel, MetaBusinessRelShipObject, \
MetaProcQueryObject
metaController = APIRouter(prefix='/dasset', dependencies=[Depends(LoginService.get_current_user)])
@ -67,8 +69,8 @@ async def getBusinessRelationShip(request: Request,
@metaController.get("/meta/business/proc")
async def getBusinessProc(request: Request,
meta_query: MetaProcQueryObject = Depends(MetaProcQueryObject.as_query),
query_db: AsyncSession = Depends(get_db)):
meta_query: MetaProcQueryObject = Depends(MetaProcQueryObject.as_query),
query_db: AsyncSession = Depends(get_db)):
result = await MetaService.getMetaProc(query_db, meta_query)
return ResponseUtil.success(data=result)
@ -79,3 +81,19 @@ async def getBloodRelationShip(request: Request,
query_db: AsyncSession = Depends(get_db)):
result = await MetaService.getBloodRelationShip(query_db, procId)
return ResponseUtil.success(data=result)
@metaController.post("/meta/importTemplate")
async def export_system_user_template(request: Request, query_db: AsyncSession = Depends(get_db)):
meta_import_template_result = await MetaService.get_meta_import_template_services()
return ResponseUtil.streaming(data=bytes2file_response(meta_import_template_result))
@metaController.post('/meta/importData')
async def batch_import_meta_data(
request: Request,
file: UploadFile = File(...),
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
batch_import_result = await MetaService.batch_import_meta_services(query_db, file, current_user)
return ResponseUtil.success(msg=batch_import_result)

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

@ -590,6 +590,18 @@ class DataStdDao:
).scalars().first()
return List
@classmethod
async def get_data_dict_by_code(cls, db: AsyncSession, code: str):
List = (
await db.execute(
select(DataStdDict)
.where(
DataStdDict.data_dict_no == code
)
)
).scalars().first()
return List
@classmethod
async def get_data_sec_lvl_by_dict_id(cls, db: AsyncSession, id: str):
List = (

21
vue-fastapi-backend/module_admin/dao/meta_dao.py

@ -291,7 +291,18 @@ class MetaDao:
return query_result
@classmethod
async def get_supp_column_vett_by_tableInfo(cls, db: AsyncSession, tableInfo: MetadataSuppInfoVett):
async def get_supp_table_vett_by_businessId(cls, businessId: str, db: AsyncSession):
query_result = (
(
await db.execute(
select(MetadataSuppInfoVett).where(MetadataSuppInfoVett.business_id == businessId).distinct()
)
).scalars().all()
)
return query_result
@classmethod
async def get_supp_column_vett_by_tableInfo(cls, db: AsyncSession, tableInfo):
query_result = (
(
await db.execute(
@ -302,10 +313,10 @@ class MetaDao:
MetadataFldSuppInfoVett.data_dict_id == DataStdDict.onum, # 假设关联条件
isouter=True, # 可选,是否左连接
).where(
MetadataFldSuppInfoVett.ssys_id == tableInfo.ssys_id,
MetadataFldSuppInfoVett.mdl_name == tableInfo.mdl_name,
MetadataFldSuppInfoVett.tab_eng_name == tableInfo.tab_eng_name,
MetadataFldSuppInfoVett.apply_time == tableInfo.apply_time
MetadataFldSuppInfoVett.ssys_id == tableInfo['ssysId'],
MetadataFldSuppInfoVett.mdl_name == tableInfo['mdlName'],
MetadataFldSuppInfoVett.tab_eng_name == tableInfo['tabEngName'],
MetadataFldSuppInfoVett.apply_time == tableInfo['applyTime']
)
)
).all()

2
vue-fastapi-backend/module_admin/entity/do/meta_do.py

@ -68,6 +68,7 @@ class MetadataSuppInfoVett(Base):
apply_time = Column(String(255, collation='utf8_general_ci'), comment='申请时间')
apply_status = Column(String(255, collation='utf8_general_ci'), comment='申请状态')
upd_time = Column(String(255, collation='utf8_general_ci'), comment='更新时间')
business_id = Column(String(255, collation='utf8_general_ci'), comment='审批业务相关ID')
oldTableData = Column(Text, comment='修改前表格数据')
@ -161,6 +162,7 @@ class MetadataFldSuppInfoVett(Base):
rec_subm_prsn = Column(String(255, collation='utf8_general_ci'), comment='记录提交人')
apply_time = Column(String(255, collation='utf8_general_ci'), comment='申请时间')
apply_status = Column(String(255, collation='utf8_general_ci'), comment='申请状态')
business_id = Column(String(255, collation='utf8_general_ci'), comment='审批业务相关ID')
oldColumnData = Column(Text, comment='修改前字段信息')

47
vue-fastapi-backend/module_admin/service/approval_service.py

@ -112,32 +112,33 @@ class ApprovalService:
return CrudResponseModel(is_success=True, message='操作成功')
@classmethod
async def syncSuppInfo(cls, result_db: AsyncSession, suppId: str, operateType: str):
table = await MetaDao.get_supp_table_vett_by_id(suppId, result_db)
if table is None:
async def syncSuppInfo(cls, result_db: AsyncSession, businessId: str, operateType: str):
tableList = await MetaDao.get_supp_table_vett_by_businessId(businessId, result_db)
if tableList is None or len(tableList) == 0:
raise ServiceException(message='所查询的业务数据不存在')
if table.apply_status == 'succeed' or table.apply_status == 'rejected':
if tableList[0].apply_status == 'succeed' or tableList[0].apply_status == 'rejected':
raise ServiceException(message='所改业务已审核完毕')
if table.apply_status == 'canceled':
if tableList[0].apply_status == 'canceled':
raise ServiceException(message='所改业务已撤销申请')
column_list = await MetaDao.get_meta_col_supp_vett(table, result_db)
if column_list is not None and len(column_list) > 0:
for column in column_list:
column.apply_status = operateType
suppColumn = await MetaDao.get_supp_column_by_vett(column, result_db)
await MetaDao.updateMetadataFldSuppInfoVett(column.onum, operateType, result_db)
if operateType != 'canceled':
if suppColumn is None:
await MetaDao.insertMetadataFldSuppInfo(column, result_db)
else:
await MetaDao.updateMetadataFldSuppInfo(suppColumn.onum, column, result_db)
suppTable = await MetaDao.get_supp_table_by_vett(table.ssys_id, table.mdl_name, table.tab_eng_name, result_db)
await MetaDao.updateMetadataSuppInfoVett(table.onum, operateType, result_db)
if operateType != 'canceled':
if suppTable is None:
await MetaDao.insertMetadataSuppInfo(table, result_db)
else:
await MetaDao.updateMetadataSuppInfo(suppTable.onum, table, result_db)
for table in tableList:
column_list = await MetaDao.get_meta_col_supp_vett(table, result_db)
if column_list is not None and len(column_list) > 0:
for column in column_list:
column.apply_status = operateType
suppColumn = await MetaDao.get_supp_column_by_vett(column, result_db)
await MetaDao.updateMetadataFldSuppInfoVett(column.onum, operateType, result_db)
if operateType != 'canceled':
if suppColumn is None:
await MetaDao.insertMetadataFldSuppInfo(column, result_db)
else:
await MetaDao.updateMetadataFldSuppInfo(suppColumn.onum, column, result_db)
suppTable = await MetaDao.get_supp_table_by_vett(table.ssys_id, table.mdl_name, table.tab_eng_name, result_db)
await MetaDao.updateMetadataSuppInfoVett(table.onum, operateType, result_db)
if operateType != 'canceled':
if suppTable is None:
await MetaDao.insertMetadataSuppInfo(table, result_db)
else:
await MetaDao.updateMetadataSuppInfo(suppTable.onum, table, result_db)
return CrudResponseModel(is_success=True, message='操作成功')
@classmethod

270
vue-fastapi-backend/module_admin/service/meta_service.py

@ -1,6 +1,9 @@
import io
import json
import uuid
import pandas as pd
from fastapi import UploadFile
from module_admin.entity.vo.meta_vo import MetaPageObject, MetaColObject, SuppleModel, MetaBusinessRelShipObject, \
MetaProcQueryObject
from module_admin.entity.do.meta_do import MetadataSuppInfo, MetadataFldSuppInfo, MetadataSuppInfoVett, \
@ -21,6 +24,8 @@ from module_admin.service.approval_service import ApprovalService
from module_admin.entity.vo.common_vo import CrudResponseModel
from module_admin.entity.vo.user_vo import CurrentUserModel
from utils.common_util import CamelCaseUtil
from config.env import AppConfig
import requests
class MetaService:
@ -81,6 +86,7 @@ class MetaService:
oldTable = await MetaDao.get_supp_table_by_vett(supple.ssys_id, supple.mdl_name, supple.tab_eng_name, result_db)
tableInfo = await MetaDao.get_meta_table(supple.ssys_id, supple.mdl_name, supple.tab_eng_name, result_db)
tableOnum = uuid.uuid4()
businessId = uuid.uuid4()
if hasTable is not None:
if hasTable.apply_status == 'waiting':
raise ServiceException(message=f'所补录对象已存在补录待审核记录,请等待审批完成或撤回申请后,再行补录')
@ -99,6 +105,7 @@ class MetaService:
suppTableInfo.tab_clas = supple.tab_clas
suppTableInfo.rec_subm_prsn = current_user.user.user_name
suppTableInfo.apply_time = applyTime
suppTableInfo.business_id = businessId
suppTableInfo.apply_status = 'waiting'
suppTableInfo.oldTableData = cls.castToTableStr(oldTable, tableInfo)
await MetaDao.insertMetadataSuppInfoVett(suppTableInfo, result_db)
@ -135,7 +142,7 @@ class MetaService:
await MetaDao.insertMetadataFldSuppInfoVett(suppColumnInfo, result_db)
applyModel = ApplyModel()
applyModel.businessType = "metaDataInfo"
applyModel.businessId = tableOnum
applyModel.businessId = businessId
applyModel.applicant = current_user.user.user_name
await ApprovalService.apply_services(result_db, applyModel, 'metaDataInfo')
await result_db.commit()
@ -193,22 +200,20 @@ class MetaService:
@classmethod
async def get_meta_apply_detail_services(cls, result_db: AsyncSession, businessId: str):
tableData = await MetaDao.get_supp_table_vett_by_id(businessId, result_db)
table = CamelCaseUtil.transform_result(tableData)
clas_list = await MetaDao.get_meta_tab_clas(result_db, tableData.ssys_id, tableData.mdl_name,
tableData.tab_eng_name)
table['batchTabClas'] = CamelCaseUtil.transform_result(clas_list)
columnData = await MetaDao.get_supp_column_vett_by_tableInfo(result_db, tableData)
column_list = CamelCaseUtil.transform_result(columnData)
for column in column_list:
col_list = await MetaDao.get_meta_fld_clas(result_db, column['ssysId'], column['mdlName'],
column['tabEngName'], column['fldEngName'])
column['batchColClas'] = CamelCaseUtil.transform_result(col_list)
result = dict(
table=table,
column=column_list
)
return result
tableDataList = await MetaDao.get_supp_table_vett_by_businessId(businessId, result_db)
tableList = CamelCaseUtil.transform_result(tableDataList)
for tableData in tableList:
clas_list = await MetaDao.get_meta_tab_clas(result_db, tableData['ssysId'], tableData['mdlName'],
tableData['tabEngName'])
tableData['batchTabClas'] = CamelCaseUtil.transform_result(clas_list)
columnData = await MetaDao.get_supp_column_vett_by_tableInfo(result_db, tableData)
column_list = CamelCaseUtil.transform_result(columnData)
for column in column_list:
col_list = await MetaDao.get_meta_fld_clas(result_db, column['ssysId'], column['mdlName'],
column['tabEngName'], column['fldEngName'])
column['batchColClas'] = CamelCaseUtil.transform_result(col_list)
tableData['columnList'] = column_list
return tableList
@classmethod
async def get_table_by_id(cls, result_db: AsyncSession, tableId: int):
@ -513,3 +518,234 @@ class MetaService:
"tableList": tableList
}
return result
@staticmethod
async def get_meta_import_template_services():
"""
获取元数据导入模板service
:return: 元数据导入模板excel的二进制数据
"""
table_header_list = ['系统代码', '模式名称', '对象英文名', '补录对象名称', '补录对象描述', '负责人']
column_header_list = ['系统代码', '模式名称', '对象英文名', '字段英文名', '字段补录名', '补录主键',
'补录字段描述', '引用字典/标准', '安全等级', '负责人']
selector_header_list = ['补录主键', '安全等级']
option_list = [{}, {'补录主键': ['', ''], '安全等级': ['S1', 'S2', 'S3', 'S4']}]
sheet_config1 = dict(
sheet_name="表信息", header_list=table_header_list, selector_header_list=[]
)
sheet_config2 = dict(
sheet_name="字段信息", header_list=column_header_list, selector_header_list=selector_header_list
)
sheet_configs = [sheet_config1, sheet_config2]
binary_data = get_excel_template_with_sheets(
sheet_configs, # 每个Sheet的配置(包含表头、选择器等)
option_list
)
return binary_data
@classmethod
async def batch_import_meta_services(cls,
result_db: AsyncSession,
file: UploadFile,
current_user: CurrentUserModel):
import_err_msg = []
# 调用DS接口通过系统代码查询系统ID
url = f'{AppConfig.ds_server_url}/dolphinscheduler/datasources?pageNo=1&pageSize=100'
headers = {'dashUserName': current_user.user.user_name, 'dashPassword': current_user.user.password}
response = requests.get(url, headers=headers, verify=False)
dataSourceList = []
if response.reason == 'OK':
response_text = response.text
data = json.loads(response_text)
dataSourceList = data["data"]["totalList"]
else:
raise ServiceException(message=f'系统异常,获取数据源失败')
skip_table = []
businessId = uuid.uuid4()
applyTime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
table_header_dict = {
'系统代码': 'ssys_cd',
'模式名称': 'mdl_name',
'对象英文名': 'tab_eng_name',
'补录对象名称': 'tab_crrct_name',
'补录对象描述': 'tab_desc',
'负责人': 'rec_subm_prsn'
}
column_header_dict = {
'系统代码': 'ssys_cd',
'模式名称': 'mdl_name',
'对象英文名': 'tab_eng_name',
'字段英文名': 'fld_eng_name',
'字段补录名': 'fld_crrct_name',
'补录主键': 'crrct_pk_flag',
'补录字段描述': 'fld_desc',
'引用字典/标准': 'data_dict_id',
'安全等级': 'data_sec_lvl',
'负责人': 'rec_subm_prsn'
}
contents = await file.read()
excel_file = pd.ExcelFile(io.BytesIO(contents))
await file.close()
# 获取所有sheet名称
sheet_names = excel_file.sheet_names
# 逐个读取
tableSheet = sheet_names[0]
columnSheet = sheet_names[1]
successCount = 0
# 校验, 1、各必填内容不能为空, 2.系统代码映射的系统是否存在 3.表是否存在 4.字段是否存在5.引用的字典标准是否存在6.标准的系统与表系统是否对应
if tableSheet == '表信息':
# 表信息补录
df = excel_file.parse(sheet_name=tableSheet)
df.rename(columns=table_header_dict, inplace=True)
for index, row in df.iterrows():
noneValid = ''
if row['ssys_cd'] is None or len(row['ssys_cd']) == 0:
noneValid += "sheet[表信息]中行:" + str(index+1) + "中的系统代码不能为空"
if row['mdl_name'] is None or len(row['mdl_name']) == 0:
if len(noneValid) > 0:
noneValid += ",模式名称不能为空"
else:
noneValid += "sheet[表信息]中行:" + str(index+1) + "中的模式名称不能为空"
if row['tab_eng_name'] is None or len(row['tab_eng_name']) == 0:
if len(noneValid) > 0:
noneValid += ",表英文名称不能为空"
else:
noneValid += "sheet[表信息]中行:" + str(index+1) + "中的表英文名不能为空"
if len(noneValid) > 0:
import_err_msg.append(noneValid)
continue
ssysId = next((item["id"] for item in dataSourceList if item["name"] == row['ssys_cd']), None)
if ssysId is None:
import_err_msg.append("行:" + str(index+1) + "中的系统不存在,需重新修正")
continue
hasTable = await MetaDao.get_lastest_meta_data_supp_vett(result_db, ssysId, row['mdl_name'],
row['tab_eng_name'])
if hasTable:
if hasTable.apply_status == 'waiting':
import_err_msg.append(
'sheet[表信息]中行:' + str(index+1) + ' 导入的系统代码:' + row['ssys_cd'] + ',模式名称:' + row['mdl_name'] +
',对象英文名:' + row['tab_eng_name'] +
'已存在补录待审核记录,请等待审批完成或撤回申请后,再行导入')
if hasTable.apply_status == 'pending':
import_err_msg.append(
'sheet[字段信息]中行:' + str(index+1) + ' 导入的系统代码:' + row['ssys_cd'] + ',模式名称:' + row['mdl_name'] +
',对象英文名:' + row['tab_eng_name'] +
'已存在待审核记录,请等待审批完成或撤回申请后,再行导入')
skip_table.append({'ssys_id': ssysId, 'mdl_name': row['mdl_name'],
'tab_eng_name': row['tab_eng_name']})
continue
oldTable = await MetaDao.get_supp_table_by_vett(ssysId, row['mdl_name'],
row['tab_eng_name'], result_db)
tableInfo = await MetaDao.get_meta_table(ssysId, row['mdl_name'],
row['tab_eng_name'], result_db)
if tableInfo is None:
import_err_msg.append("sheet[表信息]中行:"+str(index+1) + "中所对应的表不存在,无法上传补录")
continue
tableOnum = uuid.uuid4()
suppTableInfo = MetadataSuppInfoVett()
suppTableInfo.onum = tableOnum
suppTableInfo.ssys_id = ssysId
suppTableInfo.mdl_name = row['mdl_name']
suppTableInfo.tab_eng_name = row['tab_eng_name']
suppTableInfo.tab_crrct_name = row['tab_crrct_name']
suppTableInfo.tab_desc = row['tab_desc']
suppTableInfo.pic = oldTable.pic if oldTable else None
suppTableInfo.gov_flag = oldTable.gov_flag if oldTable else None
suppTableInfo.tab_clas = oldTable.tab_clas if oldTable else None
suppTableInfo.rec_subm_prsn = row['rec_subm_prsn']
suppTableInfo.apply_time = applyTime
suppTableInfo.apply_status = 'waiting'
suppTableInfo.business_id = businessId
suppTableInfo.oldTableData = cls.castToTableStr(oldTable, tableInfo)
await MetaDao.insertMetadataSuppInfoVett(suppTableInfo, result_db)
successCount += 1
if columnSheet == '字段信息':
# 字段信息补录
df = excel_file.parse(sheet_name=columnSheet)
df.rename(columns=column_header_dict, inplace=True)
for index, row in df.iterrows():
noneValid = ''
if row['ssys_cd'] is None or len(row['ssys_cd']) == 0:
noneValid += "sheet[字段信息]中行:" + str(index+1) + "中的系统代码不能为空"
if row['mdl_name'] is None or len(row['mdl_name']) == 0:
if len(noneValid) > 0:
noneValid += ",模式名称不能为空"
else:
noneValid += "sheet[字段信息]中行:" + str(index+1) + "中的模式名称不能为空"
if row['tab_eng_name'] is None or len(row['tab_eng_name']) == 0:
if len(noneValid) > 0:
noneValid += ",表英文名称不能为空"
else:
noneValid += "sheet[字段信息]中行:" + str(index+1) + "中的表英文名不能为空"
if len(noneValid) > 0:
import_err_msg.append(noneValid)
continue
ssysId = next((item["id"] for item in dataSourceList if item["name"] == row['ssys_cd']), None)
if any(
table['ssys_id'] == ssysId
and table['mdl_name'] == row['mdl_name']
and table['tab_eng_name'] == row['tab_eng_name']
for table in skip_table
):
continue
oldColumn = await MetaDao.get_supp_column_by_columnInfo(ssysId, row['mdl_name'],
row['tab_eng_name'],
row['fld_eng_name'], result_db)
data_dict_name = ''
if oldColumn and oldColumn.data_dict_id and oldColumn.data_dict_id != '':
oldDict = await DataStdDao.get_data_dict_by_id(result_db, oldColumn.data_dict_id)
data_dict_name = oldDict.data_dict_cn_name if oldDict else ''
columnInfo = await MetaDao.get_meta_column(ssysId, row['mdl_name'],
row['tab_eng_name'],
row['fld_eng_name'], result_db)
if columnInfo is None:
import_err_msg.append("sheet[字段信息]中行:"+str(index+1) + "中所对应的字段不存在,无法上传补录")
continue
dataDictId = ''
if row['data_dict_id'] and len(row['data_dict_id']) > 0:
dataDict = await DataStdDao.get_data_dict_by_code(result_db, row['data_dict_id'])
if dataDict is None:
import_err_msg.append("sheet[字段信息]中行:"+str(index+1) + "中所对应的数据字典不存在,无法上传补录")
continue
else:
if int(dataDict.src_sys) != ssysId:
import_err_msg.append("sheet[字段信息]中行:"+str(index+1) + "中所对应的数据字典所属系统与表所属系统不一致,无法上传补录")
continue
else:
dataDictId = dataDict.onum
suppColumnInfo = MetadataFldSuppInfoVett()
suppColumnInfo.onum = uuid.uuid4()
suppColumnInfo.ssys_id = ssysId
suppColumnInfo.mdl_name = row['mdl_name']
suppColumnInfo.tab_eng_name = row['tab_eng_name']
suppColumnInfo.fld_eng_name = row['fld_eng_name']
suppColumnInfo.fld_crrct_name = row['fld_crrct_name']
suppColumnInfo.crrct_pk_flag = True if row['crrct_pk_flag'] and row['crrct_pk_flag'] == '' else False
suppColumnInfo.fld_desc = row['fld_desc']
suppColumnInfo.pic = oldColumn.pic if oldColumn else None
suppColumnInfo.fld_clas = oldColumn.fld_clas if oldColumn else None
suppColumnInfo.fld_null_rate = oldColumn.fld_null_rate if oldColumn else None
suppColumnInfo.data_dict_id = dataDictId if dataDictId != '' else None
suppColumnInfo.data_sec_lvl = row['data_sec_lvl']
suppColumnInfo.rec_stat = oldColumn.rec_stat if oldColumn else None
suppColumnInfo.rec_subm_prsn = row['rec_subm_prsn']
suppColumnInfo.business_id = businessId
suppColumnInfo.apply_time = applyTime
suppColumnInfo.apply_status = 'waiting'
suppColumnInfo.oldColumnData = cls.castToColumnStr(oldColumn, columnInfo, data_dict_name)
await MetaDao.insertMetadataFldSuppInfoVett(suppColumnInfo, result_db)
successCount += 1
if successCount > 0:
applyModel = ApplyModel()
applyModel.businessType = "metaDataInfo"
applyModel.businessId = businessId
applyModel.applicant = current_user.user.user_name
await ApprovalService.apply_services(result_db, applyModel, 'metaDataInfo')
await result_db.commit()
else:
import_err_msg.append("上传的数据均有问题,本次导入0条")
if len(import_err_msg) > 0:
return ";".join(import_err_msg)
else:
return "操作成功"

110
vue-fastapi-frontend/src/views/meta/metaInfo/index.vue

@ -98,6 +98,14 @@
@click="runBloodAnalysisTask"
>执行血缘解析任务</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="Upload"
@click="openUploadMetaInfoDialog"
>导入</el-button>
</el-col>
</el-row>
<el-table
@ -620,7 +628,7 @@
<el-table v-loading="loading" :data="dataAstList">
<el-table-column label="数据资产编号" align="center" prop="astNo"></el-table-column>
<el-table-column label="数据资产来源" align="center" prop="dataAstSrc"></el-table-column>
<el-table-column label="数据资产来源" align="center" prop="showDataAstSrc"></el-table-column>
<el-table-column label="数据资产英文名称" align="center" prop="dataAstEngName"></el-table-column>
<el-table-column label="数据资产中文名称" align="center" prop="dataAstCnName"></el-table-column>
<el-table-column label="数据资产类型" align="center" prop="dataAstType"></el-table-column>
@ -741,7 +749,45 @@
</div>
</template>
</el-dialog>
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
<el-upload
ref="uploadRef"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip text-center">
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</template>
</el-upload>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</template>
</el-dialog>
<el-dialog title="导入结果" v-model="upload.showResult" width="1000px" append-to-body>
<template v-for="item in upload.resultMsg">
<span>{{item}}<br></span>
</template>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="upload.showResult = false"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
@ -755,6 +801,7 @@
import BusinssRelation from "./businssRelation.vue";
import BloodRelation from "./bloodRelation.vue";
import {listMetadataSecOptions} from "@/api/metadataConfig/metadataConfig.js";
import {getToken} from "@/utils/auth.js";
const data = reactive({
queryParams:{
@ -842,6 +889,21 @@
});
const stddictOptions = ref([])
const secLvlOptions = ref([])
/*** 导入参数 */
const upload = reactive({
//
open: false,
//
title: "",
//
isUploading: false,
//
headers: { Authorization: "Bearer " + getToken() },
//
url: import.meta.env.VITE_APP_BASE_API + "/dasset/meta/importData",
showResult: false,
resultMsg: []
});
function changeColumnTab(){
if (activeColumnTab.value === 'businessRelation'){
@ -876,7 +938,7 @@
}
function generateDemoData(){
let param ={
dataAstSrc: currentMetaData.value.ssysId,
dataAstSrc: currentMetaData.value.ssysCd,
dataAstEngName:currentMetaData.value.mdlName+"."+currentMetaData.value.tabEngName
}
getMetaSecurityData(param).then(res=>{
@ -1458,7 +1520,11 @@
proxy.$modal.msgSuccess(response.data);
}
function confirmPublish(){
publishAstData({assetItems:dataAstList.value}).then(res=>{
let data = dataAstList.value
data.forEach(dataAst =>{
delete dataAst.showDataAstSrc
})
publishAstData({assetItems:data}).then(res=>{
proxy.$modal.msgSuccess(res.msg)
astPublish.value = false
})
@ -1482,9 +1548,38 @@
getMetaClasList().then(res=>{
metaClasList.value = res.data
})
}
function openUploadMetaInfoDialog(){
upload.title = "数据导入";
upload.open = true;
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
upload.isUploading = true;
}
/** 提交上传文件 */
function submitFileForm() {
proxy.$refs["uploadRef"].submit();
}
/** 下载模板操作 */
function importTemplate() {
proxy.download("/dasset/meta/importTemplate", {
}, `meta_template_${new Date().getTime()}.xlsx`);
}
/** 文件上传成功处理 */
const handleFileSuccess = (response, file, fileList) => {
upload.open = false;
upload.isUploading = false;
proxy.$refs["uploadRef"].handleRemove(file);
if (response.msg === '操作成功'){
proxy.$modal.msgSuccess(response.msg)
}else {
upload.showResult = true
upload.resultMsg = response.msg.split(";")
}
getList();
}
function applyDataAst(){
if(selectedRows.value.length === 0){
proxy.$modal.msgWarning("请至少选择一条元数据进行发布")
@ -1498,6 +1593,7 @@
dataAstStat: '1',
dataAstDesc:'',
dataAstSrc: row.ssysId,
showDataAstSrc: row.ssysCd,
astNo: row.extractOnum,
dataAstClas: JSON.stringify(row.batchTabClas),
showTabClas: row.showTabClas,
@ -1511,7 +1607,7 @@
const filterNode = (value, data) => {
if (!value) return true;
return data.name.indexOf(value) !== -1;
};
}
function handleNodeClick(data) {
queryParams.value.ssysId = data.id;
handleQuery();

345
vue-fastapi-frontend/src/views/system/flow/index.vue

@ -539,8 +539,67 @@
</el-table>
</div>
</el-dialog>
<el-dialog v-model="metaDataListDialog" width="80%" title="导入元数据">
<el-table
:data="metaDataList"
style="width: 100%"
>
<el-table-column type="expand">
<template #default="props">
<el-table :data="props.row.columnList">
<el-table-column prop="fldEngName" label="字段英文名" align="center" />
<el-table-column prop="fldCrrctName" label="补录字段中文名" align="center" />
<el-table-column prop="fldCrrctName" label="补录字段中文名" align="center" />
<el-table-column prop="crrctPkFlag" label="补录主键" align="center" >
<template #default="secondProps">
<span>{{secondProps.row.crrctPkFlag?"是":"否"}}</span>
</template>
</el-table-column>
<el-table-column prop="fldDesc" label="补录字段描述" align="center" />
<el-table-column prop="dataDictName" label="引用字典/标准" align="center" />
<el-table-column prop="dataSecLvl" label="安全等级" align="center" />
<el-table-column prop="recSubmPrsn" label="负责人" align="center" />
</el-table>
</template>
</el-table-column>
<el-table-column prop="ssysId" label="所属系统" align="center" >
<template #default="scope">
<span >
{{
getSrcSysName(scope.row.ssysId)
}}
</span>
</template>
</el-table-column>
<el-table-column prop="mdlName" label="模式名称" align="center" />
<el-table-column prop="tabEngName" label="表英文名" align="center" />
<el-table-column prop="tabCnName" label="表中文名" align="center" />
<el-table-column prop="tabCrrctName" label="表补录名" align="center" />
<el-table-column prop="tabRecNum" label="记录数" align="center" />
<el-table-column prop="tabType" label="对象类型" align="center" />
<el-table-column prop="govFlag" label="对象治理标志" align="center" />
<el-table-column prop="pic" label="负责人" align="center" />
<el-table-column prop="pic" label="对象标签" align="center" >
<template #default="scope">
<template v-if="scope.row.showTabClas && scope.row.showTabClas.length > 0">
<template v-for="item in scope.row.showTabClas">
<el-tag style="margin:5px" v-if="item.clasEffFlag === '1'">{{item.clasName}}</el-tag>
<el-tag style="margin:5px" type="danger" v-if="item.clasEffFlag === '0'">{{item.clasName}}</el-tag>
</template>
</template>
</template>
</el-table-column>
<el-table-column prop="tabDesc" label="补录对象描述" align="center" />
<el-table-column label="操作" width="100" align="center">
<template #default="scope">
<el-button @click="handleViewMetadata(scope.row)" size="small" type="primary">查看详情</el-button>
</template>
</el-table-column>
</el-table>
</el-dialog>
<!-- 弹窗 -->
<el-dialog v-model="stdMainVisible" title="数据标准变更详情" width="80%">
<el-dialog v-model="stdMainVisible" title="数据标准变更详情" width="80%">
<DataStdMainTable :flowId="selectedFlowId" :stdMainVisible="stdMainVisible"/>
</el-dialog>
<el-dialog v-model="stdDictVisible" title="数据字典变更详情" width="80%" >
@ -589,7 +648,9 @@ const data = reactive({
});
const showFlowDialog = ref(false);
const businessDialog = ref(false);
const metaDataListDialog = ref(false);
const oldTableInfo = ref([]);
const metaDataList = ref([]);
const oldColumnList = ref([]);
const newTableInfo = ref([]);
const newColumnList = ref([]);
@ -604,6 +665,13 @@ function getList() {
total.value = res.data.total
})
}
const getSrcSysName = (id) => {
const match = dsSysList.find(item => item.id === id);
return match ? match.name : id;
};
function handleViewMetadata(row) {
transformMetaDetailData(row)
}
function register(){
Graph.registerNode(
'activity',
@ -853,155 +921,162 @@ function resetQuery(){
}
getList()
}
function showBusinessDataDialog(row){
if (row.businessType === 'metaDataInfo'){
businessDialog.value = true
let param = {
businessId: row.businessId
}
getMetaInfoApplyBusinessDetail(param).then(res=>{
let data = JSON.parse(JSON.stringify(res.data))
let table = JSON.parse(data.table.oldTableData)
let batchTabClas = data.table.batchTabClas
let showOldTabClas = []
if (batchTabClas && batchTabClas.length>0){
showOldTabClas = JSON.parse(JSON.stringify(batchTabClas))
if (table.tabClas && table.tabClas !== '[]' && table.tabClas !== 'null'){
let oldTabClas = JSON.parse(table.tabClas)
for (let i = 0; i < oldTabClas.length; i++) {
for (let j = 0; j < showOldTabClas.length; j++) {
if (showOldTabClas[j].clasPriClas === oldTabClas[i].clasPriClas
&& showOldTabClas[j].clasScdClas === oldTabClas[i].clasScdClas
&& showOldTabClas[j].clasThreClas === oldTabClas[i].clasThreClas
&& showOldTabClas[j].clasName === oldTabClas[i].clasName
){
showOldTabClas[j] = oldTabClas[i]
}
}
function transformMetaDetailData(data){
let table = JSON.parse(data.oldTableData)
let batchTabClas = data.batchTabClas
let showOldTabClas = []
if (batchTabClas && batchTabClas.length>0){
showOldTabClas = JSON.parse(JSON.stringify(batchTabClas))
if (table.tabClas && table.tabClas !== '[]' && table.tabClas !== 'null'){
let oldTabClas = JSON.parse(table.tabClas)
for (let i = 0; i < oldTabClas.length; i++) {
for (let j = 0; j < showOldTabClas.length; j++) {
if (showOldTabClas[j].clasPriClas === oldTabClas[i].clasPriClas
&& showOldTabClas[j].clasScdClas === oldTabClas[i].clasScdClas
&& showOldTabClas[j].clasThreClas === oldTabClas[i].clasThreClas
&& showOldTabClas[j].clasName === oldTabClas[i].clasName
){
showOldTabClas[j] = oldTabClas[i]
}
}
}else {
showOldTabClas = JSON.parse(table.tabClas)
}
table.showTabClas = showOldTabClas
oldTableInfo.value = JSON.parse(JSON.stringify(table))
oldTableInfo.value.ssysCd = dsSysList.find(item => item.id === oldTableInfo.value.ssysId)?.name
newTableInfo.value = {
applyStatus:data.table.applyStatus,
applyTime:data.table.applyTime,
crrctVerNum:data.table.crrctVerNum,
govFlag:data.table.govFlag,
mdlName:data.table.mdlName,
onum:data.table.onum,
pic:data.table.pic,
recStat:data.table.recStat,
recSubmPrsn:data.table.recSubmPrsn,
ssysCd:dsSysList.find(item => item.id === data.table.ssysId)?.name,
tabClas:data.table.tabClas,
tabCrrctName:data.table.tabCrrctName,
tabDesc:data.table.tabDesc,
tabEngName:data.table.tabEngName,
updTime:data.table.updTime,
tabCnName:table.tabCnName,
tabRecNum:table.tabRecNum,
tabType:table.tabType,
}
}else {
showOldTabClas = JSON.parse(table.tabClas)
}
table.showTabClas = showOldTabClas
oldTableInfo.value = JSON.parse(JSON.stringify(table))
oldTableInfo.value.ssysCd = dsSysList.find(item => item.id === oldTableInfo.value.ssysId)?.name
newTableInfo.value = {
applyStatus:data.applyStatus,
applyTime:data.applyTime,
crrctVerNum:data.crrctVerNum,
govFlag:data.govFlag,
mdlName:data.mdlName,
onum:data.onum,
pic:data.pic,
recStat:data.recStat,
recSubmPrsn:data.recSubmPrsn,
ssysCd:dsSysList.find(item => item.id === data.ssysId)?.name,
tabClas:data.tabClas,
tabCrrctName:data.tabCrrctName,
tabDesc:data.tabDesc,
tabEngName:data.tabEngName,
updTime:data.updTime,
tabCnName:table.tabCnName,
tabRecNum:table.tabRecNum,
tabType:table.tabType,
}
let showNewTabClas = []
if (batchTabClas && batchTabClas.length>0){
showNewTabClas = JSON.parse(JSON.stringify(batchTabClas))
if (newTableInfo.value.tabClas && newTableInfo.value.tabClas !== '[]' && newTableInfo.value.tabClas !== 'null'){
let newTabClas = JSON.parse(newTableInfo.value.tabClas)
for (let i = 0; i < newTabClas.length; i++) {
for (let j = 0; j < showNewTabClas.length; j++) {
if (showNewTabClas[j].clasPriClas === newTabClas[i].clasPriClas
&& showNewTabClas[j].clasScdClas === newTabClas[i].clasScdClas
&& showNewTabClas[j].clasThreClas === newTabClas[i].clasThreClas
&& showNewTabClas[j].clasName === newTabClas[i].clasName
){
showNewTabClas[j] = newTabClas[i]
}
}
}
let showNewTabClas = []
if (batchTabClas && batchTabClas.length>0){
showNewTabClas = JSON.parse(JSON.stringify(batchTabClas))
if (newTableInfo.value.tabClas && newTableInfo.value.tabClas !== '[]' && newTableInfo.value.tabClas !== 'null'){
let newTabClas = JSON.parse(newTableInfo.value.tabClas)
for (let i = 0; i < newTabClas.length; i++) {
for (let j = 0; j < showNewTabClas.length; j++) {
if (showNewTabClas[j].clasPriClas === newTabClas[i].clasPriClas
&& showNewTabClas[j].clasScdClas === newTabClas[i].clasScdClas
&& showNewTabClas[j].clasThreClas === newTabClas[i].clasThreClas
&& showNewTabClas[j].clasName === newTabClas[i].clasName
}
}else {
showNewTabClas = JSON.parse(data.tabClas)
}
newTableInfo.value.showTabClas = showNewTabClas
newColumnList.value = []
oldColumnList.value = []
if (data.columnList && data.columnList.length > 0){
for (let i = 0; i < data.columnList.length; i++) {
let col = data.columnList[i]
let column = JSON.parse(col.oldColumnData)
let batchColClas = col.batchColClas
let showOldColClas = []
if (batchColClas && batchColClas.length>0){
showOldColClas = JSON.parse(JSON.stringify(batchColClas))
if (column.fldClas && column.fldClas !== '[]' && column.fldClas !== 'null'){
let oldColClas = JSON.parse(column.fldClas)
for (let i = 0; i < oldColClas.length; i++) {
for (let j = 0; j < showOldColClas.length; j++) {
if (showOldColClas[j].clasPriClas === oldColClas[i].clasPriClas
&& showOldColClas[j].clasScdClas === oldColClas[i].clasScdClas
&& showOldColClas[j].clasThreClas === oldColClas[i].clasThreClas
&& showOldColClas[j].clasName === oldColClas[i].clasName
){
showNewTabClas[j] = newTabClas[i]
showOldColClas[j] = oldColClas[i]
}
}
}
}
}else {
showNewTabClas = JSON.parse(data.table.tabClas)
showOldColClas = JSON.parse(column.fldClas)
}
newTableInfo.value.showTabClas = showNewTabClas
newColumnList.value = []
oldColumnList.value = []
if (data.column && data.column.length > 0){
for (let i = 0; i < data.column.length; i++) {
let col = data.column[i]
let column = JSON.parse(col.oldColumnData)
let batchColClas = col.batchColClas
let showOldColClas = []
if (batchColClas && batchColClas.length>0){
showOldColClas = JSON.parse(JSON.stringify(batchColClas))
if (column.fldClas && column.fldClas !== '[]' && column.fldClas !== 'null'){
let oldColClas = JSON.parse(column.fldClas)
for (let i = 0; i < oldColClas.length; i++) {
for (let j = 0; j < showOldColClas.length; j++) {
if (showOldColClas[j].clasPriClas === oldColClas[i].clasPriClas
&& showOldColClas[j].clasScdClas === oldColClas[i].clasScdClas
&& showOldColClas[j].clasThreClas === oldColClas[i].clasThreClas
&& showOldColClas[j].clasName === oldColClas[i].clasName
){
showOldColClas[j] = oldColClas[i]
}
}
}
}
}else {
showOldColClas = JSON.parse(column.fldClas)
}
column.showColClas = showOldColClas
oldColumnList.value.push(column)
let showNewColClas = []
if (batchColClas && batchColClas.length>0){
showNewColClas = batchColClas
if (col.fldClas && col.fldClas !== '[]' && col.fldClas !== 'null'){
let newColClas = JSON.parse(col.fldClas)
for (let i = 0; i < newColClas.length; i++) {
for (let j = 0; j < showNewColClas.length; j++) {
if (showNewColClas[j].clasPriClas === newColClas[i].clasPriClas
&& showNewColClas[j].clasScdClas === newColClas[i].clasScdClas
&& showNewColClas[j].clasThreClas === newColClas[i].clasThreClas
&& showNewColClas[j].clasName === newColClas[i].clasName
){
showNewColClas[j] = newColClas[i]
}
}
column.showColClas = showOldColClas
oldColumnList.value.push(column)
let showNewColClas = []
if (batchColClas && batchColClas.length>0){
showNewColClas = batchColClas
if (col.fldClas && col.fldClas !== '[]' && col.fldClas !== 'null'){
let newColClas = JSON.parse(col.fldClas)
for (let i = 0; i < newColClas.length; i++) {
for (let j = 0; j < showNewColClas.length; j++) {
if (showNewColClas[j].clasPriClas === newColClas[i].clasPriClas
&& showNewColClas[j].clasScdClas === newColClas[i].clasScdClas
&& showNewColClas[j].clasThreClas === newColClas[i].clasThreClas
&& showNewColClas[j].clasName === newColClas[i].clasName
){
showNewColClas[j] = newColClas[i]
}
}
}else {
showNewColClas = JSON.parse(col.fldClas)
}
newColumnList.value.push({
applyStatus:col.applyStatus,
applyTime:col.applyTime,
crrctPkFlag:col.crrctPkFlag,
crrctVerNum:col.crrctVerNum,
fldClas:col.fldClas,
fldCrrctName:col.fldCrrctName,
fldDesc:col.fldDesc,
fldEngName:col.fldEngName,
fldNullRate:col.fldNullRate,
mdlName:col.mdlName,
onum:col.onum,
pic:col.pic,
recStat:col.recStat,
recSubmPrsn:col.recSubmPrsn,
ssysCd:col.ssysCd,
tabEngName:col.tabEngName,
updTime:col.updTime,
fldCnName:column.fldCnName,
fldType:column.fldType,
dataDictName: col.dataDictName,
dataSecLvl: col.dataSecLvl,
showColClas: showNewColClas
})
}
}else {
showNewColClas = JSON.parse(col.fldClas)
}
newColumnList.value.push({
applyStatus:col.applyStatus,
applyTime:col.applyTime,
crrctPkFlag:col.crrctPkFlag,
crrctVerNum:col.crrctVerNum,
fldClas:col.fldClas,
fldCrrctName:col.fldCrrctName,
fldDesc:col.fldDesc,
fldEngName:col.fldEngName,
fldNullRate:col.fldNullRate,
mdlName:col.mdlName,
onum:col.onum,
pic:col.pic,
recStat:col.recStat,
recSubmPrsn:col.recSubmPrsn,
ssysCd:col.ssysCd,
tabEngName:col.tabEngName,
updTime:col.updTime,
fldCnName:column.fldCnName,
fldType:column.fldType,
dataDictName: col.dataDictName,
dataSecLvl: col.dataSecLvl,
showColClas: showNewColClas
})
}
}
businessDialog.value = true
}
function showBusinessDataDialog(row){
if (row.businessType === 'metaDataInfo'){
let param = {
businessId: row.businessId
}
getMetaInfoApplyBusinessDetail(param).then(res=>{
let data = JSON.parse(JSON.stringify(res.data))
if (data.length === 1){
transformMetaDetailData(data[0])
}else if (data.length > 1){
metaDataList.value = data
metaDataListDialog.value = true
}
})
}else if(row.businessType ==="dataStdMain"){

Loading…
Cancel
Save