Browse Source

修复元数据信息页面bug

master
xueyinfei 3 weeks ago
parent
commit
91bfb8a0b0
  1. 2
      vue-fastapi-backend/module_admin/controller/meta_controller.py
  2. 172
      vue-fastapi-backend/module_admin/service/meta_service.py
  3. 14
      vue-fastapi-backend/utils/common_util.py
  4. 40
      vue-fastapi-frontend/src/views/meta/metaInfo/index.vue

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

@ -97,4 +97,4 @@ async def batch_import_meta_data(
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, overWrite, current_user)
return ResponseUtil.success(msg=batch_import_result)
return ResponseUtil.success(data=batch_import_result)

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

@ -10,6 +10,7 @@ from module_admin.entity.do.meta_do import MetadataSuppInfo, MetadataFldSuppInfo
MetadataFldSuppInfoVett, MetadataExtractInfo, MetadataFldTabExtractInfo
from module_admin.dao.meta_dao import MetaDao
from module_admin.dao.datastd_dao import DataStdDao
from module_admin.dao.user_dao import UserDao
from datetime import datetime
from module_admin.entity.vo.user_vo import CurrentUserModel
from module_admin.entity.vo.approval_vo import ApplyModel
@ -532,16 +533,20 @@ class MetaService:
获取元数据导入模板service
:return: 元数据导入模板excel的二进制数据
"""
table_header_list = ['系统代码', '模式名称', '对象英文名', '补录对象名称', '补录对象描述', '负责人']
table_header_list = ['系统代码', '模式名称', '对象英文名', '补录对象名称', '补录对象描述', '对象治理标志', '负责人']
column_header_list = ['系统代码', '模式名称', '对象英文名', '字段英文名', '字段补录名', '补录主键',
'补录字段描述', '引用字典/标准', '安全等级']
selector_header_list = ['补录主键', '安全等级']
option_list = [{}, {'补录主键': ['', ''], '安全等级': ['S1', 'S2', 'S3', 'S4']}]
option_list = [{'对象治理标志': ['', '']}, {'补录主键': ['', ''], '安全等级': ['S1', 'S2', 'S3', 'S4']}]
table_data_list = [['sys_cd', 'mdl_name', 'tab_eng_name', '补录对象中文名', '补录对象描述', '', 'admin']]
column_data_list = [['sys_cd', 'mdl_name', 'tab_eng_name', 'fld_eng_name', '字段补录中文名', '',
'描述内容', 'dict_code(字典编号)', 'S1']]
sheet_config1 = dict(
sheet_name="表信息", header_list=table_header_list, selector_header_list=[]
sheet_name="表信息", header_list=table_header_list, data_list=table_data_list, selector_header_list=[]
)
sheet_config2 = dict(
sheet_name="字段信息", header_list=column_header_list, selector_header_list=selector_header_list
sheet_name="字段信息", header_list=column_header_list, data_list=column_data_list,
selector_header_list=selector_header_list
)
sheet_configs = [sheet_config1, sheet_config2]
binary_data = get_excel_template_with_sheets(
@ -557,7 +562,6 @@ class MetaService:
file: UploadFile,
overWrite: bool,
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}
@ -570,6 +574,11 @@ class MetaService:
else:
raise ServiceException(message=f'系统异常,获取数据源失败')
skip_table = []
result_list = {
"table": [],
"column": [],
"successCount": 0
}
businessId = uuid.uuid4()
applyTime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
table_header_dict = {
@ -578,6 +587,7 @@ class MetaService:
'对象英文名': 'tab_eng_name',
'补录对象名称': 'tab_crrct_name',
'补录对象描述': 'tab_desc',
'对象治理标志': 'gov_flag',
'负责人': 'pic'
}
column_header_dict = {
@ -599,7 +609,6 @@ class MetaService:
# 逐个读取
tableSheet = sheet_names[0]
columnSheet = sheet_names[1]
successCount = 0
# 校验, 1、各必填内容不能为空, 2.系统代码映射的系统是否存在 3.表是否存在 4.字段是否存在5.引用的字典标准是否存在6.标准的系统与表系统是否对应
if tableSheet == '表信息':
# 表信息补录
@ -608,52 +617,85 @@ class MetaService:
for index, row in df.iterrows():
noneValid = ''
if row['ssys_cd'] is None or len(row['ssys_cd']) == 0:
noneValid += "sheet[表信息]中行:" + str(index + 2) + "中的系统代码不能为空"
noneValid += "系统代码不能为空"
if row['mdl_name'] is None or len(row['mdl_name']) == 0:
if len(noneValid) > 0:
noneValid += ",模式名称不能为空"
else:
noneValid += "sheet[表信息]中行:" + str(index + 2) + "中的模式名称不能为空"
noneValid += "模式名称不能为空"
if row['tab_eng_name'] is None or len(row['tab_eng_name']) == 0:
if len(noneValid) > 0:
noneValid += ",表英文名不能为空"
noneValid += ",表英文名不能为空"
else:
noneValid += "sheet[表信息]中行:" + str(index + 2) + "中的表英文名不能为空"
noneValid += "表英文名不能为空"
if len(noneValid) > 0:
import_err_msg.append(noneValid)
result_list['table'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"errorInfo": 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 + 2) + "中的系统不存在,需重新修正")
result_list['table'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"errorInfo": "系统不存在,为无效系统"
})
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 + 2) + ' 导入的系统代码:' + row['ssys_cd'] + ',模式名称:' +
row['mdl_name'] +
',对象英文名:' + row['tab_eng_name'] +
'已存在补录待审核记录,请等待审批完成或撤回申请后,再行导入')
result_list['table'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"errorInfo": "已存在补录待审核记录,请等待审批完成或撤回申请后,再行导入"
})
skip_table.append({'ssys_id': ssysId, 'mdl_name': row['mdl_name'],
'tab_eng_name': row['tab_eng_name']})
continue
if hasTable.apply_status == 'pending':
import_err_msg.append(
'sheet[字段信息]中行:' + str(index + 2) + ' 导入的系统代码:' + row[
'ssys_cd'] + ',模式名称:' + row['mdl_name'] +
',对象英文名:' + row['tab_eng_name'] +
'已存在待审核记录,请等待审批完成或撤回申请后,再行导入')
result_list['table'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"errorInfo": "已存在待审核记录,请等待审批完成或撤回申请后,再行导入"
})
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 + 2) + "中所对应的表不存在,无法上传补录")
result_list['table'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"errorInfo": "对应的表不存在,无法上传补录"
})
continue
if row['pic'] and len(row['pic']) > 0:
# 校验负责人是否存在
user = await UserDao.get_user_by_name(result_db,row['pic'])
if user is None:
result_list['table'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"errorInfo": "对应的负责人不存在,无法上传补录"
})
continue
tableOnum = uuid.uuid4()
suppTableInfo = MetadataSuppInfoVett()
@ -664,7 +706,8 @@ class MetaService:
if overWrite:
suppTableInfo.tab_crrct_name = row['tab_crrct_name']
suppTableInfo.tab_desc = row['tab_desc']
suppTableInfo.rec_subm_prsn = row['pic']
suppTableInfo.pic = row['pic']
suppTableInfo.gov_flag = row['gov_flag']
else:
suppTableInfo.tab_crrct_name = row['tab_crrct_name'] if row['tab_crrct_name'] and \
str(row[
@ -672,18 +715,20 @@ class MetaService:
suppTableInfo.tab_desc = row['tab_desc'] if row['tab_desc'] and \
str(row[
'tab_desc']).strip() != '' else oldTable.tab_desc if oldTable else None
suppTableInfo.rec_subm_prsn = row['pic'] if row['pic'] and \
suppTableInfo.pic = row['pic'] if row['pic'] and \
str(row[
'pic']).strip() != '' else oldTable.pic if oldTable else None
suppTableInfo.gov_flag = row['gov_flag'] if row['gov_flag'] and \
str(row[
'gov_flag']).strip() != '' else oldTable.gov_flag if oldTable else None
suppTableInfo.rec_subm_prsn = current_user.user.user_name
suppTableInfo.gov_flag = oldTable.gov_flag if oldTable else None
suppTableInfo.tab_clas = oldTable.tab_clas if oldTable else None
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
result_list['successCount'] += 1
if columnSheet == '字段信息':
# 字段信息补录
df = excel_file.parse(sheet_name=columnSheet, dtype=str, keep_default_na=False, na_values=[])
@ -691,19 +736,31 @@ class MetaService:
for index, row in df.iterrows():
noneValid = ''
if row['ssys_cd'] is None or len(row['ssys_cd']) == 0:
noneValid += "sheet[字段信息]中行:" + str(index + 2) + "中的系统代码不能为空"
noneValid += "系统代码不能为空"
if row['mdl_name'] is None or len(row['mdl_name']) == 0:
if len(noneValid) > 0:
noneValid += ",模式名称不能为空"
else:
noneValid += "sheet[字段信息]中行:" + str(index + 2) + "中的模式名称不能为空"
noneValid += "模式名称不能为空"
if row['tab_eng_name'] is None or len(row['tab_eng_name']) == 0:
if len(noneValid) > 0:
noneValid += ",表英文名称不能为空"
else:
noneValid += "sheet[字段信息]中行:" + str(index + 2) + "中的表英文名不能为空"
noneValid += "表英文名不能为空"
if row['fld_eng_name'] is None or len(row['fld_eng_name']) == 0:
if len(noneValid) > 0:
noneValid += ",字段英文名称不能为空"
else:
noneValid += "字段英文名不能为空"
if len(noneValid) > 0:
import_err_msg.append(noneValid)
result_list['column'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"fldEngName": row['fld_eng_name'],
"errorInfo": noneValid
})
continue
ssysId = next((item["id"] for item in dataSourceList if item["name"] == row['ssys_cd']), None)
if any(
@ -724,22 +781,52 @@ class MetaService:
row['tab_eng_name'],
row['fld_eng_name'], result_db)
if columnInfo is None:
import_err_msg.append("sheet[字段信息]中行:" + str(index + 2) + "中所对应的字段不存在,无法上传补录")
result_list['column'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"fldEngName": row['fld_eng_name'],
"errorInfo": "对应的字段不存在,无法上传补录"
})
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 + 2) + "中所对应的数据字典不存在,无法上传补录")
result_list['column'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"fldEngName": row['fld_eng_name'],
"errorInfo": "对应的数据字典不存在,无法上传补录,字段编号:" + row['data_dict_id']
})
continue
else:
if int(dataDict.src_sys) != ssysId:
import_err_msg.append("sheet[字段信息]中行:" + str(
index + 2) + "中所对应的数据字典所属系统与表所属系统不一致,无法上传补录")
result_list['column'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"fldEngName": row['fld_eng_name'],
"errorInfo": "对应的数据字典所属系统与表所属系统不一致,无法上传补录,字典编号:" + row[
'data_dict_id']
})
continue
else:
dataDictId = dataDict.onum
if row['data_sec_lvl'] and len(row['data_sec_lvl']) and row['data_sec_lvl'] \
not in ('S1', 'S2', 'S3', 'S4'):
result_list['column'].append({
"row": index + 2,
"ssysCd": row['ssys_cd'],
"mdlName": row['mdl_name'],
"tabEngName": row['tab_eng_name'],
"fldEngName": row['fld_eng_name'],
"errorInfo": "安全等级:" + row['data_sec_lvl'] + "不是S1,S2,S3,S4中的值,无法上传"
})
suppColumnInfo = MetadataFldSuppInfoVett()
suppColumnInfo.onum = uuid.uuid4()
suppColumnInfo.ssys_id = ssysId
@ -776,17 +863,12 @@ class MetaService:
suppColumnInfo.apply_status = 'waiting'
suppColumnInfo.oldColumnData = cls.castToColumnStr(oldColumn, columnInfo, data_dict_name)
await MetaDao.insertMetadataFldSuppInfoVett(suppColumnInfo, result_db)
successCount += 1
if successCount > 0:
result_list['successCount'] += 1
if result_list['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 "操作成功"
return result_list

14
vue-fastapi-backend/utils/common_util.py

@ -266,11 +266,13 @@ def get_excel_template_with_sheets(sheet_configs: List[Dict], # 每个Sheet的
{
"sheet_name": "Sheet1", # Sheet名称
"header_list": ["姓名", "性别", "城市"], # 表头
"data_list":[['name','sex','city']], #数据集
"selector_header_list": ["性别", "城市"], # 需要下拉选择的表头
},
{
"sheet_name": "Sheet2",
"header_list": ["产品", "类别", "价格"],
"data_list":[['name','sex','city']], #数据集
"selector_header_list": ["类别"],
}
]
@ -290,6 +292,7 @@ def get_excel_template_with_sheets(sheet_configs: List[Dict], # 每个Sheet的
for sheet_config in sheet_configs:
sheet_name = sheet_config["sheet_name"]
header_list = sheet_config["header_list"]
data_list = sheet_config["data_list"]
selector_header_list = sheet_config["selector_header_list"]
# 创建Sheet
ws = wb.create_sheet(title=sheet_name)
@ -301,7 +304,16 @@ def get_excel_template_with_sheets(sheet_configs: List[Dict], # 每个Sheet的
cell.value = header
cell.fill = header_fill
cell.alignment = Alignment(horizontal="center")
ws.column_dimensions[get_column_letter(col_num)].width = 12
ws.column_dimensions[get_column_letter(col_num)].width = 25
# 写入数据
data_start_row = 2
current_row = data_start_row
for row_data in data_list:
for col_num, value in enumerate(row_data, 1):
# 写入单元格数据
cell = ws.cell(row=current_row, column=col_num, value=value)
cell.alignment = Alignment(wrap_text=True)
current_row += 1
# 设置下拉选择器
for selector_header in selector_header_list:
if selector_header not in header_list:

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

@ -809,8 +809,31 @@
</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 v-if="upload.showResult">
<el-tabs type="border-card" v-if=" (upload.resultMsg.table && upload.resultMsg.table.length>0) || (upload.resultMsg.column && upload.resultMsg.column.length>0)">
<el-tab-pane label="表级问题" v-if="upload.resultMsg.table && upload.resultMsg.table.length>0">
<el-table :data="upload.resultMsg.table" stripe style="width: 100%">
<el-table-column prop="row" label="行" />
<el-table-column prop="ssysCd" label="系统" />
<el-table-column prop="mdlName" label="模式" />
<el-table-column prop="tabEngName" label="表名称" />
<el-table-column prop="errorInfo" label="问题" />
</el-table>
</el-tab-pane>
<el-tab-pane label="字段级问题" v-if="upload.resultMsg.column && upload.resultMsg.column.length>0">
<el-table :data="upload.resultMsg.column" stripe style="width: 100%">
<el-table-column prop="row" label="行" />
<el-table-column prop="ssysCd" label="系统" />
<el-table-column prop="mdlName" label="模式" />
<el-table-column prop="tabEngName" label="表名称" />
<el-table-column prop="fldEngName" label="字段名称" />
<el-table-column prop="errorInfo" label="问题" />
</el-table>
</el-tab-pane>
</el-tabs>
<span v-if=" (upload.resultMsg.table && upload.resultMsg.table.length===0) && (upload.resultMsg.column && upload.resultMsg.column.length===0) && upload.resultMsg.successCount === 0">
上传的文档内容为空请进行有效上传
</span>
</template>
<template #footer>
<div class="dialog-footer">
@ -933,7 +956,7 @@
//
url: import.meta.env.VITE_APP_BASE_API + "/dasset/meta/importData",
showResult: false,
resultMsg: []
resultMsg: {}
});
function changeColumnTab(){
@ -1008,9 +1031,6 @@
tableTagDialog.value = false
}
function confirmAstTags(){
console.log(dataAstList.value)
console.log(currentAstTag.value)
console.log(dataAstList.value[currentAstTag.value.index])
dataAstList.value[currentAstTag.value.index].dataAstClas = JSON.parse(JSON.stringify(astTags.value))
let tempTabClas = []
if (astTags.value.length>0){
@ -1475,7 +1495,6 @@
getMetaDataList(queryParams.value).then(res=>{
dataList.value = res.data.rows
let dbList = databaseList.value[0].children
console.log(dataList.value[0].ssysId)
if (dataList.value.length>0){
for (let i = 0; i < dataList.value.length; i++) {
for (let j = 0; j < dbList.length; j++) {
@ -1603,11 +1622,12 @@
upload.open = false;
upload.isUploading = false;
proxy.$refs["uploadRef"].handleRemove(file);
if (response.msg === '操作成功'){
proxy.$modal.msgSuccess(response.msg)
let resData = response.data
if (resData.successCount > 0 && resData.table.length === 0 && resData.column.length === 0){
proxy.$modal.msgSuccess("导入成功")
}else {
upload.resultMsg = resData
upload.showResult = true
upload.resultMsg = response.msg.split(";")
}
getList();
}

Loading…
Cancel
Save