Browse Source

元数据上传

master
xueyinfei 3 days ago
parent
commit
2f71cf8e04
  1. 22
      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. 11
      vue-fastapi-backend/module_admin/service/approval_service.py
  6. 258
      vue-fastapi-backend/module_admin/service/meta_service.py
  7. 110
      vue-fastapi-frontend/src/views/meta/metaInfo/index.vue
  8. 135
      vue-fastapi-frontend/src/views/system/flow/index.vue

22
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 sqlalchemy.ext.asyncio import AsyncSession
from config.get_db import get_db from config.get_db import get_db
from module_admin.entity.vo.user_vo import CurrentUserModel from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.service.login_service import LoginService from module_admin.service.login_service import LoginService
from utils.response_util import ResponseUtil from utils.response_util import ResponseUtil
from utils.common_util import bytes2file_response
from module_admin.service.meta_service import MetaService 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)]) metaController = APIRouter(prefix='/dasset', dependencies=[Depends(LoginService.get_current_user)])
@ -79,3 +81,19 @@ async def getBloodRelationShip(request: Request,
query_db: AsyncSession = Depends(get_db)): query_db: AsyncSession = Depends(get_db)):
result = await MetaService.getBloodRelationShip(query_db, procId) result = await MetaService.getBloodRelationShip(query_db, procId)
return ResponseUtil.success(data=result) 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() ).scalars().first()
return List 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 @classmethod
async def get_data_sec_lvl_by_dict_id(cls, db: AsyncSession, id: str): async def get_data_sec_lvl_by_dict_id(cls, db: AsyncSession, id: str):
List = ( List = (

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

@ -291,7 +291,18 @@ class MetaDao:
return query_result return query_result
@classmethod @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 = ( query_result = (
( (
await db.execute( await db.execute(
@ -302,10 +313,10 @@ class MetaDao:
MetadataFldSuppInfoVett.data_dict_id == DataStdDict.onum, # 假设关联条件 MetadataFldSuppInfoVett.data_dict_id == DataStdDict.onum, # 假设关联条件
isouter=True, # 可选,是否左连接 isouter=True, # 可选,是否左连接
).where( ).where(
MetadataFldSuppInfoVett.ssys_id == tableInfo.ssys_id, MetadataFldSuppInfoVett.ssys_id == tableInfo['ssysId'],
MetadataFldSuppInfoVett.mdl_name == tableInfo.mdl_name, MetadataFldSuppInfoVett.mdl_name == tableInfo['mdlName'],
MetadataFldSuppInfoVett.tab_eng_name == tableInfo.tab_eng_name, MetadataFldSuppInfoVett.tab_eng_name == tableInfo['tabEngName'],
MetadataFldSuppInfoVett.apply_time == tableInfo.apply_time MetadataFldSuppInfoVett.apply_time == tableInfo['applyTime']
) )
) )
).all() ).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_time = Column(String(255, collation='utf8_general_ci'), comment='申请时间')
apply_status = 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='更新时间') 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='修改前表格数据') oldTableData = Column(Text, comment='修改前表格数据')
@ -161,6 +162,7 @@ class MetadataFldSuppInfoVett(Base):
rec_subm_prsn = Column(String(255, collation='utf8_general_ci'), comment='记录提交人') rec_subm_prsn = Column(String(255, collation='utf8_general_ci'), comment='记录提交人')
apply_time = 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='申请状态') 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='修改前字段信息') oldColumnData = Column(Text, comment='修改前字段信息')

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

@ -112,14 +112,15 @@ class ApprovalService:
return CrudResponseModel(is_success=True, message='操作成功') return CrudResponseModel(is_success=True, message='操作成功')
@classmethod @classmethod
async def syncSuppInfo(cls, result_db: AsyncSession, suppId: str, operateType: str): async def syncSuppInfo(cls, result_db: AsyncSession, businessId: str, operateType: str):
table = await MetaDao.get_supp_table_vett_by_id(suppId, result_db) tableList = await MetaDao.get_supp_table_vett_by_businessId(businessId, result_db)
if table is None: if tableList is None or len(tableList) == 0:
raise ServiceException(message='所查询的业务数据不存在') 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='所改业务已审核完毕') raise ServiceException(message='所改业务已审核完毕')
if table.apply_status == 'canceled': if tableList[0].apply_status == 'canceled':
raise ServiceException(message='所改业务已撤销申请') raise ServiceException(message='所改业务已撤销申请')
for table in tableList:
column_list = await MetaDao.get_meta_col_supp_vett(table, result_db) column_list = await MetaDao.get_meta_col_supp_vett(table, result_db)
if column_list is not None and len(column_list) > 0: if column_list is not None and len(column_list) > 0:
for column in column_list: for column in column_list:

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

