You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1781 lines
70 KiB

<template>
<div class="app-container">
<el-row :gutter="20">
<el-col :span="4" :xs="24">
<div class="head-container">
<el-input
v-model="database"
placeholder="请输入搜索系统名/模式名"
clearable
prefix-icon="Search"
style="margin-bottom: 20px"
/>
</div>
<div class="head-container">
<el-tree
:data="databaseList"
:props="{ label: 'name', children: 'children' }"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="databaseTreeRef"
node-key="id"
highlight-current
default-expand-all
@node-click="handleNodeClick"
/>
</div>
</el-col>
<el-col :span="20" :xs="24">
<el-form :model="queryParams" :inline="true" label-width="75px">
<el-form-item label="对象名称:">
<el-input
v-model="queryParams.tabName"
placeholder="请输入搜索表中文/英文名"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="模式名称:">
<el-input
v-model="queryParams.mdlName"
placeholder="请输入搜索模式名称"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="列名称:">
<el-input
v-model="queryParams.colName"
placeholder="请输入搜索字段中文/英文名"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="对象类型:">
<el-select
v-model="queryParams.tabType"
placeholder="请输入数据类型"
clearable
style="width: 240px"
>
<el-option key="TABLE" value="TABLE" label="表"/>
<el-option key="VIEW" value="VIEW" label="视图"/>
<el-option key="PROCEDURE" value="PROCEDURE" label="存储过程"/>
<el-option key="FUNCTION" value="FUNCTION" label="函数"/>
</el-select>
</el-form-item>
<el-form-item label="标签名称:">
<el-input
v-model="queryParams.tagName"
placeholder="请输入搜索标签名称"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="补录状态:">
<el-input
v-model="queryParams.recStat"
placeholder="请输入搜索状态"
clearable
style="width: 240px"
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="Plus"
@click="applyDataAst"
>数据资产发布</el-button>
</el-col>
<el-col :span="1.5">
<el-button
type="success"
plain
icon="CaretRight"
@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
v-loading="loading"
:data="dataList"
ref="metaTable"
@select="handleSelection"
@select-all="handleSelectionAll"
>
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="系统英文名" width="100" align="center" prop="ssysCd"></el-table-column>
<el-table-column label="模式名称" align="center" prop="mdlName"></el-table-column>
<el-table-column label="对象英文名" width="170" align="center" prop="tabEngName" >
<template #default="scope">
<el-link type="primary" @click="showColumnDialog(scope.row)" :underline="false">{{ scope.row.tabEngName }}</el-link>
</template>
</el-table-column>
<el-table-column label="对象中文名" width="100" align="center" prop="tabCnName"></el-table-column>
<el-table-column label="对象标签" width="200" align="center" prop="batchTabClas">
<template #default="scope">
<el-popover v-for="item in scope.row.tempTabClas" placement="right" width="auto" trigger="hover">
<template #reference>
<el-tag v-if="item.clasEffFlag && item.clasEffFlag === '1'">{{item.clasName}}</el-tag>
</template>
<div>
<div style="margin: 5px" v-for="item in scope.row.showTabClas"><el-tag v-if="item.clasEffFlag && item.clasEffFlag === '1'">{{item.clasName + ":" + item.clasValue}}</el-tag></div>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column label="记录数" width="80" align="center" prop="tabRecNum"></el-table-column>
<el-table-column label="补录对象名称" width="150" align="center" prop="tabCrrctName"></el-table-column>
<el-table-column label="补录对象描述" width="150" align="center" prop="tabDesc"></el-table-column>
<el-table-column label="对象类型" align="center" prop="tabType"></el-table-column>
<el-table-column label="对象治理标志" width="120" align="center" prop="govFlag"></el-table-column>
<el-table-column label="补录审批状态" width="120" align="center" prop="recStat"></el-table-column>
<el-table-column label="负责人" align="center" prop="pic"></el-table-column>
<el-table-column label="采集时间" width="200" align="center" prop="extractUpdTime">
<template #default="scope">
<span>{{scope.row.extractUpdTime.replace("T"," ")}}</span>
</template>
</el-table-column>
<el-table-column label="补录时间" align="center" prop="suppUpdTime"></el-table-column>
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</el-col>
</el-row>
<el-drawer v-model="drawer" size="80%" :show-close="false">
<template #header>
<h3>元数据信息</h3>
<div style="flex: none">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="submit">提交</el-button>
</div>
</template>
<template #default>
<el-row :gutter="20">
<el-col :span="6">
<el-form :model="currentMetaData" :inline="true" label-width="120px">
<el-form-item label="对象英文名">
<el-input
v-model="currentMetaData.tabEngName"
disabled
/>
</el-form-item>
<el-form-item label="对象中文名">
<el-input
v-model="currentMetaData.tabCnName"
disabled
/>
</el-form-item>
<el-form-item label="所属系统">
<el-input
v-model="currentMetaData.ssysCd"
disabled
/>
</el-form-item>
<el-form-item label="所属SCHEMA">
<el-input
v-model="currentMetaData.mdlName"
disabled
/>
</el-form-item>
</el-form>
</el-col>
<el-col :span="6">
<el-form :model="currentMetaData" label-width="120px">
<el-form-item label="补录对象名称">
<el-input
v-model="currentMetaData.tabCrrctName"
placeholder="补录对象名称"
clearable
/>
</el-form-item>
<el-form-item label="补录对象描述">
<el-input
v-model="currentMetaData.tabDesc"
placeholder="请输入描述内容"
clearable
/>
</el-form-item>
<el-form-item label="对象治理标志">
<el-select
v-model="currentMetaData.govFlag"
placeholder="请输入数据类型"
clearable
style="width: 100%"
>
<el-option key="0" :value="'0'" label="是"/>
<el-option key="1" :value="'1'" label="否"/>
</el-select>
</el-form-item>
<el-form-item label="对象负责人">
<el-input
v-model="currentMetaData.pic"
placeholder="请输入负责人"
clearable
/>
</el-form-item>
</el-form>
</el-col>
<el-col :span="12" :xs="24">
<el-divider content-position="left">对象标签集合
<el-button icon="Plus" type="primary" text @click="openTableTagsDialog">新增</el-button>
</el-divider>
<template v-for="(tag,index) in currentMetaData.tags">
<el-tag style="margin-left: 10px;margin-top: 10px" :key="tag.clasName +'-'+tag.clasValue"
v-if="tag.clasEffFlag && tag.clasEffFlag === '1'"
size="large" closable type="primary" @close="handleTableTagClose(index)">
{{ tag.clasName}}
</el-tag>
</template>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<el-tabs v-model="activeColumnTab" type="border-card" class="full-height-tabs" @tab-change="changeColumnTab">
<el-tab-pane label="字段信息" name="column">
<div class="table-container">
<el-table :data="columnList" height="calc(100vh - 395px)">
<el-table-column label="字段英文名" width="100" align="center" prop="fldEngName">
<template #default="scope">
<el-link type="primary" @click="openEditColumnDialog(scope.row,scope.$index)" :underline="false">{{ scope.row.fldEngName }}</el-link>
</template>
</el-table-column>
<el-table-column label="字段中文名" align="center" prop="fldCnName"></el-table-column>
<el-table-column label="字段类型" width="170" align="center" prop="fldType" ></el-table-column>
<el-table-column label="主键标志" width="100" align="center" prop="pkFlag">
<template #default="scope">
<span v-if="scope.row.pkFlag === 'Y'">是</span>
<span v-else>否</span>
</template>
</el-table-column>
<!-- <el-table-column label="字段描述" width="250" align="center" prop="fldDesc"></el-table-column>-->
<el-table-column label="是否必填" width="70" align="center" prop="requireFlag">
<template #default="scope">
<span v-if="scope.row.requireFlag === 'Y'">是</span>
<span v-else>否</span>
</template>
</el-table-column>
<el-table-column label="是否索引" width="150" align="center" prop="idxFlag">
<template #default="scope">
<span v-if="scope.row.idxFlag === 'Y'">是</span>
<span v-else>否</span>
</template>
</el-table-column>
<el-table-column label="字段补录名" width="150" align="center" prop="fldCrrctName">
<template #default="scope">
<span>{{scope.row.fldCrrctName}}</span>
</template>
</el-table-column>
<el-table-column label="补录主键" align="center" prop="crrctPkFlag">
<template #default="scope">
<span v-if="scope.row.crrctPkFlag">是</span>
<span v-else>否</span>
</template>
</el-table-column>
<el-table-column label="补录字段描述" align="center" prop="fldDesc">
<template #default="scope">
<span>{{scope.row.fldDesc}}</span>
</template>
</el-table-column>
<!-- <el-table-column label="状态" width="120" align="center" prop="suppRecStat">-->
<!-- <template #default="scope">-->
<!-- <span>{{scope.row.suppRecStat}}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<!-- <el-table-column label="负责人" align="center" prop="pic">-->
<!-- <template #default="scope">-->
<!-- <span>{{scope.row.pic}}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="字段标签" width="150" align="center" prop="fldClas">
<template #default="scope">
<el-popover v-for="item in scope.row.tempFldClas" placement="right" width="auto" trigger="hover">
<template #reference>
<el-tag v-if="item.clasEffFlag === '1'">{{item.clasName}}</el-tag>
</template>
<div>
<div style="margin: 5px" v-for="item in scope.row.showFldClas"><el-tag v-if="item.clasEffFlag === '1'">{{item.clasName + ":" + item.clasValue}}</el-tag></div>
</div>
</el-popover>
</template>
</el-table-column>
<!-- <el-table-column label="字段空值率" align="center" prop="fldNullRate">-->
<!-- <template #default="scope">-->
<!-- <span>{{scope.row.fldNullRate}}</span>-->
<!-- </template>-->
<!-- </el-table-column>-->
<el-table-column label="引用字典/标准" align="center" prop="dataDictName"></el-table-column>
<el-table-column label="安全等级" align="center" prop="dataSecLvl"></el-table-column>
<el-table-column label="更新时间" align="center" prop="suppUpdTime" width="180">
<template #default="scope">
<template v-if="scope.row.suppUpdTime && scope.row.suppUpdTime !== ''">
<span>{{scope.row.suppUpdTime.replace("T"," ")}}</span>
</template>
</template>
</el-table-column>
</el-table>
</div>
</el-tab-pane>
<el-tab-pane label="样例数据" name="demoData">
<div class="table-container">
<el-table :data="demoDataList" height="calc(100vh - 395px)">
<template v-for="item in columnList">
<el-table-column :label="(item.fldCnName && item.fldCnName.length>0)?item.fldCnName:((item.fldCrrctName && item.fldCrrctName.length>0)?item.fldCrrctName:item.fldEngName)" width="100" align="center" :prop="item.fldEngName"></el-table-column>
</template>
</el-table>
</div>
</el-tab-pane>
<el-tab-pane label="业务关系" name="businessRelation">
<div v-loading="loadingBusiness" v-if="activeColumnTab=== 'businessRelation'" style="height: calc(100vh - 395px);">
<div style="position: absolute;top:10px;left: 10px;z-index: 10">
<el-form>
<el-form-item label="关系选择:">
<el-radio-group v-model="businessOptionSelect" @change="changeBusinessOption">
<el-radio-button label="ER关系" value="er" />
<el-radio-button label="字段关系" value="op" />
</el-radio-group>
</el-form-item>
</el-form>
</div>
<div style="width: 100%;height: 100%">
<businss-relation :currentTable="currentMetaData" :data="businessRelation" :type="businessOptionSelect"></businss-relation>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="血缘关系" name="bloodRelation">
<div style="width: 100%;height: 100%">
<blood-relation v-if="activeColumnTab === 'bloodRelation'" :currentTable="currentMetaData" :data="bloodRelation"></blood-relation>
</div>
</el-tab-pane>
<el-tab-pane label="存储过程" name="proc">
<SQLCodeMirror v-if="activeColumnTab === 'proc'" :data="procStr" :dbType="dbType"></SQLCodeMirror>
</el-tab-pane>
</el-tabs>
</el-col>
</el-row>
</template>
</el-drawer>
<el-dialog
v-model="tableTagDialog"
title="配置标签分类"
width="1100"
>
<el-form :model="currentTableTag" :inline="true" label-width="75px">
<template v-for="item in currentTableTag.clasList">
<el-form-item :label="item.idxName + '级分类:'">
<el-input
v-model="item.clasName"
disabled
style="width: 240px"
/>
</el-form-item>
</template>
<el-row>
<el-form-item label="选择标签:">
<el-select
v-model="currentTableTag.clasOnum"
filterable
style="width: 240px"
@change="changeTableTag"
>
<el-option v-for="item in metaClasList" :key="item.clasOnum" :value="item.clasOnum" :label="item.clasOnum+' - '+item.clasName"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Plus" @click="addTableTag">新增</el-button>
</el-form-item>
</el-row>
</el-form>
<el-table v-loading="loading" :data="tableTags">
<el-table-column label="标签编号" width="80" align="center" prop="onum"></el-table-column>
<el-table-column label="标签名称" width="120" align="center" prop="clasName"></el-table-column>
<el-table-column label="标签值" width="170" align="center" prop="clasValue" >
<template #default="scope">
<el-input @input="changeTagValue(scope.row)" v-model="scope.row.clasValue" :disabled="scope.row.clasEffFlag !== '1'"></el-input>
</template>
</el-table-column>
<el-table-column label="标签值说明" width="170" align="center" prop="tagRemark">
<template #default="scope">
<el-input @input="changeTagValue(scope.row)" v-model="scope.row.tagRemark" :disabled="scope.row.clasEffFlag !== '1'"></el-input>
</template>
</el-table-column>
<el-table-column label="标签状态" align="center" prop="clasEffFlag">
<template #default="scope">
<span v-if="scope.row.clasEffFlag === '1'" style="color:#67C23A;">{{'有效'}}</span>
<span v-else style="color: #F56C6C">{{'已删除'}}</span>
</template>
</el-table-column>
<el-table-column label="设置方式" width="80" align="center" prop="tagSource">
<template #default="scope">
<span>{{scope.row.tagSource ? scope.row.tagSource:'自动'}}</span>
</template>
</el-table-column>
<el-table-column label="设置对象" width="80" align="center" prop="setUser"></el-table-column>
<el-table-column label="设置时间" width="150" align="center" prop="setTime"></el-table-column>
<el-table-column label="操作" align="center" width="80">
<template #default="scope">
<el-button v-if="scope.row.clasEffFlag === '1'" link type="danger" icon="Delete" @click.prevent="deleteTag(scope.row)">删除</el-button>
<el-button v-if="scope.row.clasEffFlag === '0'" link type="success" icon="RefreshLeft" @click.prevent="revertTag(scope.row)">恢复</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button @click="tableTagDialog = false">取消</el-button>
<el-button type="primary" @click="confirmTableTags">
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog
v-model="columnInfoDialog"
title="字段信息"
width="1100"
>
<el-form :model="currentColumnData" :inline="true" label-width="100px">
<el-form-item label="字段英文名">
<el-input disabled v-model="currentColumnData.fldEngName"></el-input>
</el-form-item>
<el-form-item label="字段中文名">
<el-input disabled v-model="currentColumnData.fldCnName"></el-input>
</el-form-item>
<el-form-item label="字段类型">
<el-input disabled v-model="currentColumnData.fldType"></el-input>
</el-form-item>
<el-form-item label="主键标志">
<template v-if="currentColumnData.pkFlag === 'Y'">
<el-input disabled :model-value="'是'"></el-input>
</template>
<template v-else>
<el-input disabled :model-value="'否'"></el-input>
</template>
</el-form-item>
<el-form-item label="是否必填">
<template v-if="currentColumnData.requireFlag === 'Y'">
<el-input disabled :model-value="'是'"></el-input>
</template>
<template v-else>
<el-input disabled :model-value="'否'"></el-input>
</template>
</el-form-item>
<el-form-item label="是否索引">
<template v-if="currentColumnData.idxFlag === 'Y'">
<el-input disabled :model-value="'是'"></el-input>
</template>
<template v-else>
<el-input disabled :model-value="'否'"></el-input>
</template>
</el-form-item>
<el-form-item label="字段补录名">
<el-input v-model="currentColumnData.fldCrrctName"></el-input>
</el-form-item>
<el-form-item label="补录字段描述">
<el-input v-model="currentColumnData.fldDesc"/>
</el-form-item>
<el-form-item label="补录主键">
<div style="width: 192px">
<el-switch v-model="currentColumnData.crrctPkFlag"/>
</div>
</el-form-item>
<!-- <el-form-item label="状态">-->
<!-- <el-input v-model="currentColumnData.suppRecStat"/>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="负责人">-->
<!-- <el-input v-model="currentColumnData.pic"/>-->
<!-- </el-form-item>-->
<!-- <el-form-item label="字段空值率">-->
<!-- <el-input v-model="currentColumnData.fldNullRate"/>-->
<!-- </el-form-item>-->
<el-form-item label="引用字典/标准">
<el-select
v-model="currentColumnData.dataDictId"
filterable
style="width: 192px"
placeholder="请输入关键词"
@change="changestdDict"
:loading="loading">
<el-option
v-for="item in stddictOptions"
:key="item.onum"
:label="item.dataDictCnName"
:value="item.onum">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="安全等级">
<el-select
v-model="currentColumnData.dataSecLvl"
filterable
style="width: 192px"
placeholder="请输入关键词"
:loading="loading">
<el-option
v-for="item in secLvlOptions"
:key="item.onum"
:label="item.secLevelSummary + ' - ' + item.secLevelName"
:value="item.secLevelSummary">
</el-option>
</el-select>
</el-form-item>
</el-form>
<el-form :model="currentColumnTag" :inline="true" label-width="100px">
<template v-for="item in currentColumnTag.clasList">
<el-form-item :label="item.idxName + '级分类:'">
<el-input
v-model="item.clasName"
disabled
/>
</el-form-item>
</template>
<el-form-item label="选择标签:">
<el-select
v-model="currentColumnTag.clasOnum"
filterable
style="width: 192px"
@change="changeColumnTag"
>
<el-option v-for="item in metaClasList" :key="item.clasOnum" :value="item.clasOnum" :label="item.clasOnum+' - '+item.clasName"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Plus" @click="addColumnTag">新增</el-button>
</el-form-item>
</el-form>
<el-table :data="currentColumnData.showFldClas">
<el-table-column label="标签编号" width="80" align="center" prop="onum"></el-table-column>
<el-table-column label="标签名称" width="120" align="center" prop="clasName"></el-table-column>
<el-table-column label="标签值" width="170" align="center" prop="clasValue" >
<template #default="scope">
<el-input :disabled="scope.row.clasEffFlag === '0'" @input="changeTagValue(scope.row)" v-model="scope.row.clasValue"></el-input>
</template>
</el-table-column>
<el-table-column label="标签值说明" width="170" align="center" prop="tagRemark">
<template #default="scope">
<el-input :disabled="scope.row.clasEffFlag === '0'" @input="changeTagValue(scope.row)" v-model="scope.row.tagRemark"></el-input>
</template>
</el-table-column>
<el-table-column label="标签状态" align="center" prop="clasEffFlag">
<template #default="scope">
<span>{{ (scope.row.clasEffFlag === '1')?'有效':'无效' }}</span>
</template>
</el-table-column>
<el-table-column label="设置方式" width="80" align="center" prop="tagSource">
<template #default="scope">
<span>{{scope.row.tagSource?scope.row.tagSource:'自动'}}</span>
</template>
</el-table-column>
<el-table-column label="设置对象" width="80" align="center" prop="setUser"></el-table-column>
<el-table-column label="设置时间" width="150" align="center" prop="setTime"></el-table-column>
<el-table-column label="操作" align="center" width="80">
<template #default="scope">
<el-button v-if="scope.row.clasEffFlag === '1'" link type="danger" icon="Delete" @click.prevent="deleteTag(scope.row)">删除</el-button>
<el-button v-if="scope.row.clasEffFlag === '0'" link type="success" icon="RefreshLeft" @click.prevent="revertTag(scope.row)">恢复</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button @click="columnInfoDialog = false">取消</el-button>
<el-button type="primary" @click="confirmColumn">
确定
</el-button>
</div>
</template>
</el-dialog>
<el-dialog
v-model="astPublish"
title="数据资产发布"
width="1400"
>
<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="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>
<el-table-column label="数据资产描述" align="center" prop="dataAstDesc">
<template #default="scope">
<el-input v-model="scope.row.dataAstDesc" ></el-input>
</template>
</el-table-column>
<el-table-column label="数据资产标签" align="center" prop="dataAstClas">
<template #default="scope">
<el-popover v-for="item in scope.row.tempTabClas" placement="right" width="auto" trigger="hover">
<template #reference>
<el-tag v-if="item.clasEffFlag && item.clasEffFlag === '1'">{{item.clasName}}</el-tag>
</template>
<div>
<div style="margin: 5px" v-for="item in scope.row.showTabClas"><el-tag v-if="item.clasEffFlag && item.clasEffFlag === '1'">{{item.clasName + ":" + item.clasValue}}</el-tag></div>
</div>
</el-popover>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="180">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click.prevent="editAstTab(scope.$index,scope.row)">编辑标签</el-button>
<el-button link type="danger" icon="Delete" @click.prevent="deleteAstData(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button @click="astPublish = false">取消</el-button>
<el-button type="primary" @click="confirmPublish">
发布
</el-button>
</div>
</template>
</el-dialog>
<el-dialog
v-model="astTagDialog"
title="配置标签分类"
width="1100"
>
<el-form :model="currentAstTag" :inline="true" label-width="75px">
<el-form-item label="一级分类:" prop="userName">
<el-input
v-model="currentAstTag.clasPriClas"
disabled
style="width: 240px"
/>
</el-form-item>
<el-form-item label="二级分类:">
<el-input
v-model="currentAstTag.clasScdClas"
disabled
style="width: 240px"
/>
</el-form-item>
<el-form-item label="三级分类:">
<el-input
v-model="currentAstTag.clasThreClas"
disabled
style="width: 240px"
></el-input>
</el-form-item>
<el-form-item label="选择标签:">
<el-select
v-model="currentAstTag.clasOnum"
filterable
style="width: 240px"
@change="changeAstTag"
>
<el-option v-for="item in metaClasList" :key="item.clasOnum" :value="item.clasOnum" :label="item.clasOnum+' - '+item.clasName"/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Plus" @click="addAstTag">新增</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="astTags">
<el-table-column label="标签编号" width="80" align="center" prop="onum"></el-table-column>
<el-table-column label="标签名称" width="120" align="center" prop="clasName"></el-table-column>
<el-table-column label="标签值" width="170" align="center" prop="clasValue" >
<template #default="scope">
<el-input @input="changeTagValue(scope.row)" v-model="scope.row.clasValue" :disabled="scope.row.clasEffFlag !== '1'"></el-input>
</template>
</el-table-column>
<el-table-column label="标签值说明" width="170" align="center" prop="tagRemark">
<template #default="scope">
<el-input @input="changeTagValue(scope.row)" v-model="scope.row.tagRemark" :disabled="scope.row.clasEffFlag !== '1'"></el-input>
</template>
</el-table-column>
<el-table-column label="标签状态" align="center" prop="clasEffFlag">
<template #default="scope">
<span v-if="scope.row.clasEffFlag === '1'" style="color:#67C23A;">{{'有效'}}</span>
<span v-else style="color: #F56C6C">{{'已删除'}}</span>
</template>
</el-table-column>
<el-table-column label="设置方式" width="80" align="center" prop="tagSource">
<template #default="scope">
<span>{{scope.row.tagSource ? scope.row.tagSource:'自动'}}</span>
</template>
</el-table-column>
<el-table-column label="设置对象" width="80" align="center" prop="setUser"></el-table-column>
<el-table-column label="设置时间" width="150" align="center" prop="setTime"></el-table-column>
<el-table-column label="操作" align="center" width="80">
<template #default="scope">
<el-button v-if="scope.row.clasEffFlag === '1'" link type="danger" icon="Delete" @click.prevent="deleteTag(scope.row)">删除</el-button>
<el-button v-if="scope.row.clasEffFlag === '0'" link type="success" icon="RefreshLeft" @click.prevent="revertTag(scope.row)">恢复</el-button>
</template>
</el-table-column>
</el-table>
<template #footer>
<div class="dialog-footer">
<el-button @click="astTagDialog = false">取消</el-button>
<el-button type="primary" @click="confirmAstTags">
确定
</el-button>
</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 + '?overWrite=' + upload.overWrite"
: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>仅允许导入xls、xlsx格式文件。</span>
<el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div>
</template>
</el-upload>
<el-form>
<el-form-item>
<template #label>
开启覆盖
<el-tooltip
class="box-item"
effect="dark"
placement="right"
>
<template #content>
<div>打开“开启覆盖”则原补录信息会被模板中未填信息覆盖为空值。<br>
关闭“开启覆盖”则模板中留空数据不会影响原补录信息
</div>
</template>
<el-link :underline="false" type="primary"><i class="ri-question-line"></i></el-link>
</el-tooltip>
</template>
<el-switch v-model="upload.overWrite"></el-switch>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" :disabled="upload.isUploading" @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-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">
<el-button type="primary" @click="upload.showResult = false">确 定</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="Meta">
import {getDataSourceList, getMetaDataList, getColumnList, getMetaClasList, postMetaSupp, getMetaDataRelship, getMetaDataBloodRelship, getProcData, runBloodAnalysis, publishAstData} from "@/api/meta/metaInfo"
import { getMetaSecurityData } from "@/api/dataAsset/directory"
import { listStdDictNoPage } from "@/api/datastd/std.js"
import { ref, nextTick, computed, watch, reactive, onMounted } from 'vue'
import SQLCodeMirror from "@/components/codemirror/SQLCodeMirror.vue";
import cache from "@/plugins/cache";
import BusinssRelation from "./businssRelation.vue";
import BloodRelation from "./bloodRelation.vue";
import {listMetadataSecOptions} from "@/api/metadataConfig/metadataConfig.js";
import {getToken} from "@/utils/auth.js";
import {getDirectoryTree} from "@/api/metadataConfig/directory.js";
const data = reactive({
queryParams:{
ssysId:'',
mdlName:'',
tabName:'',
colName:'',
tabType:'',
tagName:'',
recStat:'',
pageNum:1,
pageSize:10
},
currentMetaData: {
tabEngName:'',
tabCnName:'',
ssysCd:'',
ssysId:-1,
mdlName:'',
tabCrrctName:'',
tabDesc:'',
govFlag:null,
pic:'',
tags:[]
}
})
const { queryParams, currentMetaData } = toRefs(data);
const loading = ref(true);
const drawer = ref(false);
const dataList = ref([]);
const columnList = ref([]);
const tableTagDialog = ref(false);
const metaClasList = ref([]);
const columnInfoDialog = ref(false);
const currentColumnData = ref({});
const loadingBusiness = ref(false);
const currentTableTag = ref({
"clasOnum": null,
"clasName": "",
"recSubmPrsn": "",
"clasList":[]
});
const currentColumnTag = ref({
"clasOnum": null,
"clasName": "",
"recSubmPrsn": "",
"clasList":[]
});
const columnParam = ref({
total:0,
pageNum:1,
pageSize:10
});
const total = ref(0);
const databaseList = ref([]);
const tableTags = ref([]);
const database = ref("");
const procStr = ref("");
const procId = ref(-1);
const activeColumnTab = ref("column");
const businessOptionSelect = ref("er");
const { proxy } = getCurrentInstance();
const changedColumns = ref([])
const businessRelation = ref([])
const bloodRelation = ref([])
const demoDataList = ref([])
const dbType = ref("MYSQL")
const selectedRows = ref([])
const dataAstList= ref([])
const astPublish = ref(false)
const astTagDialog = ref(false)
const astTags = ref([])
const currentAstTag = ref({
"index":-1,
"clasThreClas": "",
"clasOnum": null,
"clasName": "",
"recSubmPrsn": "",
"clasPriClas": "",
"clasScdClas": ""
});
const stddictOptions = ref([])
const secLvlOptions = ref([])
const directoryTree = ref([])
/*** 导入参数 */
const upload = reactive({
// 是否显示弹出层(导入)
open: false,
// 弹出层标题(导入)
title: "",
// 是否禁用上传
isUploading: false,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
overWrite: false,
// 上传的地址
url: import.meta.env.VITE_APP_BASE_API + "/dasset/meta/importData",
showResult: false,
resultMsg: {}
});
function changeColumnTab(){
if (activeColumnTab.value === 'businessRelation'){
changeBusinessOption()
}
if (activeColumnTab.value === 'demoData'){
generateDemoData()
}
if (activeColumnTab.value === 'bloodRelation'){
changeBloodOption()
}
}
function changestdDict(val){
for (let i = 0; i < stddictOptions.value.length; i++) {
if (val === stddictOptions.value[i].onum){
currentColumnData.value.dataDictName = stddictOptions.value[i].dataDictCnName
}
}
}
function remoteStddict(){
let param = {ssysCd:currentMetaData.value.ssysId + ""}
listStdDictNoPage(param).then(res=>{
stddictOptions.value = res.data
})
}
function remoteSecLvl(){
listMetadataSecOptions().then(res=>{
secLvlOptions.value = res.data
})
}
function generateDemoData(){
demoDataList.value = []
let param ={
dataAstSrc: currentMetaData.value.ssysCd,
dataAstEngName:currentMetaData.value.mdlName+"."+currentMetaData.value.tabEngName
}
getMetaSecurityData(param).then(res=>{
demoDataList.value = res.data.data
})
}
function changeBusinessOption(){
loadingBusiness.value = true;
let data = {
ssysId: currentMetaData.value.ssysId,
mdlName: currentMetaData.value.mdlName,
tabEngName: currentMetaData.value.tabEngName,
type: businessOptionSelect.value
}
getMetaDataRelship(data).then(res=>{
businessRelation.value = res.data
loadingBusiness.value = false;
})
}
function changeBloodOption(){
if (procId.value === -1){
proxy.$modal.msgWarning("此表暂无血缘,请执行存储过程跑批任务后查看");
bloodRelation.value = {}
}else {
getMetaDataBloodRelship(procId.value).then(res=>{
bloodRelation.value = res.data
})
}
}
function confirmTableTags(){
currentMetaData.value.tags = JSON.parse(JSON.stringify(tableTags.value))
tableTagDialog.value = false
}
function confirmAstTags(){
dataAstList.value[currentAstTag.value.index].dataAstClas = JSON.parse(JSON.stringify(astTags.value))
let tempTabClas = []
if (astTags.value.length>0){
for (let j = 0; j < astTags.value.length; j++) {
if (tempTabClas.length > 0){
let hasClas = false
for (let k = 0; k < tempTabClas.length; k++) {
if (tempTabClas[k].clasPriClas === astTags.value[j].clasPriClas
&& tempTabClas[k].clasScdClas === astTags.value[j].clasScdClas
&& tempTabClas[k].clasThreClas === astTags.value[j].clasThreClas){
hasClas = true
}
}
if (hasClas){
break
}else {
if (astTags.value[j].clasEffFlag === '1'){
tempTabClas.push(astTags.value[j])
}
}
}else {
if (astTags.value[j].clasEffFlag === '1') {
tempTabClas.push(astTags.value[j])
}
}
}
}
dataAstList.value[currentAstTag.value.index].showTabClas = astTags.value
dataAstList.value[currentAstTag.value.index].tempTabClas = tempTabClas
dataAstList.value[currentAstTag.value.index].dataAstClas = JSON.stringify(astTags.value)
astTagDialog.value = false
}
function confirmColumn(){
let changed = false
for (let i = 0; i < columnList.value.length; i++) {
if (columnList.value[i].fldEngName === currentColumnData.value.fldEngName){
if (columnList.value[i].fldCrrctName !== currentColumnData.value.fldCrrctName){
columnList.value[i].fldCrrctName = currentColumnData.value.fldCrrctName
changed = true
}
if (columnList.value[i].fldDesc !== currentColumnData.value.fldDesc){
columnList.value[i].fldDesc = currentColumnData.value.fldDesc
changed = true
}
if (columnList.value[i].crrctPkFlag !== currentColumnData.value.crrctPkFlag){
columnList.value[i].crrctPkFlag = currentColumnData.value.crrctPkFlag
changed = true
}
// if (columnList.value[i].suppRecStat !== currentColumnData.value.suppRecStat){
// columnList.value[i].suppRecStat = currentColumnData.value.suppRecStat
// }
// if (columnList.value[i].pic !== currentColumnData.value.pic){
// columnList.value[i].pic = currentColumnData.value.pic
// changed = true
// }
// if (columnList.value[i].fldNullRate !== currentColumnData.value.fldNullRate){
// columnList.value[i].fldNullRate = currentColumnData.value.fldNullRate
// changed = true
// }
if (columnList.value[i].dataDictId !== currentColumnData.value.dataDictId){
columnList.value[i].dataDictId = currentColumnData.value.dataDictId
columnList.value[i].dataDictName = currentColumnData.value.dataDictName
changed = true
}
if (columnList.value[i].dataSecLvl !== currentColumnData.value.dataSecLvl){
columnList.value[i].dataSecLvl = currentColumnData.value.dataSecLvl
changed = true
}
if (currentColumnData.value.showFldClas && currentColumnData.value.showFldClas.length > 0){
let showFldClas = currentColumnData.value.showFldClas
let fldClas = []
for (let j = 0; j < showFldClas.length; j++) {
let col = showFldClas[j]
if (col.clasEffFlag === '0'){ // 无效
fldClas.push(col)
}else{ // 有效
if (col.tagSource === '手动'){
fldClas.push(col)
}
}
}
if (columnList.value[i].fldClas && columnList.value[i].fldClas !== '[]'){
if (JSON.stringify(fldClas) !== columnList.value[i].fldClas){
columnList.value[i].fldClas = JSON.stringify(fldClas)
changed = true
}
}else {
if (fldClas.length !== 0){
columnList.value[i].fldClas = JSON.stringify(fldClas)
changed = true
}
}
let batchFldClas = columnList.value[i].batchFldClas
if (fldClas.length > 0){
for (let j = 0; j < fldClas.length; j++) {
for (let k = 0; k < batchFldClas.length; k++) {
if (batchFldClas[k].clasPriClas === fldClas[j].clasPriClas
&& batchFldClas[k].clasScdClas === fldClas[j].clasScdClas
&& batchFldClas[k].clasThreClas === fldClas[j].clasThreClas
&& batchFldClas[k].clasName === fldClas[j].clasName
){
batchFldClas[k] = fldClas[j]
}
}
}
}
let tempFldClas = []
if (batchFldClas && batchFldClas.length>0){
for (let j = 0; j < batchFldClas.length; j++) {
if (tempFldClas.length > 0){
let hasClas = false
for (let k = 0; k < tempFldClas.length; k++) {
if (tempFldClas[k].clasPriClas === batchFldClas[j].clasPriClas
&& tempFldClas[k].clasScdClas === batchFldClas[j].clasScdClas
&& tempFldClas[k].clasThreClas === batchFldClas[j].clasThreClas
){
hasClas = true
}
}
if (hasClas){
break
}else {
if (batchFldClas[j].clasEffFlag === '1'){
tempFldClas.push(batchFldClas[j])
}
}
}else {
if (batchFldClas[j].clasEffFlag === '1'){
tempFldClas.push(batchFldClas[j])
}
}
}
}
columnList.value[i].showFldClas = batchFldClas
columnList.value[i].tempFldClas = tempFldClas
}
}
}
columnInfoDialog.value = false
if (changed){
if (changedColumns.value.length>0){
let hasCol = false
for (let i = 0; i < changedColumns.value.length; i++) {
if (changedColumns.value[i].fldEngName === currentColumnData.value.fldEngName){
changedColumns.value[i] = currentColumnData.value
hasCol = true
}
}
if (!hasCol){
changedColumns.value.push(currentColumnData.value)
}
}else{
changedColumns.value.push(currentColumnData.value)
}
}
}
function addTableTag(){
let json = JSON.parse(JSON.stringify(currentTableTag.value))
if (json.clasOnum !== null){
tableTags.value.push({
onum: json.clasOnum,
clasName: json.clasName,
clasValue: '',
tagRemark:'',
clasEffFlag:'1',
tagSource:'手工',
setUser: cache.local.get("username"),
setTime: getNowDateTime()
})
} else {
proxy.$modal.msgWarning("请选择一个标签");
}
}
function addAstTag(){
let json = JSON.parse(JSON.stringify(currentAstTag.value))
if (json.clasOnum !== null){
astTags.value.push({
onum: json.clasOnum,
clasName: json.clasName,
clasValue: '',
tagRemark:'',
clasEffFlag:'1',
tagSource:'手工',
setUser: cache.local.get("username"),
setTime: getNowDateTime()
})
} else {
proxy.$modal.msgWarning("请选择一个标签");
}
}
function addColumnTag(){
let json = JSON.parse(JSON.stringify(currentColumnTag.value))
if (json.clasOnum !== null){
currentColumnData.value.showFldClas.push({
onum: json.clasOnum,
clasName: json.clasName,
clasValue: '',
tagRemark:'',
clasEffFlag:'1',
tagSource:'手工',
setUser: cache.local.get("username"),
setTime: getNowDateTime()
})
} else {
proxy.$modal.msgWarning("请选择一个标签");
}
}
function getNowDateTime(){
const now = new Date();
const year = now.getFullYear();
const month = String(now.getMonth() + 1).padStart(2, '0');
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}
function deleteTag(row){
row.clasEffFlag = '0'
row.tagSource = '手动'
}
function revertTag(row){
row.clasEffFlag = '1'
row.tagSource = '手动'
}
function changeTagValue(row){
row.tagSource = '手动'
}
function changeTableTag(){
if (typeof currentTableTag.value.clasOnum !== null){
for (let i = 0; i <metaClasList.value.length; i++) {
let item = metaClasList.value[i]
if (item.clasOnum === currentTableTag.value.clasOnum){
currentTableTag.value = item
}
}
currentTableTag.value.clasList = []
let array = findFullPathNames(currentTableTag.value.beltBatchContent)
if (array && array.length>0){
const index = array.indexOf("表标签");
let arr = index !== -1 ? array.slice(index + 1) : [];
let numberMap = {
1: '一',
2: '二',
3: '三',
4: '四',
5: '五',
6: '六',
7: '七',
8: '八',
9: '九',
10: '十'
};
if (arr.length > 0){
for (let i = 0; i < arr.length; i++) {
currentTableTag.value.clasList.push({idxName: numberMap[i+1], clasName: arr[i]})
}
}
}
}
}
function changeAstTag(){
if (typeof currentAstTag.value.clasOnum !== null){
for (let i = 0; i <metaClasList.value.length; i++) {
let item = metaClasList.value[i]
if (item.clasOnum === currentAstTag.value.clasOnum){
let index = currentAstTag.value.index
currentAstTag.value = item
currentAstTag.value.index = index
}
}
}
}
function changeColumnTag(){
if (typeof currentColumnTag.value.clasOnum !== null){
for (let i = 0; i <metaClasList.value.length; i++) {
let item = metaClasList.value[i]
if (item.clasOnum === currentColumnTag.value.clasOnum){
currentColumnTag.value = item
}
}
currentColumnTag.value.clasList = []
let array = findFullPathNames(currentColumnTag.value.beltBatchContent)
if (array && array.length>0){
const index = array.indexOf("字段标签");
let arr = index !== -1 ? array.slice(index + 1) : [];
let numberMap = {
1: '一',
2: '二',
3: '三',
4: '四',
5: '五',
6: '六',
7: '七',
8: '八',
9: '九',
10: '十'
};
if (arr.length > 0){
for (let i = 0; i < arr.length; i++) {
currentColumnTag.value.clasList.push({idxName: numberMap[i+1], clasName: arr[i]})
}
}
}
}
}
function handleTableTagClose(index){
currentMetaData.value.tags[index].clasEffFlag = '0'
// for (let i = 0; i < currentMetaData.value.tags.length; i++) {
// if (tag.tagName === currentMetaData.value.tags[i].tagName && tag.tagValue === currentMetaData.value.tags[i].tagValue){
// currentMetaData.value.tags.splice(i, 1);
// }
// }
}
function openTableTagsDialog(){
tableTagDialog.value = true
currentTableTag.value = {
"clasThreClas": "",
"clasOnum": null,
"clasName": "",
"recSubmPrsn": "",
"clasPriClas": "",
"clasScdClas": ""
}
tableTags.value = JSON.parse(JSON.stringify(currentMetaData.value.tags))
getMetaClasList().then(res=>{
metaClasList.value = res.data
})
}
function openEditColumnDialog(row,index){
columnInfoDialog.value = true
currentColumnData.value = JSON.parse(JSON.stringify(row))
currentColumnTag.value = {
"clasThreClas": "",
"clasOnum": null,
"clasName": "",
"recSubmPrsn": "",
"clasPriClas": "",
"clasScdClas": ""
}
currentColumnData.value.showFldClas = JSON.parse(JSON.stringify(row.showFldClas))
getMetaClasList().then(res=>{
metaClasList.value = res.data
})
remoteStddict()
remoteSecLvl()
}
function showColumnDialog(row) {
columnList.value = []
let tableData = JSON.parse(JSON.stringify(row))
currentMetaData.value = {
tabEngName: tableData.tabEngName,
tabCnName: tableData.tabCnName,
ssysCd: tableData.ssysCd,
ssysId: tableData.ssysId,
mdlName:tableData.mdlName,
tabCrrctName:tableData.tabCrrctName,
tabDesc:tableData.tabDesc,
govFlag:tableData.govFlag,
pic:tableData.pic,
tags: tableData.showTabClas
}
let columnData = {
tabName: row.tabEngName,
ssysId: row.ssysId,
mdlName: row.mdlName
}
getColumnList(columnData).then(res=>{
columnList.value = res.data
if (columnList.value.length>0){
for (let i = 0; i < columnList.value.length; i++) {
let batchFldClas = columnList.value[i].batchFldClas
let fldClas =[]
if (columnList.value[i].fldClas && columnList.value[i].fldClas !== '[]'){
fldClas = JSON.parse(columnList.value[i].fldClas)
}
if (fldClas.length > 0){
for (let j = 0; j < fldClas.length; j++) {
for (let k = 0; k < batchFldClas.length; k++) {
if (batchFldClas[k].clasPriClas === fldClas[j].clasPriClas
&& batchFldClas[k].clasScdClas === fldClas[j].clasScdClas
&& batchFldClas[k].clasThreClas === fldClas[j].clasThreClas
&& batchFldClas[k].clasName === fldClas[j].clasName
){
batchFldClas[k] = fldClas[j]
}
}
}
}
let tempFldClas = []
if (batchFldClas && batchFldClas.length>0){
for (let j = 0; j < batchFldClas.length; j++) {
if (tempFldClas.length > 0){
let hasClas = false
for (let k = 0; k < tempFldClas.length; k++) {
if (tempFldClas[k].clasPriClas === batchFldClas[j].clasPriClas
&& tempFldClas[k].clasScdClas === batchFldClas[j].clasScdClas
&& tempFldClas[k].clasThreClas === batchFldClas[j].clasThreClas){
hasClas = true
}
}
if (hasClas){
break
}else {
if (batchFldClas[j].clasEffFlag === '1'){
tempFldClas.push(batchFldClas[j])
}
}
}else {
if (batchFldClas[j].clasEffFlag === '1') {
tempFldClas.push(batchFldClas[j])
}
}
}
}
columnList.value[i].showFldClas = batchFldClas
columnList.value[i].tempFldClas = tempFldClas
}
}
})
activeColumnTab.value = 'column'
drawer.value = true
changedColumns.value = []
let param = {
ssysId: currentMetaData.value.ssysId,
mdlName: currentMetaData.value.mdlName,
tabEngName: currentMetaData.value.tabEngName
}
getProcData(param).then(res=>{
if(res.data.length >0){
let dbList = databaseList.value[0].children;
for (let i = 0; i < dbList.length; i++) {
if (currentMetaData.value.ssysId === dbList[i].id){
dbType.value = dbList[i].type
}
}
procStr.value = res.data[0].proc_text+""
procId.value = res.data[0].onum
}else {
procStr.value = "--暂无存储过程,等待解析任务完成后再行查询"
procId.value = -1;
}
})
getDirectoryTree({pageSize: 999}).then(res => {
directoryTree.value = res.rows
})
}
function findFullPathNames(targetId) {
function dfs(node, path = []) {
// 创建新路径数组避免引用污染
const currentPath = [...path, node.contentName];
// 检查当前节点是否为目标
if (node.contentOnum === targetId) {
return currentPath;
}
// 递归搜索子节点
if (node.children?.length > 0) {
for (const child of node.children) {
const result = dfs(child, currentPath);
if (result) return result;
}
}
return null;
}
return dfs(directoryTree.value[0],[])
}
function getDatabaseList() {
let query = {
userName:cache.local.get("username"),
password:cache.local.get("password")
}
getDataSourceList(query).then(res=>{
databaseList.value = [{ id: -1, name: "数据源", parentId: 0, children: res.data.totalList.map(element => ({ ...element, parentId: -1 })) }]
})
}
function handleQuery(){
queryParams.value.pageNum = 1;
getList()
}
function resetQuery(){
queryParams.value ={
ssysId:'',
mdlName:'',
tabName:'',
colName:'',
tabType:'',
tagName:'',
recStat:'',
pageNum:1,
pageSize:10
}
proxy.$refs.databaseTreeRef.setCurrentKey(null);
handleQuery()
}
function handleSelection(selection, row){
const isSelected = selection.some(item => item.extractOnum === row.extractOnum);
if (isSelected) {
// 选中行:添加到全局数组(避免重复)
if (!selectedRows.value.some(item => item.extractOnum === row.extractOnum)) {
selectedRows.value.push(row);
}
} else {
// 取消选中:从全局数组移除
selectedRows.value = selectedRows.value.filter(item => item.extractOnum !== row.extractOnum);
}
}
function handleSelectionAll(selection) {
if (selection.length > 0) {
// 全选:将当前页所有行添加到全局数组(去重)
const newSelected = [selectedRows.value];
dataList.value.forEach(row => {
if (!newSelected.some(item => item.extractOnum === row.extractOnum)) {
newSelected.push(row);
}
});
selectedRows.value = newSelected;
} else {
// 取消全选:移除当前页所有行
dataList.value.forEach(row => {
selectedRows.value = selectedRows.value.filter(item => item.extractOnum !== row.extractOnum)
})
}
}
function getList(){
getMetaDataList(queryParams.value).then(res=>{
dataList.value = res.data.rows
let dbList = databaseList.value[0].children
if (dataList.value.length>0){
for (let i = 0; i < dataList.value.length; i++) {
for (let j = 0; j < dbList.length; j++) {
if (dataList.value[i].ssysId === dbList[j].id){
dataList.value[i].ssysCd = dbList[j].name
}
}
let batchTabClas = dataList.value[i].batchTabClas
let tabClas =[]
if (dataList.value[i].tabClas && dataList.value[i].tabClas !== '[]'){
tabClas = JSON.parse(dataList.value[i].tabClas)
}
if (tabClas.length > 0){
for (let j = 0; j < tabClas.length; j++) {
for (let k = 0; k < batchTabClas.length; k++) {
if (batchTabClas[k].clasPriClas === tabClas[j].clasPriClas
&& batchTabClas[k].clasScdClas === tabClas[j].clasScdClas
&& batchTabClas[k].clasThreClas === tabClas[j].clasThreClas
&& batchTabClas[k].clasName === tabClas[j].clasName
){
batchTabClas[k] = tabClas[j]
}
}
}
}
let tempTabClas = []
if (batchTabClas && batchTabClas.length>0){
for (let j = 0; j < batchTabClas.length; j++) {
if (tempTabClas.length > 0){
let hasClas = false
for (let k = 0; k < tempTabClas.length; k++) {
if (tempTabClas[k].clasPriClas === batchTabClas[j].clasPriClas
&& tempTabClas[k].clasScdClas === batchTabClas[j].clasScdClas
&& tempTabClas[k].clasThreClas === batchTabClas[j].clasThreClas){
hasClas = true
}
}
if (hasClas){
break
}else {
if (batchTabClas[j].clasEffFlag === '1'){
tempTabClas.push(batchTabClas[j])
}
}
}else {
if (batchTabClas[j].clasEffFlag === '1') {
tempTabClas.push(batchTabClas[j])
}
}
}
}
dataList.value[i].showTabClas = batchTabClas
dataList.value[i].tempTabClas = tempTabClas
}
}
loading.value = false
total.value = res.data.total
proxy.$nextTick(() => {
// 恢复当前页的选中状态
dataList.value.forEach(row => {
const isSelected =selectedRows.value.some(item => item.extractOnum === row.extractOnum);
proxy.$refs.metaTable.toggleRowSelection(row, isSelected);
});
});
})
}
async function runBloodAnalysisTask() {
let query = {
userName: cache.local.get("username"),
password: cache.local.get("password")
}
let response = await runBloodAnalysis(query)
proxy.$modal.msgSuccess(response.data);
}
function confirmPublish(){
let data = dataAstList.value
data.forEach(dataAst =>{
delete dataAst.showDataAstSrc
})
publishAstData({assetItems:data}).then(res=>{
proxy.$modal.msgSuccess("发布成功,已提交审批")
// proxy.$modal.msgSuccess(res.msg)
astPublish.value = false
})
}
function deleteAstData(row){
const index = dataAstList.value.findIndex(item => item.astNo === row.astNo);
dataAstList.value.splice(index,1)
}
function editAstTab(index,row) {
astTagDialog.value = true
astTags.value = JSON.parse(JSON.stringify(row.showTabClas))
currentAstTag.value = {
"index": index,
"clasThreClas": "",
"clasOnum": null,
"clasName": "",
"recSubmPrsn": "",
"clasPriClas": "",
"clasScdClas": ""
}
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);
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
}
getList();
}
function applyDataAst(){
if(selectedRows.value.length === 0){
proxy.$modal.msgWarning("请至少选择一条元数据进行发布")
}else{
dataAstList.value = []
selectedRows.value.forEach( row =>{
dataAstList.value.push({
dataAstEngName: row.tabEngName,
dataAstCnName: row.tabCnName?row.tabCnName:row.tabCrrctName,
dataAstType: row.tabType,
dataAstStat: '1',
dataAstDesc:'',
dataAstSrc: row.ssysId,
showDataAstSrc: row.ssysCd,
astNo: row.extractOnum,
dataAstClas: JSON.stringify(row.batchTabClas),
showTabClas: row.showTabClas,
tempTabClas: row.tempTabClas
})
})
astPublish.value = true
}
}
const filterNode = (value, data) => {
if (!value) return true;
return data.name.indexOf(value) !== -1;
}
function handleNodeClick(data) {
queryParams.value.ssysId = data.id;
handleQuery();
}
watch(database, val => {
proxy.$refs["databaseTreeRef"].filter(val);
});
function submit(){
let data = {
ssysId: currentMetaData.value.ssysId,
mdlName: currentMetaData.value.mdlName,
tabEngName: currentMetaData.value.tabEngName,
tabCrrctName: currentMetaData.value.tabCrrctName,
tabDesc: currentMetaData.value.tabDesc,
pic: currentMetaData.value.pic,
govFlag: currentMetaData.value.govFlag,
tabClas: JSON.stringify(currentMetaData.value.tags),
columnInfo: []
}
if (changedColumns.value.length > 0){
for (let i = 0; i < changedColumns.value.length; i++) {
let column = changedColumns.value[i]
data.columnInfo.push({
fldEngName: column.fldEngName,
fldCrrctName: column.fldCrrctName,
crrctPkFlag: column.crrctPkFlag,
fldDesc: column.fldDesc,
pic: column.pic,
fldClas: JSON.stringify(column.showFldClas),
// fldNullRate: column.fldNullRate,
dataDictId: column.dataDictId,
dataSecLvl: column.dataSecLvl,
recStat: column.recStat
})
}
}
postMetaSupp(data).then(res=>{
proxy.$modal.msgSuccess("操作成功");
drawer.value = false
getList()
})
}
function cancel(){
drawer.value = false
}
onMounted(async () => {
await getDatabaseList()
handleQuery()
})
</script>
<style scoped lang="scss">
:deep(.el-drawer__header) {
margin-bottom: 0 !important;
}
.full-height-tabs {
height: calc(100vh - 320px);
}
:deep(.el-tabs__content) {
height: 100%;
overflow: auto;
}
.table-container {
height: 100%;
overflow: auto;
}
</style>