@ -1,6 +1,9 @@
import io
import json import json
import uuid import uuid
import pandas as pd
from fastapi import UploadFile
from module_admin.entity.vo.meta_vo import MetaPageObject, MetaColObject, SuppleModel, MetaBusinessRelShipObject, \ from module_admin.entity.vo.meta_vo import MetaPageObject, MetaColObject, SuppleModel, MetaBusinessRelShipObject, \
MetaProcQueryObject MetaProcQueryObject
from module_admin.entity.do.meta_do import MetadataSuppInfo, MetadataFldSuppInfo, MetadataSuppInfoVett, \ 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.common_vo import CrudResponseModel
from module_admin.entity.vo.user_vo import CurrentUserModel from module_admin.entity.vo.user_vo import CurrentUserModel
from utils.common_util import CamelCaseUtil from utils.common_util import CamelCaseUtil
from config.env import AppConfig
import requests
class MetaService: 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) 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) tableInfo = await MetaDao.get_meta_table(supple.ssys_id, supple.mdl_name, supple.tab_eng_name, result_db)
tableOnum = uuid.uuid4() tableOnum = uuid.uuid4()
businessId = uuid.uuid4()
if hasTable is not None: if hasTable is not None:
if hasTable.apply_status == 'waiting': if hasTable.apply_status == 'waiting':
raise ServiceException(message=f'所补录对象已存在补录待审核记录,请等待审批完成或撤回申请后,再行补录') raise ServiceException(message=f'所补录对象已存在补录待审核记录,请等待审批完成或撤回申请后,再行补录')
@ -99,6 +105,7 @@ class MetaService:
suppTableInfo.tab_clas = supple.tab_clas suppTableInfo.tab_clas = supple.tab_clas
suppTableInfo.rec_subm_prsn = current_user.user.user_name suppTableInfo.rec_subm_prsn = current_user.user.user_name
suppTableInfo.apply_time = applyTime suppTableInfo.apply_time = applyTime
suppTableInfo.business_id = businessId
suppTableInfo.apply_status = 'waiting' suppTableInfo.apply_status = 'waiting'
suppTableInfo.oldTableData = cls.castToTableStr(oldTable, tableInfo) suppTableInfo.oldTableData = cls.castToTableStr(oldTable, tableInfo)
await MetaDao.insertMetadataSuppInfoVett(suppTableInfo, result_db) await MetaDao.insertMetadataSuppInfoVett(suppTableInfo, result_db)
@ -135,7 +142,7 @@ class MetaService:
await MetaDao.insertMetadataFldSuppInfoVett(suppColumnInfo, result_db) await MetaDao.insertMetadataFldSuppInfoVett(suppColumnInfo, result_db)
applyModel = ApplyModel() applyModel = ApplyModel()
applyModel.businessType = "metaDataInfo" applyModel.businessType = "metaDataInfo"
applyModel.businessId = tableOnum applyModel.businessId = businessId
applyModel.applicant = current_user.user.user_name applyModel.applicant = current_user.user.user_name
await ApprovalService.apply_services(result_db, applyModel, 'metaDataInfo') await ApprovalService.apply_services(result_db, applyModel, 'metaDataInfo')
await result_db.commit() await result_db.commit()
@ -193,22 +200,20 @@ class MetaService:
@classmethod @classmethod
async def get_meta_apply_detail_services(cls, result_db: AsyncSession, businessId: str): 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) tableDataList = await MetaDao.get_supp_table_vett_by_businessId(businessId, result_db)
table = CamelCaseUtil.transform_result(tableData) tableList = CamelCaseUtil.transform_result(tableDataList)
clas_list = await MetaDao.get_meta_tab_clas(result_db, tableData.ssys_id, tableData.mdl_name, for tableData in tableList:
tableData.tab_eng_name) clas_list = await MetaDao.get_meta_tab_clas(result_db, tableData['ssysId'], tableData['mdlName'],
table['batchTabClas'] = CamelCaseUtil.transform_result(clas_list) tableData['tabEngName'])
tableData['batchTabClas'] = CamelCaseUtil.transform_result(clas_list)
columnData = await MetaDao.get_supp_column_vett_by_tableInfo(result_db, tableData) columnData = await MetaDao.get_supp_column_vett_by_tableInfo(result_db, tableData)
column_list = CamelCaseUtil.transform_result(columnData) column_list = CamelCaseUtil.transform_result(columnData)
for column in column_list: for column in column_list:
col_list = await MetaDao.get_meta_fld_clas(result_db, column['ssysId'], column['mdlName'], col_list = await MetaDao.get_meta_fld_clas(result_db, column['ssysId'], column['mdlName'],
column['tabEngName'], column['fldEngName']) column['tabEngName'], column['fldEngName'])
column['batchColClas'] = CamelCaseUtil.transform_result(col_list) column['batchColClas'] = CamelCaseUtil.transform_result(col_list)
result = dict( tableData['columnList'] = column_list
table=table, return tableList
column=column_list
)
return result
@classmethod @classmethod
async def get_table_by_id(cls, result_db: AsyncSession, tableId: int): async def get_table_by_id(cls, result_db: AsyncSession, tableId: int):
@ -513,3 +518,234 @@ class MetaService:
"tableList": tableList "tableList": tableList
} }
return result 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" @click="runBloodAnalysisTask"
>执行血缘解析任务</el-button> >执行血缘解析任务</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="Upload"
@click="openUploadMetaInfoDialog"
>导入</el-button>
</el-col>
</el-row> </el-row>
<el-table <el-table
@ -620,7 +628,7 @@
<el-table v-loading="loading" :data="dataAstList"> <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="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="dataAstEngName"></el-table-column>
<el-table-column label="数据资产中文名称" align="center" prop="dataAstCnName"></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> <el-table-column label="数据资产类型" align="center" prop="dataAstType"></el-table-column>
@ -741,7 +749,45 @@
</div> </div>
</template> </template>
</el-dialog> </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> </div>
</template> </template>
@ -755,6 +801,7 @@
import BusinssRelation from "./businssRelation.vue"; import BusinssRelation from "./businssRelation.vue";
import BloodRelation from "./bloodRelation.vue"; import BloodRelation from "./bloodRelation.vue";
import {listMetadataSecOptions} from "@/api/metadataConfig/metadataConfig.js"; import {listMetadataSecOptions} from "@/api/metadataConfig/metadataConfig.js";
import {getToken} from "@/utils/auth.js";
const data = reactive({ const data = reactive({
queryParams:{ queryParams:{
@ -842,6 +889,21 @@
}); });
const stddictOptions = ref([]) const stddictOptions = ref([])
const secLvlOptions = 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(){ function changeColumnTab(){
if (activeColumnTab.value === 'businessRelation'){ if (activeColumnTab.value === 'businessRelation'){
@ -876,7 +938,7 @@
} }
function generateDemoData(){ function generateDemoData(){
let param ={ let param ={
dataAstSrc: currentMetaData.value.ssysId, dataAstSrc: currentMetaData.value.ssysCd,
dataAstEngName:currentMetaData.value.mdlName+"."+currentMetaData.value.tabEngName dataAstEngName:currentMetaData.value.mdlName+"."+currentMetaData.value.tabEngName
} }
getMetaSecurityData(param).then(res=>{ getMetaSecurityData(param).then(res=>{
@ -1458,7 +1520,11 @@
proxy.$modal.msgSuccess(response.data); proxy.$modal.msgSuccess(response.data);
} }
function confirmPublish(){ 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) proxy.$modal.msgSuccess(res.msg)
astPublish.value = false astPublish.value = false
}) })
@ -1482,9 +1548,38 @@
getMetaClasList().then(res=>{ getMetaClasList().then(res=>{
metaClasList.value = res.data 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(){ function applyDataAst(){
if(selectedRows.value.length === 0){ if(selectedRows.value.length === 0){
proxy.$modal.msgWarning("请至少选择一条元数据进行发布") proxy.$modal.msgWarning("请至少选择一条元数据进行发布")
@ -1498,6 +1593,7 @@
dataAstStat: '1', dataAstStat: '1',
dataAstDesc:'', dataAstDesc:'',
dataAstSrc: row.ssysId, dataAstSrc: row.ssysId,
showDataAstSrc: row.ssysCd,
astNo: row.extractOnum, astNo: row.extractOnum,
dataAstClas: JSON.stringify(row.batchTabClas), dataAstClas: JSON.stringify(row.batchTabClas),
showTabClas: row.showTabClas, showTabClas: row.showTabClas,
@ -1511,7 +1607,7 @@
const filterNode = (value, data) => { const filterNode = (value, data) => {
if (!value) return true; if (!value) return true;
return data.name.indexOf(value) !== -1; return data.name.indexOf(value) !== -1;
}; }
function handleNodeClick(data) { function handleNodeClick(data) {
queryParams.value.ssysId = data.id; queryParams.value.ssysId = data.id;
handleQuery(); handleQuery();

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

@ -539,6 +539,65 @@
</el-table> </el-table>
</div> </div>
</el-dialog> </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"/> <DataStdMainTable :flowId="selectedFlowId" :stdMainVisible="stdMainVisible"/>
@ -589,7 +648,9 @@ const data = reactive({
}); });
const showFlowDialog = ref(false); const showFlowDialog = ref(false);
const businessDialog = ref(false); const businessDialog = ref(false);
const metaDataListDialog = ref(false);
const oldTableInfo = ref([]); const oldTableInfo = ref([]);
const metaDataList = ref([]);
const oldColumnList = ref([]); const oldColumnList = ref([]);
const newTableInfo = ref([]); const newTableInfo = ref([]);
const newColumnList = ref([]); const newColumnList = ref([]);
@ -604,6 +665,13 @@ function getList() {
total.value = res.data.total 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(){ function register(){
Graph.registerNode( Graph.registerNode(
'activity', 'activity',
@ -853,17 +921,9 @@ function resetQuery(){
} }
getList() getList()
} }
function showBusinessDataDialog(row){ function transformMetaDetailData(data){
let table = JSON.parse(data.oldTableData)
if (row.businessType === 'metaDataInfo'){ let batchTabClas = data.batchTabClas
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 = [] let showOldTabClas = []
if (batchTabClas && batchTabClas.length>0){ if (batchTabClas && batchTabClas.length>0){
showOldTabClas = JSON.parse(JSON.stringify(batchTabClas)) showOldTabClas = JSON.parse(JSON.stringify(batchTabClas))
@ -888,21 +948,21 @@ function showBusinessDataDialog(row){
oldTableInfo.value = JSON.parse(JSON.stringify(table)) oldTableInfo.value = JSON.parse(JSON.stringify(table))
oldTableInfo.value.ssysCd = dsSysList.find(item => item.id === oldTableInfo.value.ssysId)?.name oldTableInfo.value.ssysCd = dsSysList.find(item => item.id === oldTableInfo.value.ssysId)?.name
newTableInfo.value = { newTableInfo.value = {
applyStatus:data.table.applyStatus, applyStatus:data.applyStatus,
applyTime:data.table.applyTime, applyTime:data.applyTime,
crrctVerNum:data.table.crrctVerNum, crrctVerNum:data.crrctVerNum,
govFlag:data.table.govFlag, govFlag:data.govFlag,
mdlName:data.table.mdlName, mdlName:data.mdlName,
onum:data.table.onum, onum:data.onum,
pic:data.table.pic, pic:data.pic,
recStat:data.table.recStat, recStat:data.recStat,
recSubmPrsn:data.table.recSubmPrsn, recSubmPrsn:data.recSubmPrsn,
ssysCd:dsSysList.find(item => item.id === data.table.ssysId)?.name, ssysCd:dsSysList.find(item => item.id === data.ssysId)?.name,
tabClas:data.table.tabClas, tabClas:data.tabClas,
tabCrrctName:data.table.tabCrrctName, tabCrrctName:data.tabCrrctName,
tabDesc:data.table.tabDesc, tabDesc:data.tabDesc,
tabEngName:data.table.tabEngName, tabEngName:data.tabEngName,
updTime:data.table.updTime, updTime:data.updTime,
tabCnName:table.tabCnName, tabCnName:table.tabCnName,
tabRecNum:table.tabRecNum, tabRecNum:table.tabRecNum,
tabType:table.tabType, tabType:table.tabType,
@ -925,14 +985,14 @@ function showBusinessDataDialog(row){
} }
} }
}else { }else {
showNewTabClas = JSON.parse(data.table.tabClas) showNewTabClas = JSON.parse(data.tabClas)
} }
newTableInfo.value.showTabClas = showNewTabClas newTableInfo.value.showTabClas = showNewTabClas
newColumnList.value = [] newColumnList.value = []
oldColumnList.value = [] oldColumnList.value = []
if (data.column && data.column.length > 0){ if (data.columnList && data.columnList.length > 0){
for (let i = 0; i < data.column.length; i++) { for (let i = 0; i < data.columnList.length; i++) {
let col = data.column[i] let col = data.columnList[i]
let column = JSON.parse(col.oldColumnData) let column = JSON.parse(col.oldColumnData)
let batchColClas = col.batchColClas let batchColClas = col.batchColClas
let showOldColClas = [] let showOldColClas = []
@ -1003,6 +1063,21 @@ function showBusinessDataDialog(row){
}) })
} }
} }
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"){ }else if(row.businessType ==="dataStdMain"){
selectedFlowId.value = row.businessId; selectedFlowId.value = row.businessId;

Loading…
Cancel
Save