7daf9d9d by xukangle

Merge branch 'develop' into dev_20241202_xukangle

2 parents ae2ab82f b4f46b1b
This diff could not be displayed because it is too large.
......@@ -76,7 +76,7 @@ export const updateRuleBizState = (params) => request({
/** 获取数据库表列表 */
export const getDatabase = (params) => request({
url: `${import.meta.env.VITE_APP_API_BASEURL}/data-source/get-source-list`,
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/get-source-list`,
method: 'post',
data: params
})
......@@ -138,23 +138,20 @@ export const getRuleTypeList = () => request({
// 获取规则大类的接口
export const getLargeCategoryList = () => request({
url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
method: 'post',
data: { paramCode: "LARGE-CATEGORY" }
url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType?dictType=${'规则大类'}`,
method: 'get',
})
// 获取规则小类的接口
export const getSmallCategoryList = () => request({
url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
method: 'post',
data: { paramCode: "SMALL-CATEGORY" }
url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType?dictType=${'规则小类'}`,
method: 'get',
})
// 获取规范性检验规则。
export const getCheckRulesList = () => request({
url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
method: 'post',
data: { paramCode: "REGULAR_RULE" }
url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType?dictType=${'正则校验'}`,
method: 'get',
})
// 根据规则guid获取规则的详情信息。
......
......@@ -23,6 +23,7 @@ export const parseAndDecodeUrl = (url:string) => {
// 返回去掉主机信息和开头斜杠后的解码部分以及最后一个斜杠后面的内容
return {
fileName: pathname,
decodedPath: pathname + search + hash,
lastPart: lastPart
};
......
......@@ -27,9 +27,8 @@ export const refreshToken = (params) => {
export const getSystemMenu = (params) => {
return request({
url: `${
import.meta.env.VITE_APP_AUTH_URL
}/product-menu-permission/tenant/get-product-menu?tenantGuid=${params.tenantGuid}&platformSystemGuid=32774fcfdf5e43e8b866660374d8bced`,
url: `${import.meta.env.VITE_APP_AUTH_URL
}/product-menu-permission/tenant/get-product-menu?tenantGuid=${params.tenantGuid}&platformSystemGuid=32774fcfdf5e43e8b866660374d8bced`,
method: "get",
});
};
......@@ -130,7 +129,7 @@ export const getServiceTenants = (params) => request({
})
/** 获取会员的附件模板 */
export const getTenantAttach = (params) => request({
export const getTenantAttach = (params) => request({
url: `${import.meta.env.VITE_APP_API_BASEURL}/attachment-template/list-attachment?tenantGuid=${params}`,
method: 'get'
})
......@@ -152,7 +151,7 @@ export const resetUserPwd = (params) => request({
/** ----------------- 消息管理 ------------------- */
/** 获取所有的消息列表 */
export const getAllMessageList = (params) => request({
export const getAllMessageList = (params) => request({
url: `${import.meta.env.VITE_API_MESSAGE}/message/data/get-message-list`,
method: 'post',
data: params
......@@ -217,3 +216,62 @@ export const exportDictionary = (params) => request({
data: params,
responseType: 'blob'
})
/**
* 数据源管理
**/
// 分页查询
export const getDataSourceList = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/list`,
method: "post",
data: params,
});
// 获取数据源列表
export const getDataSource = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/get-source-list`,
method: "post",
data: params,
});
// 新增
export const addDataSource = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/save`,
method: "post",
data: params,
});
// 删除
export const deleteDataSource = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/delete`,
method: "delete",
data: params,
});
// 修改
export const updateDataSource = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/update`,
method: "put",
data: params,
});
// 查看数据源详情
export const getDataSourceDetail = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/detail/${params}`,
method: "get",
});
// 连通检测
export const checkDataSourceConnect = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/check-connect`,
method: "post",
params,
});
// 连接测试
export const checkDataSourceConnectTest = (params) => request({
url: `${import.meta.env.VITE_APP_DATA_SOURCE_URL}/data-source/check-connect-test`,
method: "post",
data: params,
});
// 获取所有参数列表
export const getAllFlowData = (params) => request({
url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType`,
method: 'get',
params
})
......
......@@ -337,7 +337,8 @@ const handlePictureCardPreview = (file, item) => {
const onUploadFilePreview = async (file, item) => {
let f = formInline.value[item.field].find(i => i.name == file.name);
let url = f.url;
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(url).decodedPath);
let fileName: string = parseAndDecodeUrl(url).fileName;
const refSignInfo: any = await getDownFileSignByUrl(fileName);
if (!refSignInfo?.data) {
refSignInfo?.msg && ElMessage.error(refSignInfo?.msg);
return;
......@@ -360,7 +361,7 @@ const onUploadFilePreview = async (file, item) => {
}
const downloadTemplate = async (url) => {
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(url).decodedPath);
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(url).fileName);
if (!refSignInfo?.data) {
refSignInfo?.msg && ElMessage.error(refSignInfo?.msg);
return;
......@@ -379,7 +380,7 @@ const downloadTemplate = async (url) => {
const onUploadFileDownload = async (file, item) => {
let url = file.url;
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(url).decodedPath);
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(url).fileName);
if (!refSignInfo?.data) {
refSignInfo?.msg && ElMessage.error(refSignInfo?.msg);
return;
......
......@@ -63,7 +63,7 @@ const routes: RouteRecordRaw[] = [
to.meta.title = `${to.query.name}-${to.query.status == 'Y'?'查看结果':'结果确认'}`;
to.meta.editPage = to.query.status == 'Y'? false: true;
} else {
to.meta.title = `${to.query.name}-${to.query.type == 'confirm'?'结果确认':'结果修改'}`;
to.meta.title = `${to.query.name}-${to.query.status == 'Y'?'结果修改':'结果确认'}`;
to.meta.editPage = true;
}
}
......@@ -282,6 +282,27 @@ const routes: RouteRecordRaw[] = [
},
],
},
{
path: '/data-inventory/data-source',
component: Layout,
meta: {
title: '数据源管理',
icon: 'sidebar-videos',
},
children: [
{
path: '',
name: 'dataSource',
component: () => import('@/views/data_inventory/dataSource.vue'),
meta: {
title: '数据源管理',
sidebar: false,
breadcrumb: false,
cache: true
},
},
],
},
]
export default routes
......
......@@ -9,6 +9,7 @@ import { ElMessage, ElMessageBox } from 'element-plus';
import { useRouter, useRoute } from "vue-router";
import { MoreFilled } from "@element-plus/icons-vue";
import {
changeNum,
tagMethod,
tagType,
} from "@/utils/common";
......@@ -34,6 +35,13 @@ const route = useRoute();
const { proxy } = getCurrentInstance() as any;
const path = route.path;
const loading = ref(false);
const defaultItemLogo = new URL('@/assets/images/home-finance-product.png', import.meta.url).href
const demandListData: any = ref([
{ companyName: '北数所', listedNum: 16, processNum: 1235 },
{ companyName: '深数所', listedNum: 16, processNum: 1235 },
{ companyName: '苏数所', listedNum: 16, processNum: 1235 },
]);
const searchItemList = ref([
{
type: "input",
......@@ -167,6 +175,9 @@ const getTableBtns = (row, includeDetail = true) => {
const currTableData: any = ref({});
const btnClick = (btn) => {
}
const tableBtnClick = (scope, btn) => {
const type = btn.value;
const row = scope.row;
......@@ -486,73 +497,100 @@ const createBtnVisible = computed(() => {
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'register-data-search'" @search="toSearch" />
<div class="tools_btns">
<el-button type="primary" @click="handleCreate" v-if="createBtnVisible" v-preReClick>新建</el-button>
<div class="view-change">
<div class="list-btn" :class="[activeListType === 'list' ? 'active' : '']" @click="activeListType = 'list'">
<el-icon style="width: 12px;height: 12px;">
<svg-icon style="width: 12px;height: 12px;"
:name="activeListType === 'list' ? 'btn-list-white' : 'btn-list'" />
</el-icon>
</div>
<div class="card-btn" :class="[activeListType === 'card' ? 'active' : '']" @click="activeListType = 'card'">
<el-icon style="width: 12px;height: 12px;">
<svg-icon style="width: 12px;height: 12px;"
:name="activeListType === 'card' ? 'btn-card-white' : 'btn-card'" />
</el-icon>
<div class="container_wrap" v-loading="loading">
<div class="list-content">
<div class="card-content" v-for="item in demandListData" :key="item.guid">
<div class="header">
<img class="left-img" :src="(item.picUrl && typeof item.picUrl == 'string') ? item.picUrl : defaultItemLogo"
alt="" />
<div class="right-main">
<div class="title">{{ item.companyName ?? '--' }}</div>
<div class="count-group">
<div class="count-item">
<div class="item-label">已上架产品数</div>
<div class="item-num">{{ changeNum(item.listedNum) }}</div>
</div>
<div class="count-item">
<div class="item-label">审批中产品数</div>
<div class="item-num">{{ changeNum(item.processNum) }}</div>
</div>
</div>
</div>
</div>
<div class="operator-btn">
<div class="left-btn borderRight" @click="btnClick(item)">更新模板</div>
<div class="left-btn" @click="btnClick(item)">资产登记</div>
</div>
</div>
</div>
<div class="table_panel_wrap" :style="{ height: createBtnVisible ? 'calc(100% - 89px)' : 'calc(100% - 40px)' }">
<div v-if="activeListType === 'card'" class="data-content" v-loading="listDataLoading">
<div class="card-content" v-for="item in listData" :key="item.guid" @click="handleDataClick(item)">
<div class="title-row">
<div class="title">
<ellipsis-tooltip :content="item.daName" class-name="w100f"
:refName="'tooltipOver' + item.guid"></ellipsis-tooltip>
<div class="content_main_wrap">
<div class="table_tool_wrap">
<TableTools :searchItems="searchItemList" :searchId="'register-data-search'" @search="toSearch" />
<div class="tools_btns">
<el-button type="primary" @click="handleCreate" v-if="createBtnVisible" v-preReClick>新建</el-button>
<div class="view-change">
<div class="list-btn" :class="[activeListType === 'list' ? 'active' : '']" @click="activeListType = 'list'">
<el-icon style="width: 12px;height: 12px;">
<svg-icon style="width: 12px;height: 12px;"
:name="activeListType === 'list' ? 'btn-list-white' : 'btn-list'" />
</el-icon>
</div>
<div class="card-btn" :class="[activeListType === 'card' ? 'active' : '']" @click="activeListType = 'card'">
<el-icon style="width: 12px;height: 12px;">
<svg-icon style="width: 12px;height: 12px;"
:name="activeListType === 'card' ? 'btn-card-white' : 'btn-card'" />
</el-icon>
</div>
<el-tag :type="(tagType(item, 'approveState') as any)">{{
tagMethod(item, 'approveState')
}}</el-tag>
</div>
<div v-if="!isCompanyPlatform" class="desc">{{ item.tenantName ?? '深圳传世般若有限公司' }}</div>
<div class="desc">{{ item.updateTime }}</div>
<div class="type-btn">
<template v-if="item.ownIndustryName?.length">
<div class="type-items">
<div v-for="(info) in item.ownIndustryName" class="type">{{ info }}</div>
</div>
</div>
<div class="table_panel_wrap" :style="{ height: createBtnVisible ? 'calc(100% - 89px)' : 'calc(100% - 40px)' }">
<div v-if="activeListType === 'card'" class="data-content" v-loading="listDataLoading">
<div class="card-content" v-for="item in listData" :key="item.guid" @click="handleDataClick(item)">
<div class="title-row">
<div class="title">
<ellipsis-tooltip :content="item.daName" class-name="w100f"
:refName="'tooltipOver' + item.guid"></ellipsis-tooltip>
</div>
</template>
<template v-else>
<div class="type-items"></div>
</template>
<el-popover v-model="cardBtnVisible" placement="bottom" width="96" trigger="click"
popper-class="tree-item-edit-menu" :show-arrow="false" :hide-after="0">
<template #reference>
<el-icon class="list-more" color="#666" v-show="getTableBtns(item, false)?.length > 0"
@click.stop="cardBtnVisible = true">
<MoreFilled />
</el-icon>
<el-tag :type="(tagType(item, 'approveState') as any)">{{
tagMethod(item, 'approveState')
}}</el-tag>
</div>
<div v-if="!isCompanyPlatform" class="desc">{{ item.tenantName ?? '深圳传世般若有限公司' }}</div>
<div class="desc">{{ item.updateTime }}</div>
<div class="type-btn">
<template v-if="item.ownIndustryName?.length">
<div class="type-items">
<div v-for="(info) in item.ownIndustryName" class="type">{{ info }}</div>
</div>
</template>
<div class="levitation-ul">
<span class="levitation-li" v-for="btn in getTableBtns(item, false)"
@click="tableBtnClick({ row: item }, btn)">{{
btn.label }}</span>
</div>
</el-popover>
<template v-else>
<div class="type-items"></div>
</template>
<el-popover v-model="cardBtnVisible" placement="bottom" width="96" trigger="click"
popper-class="tree-item-edit-menu" :show-arrow="false" :hide-after="0">
<template #reference>
<el-icon class="list-more" color="#666" v-show="getTableBtns(item, false)?.length > 0"
@click.stop="cardBtnVisible = true">
<MoreFilled />
</el-icon>
</template>
<div class="levitation-ul">
<span class="levitation-li" v-for="btn in getTableBtns(item, false)"
@click="tableBtnClick({ row: item }, btn)">{{
btn.label }}</span>
</div>
</el-popover>
</div>
</div>
<div v-if="!listData.length" class="card-noData">
<img src="../../assets/images/no-data.png" :style="{ width: '96px', height: '96px' }" />
<span>暂无数据资产</span>
</div>
</div>
<div v-if="!listData.length" class="card-noData">
<img src="../../assets/images/no-data.png" :style="{ width: '96px', height: '96px' }" />
<span>暂无数据资产</span>
</div>
<Table v-else :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" />
<PageNav :class="[pageInfo.type]" :pageInfo="pageInfo" @pageChange="pageChange" />
</div>
<Table v-else :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" />
<PageNav :class="[pageInfo.type]" :pageInfo="pageInfo" @pageChange="pageChange" />
</div>
<Dialog :dialogInfo="passDialogInfo" @btnClick="passDialogBtnClick" />
<Dialog :dialogInfo="rejectDialogInfo" @btnClick="rejectDialogBtnClick" />
......@@ -561,7 +599,13 @@ const createBtnVisible = computed(() => {
<style scoped lang="scss">
.container_wrap {
padding: 0 16px;
padding: 16px 16px 0;
display: flex;
flex-direction: column;
}
.content_main_wrap {
flex: 1;
}
.table_panel {
......@@ -696,4 +740,83 @@ const createBtnVisible = computed(() => {
}
}
}
</style>
\ No newline at end of file
.list-content {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
margin-bottom: 8px;
.card-content {
width: calc(33.33% - 10px);
padding: 16px;
box-shadow: 0 0 0 1px #d9d9d9;
.header {
display: flex;
margin-bottom: 16px;
img {
width: 80px;
margin-right: 16px;
}
.title {
font-size: 16px;
color: #212121;
font-weight: 600;
margin-bottom: 8px;
}
.right-main {
width: calc(100% - 96px);
display: flex;
flex-direction: column;
justify-content: space-between;
.count-group {
display: flex;
justify-content: space-between;
.item-num {
font-size: 20px;
font-weight: 600;
color: #212121;
margin-top: 8px;
}
}
}
}
.operator-btn {
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 0 0 0 1px #d9d9d9;
position: relative;
&::after {
content: '';
width: 0;
height: 100%;
border-left: 1px solid #d9d9d9;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
>.left-btn {
width: 50%;
height: 40px;
line-height: 40px;
text-align: center;
cursor: pointer;
&:hover {
color: #4fa1a4;
}
}
}
}
}
</style>
......
<route lang="yaml">
name: dataSource
</route>
<script lang="ts" setup name="dataSource">
import { ref, onMounted } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import TableTools from "@/components/Tools/table_tools.vue";
import {
addDataSource,
getDataSourceList,
deleteDataSource,
updateDataSource,
getDataSourceDetail,
checkDataSourceConnect,
checkDataSourceConnectTest,
getAllFlowData
} from "@/api/modules/queryService";
const { proxy } = getCurrentInstance() as any;
const searchItemList = ref([
{
type: "select",
label: "",
field: "systemLayer",
default: "",
placeholder: "系统分层",
options: [
{ label: "业务系统", value: "业务系统" },
{ label: "数据中心", value: "数据中心" },
],
clearable: true,
},
{
type: "select",
label: "",
field: "databaseType",
default: "",
placeholder: "库类型",
options: [
{ label: "mysql", value: "mysql" },
{ label: "doris", value: "doris" },
{ label: "oracle", value: "oracle" },
],
clearable: true,
},
{
type: "select",
label: "",
field: "connectStatus",
default: "",
placeholder: "连通状态",
options: [
{ label: "已连通", value: "1" },
{ label: "连通失败", value: "2" },
],
clearable: true,
},
{
type: "input",
label: "",
field: "databaseNameZh",
default: "",
placeholder: "数据源名称",
clearable: true,
},
{
type: "input",
label: "",
field: "databaseNameEn",
default: "",
placeholder: "数据库名",
clearable: true,
},
]);
const currTableData: any = ref<Object>({});
const page = ref({
limit: 50,
curr: 1,
sizes: [
{ label: "10", value: 10 },
{ label: "50", value: 50 },
{ label: "100", value: 100 },
{ label: "150", value: 150 },
{ label: "200", value: 200 },
],
systemLayer: '',
databaseType: '',
connectStatus: '',
databaseNameZh: '',
databaseNameEn: ''
});
const selectRowData = ref([]);
const tableInfo = ref({
id: "data-source-table",
multiple: true,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "数据源名称", field: "databaseNameZh", width: 120 },
{ label: "系统分层", field: "systemLayer", width: 96 },
{ label: "库类型", field: "databaseType", width: 96 },
{ label: "数据库名", field: "databaseNameEn", width: 200 },
{
label: "连通状态",
field: "connectStatus",
type: "tag",
width: 96,
align: "center",
},
{ label: "连通时间", field: "lastCheckTime", width: 172 },
{ label: "操作人", field: "updateUserName", width: 140 },
{ label: "更新时间", field: "updateTime", width: 172 },
],
data: [],
page: {
type: "normal",
rows: 0,
...page.value,
},
actionInfo: {
label: "操作",
type: "btn",
width: 160,
btns: [
{ label: "编辑", value: "edit" },
{ label: "连通测试", value: "test" },
{ label: "删除", value: "delete" },
],
},
loading: false,
});
const tabActiveName = ref("1");
const tabsInfo: any = ref({
type: "tabs",
title: "",
style: {
padding: "0 24px",
},
tabsInfo: {
activeName: "",
tabs: [
{ label: "常规", name: "常规" },
// { label: "SSL", name: "SSL" }, //未支持,先隐藏掉
// { label: "SSH", name: "SSH" },
// { label: "HTTP", name: "HTTP" },
],
},
});
const formItems: any = ref([]);
const formRules: any = ref({});
const flowList: any = ref([])
const formInfo: any = ref({
type: "form",
title: "",
style: {
padding: "0 24px",
overflow: 'hidden auto'
},
formInfo: {
id: "add-source-form",
items: formItems.value,
rules: formRules.value,
},
});
const contents: any = ref({
normal: {
items: [
{
label: "数据源名称",
type: "input",
placeholder: "请输入",
field: "databaseNameZh",
default: "",
clearable: true,
required: true,
},
{
label: "系统分层",
type: "select",
placeholder: "请选择",
field: "systemLayer",
default: "",
options: [
{
label: "业务系统",
value: "业务系统",
},
{
label: "数据中心",
value: "数据中心",
},
],
clearable: true,
required: true,
},
{
label: "库类型",
type: "select",
placeholder: "请选择",
field: "databaseType",
default: "",
options: [
{ label: "mysql", value: "mysql" },
{ label: "doris", value: "doris" },
{ label: "oracle", value: "oracle" },
],
clearable: true,
required: true,
},
{
label: "业务系统",
type: "select",
placeholder: "请选择",
field: "bizSystem",
default: "",
options: [],
clearable: true,
required: true,
},
{
label: "集群信息",
type: "textarea-group",
placeholder: "请输入",
field: "jqxx",
default: "",
tooltipContent:
"格式:doris-fe-zs.doris:8030,doris-fe-zs.doris:8090 多个地址用英文半角逗号分隔",
children: [
{
label: "feLoadUrl",
type: "textarea",
placeholder: "请输入",
field: "feLoadUrl",
default: "",
clearable: true,
required: true,
block: true,
},
{
label: "beLoadUrl",
type: "textarea",
placeholder: "请输入",
field: "beLoadUrl",
default: "",
clearable: true,
required: true,
block: true,
},
{
label: "dorisJdbcUrl",
type: "textarea",
placeholder: "请输入",
field: "dorisJdbcUrl",
default: "",
clearable: true,
required: true,
block: true,
},
],
block: true,
visible: false,
},
{
label: "服务器",
type: "input",
placeholder: "请输入",
field: "host",
default: "",
clearable: true,
required: true,
},
{
label: "端口",
type: "input",
placeholder: "请输入",
field: "port",
default: "",
clearable: true,
required: true,
},
{
label: "用户名",
type: "input",
placeholder: "请输入",
field: "logonUser",
default: "",
clearable: true,
required: true,
autocompleteSetting: {
autocomplete: "off",
readonly: true,
},
},
{
label: "密码",
type: "password",
placeholder: "请输入",
field: "password",
default: "",
clearable: true,
required: true,
autocompleteSetting: {
autocomplete: "off",
readonly: true,
},
},
{
label: "数据库名",
type: "input",
placeholder: "请输入",
field: "databaseNameEn",
default: "",
clearable: true,
required: true,
},
{
label: "连接属性",
type: "textarea-tips",
placeholder: "请输入",
field: "linkage",
default: "",
tips: {
type: "table",
size: 400,
placement: "right",
offset: 12,
tableInfo: {
id: "",
fields: [
{ label: "数据库", field: "jsmc", width: 120 },
{ label: "连接属性", field: "sx", width: 200 },
],
data: [
{
jsmc: "MYSQL8.0",
sx: "列出支持的连接属性,并给出解释和范例,多个属性用;分割",
cjsj: "2022-12-12 08:12:12",
},
{
jsmc: "MYSQL8.0",
sx: "服务器的时区:serverTimezone=Asia/Shanghai;",
cjsj: "2022-12-12 08:12:12",
},
{
jsmc: "MYSQL8.0",
sx: "useUnicode=utf8;",
cjsj: "2022-12-12 08:12:12",
},
{
jsmc: "MYSQL8.0",
sx: "characterEncoding=utf8;",
cjsj: "2022-12-12 08:12:12",
},
{
jsmc: "MYSQL8.0",
sx: "useSSL=false",
cjsj: "2022-12-12 08:12:12",
},
],
showPage: false,
tableTool: [],
actionInfo: {
show: false,
},
btn: {
label: "",
value: "QuestionFilled",
},
},
},
clearable: true,
required: false,
block: true,
},
],
rules: {
databaseNameZh: [
{
validator: (rule: any, value: any, callback: any) => {
if (value === "") {
callback(new Error("请填写数据源名称"));
} else {
if (
dialogInfo.value.type == "edit" &&
value == currTableData.value.databaseNameZh
) {
callback();
return;
}
callback();
// let params: any = {
// dataPermissionName: value,
// };
// if (dialogInfo.value.type == 'edit') {
// params.guid = currTableData.value.guid
// }
// checkPermissionDict(params)
// .then((res: any) => {
// if (res.code == proxy.$passCode) {
// if (res.data) {
// callback(new Error("该名称已存在,请填写其他名称"));
// } else {
// callback();
// }
// } else {
// callback(new Error(res.msg));
// }
// })
// .catch((xhr) => {
// callback(new Error(xhr.msg));
// });
}
},
trigger: "blur",
},
],
bizSystem: [{
required: true,
message: "请选择业务系统",
trigger: "change",
}],
systemLayer: [
{
required: true,
message: "请选择系统分层",
trigger: "change",
},
],
databaseType: [
{
required: true,
message: "请选择库类型",
trigger: "change",
},
],
host: [
{
required: true,
message: "请填写服务器ip地址",
trigger: "blur",
},
],
port: [
{
required: true,
message: "请填写端口号",
trigger: "blur",
},
],
logonUser: [
{
required: true,
message: "请填写用户名",
trigger: "blur",
},
],
password: [
{
required: true,
message: "请填写密码",
trigger: "blur",
},
],
databaseNameEn: [
{
required: true,
message: "请填写数据库名",
trigger: "blur",
},
],
feLoadUrl: [
{
validator: (rule: any, value: any, callback: any) => {
if (value === "") {
callback(new Error("请填写feLoadUrl"));
} else {
if (
dialogInfo.value.type == "edit" &&
value == currTableData.value.feLoadUrl
) {
callback();
return;
}
callback();
}
},
trigger: "blur",
},
],
beLoadUrl: [
{
validator: (rule: any, value: any, callback: any) => {
if (value === "") {
callback(new Error("请填写beLoadUrl"));
} else {
if (
dialogInfo.value.type == "edit" &&
value == currTableData.value.beLoadUrl
) {
callback();
return;
}
callback();
}
},
trigger: "blur",
},
],
dorisJdbcUrl: [
{
validator: (rule: any, value: any, callback: any) => {
if (value === "") {
callback(new Error("请填写dorisJdbcUrl"));
} else {
if (
dialogInfo.value.type == "edit" &&
value == currTableData.value.dorisJdbcUrl
) {
callback();
return;
}
callback();
}
},
trigger: "blur",
},
],
},
},
ssl: {
items: [
{
label: "",
type: "checkbox",
col: "margin_b_0",
placeholder: "使用SSL",
field: "useSsl",
required: false,
block: true,
},
{
label: "",
type: "checkbox-panel",
placeholder: "使用验证",
field: "yz",
children: [
{
label: "客户端秘钥",
type: "file-upload",
placeholder: "选择文件上传",
field: "khdmy",
disabled: true,
required: true,
block: true,
},
{
label: "客户端证书",
type: "file-upload",
placeholder: "选择文件上传",
field: "khdzs",
disabled: true,
required: true,
block: true,
},
{
label: "CA证书",
type: "file-upload",
placeholder: "选择文件上传",
field: "cazs",
disabled: true,
required: true,
block: true,
},
{
label: "指定密码检索表",
type: "append-empty",
placeholder: "请输入",
field: "khdzs",
disabled: true,
required: true,
block: true,
},
],
required: false,
block: true,
},
],
rules: {},
},
ssh: {
items: [
{
label: "",
type: "checkbox-panel",
placeholder: "使用SSH",
field: "yz",
children: [
{
label: "主机名或IP地址",
type: "input",
placeholder: "请输入",
field: "khdmy",
required: false,
disabled: true,
},
{
label: "端口",
type: "input",
placeholder: "请输入",
field: "khdzs",
required: false,
disabled: true,
},
{
label: "用户名",
type: "input",
placeholder: "请输入",
field: "cazs",
required: false,
disabled: true,
},
{
label: "验证方法",
type: "select",
placeholder: "请选择",
field: "yzfs",
options: [
{ label: "密码", value: "pwd" },
{ label: "手机号", value: "tel" },
],
required: false,
disabled: true,
},
{
label: "密码",
type: "input",
placeholder: "请输入",
field: "pwd",
required: false,
disabled: true,
},
{
label: "",
type: "checkbox",
placeholder: "保存密码",
field: "savePwd",
required: false,
},
],
required: false,
block: true,
},
],
rules: {},
},
http: {
items: [
{
label: "",
type: "checkbox-input",
placeholder: "使用HTTP通道",
field: "tddz",
children: [
{
label: "",
type: "input",
placeholder: "通道地址",
field: "khdmy",
required: false,
disabled: true,
},
],
block: true,
},
{
label: "",
type: "tabs-panel-card",
placeholder: "用base64编码传出查询",
field: "basebm",
tabsInfo: {
type: "card",
activeName: "yz",
col: "border",
tabs: [
{
label: "验证",
name: "yz",
pane: {
type: "form",
title: "",
formInfo: {
id: "",
items: [
{
label: "",
type: "checkbox-panel",
col: "margin_b_0 border_none col_3",
placeholder: "使用密码验证",
field: "mmyz",
children: [
{
label: "",
type: "input",
placeholder: "用户名",
field: "cazs",
required: false,
disabled: true,
},
{
label: "",
type: "input",
placeholder: "密码",
field: "pwd",
required: false,
disabled: true,
},
{
label: "",
type: "checkbox",
placeholder: "保存密码",
field: "savePwd",
required: false,
},
],
required: false,
block: true,
},
{
label: "",
type: "checkbox-panel",
col: "border_none",
placeholder: "使用证书验证",
field: "zsyz",
children: [
{
label: "客户端秘钥",
type: "file-upload",
placeholder: "选择文件上传",
field: "khdmy",
disabled: true,
required: true,
block: true,
},
{
label: "客户端证书",
type: "file-upload",
placeholder: "选择文件上传",
field: "khdzs",
disabled: true,
required: true,
block: true,
},
{
label: "CA证书",
type: "file-upload",
placeholder: "选择文件上传",
field: "cazs",
disabled: true,
required: true,
block: true,
},
{
label: "密码短语",
type: "append-empty",
placeholder: "请输入",
field: "khdzs",
disabled: true,
required: true,
block: true,
},
],
required: false,
block: true,
},
],
},
},
},
{
label: "代理服务器",
name: "dl",
pane: {
type: "form",
title: "",
formInfo: {
id: "",
items: [
{
label: "",
type: "checkbox-panel",
col: "border_none",
placeholder: "使用代理服务器",
field: "yz",
children: [
{
label: "主机名或IP地址",
type: "input",
placeholder: "请输入",
field: "khdmy",
required: false,
disabled: true,
},
{
label: "端口",
type: "input",
placeholder: "请输入",
field: "khdzs",
required: false,
disabled: true,
},
{
label: "用户名",
type: "input",
placeholder: "请输入",
field: "cazs",
required: false,
disabled: true,
},
{
label: "验证方法",
type: "select",
placeholder: "请选择",
field: "yzfs",
options: [
{ label: "密码", value: "pwd" },
{ label: "手机号", value: "tel" },
],
required: false,
disabled: true,
},
{
label: "密码",
type: "input",
placeholder: "请输入",
field: "pwd",
required: false,
disabled: true,
},
{
label: "",
type: "checkbox",
placeholder: "保存密码",
field: "savePwd",
required: false,
},
],
required: false,
block: true,
},
],
},
},
},
],
},
children: [
{
label: "主机名或IP地址",
type: "input",
placeholder: "请输入",
field: "khdmy",
required: false,
},
{
label: "端口",
type: "input",
placeholder: "请输入",
field: "khdzs",
required: false,
},
{
label: "用户名",
type: "input",
placeholder: "请输入",
field: "cazs",
required: false,
},
{
label: "验证方法",
type: "select",
placeholder: "请选择",
field: "yzfs",
default: "pwd",
options: [
{ label: "密码", value: "pwd" },
{ label: "手机号", value: "tel" },
],
required: false,
},
{
label: "密码",
type: "input",
placeholder: "请输入",
field: "pwd",
required: false,
},
{
label: "",
type: "checkbox",
placeholder: "保存密码",
field: "savePwd",
required: false,
},
],
required: false,
block: true,
},
],
rules: {},
},
});
const dialogRef = ref();
const dialogInfo = ref({
visible: false,
size: 700,
direction: "column",
height: '440px',
header: {
title: "",
},
type: "",
readonly: false,
contents: [],
footer: {
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "确定", value: "submit" },
],
textBtns: [{ type: "primary", label: "连通测试", value: "connect" }],
},
});
const setFormItems = (name, info: any = null) => {
let contentFormInfo: any = {};
if (name == "常规") {
tabActiveName.value = "1";
contentFormInfo = contents.value["normal"];
} else if (name == "SSL") {
tabActiveName.value = "2";
contentFormInfo = contents.value["ssl"];
} else if (name == "SSH") {
tabActiveName.value = "3";
contentFormInfo = contents.value["ssh"];
} else if (name == "HTTP") {
tabActiveName.value = "4";
contentFormInfo = contents.value["http"];
}
tabsInfo.value.tabsInfo.activeName = name;
formItems.value = contentFormInfo.items;
formRules.value = contentFormInfo.rules;
if (info !== null) {
const type = dialogInfo.value.type;
formItems.value.map((item) => {
if (
item.field == "host" ||
item.field == "port" ||
item.field == "logonUser" ||
item.field == "password"
) {
if (type == "edit" || type == "detail") {
item.default = info?.[item.field] ?? "";
} else {
item.default = info[item.field] ?? "";
}
if (item.field == "logonUser" || item.field == "password") {
item.autocompleteSetting.readonly = true;
}
} else if (item.field == "jqxx") {
item.visible = info.databaseType == "doris";
item.children.map((child) => {
if (type == 'edit' || type == 'detail') {
child.default = info?.[child.field] ?? "";
} else {
child.default = info[child.field] ?? "";
}
});
} else if (item.field == 'bizSystem') {
item.visible = info.systemLayer == '业务系统';
item.default = info[item.field] || "";
}
else {
item.default = info[item.field] || "";
}
});
} else {
formItems.value.map((item) => {
if (item.field == "logonUser" || item.field == "password") {
item.autocompleteSetting.readonly = true;
}
});
}
formInfo.value.formInfo.items = formItems.value;
formInfo.value.formInfo.rules = formRules.value;
const content: any = [tabsInfo.value, formInfo.value];
dialogInfo.value.contents = content;
};
const getFirstPageData = () => {
page.value.curr = 1;
getTableData();
};
onMounted(() => {
getAllFlowData({ dictType: "业务系统" }).then((res) => {
flowList.value = res.data
contents.value.normal.items[3].options = flowList.value
})
})
const toSearch = (val: any, clear: boolean = false) => {
if (clear) {
searchItemList.value.map((item) => (item.default = ""));
page.value.systemLayer = "";
page.value.databaseType = "";
page.value.connectStatus = "";
page.value.databaseNameZh = "";
page.value.databaseNameEn = "";
} else {
page.value.systemLayer = val.systemLayer;
page.value.databaseType = val.databaseType;
page.value.connectStatus = val.connectStatus;
page.value.databaseNameZh = val.databaseNameZh;
page.value.databaseNameEn = val.databaseNameEn;
}
getTableData();
};
const getTableData = () => {
tableInfo.value.loading = true;
getDataSourceList({
pageIndex: page.value.curr,
pageSize: page.value.limit,
systemLayer: page.value.systemLayer,
databaseType: page.value.databaseType,
connectStatus: page.value.connectStatus,
databaseNameZh: page.value.databaseNameZh,
databaseNameEn: page.value.databaseNameEn
})
.then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || {};
tableInfo.value.data = data.records || [];
tableInfo.value.page.limit = data.pageSize;
tableInfo.value.page.curr = data.pageIndex;
tableInfo.value.page.rows = data.totalRows;
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
tableInfo.value.loading = false;
})
.catch((xhr) => {
tableInfo.value.loading = false;
});
};
const tableSelectionChange = (val) => {
selectRowData.value = val.map((item) => item.guid);
};
const tablePageChange = (info) => {
page.value.curr = Number(info.curr);
page.value.limit = Number(info.limit);
getTableData();
};
const tabChange = (tabName) => {
// TODO.等添加了tab切换之后再保留旧值.
setFormItems(tabName);
};
/** 表单修改时的原始值 */
const originValue: any = ref({});
const formSelectChange = (val, row, info) => {
console.log(row, info)
if (row.field == "databaseType" || row.field == 'systemLayer') {
if (tabsInfo.value.tabsInfo.activeName == "常规") {
let newInfo = originValue.value = Object.assign(originValue.value, info);
setFormItems("常规", newInfo);
}
}
};
const tableBtnClick = (scope, btn) => {
const type = btn.value;
const row = scope.row;
currTableData.value = row;
if (type == "edit") {
dialogInfo.value.type = type;
dialogInfo.value.header.title = "编辑数据源";
const guid = row.guid;
getDataSourceDetail(guid).then((res: any) => {
if (res.code == proxy.$passCode && res.data) {
const data = res.data;
currTableData.value = data;
setDetailInfo();
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
});
} else if (type == "test") {
checkConnect({});
} else if (type == "delete") {
open("此操作将永久删除, 是否继续?", "warning");
}
};
const open = (msg, type, isBatch = false) => {
ElMessageBox.confirm(msg, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: type,
}).then(() => {
let guids = [currTableData.value.guid];
if (isBatch) {
guids = selectRowData.value;
}
deleteDataSource(guids).then((res: any) => {
if (res.code == proxy.$passCode) {
getTableData();
ElMessage({
type: "success",
message: "删除成功",
});
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
});
});
};
const setDetailInfo = async () => {
let info = Object.assign({}, currTableData.value, currTableData.value.dataConfigure || {});
let newInfo = originValue.value = Object.assign(originValue.value, info);
setFormItems("常规", newInfo);
dialogInfo.value.visible = true;
};
const checkConnect = (val) => {
let params = { guid: currTableData.value.guid };
checkDataSourceConnect(params).then((res: any) => {
if (res.code == proxy.$passCode && res.data && res.data == "1") {
getTableData();
ElMessage({
type: "success",
message: "连通成功",
});
} else {
getTableData();
ElMessage({
type: "error",
message: "连通失败",
});
}
});
};
const loadDialog = async () => {
dialogInfo.value.type = "add";
dialogInfo.value.header.title = "添加数据源";
originValue.value = {};
setFormItems("常规", {});
dialogInfo.value.visible = true;
};
const batching = (type) => {
if (type == "delete") {
if (selectRowData.value.length == 0) {
ElMessage({
type: "error",
message: "请选择需要删除的数据",
});
return;
}
open("此操作将永久删除, 是否继续?", "warning", true);
}
};
const dialogBtnClick = (btn, info) => {
if (btn.value == "submit") {
// dialogInfo.value.footer.btns.map((item: any) => item.disabled = true)
const params = { ...info };
delete params.host;
delete params.port;
delete params.logonUser;
delete params.password;
delete params.feLoadUrl;
delete params.beLoadUrl;
delete params.dorisJdbcUrl;
params.dataConnectionContract = tabActiveName.value;
if (dialogInfo.value.type == "add") {
params.dataConfigureAddDTO = {
host: info.host,
port: info.port,
logonUser: info.logonUser,
password: info.password,
feLoadUrl: info.feLoadUrl,
beLoadUrl: info.beLoadUrl,
dorisJdbcUrl: info.dorisJdbcUrl
};
addDataSource(params)
.then((res: any) => {
if (res.code == proxy.$passCode) {
getFirstPageData();
ElMessage({
type: "success",
message: "添加数据源成功",
});
dialogInfo.value.visible = false;
} else {
ElMessage({
type: "error",
message: res.msg,
});
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
}
})
.catch(() => {
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
});
} else {
params.dataConfigureUpdateDTO = {
guid: currTableData.value.dataConfigure.guid,
host: info.host,
port: info.port,
logonUser: info.logonUser,
password:
info.password == "******"
? currTableData.value.dataConfigure.password
: info.password,
feLoadUrl: info.feLoadUrl,
beLoadUrl: info.beLoadUrl,
dorisJdbcUrl: info.dorisJdbcUrl
};
params.guid = currTableData.value.guid;
updateDataSource(params)
.then((res: any) => {
if (res.code == proxy.$passCode) {
getTableData();
ElMessage({
type: "success",
message: "修改数据源成功",
});
dialogInfo.value.visible = false;
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
})
.catch(() => {
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
});
}
} else if (btn.value == "connect") {
const params = {
databaseType: info.databaseType,
databaseNameEn: info.databaseNameEn,
host: info.host,
port: info.port,
logonUser: info.logonUser,
password: info.password,
linkage: info.linkage,
};
checkDataSourceConnectTest(params).then((res: any) => {
if (res.code == proxy.$passCode) {
if (res.data && res.data == "1") {
ElMessage({
type: "success",
message: "连通成功",
});
} else {
ElMessage({
type: "error",
message: "连通失败",
});
}
} else {
ElMessage({
type: "error",
message: res.msg,
});
}
});
} else if (btn.value == "cancel") {
// dialogInfo.value.footer.btns.map((item: any) => delete item.disabled)
nextTick(() => {
dialogInfo.value.visible = false;
});
}
};
</script>
<template>
<div class="container_wrap">
<div class="table_tool_wrap has_search">
<TableTools :searchItems="searchItemList" :searchId="'data-source-search'" @search="toSearch" />
<div class="tools_btns">
<el-button type="primary" @click="loadDialog" v-preReClick>新建</el-button>
<el-button @click="batching('delete')" v-preReClick>批量删除</el-button>
</div>
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tableBtnClick="tableBtnClick" @tablePageChange="tablePageChange"
@tableSelectionChange="tableSelectionChange" />
</div>
<Dialog ref="dialogRef" :dialogInfo="dialogInfo" @btnClick="dialogBtnClick" @tableBtnClick="tableBtnClick"
@selectChange="formSelectChange" @tabChange="tabChange" />
</div>
</template>
<style lang="scss" scoped>
.container_wrap {
overflow: hidden auto;
}
.table_tool_wrap {
width: 100%;
height: 84px !important;
padding: 0 8px;
.tools_btns {
padding: 8px 0 0;
}
}
.table_panel_wrap {
width: 100%;
height: calc(100% - 84px);
padding: 8px 8px 0;
}
</style>
......@@ -85,11 +85,12 @@ const sheetItemList = ref([
value: 'dbGuid'
},
clearable: true,
filterable: true,
},
{
type: "select",
label: "",
placeholder: '表中文/英文名',
placeholder: '表中文名',
field: 'tableGuid',
default: '',
options: [],
......@@ -98,6 +99,7 @@ const sheetItemList = ref([
value: 'dbGuid'
},
clearable: true,
filterable: true,
disabled: true
},
]);
......@@ -128,11 +130,12 @@ const fieldItemList = ref([
value: 'dbGuid'
},
clearable: true,
filterable: true,
},
{
type: "select",
label: "",
placeholder: '表中文/英文名',
placeholder: '表中文名',
field: 'tableGuid',
default: '',
options: [],
......@@ -141,12 +144,13 @@ const fieldItemList = ref([
value: 'dbGuid'
},
clearable: true,
filterable: true,
disabled: true
},
{
type: "select",
label: "",
placeholder: '字段中文/英文名',
placeholder: '字段中文名',
field: 'fieldGuid',
default: '',
options: [],
......@@ -155,6 +159,7 @@ const fieldItemList = ref([
value: 'dbGuid'
},
clearable: true,
filterable: true,
disabled: true
},
{
......@@ -167,10 +172,7 @@ const fieldItemList = ref([
{ label: '已分类', value: 'Y' },
{ label: '未分类', value: 'N' },
],
props: {
// label: 'name',
// value: 'dbGuid'
},
props: {},
clearable: true,
},
{
......@@ -187,7 +189,6 @@ const fieldItemList = ref([
label: "classifyName",
value: "classifyDetailGuid",
},
// popperClass: 'strictiy_cascader',
filterable: true,
clearable: true,
blur: true
......@@ -226,17 +227,13 @@ const sheetTableInfo = ref({
id: "mapping-table",
fields: [
{ label: "序号", type: "index", width: 56, align: "center", fixed: "left" },
// {
// label: "分类分级变更状态", field: "isCgChange", width: 140, align: 'center', type: "tag", getName: (scope) => {
// return filterVal(scope.row.isCgChange, 'isCgChange');
// }
// },
{ label: "表中文名", field: "tableChName", width: 120 },
{ label: "表中文名", field: "tableChName", width: 180 },
{
label: "表英文名", field: "tableName", width: 200, type: "text_btn", value: 'tab'
},
{ label: "数据库名", field: "database", width: 120 },
{ label: "字段数", field: "fieldNum", width: 96, align: 'right' },
{ label: "数据库名", field: "databaseChName", width: 140 },
{ label: "数据库名称", field: "database", width: 200 },
{ label: "字段数", field: "fieldNum", width: 80, align: 'right' },
{ label: "已分类字段数", field: "classifyFieldNum", width: 120, align: 'right' },
{ label: "已分级字段数", field: "gradeFieldNum", width: 120, align: 'right' },
],
......@@ -252,6 +249,7 @@ const sheetTableInfo = ref({
},
});
const selectRowData = ref([]);
const fieldTableRef = ref();
const fieldTableInfo = ref({
id: "metadata-table",
fields: [
......@@ -297,8 +295,9 @@ const fieldTableInfo = ref({
{ label: "标签", field: "label", width: 120 },
{ label: "规则", field: "ruleDetail", width: 200 },
{ label: "表英文名", field: "tableName", width: 200 },
{ label: "表中文名", field: "tableChName", width: 120 },
{ label: "数据库名", field: "database", width: 120 },
{ label: "表中文名", field: "tableChName", width: 140 },
{ label: "数据库名", field: "databaseChName", width: 140 },
{ label: "数据库名称", field: "database", width: 200 },
],
loading: false,
data: [],
......@@ -390,25 +389,40 @@ const dialogInfo: any = ref({
},
})
/**
* 传入多个promise对象,当全部结束时取消Loading
* @param promises 传入多个promise对象,当全部结束时取消Loading
*/
const promiseList = async (...promises: Promise<void>[]) => {
// loading方法全局封装成一个组件
loading.value = true;
try {
await Promise.all(promises);
} catch (e) {
loading.value = false;
} finally {
loading.value = false;
}
};
// 获取任务详情
const getTaskDetail = (param) => {
loading.value = true;
getCgTaskDetail(param).then((res: any) => {
loading.value = false;
if (res.code == proxy.$passCode) {
taskDetail.value = res.data || {};
// taskDetail.value.confirmStatus != 'Y' && (showBtns.value = true);
getFieldCount()
getSheetFieldList({ type: 1 });
getFieldTree()
getGradeData();
nextTick(() => {
getSheetTableData();
getFieldTableData();
promiseList(
getSheetFieldList({ type: 1 }),
getFieldCount(),
getFieldTree(),
getGradeData(),
getSheetTableData(),
getFieldTableData()
)
})
} else {
ElMessage.error(res.msg);
loading.value = false;
}
}).catch(() => {
loading.value = false;
......@@ -417,7 +431,7 @@ const getTaskDetail = (param) => {
// 获取字段统计
const getFieldCount = () => {
getTaskFieldCount({ execGuid: taskDetail.value.execGuid }).then((res: any) => {
return getTaskFieldCount({ execGuid: taskDetail.value.execGuid }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || {};
fieldCounts.value = data;
......@@ -432,27 +446,24 @@ const getFieldCount = () => {
// 获取分级数据
const getGradeData = () => {
getGradeList({ classifyGradeGuid: taskDetail.value.gradeGuid, pageIndex: 1, pageSize: -1 }).then((res: any) => {
return getGradeList({ classifyGradeGuid: taskDetail.value.gradeGuid, pageIndex: 1, pageSize: -1 }).then((res: any) => {
if (res.code == proxy.$passCode) {
let data = res.data.records || [];
data.map(d => d.gradeName = d.dataGrade + '级');
gradeList.value = JSON.parse(JSON.stringify(data));
formItems.value[1].options = JSON.parse(JSON.stringify(data));
fieldItemList.value[5].options = JSON.parse(JSON.stringify(data));
fieldItemList.value[6].options = JSON.parse(JSON.stringify(data));
fieldTableInfo.value.fields[5].options = JSON.parse(JSON.stringify(data));
} else {
ElMessage.error(res.msg);
loading.value = false;
}
}).catch(() => {
loading.value = false;
})
}
// 获取分类树形数据
const getFieldTree = () => {
getTaskExeTreeList({ execGuid: taskDetail.value.execGuid }).then((res: any) => {
// treeInfo.value.loading = false;
return getTaskExeTreeList({ execGuid: taskDetail.value.execGuid }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data: any = res.data || [];
treeData.value[0].children.push(...data);
......@@ -464,16 +475,14 @@ const getFieldTree = () => {
fieldTableInfo.value.fields[4].options = JSON.parse(JSON.stringify(data));
} else {
ElMessage.error(res.msg);
loading.value = false;
}
}).catch(() => {
loading.value = false;
})
}
// 获取库、表、字段信息
const getSheetFieldList = (params, tId = null) => {
getDbFieldList({ execGuid: taskDetail.value.execGuid, ...params }).then((res: any) => {
return getDbFieldList({ execGuid: taskDetail.value.execGuid, ...params }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
if (params.type == 1) {
......@@ -495,10 +504,8 @@ const getSheetFieldList = (params, tId = null) => {
}
} else {
ElMessage.error(res.msg);
loading.value = false;
}
}).catch(() => {
loading.value = false;
})
}
......@@ -511,28 +518,30 @@ const nodeClick = (data, node) => {
if (data.classifyDetailGuid == 'all') {
fieldItemList.value[4].default = '';
fieldItemList.value[5].default = [];
getFieldTableData()
promiseList(
getFieldTableData()
)
} else {
const parentGuids = data.parentGuids || [];
parentGuids.push(data.classifyDetailGuid)
fieldItemList.value[4].default = 'Y';
fieldItemList.value[5].default = parentGuids;
getFieldTableData();
promiseList(
getFieldTableData()
)
}
}
// 获取库表数据
const getSheetTableData = () => {
loading.value = true;
const sheetParams = sheetSearchRef.value.toolSearch.formInline || {};
execTaskSheetList(
return execTaskSheetList(
Object.assign({}, { ...sheetParams }, {
execGuid: taskDetail.value.execGuid,
pageIndex: sheetTableInfo.value.page.curr,
pageSize: sheetTableInfo.value.page.limit,
})
).then((res: any) => {
loading.value = false;
if (res.code == proxy.$passCode) {
sheetTableInfo.value.data = res.data.records || [];
sheetTableInfo.value.page.curr = res.data.pageIndex;
......@@ -543,13 +552,11 @@ const getSheetTableData = () => {
}
})
.catch((res) => {
loading.value = false;
});
};
// 获取字段表格数据
const getFieldTableData = () => {
loading.value = true;
const fieldParams = fieldSearchRef.value.toolSearch.formInline || {};
let params: any = {
...fieldParams,
......@@ -559,13 +566,11 @@ const getFieldTableData = () => {
isMergeClassify: checked1.value ? 'Y' : 'N'
}
const classifyName = params.classifyName?.at(-1) || undefined;
// params.isClassify = classifyName === undefined ? '' : classifyName == 'unclassified' ? 'N' : 'Y';
if (classifyName && classifyName != 'unclassified') {
params.classifyDetail = classifyName;
}
delete params.classifyName
execTaskFieldList(params).then((res: any) => {
loading.value = false;
return execTaskFieldList(params).then((res: any) => {
if (res.code == proxy.$passCode) {
let data = res.data.records || [];
data.map(item => item.STATE = '');
......@@ -578,7 +583,6 @@ const getFieldTableData = () => {
}
})
.catch((res) => {
loading.value = false;
});
};
......@@ -622,7 +626,6 @@ const tableBtnClick = (scope, btn) => {
row.classifyDetailGuid = cascaderData.length ? cascaderData[0].value : '';
row.classifyDetailName = cascaderData.length ? cascaderData[0].label : '';
row.gradeDetailName = gradeList.value.find(item => item.guid == row.gradeDetailGuid)?.gradeName;
row.STATE = '';
if (cascaderData.length && row.gradeDetailGuid) {
const params = [
{
......@@ -632,9 +635,19 @@ const tableBtnClick = (scope, btn) => {
classifyDetailName: row.classifyDetailName,
gradeDetailGuid: row.gradeDetailGuid,
gradeDetailName: row.gradeDetailName,
execGuid: taskDetail.value.execGuid
}
];
saveFields(params)
row.STATE = '';
} else {
if (row.classifyDetailGuid && !row.gradeDetailGuid) {
ElMessage.error('分级不能为空');
} else if (!row.classifyDetailGuid && row.gradeDetailGuid) {
ElMessage.error('分类不能为空');
} else {
ElMessage.error('分类和分级均不能为空');
}
}
}
};
......@@ -643,11 +656,15 @@ const tablePageChange = (info) => {
if (tabsInfo.value.activeName == 'sheet') {
sheetTableInfo.value.page.limit = Number(info.limit);
sheetTableInfo.value.page.curr = Number(info.curr);
getSheetTableData();
promiseList(
getSheetTableData()
)
} else {
fieldTableInfo.value.page.limit = Number(info.limit);
fieldTableInfo.value.page.curr = Number(info.curr);
getFieldTableData();
promiseList(
getFieldTableData()
)
}
};
......@@ -665,7 +682,28 @@ const btnClick = async (btn, bType = null) => {
name: "taskConfig",
});
} else if (type == 'confirm') {
saveTask();
const row = fieldTableInfo.value.data.find(item => item.STATE == 'Running');
const rIndex = fieldTableInfo.value.data.findIndex(item => item.STATE == 'Running');
if (rIndex > -1) {
ElMessageBox.confirm(
'存在未保存的数据,提交后会丢失,是否确定提交',
'提示',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
).then(() => {
saveTask();
}).catch(() => {
// 设置高亮
fieldTableRef.value.setCurrentRow(row)
// 设置表格滚动的位置
fieldTableRef.value.scrollTo({ top: 36 * rIndex, behavior: 'smooth' });
})
} else {
saveTask();
}
} else if (type == 'status') {
if (selectRowData.value.length == 0) {
ElMessage.warning('请选择需要操作的数据');
......@@ -692,14 +730,12 @@ const btnClick = async (btn, bType = null) => {
const saveFields = (params, isBatch = false) => {
loading.value = true;
execFieldConfirm(params).then((res: any) => {
loading.value = false;
if (res.code == proxy.$passCode) {
ElMessage.success('保存成功');
if (isBatch) {
getFieldTableData();
} else {
currTableData.value.changeStatus = 'Y';
}
promiseList(
getFieldCount(),
getFieldTableData()
)
} else {
ElMessage.error(res.msg);
}
......@@ -735,7 +771,9 @@ const saveStatus = (params) => {
loading.value = false;
if (res.code == proxy.$passCode) {
ElMessage.success('确认成功');
getFieldTableData();
promiseList(
getFieldTableData()
)
}
})
}
......@@ -746,7 +784,9 @@ const searchSheet = (val: any, clear: boolean = false) => {
sheetItemList.value.map(item => item.default = '')
}
sheetParams.value = Object.assign({}, { ...sheetParams.value }, { ...val });
getSheetTableData();
promiseList(
getSheetTableData()
)
};
const searchField = (val: any, clear: boolean = false) => {
......@@ -756,7 +796,9 @@ const searchField = (val: any, clear: boolean = false) => {
treeInfoRef.value.setCurrentKey('all');
}
fieldParams.value = Object.assign({}, { ...fieldParams.value }, { ...val });
getFieldTableData();
promiseList(
getFieldTableData()
)
};
const cascaderChange = (val, info) => {
......@@ -768,15 +810,22 @@ const cascaderChange = (val, info) => {
if (info && info.row) {
const cascaderData = getCascaderCheckedData();
info.row.gradeDetailGuid = cascaderData.length ? cascaderData[0].data.gradeGuid : '';
} else {
treeInfoRef.value.expandedKey = val || ['all'];
treeInfoRef.value.setCurrentKey(val?.at(-1) || 'all');
getFieldTableData();
promiseList(
getFieldTableData()
)
}
}
};
const checkboxChange = (val) => {
promiseList(
getFieldTableData()
)
};
const selectChange = (val, item, scope = null) => {
if (scope && item.field == 'gradeDetailName') {
let row = scope.row;
......@@ -785,19 +834,24 @@ const selectChange = (val, item, scope = null) => {
} else if (item.field == 'databaseGuid' || item.field == 'tableGuid') {
const params: any = scope;
if (tabsInfo.value.activeName == 'sheet') {
if (!val) {
sheetItemList.value[1].default = '';
sheetItemList.value[1].disabled = true;
} else {
sheetItemList.value[1].disabled = false;
if (item.field == "databaseGuid") {
if (!val) {
sheetItemList.value[1].default = '';
sheetItemList.value[1].disabled = true;
} else {
sheetItemList.value[1].disabled = false;
}
}
item.field == "databaseGuid" && (params.tableGuid = '');
if (val && item.field != "tableGuid") {
const params = {
type: 2,
dbGuid: val || ''
}
getSheetFieldList(params)
promiseList(
getSheetFieldList(params)
)
}
} else {
if (item.field == "databaseGuid") {
......@@ -828,7 +882,9 @@ const selectChange = (val, item, scope = null) => {
type: item.field == "databaseGuid" ? 2 : 3,
dbGuid: val || ''
}
getSheetFieldList(params)
promiseList(
getSheetFieldList(params)
)
}
}
} else if (item.field == 'isClassify') {
......@@ -837,7 +893,9 @@ const selectChange = (val, item, scope = null) => {
treeInfo.value.expandedKey = ['all'];
treeInfoRef.value.setCurrentKey('all');
fieldItemList.value[4].default = val || '';
getFieldTableData();
promiseList(
getFieldTableData()
)
}
}
......@@ -854,10 +912,11 @@ const dialogBtnClick = (btn, info) => {
classifyDetailName: cascaderData[0].label,
gradeDetailGuid: info.gradeGuid,
gradeDetailName: gradeName,
execGuid: taskDetail.value.execGuid
}
params.push(param)
})
saveFields(params, true);
saveFields(params, true)
dialogInfo.value.visible = false;
} else if (btn.value == 'cancel') {
dialogInfo.value.visible = false;
......@@ -913,7 +972,7 @@ onMounted(() => {
</div>
<div class="desc_item">
<span class="desc_label">执行时间:</span>
<span class="desc_value">{{ taskDetail.updateTime || '--' }}</span>
<span class="desc_value">{{ taskDetail.execTime || '--' }}</span>
</div>
</div>
<div class="desc_group">
......@@ -967,27 +1026,27 @@ onMounted(() => {
<div class="table_tool_wrap" ref="tableToolRef">
<TableTools ref="fieldSearchRef" :searchItems="fieldItemList" :searchId="'field-search'" :init="false"
@selectChange="selectChange" @cascaderChange="cascaderChange" @search="searchField" />
<div class="tools_btns">
<div class="btns" v-if="showBtns" >
<div class="tools_btns" v-if="showBtns">
<div class="btns">
<el-button type="primary" plain @click="btnClick({ value: 'batch' })">批量变更分类分级</el-button>
<el-button type="primary" plain @click="btnClick({ value: 'status' })">批量确认</el-button>
<!-- <el-button plain @click="btnClick({ value: 'export' })">导出</el-button> -->
</div>
<!-- <div class="checkboxs">
<el-checkbox v-model="checked1" @change="getFieldTableData()">仅看多分类</el-checkbox>
<div class="checkboxs">
<el-checkbox v-model="checked1" @change="checkboxChange">仅看多分类</el-checkbox>
<el-tooltip effect="light" placement="top" content="一个字段只能有一个分类,多分类的字段需要人工确定分类">
<el-icon style="margin-left: 8px;">
<svg-icon name="icon-tip" />
</el-icon>
</el-tooltip>
</div> -->
</div>
</div>
</div>
<div class="table_panel_wrap panel" :style="{ height: 'calc(100% - ' + toolH + 'px)' }">
<div class="table_panel" v-loading="fieldTableInfo.loading">
<el-table ref="costTableRef" :data="fieldTableInfo.data" border :height="'100%'"
<el-table ref="fieldTableRef" :data="fieldTableInfo.data" border :height="'100%'"
style="width: 100%; display: inline-block" :style="{ 'max-height': 'calc(100% - 44px)' }"
:cell-class-name="tableCellClassName" @selection-change="tableSelectionChange">
:cell-class-name="tableCellClassName" @selection-change="tableSelectionChange" highlight-current-row>
<el-table-column type="selection" align="center" :width="32" :selectable="rowSelectable"
fixed="left" />
<el-table-column v-for="(item, i) in fieldTableInfo.fields" :label="item.label" :width="item.width"
......
......@@ -48,8 +48,7 @@ const treeInfo = ref({
expandOnNodeClick: false,
data: [],
});
const toolH = ref(82)
const toolRef = ref();
const expand1 = ref(true)
const expand2 = ref(true)
......@@ -154,7 +153,24 @@ const metadataTableInfo = ref({
},
})
/**
* 传入多个promise对象,当全部结束时取消Loading
* @param promises 传入多个promise对象,当全部结束时取消Loading
*/
const promiseList = async (...promises: Promise<void>[]) => {
// loading方法全局封装成一个组件
loading.value = true;
try {
await Promise.all(promises);
} catch (e) {
loading.value = false;
} finally {
loading.value = false;
}
};
const getTaskDetail = (data) => {
loading.value = true;
getCgTaskDetail(data).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || {};
......@@ -163,28 +179,31 @@ const getTaskDetail = (data) => {
item.default = data[item.field] || '';
})
selectRowData.value = data.metaGuids || [];
getPermissionList({});
getMetaTableData();
promiseList(
getPermissionList(),
getMetaTableData()
)
}
}).catch(() => {
loading.value = false;
})
}
const nodeClick = (data) => {
searchItemValue.value.classifyGuid = templateInfo.value.guid;
searchItemValue.value.detailGuid = data.guid;
getTableData();
promiseList(
getTableData()
)
}
// 获取标签数据
const getTableData = () => {
tableInfo.value.loading = true;
getCgLabelPageList(
Object.assign({}, searchItemValue.value, {
pageIndex: page.value.curr,
pageSize: page.value.limit,
})
).then((res: any) => {
tableInfo.value.loading = false;
const params = Object.assign({}, searchItemValue.value, {
pageIndex: page.value.curr,
pageSize: page.value.limit,
})
return getCgLabelPageList(params).then((res: any) => {
if (res.code == proxy.$passCode) {
tableInfo.value.data = res.data.records || [];
tableInfo.value.page.curr = res.data.pageIndex;
......@@ -193,7 +212,6 @@ const getTableData = () => {
}
})
.catch((res) => {
tableInfo.value.loading = false;
});
};
......@@ -215,7 +233,9 @@ const tablePageChange = (info) => {
page.value.limit = Number(info.limit);
tableInfo.value.page.limit = page.value.limit;
tableInfo.value.page.curr = page.value.curr;
getTableData();
promiseList(
getTableData()
)
} else {
}
......@@ -223,8 +243,7 @@ const tablePageChange = (info) => {
// 获取元数据表格
const getMetaTableData = () => {
getMetaTableCollectList({}).then((res: any) => {
metadataTableInfo.value.loading = false;
return getMetaTableCollectList({}).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data.records || [];
metadataTableInfo.value.data = data;
......@@ -236,16 +255,18 @@ const getMetaTableData = () => {
})
}
}
}).catch(() => {
})
}
const querySearch = (queryString: string) => {
listLoading.value = true
loading.value = true;
const results = queryString
? currpermissionList.value.filter(item => item.dataPermissionName.indexOf(queryString) > -1)
: permissionList.value;
currpermissionList.value = results
listLoading.value = false
loading.value = false;
}
const btnClick = async (btn, bType = null) => {
......@@ -332,7 +353,7 @@ const submitForm = (formEl, info) => {
const handleScroll = () => {
if (listPage.value.curr < listPage.value.totalPages) {
listPage.value.curr++
getPermissionList({})
getPermissionList()
}
}
......@@ -340,20 +361,21 @@ const handleScroll = () => {
const listClick = (row) => {
selectIndex.value = row.guid;
templateInfo.value = row;
getClassifyTree();
searchItemValue.value.classifyGuid = row.guid;
searchItemValue.value.detailGuid = '';
getTableData();
promiseList(
getClassifyTree(),
getTableData()
)
};
// 获取分类列表
const getPermissionList = (val, init = true) => {
const getPermissionList = (val = {}, init = true) => {
let params: any = val ? { ...val } : {}
params.pageIndex = listPage.value.curr;
params.pageSize = listPage.value.limit;
params.type = 'C';
listLoading.value = true
getClassifyGradList(params).then((res: any) => {
return getClassifyGradList(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data?.records || []
if (init) {
......@@ -366,18 +388,14 @@ const getPermissionList = (val, init = true) => {
tempInfo = data.filter(item => item.guid == taskDetail.value.classifyGuid)[0]
}
listClick(tempInfo);
nextTick(() => {
toolH.value = toolRef.value.offsetHeight
})
}
} else {
permissionList.value.push(...JSON.parse(JSON.stringify(data)))
querySearch(asideSearchInput.value)
}
}
listLoading.value = false
}).catch(() => {
listLoading.value = false
})
}
......@@ -386,16 +404,13 @@ const getClassifyTree = () => {
const params = {
classifyGradeGuid: templateInfo.value.guid
}
treeInfo.value.loading = true;
getClassifyTreeList(params).then((res: any) => {
treeInfo.value.loading = false;
return getClassifyTreeList(params).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
treeInfo.value.data = data;
treeInfoRef.value.setCurrentKey('');
}
}).catch(() => {
treeInfo.value.loading = false;
})
}
......@@ -412,15 +427,14 @@ onBeforeMount(() => {
if (route.query.type == 'edit') {
getTaskDetail({ guid: route.query.guid })
} else {
getPermissionList({});
getMetaTableData();
promiseList(
getPermissionList(),
getMetaTableData()
)
}
})
onMounted(() => {
window.addEventListener('resize', function () {
toolH.value = toolRef.value.offsetHeight
})
})
</script>
......@@ -433,14 +447,14 @@ onMounted(() => {
<el-input v-model.trim="asideSearchInput" placeholder="请输入关键字" :prefix-icon="Search" clearable
@change="querySearch" />
</div> -->
<div class="aside_list" v-loading="listLoading" v-infinite-scroll="handleScroll">
<div class="aside_list" v-infinite-scroll="handleScroll">
<div class="list_item" v-for="(item, i) in currpermissionList" :class="{ active: selectIndex == item.guid }"
@click="listClick(item);" v-preReClick>{{ item.name }}</div>
</div>
</div>
<div class="main_wrap" :class="{ full: step == 1 }">
<div class="content_main" v-show="step == 0">
<div class="template_panel" ref="toolRef">
<div class="template_panel">
<div class="title_item">
<span class="title_label">分类标准:</span>
<span class="title_text">{{ templateInfo.name || '--' }}</span>
......@@ -454,7 +468,7 @@ onMounted(() => {
<span class="title_text">{{ templateInfo.description || '--' }}</span>
</div>
</div>
<div class="panel_content" :style="{ height: 'calc(100% - ' + toolH + 'px)' }">
<div class="panel_content">
<div class="box_left">
<Tree ref="treeInfoRef" :treeInfo="treeInfo" @nodeClick="nodeClick" />
</div>
......@@ -563,6 +577,7 @@ onMounted(() => {
display: flex;
flex-wrap: wrap;
padding: 16px 16px 8px;
min-height: 82px;
.title_item {
display: flex;
......@@ -597,14 +612,15 @@ onMounted(() => {
.panel_content {
height: 100%;
display: flex;
flex: 1;
border-top: 1px solid #d9d9d9;
position: relative;
.box_left {
width: 200px;
height: 100%;
border-right: 1px solid #d9d9d9;
position: absolute;
.aside_title {
padding: 0 8px;
......@@ -622,7 +638,10 @@ onMounted(() => {
.box_right {
width: calc(100% - 200px);
height: 100%;
padding-top: 8px;
position: absolute;
right: 0;
.el-breadcrumb {
padding: 0 12px;
......
......@@ -107,7 +107,7 @@ const toPath = (type) => {
guid: currTableData.value.taskGuid,
name: currTableData.value.taskName,
status: currTableData.value.status,
type: currTableData.value.status == 'Y'? 'modify':'confirm'
type: currTableData.value.status == 'Y'? 'detail':'confirm'
},
});
}
......
......@@ -8,10 +8,14 @@ import { ElMessage, ElMessageBox } from "element-plus";
import Table from '@/components/Table/index.vue'
import TableTools from '@/components/Tools/table_tools.vue'
import {getAnalysisReportList,delAnalysisRepor,updateAnalysisRepor} from "@/api/modules/dataMetaService"
import { getImageContent } from "@/api/modules/queryService";
import Dialog from '@/components/Dialog/index.vue'
import { getDownloadUrl, download } from "@/utils/common";
import { useRouter } from 'vue-router';
import {
parseAndDecodeUrl,
getDownFileSignByUrl,
obsDownloadRequest
} from "@/api/modules/obsService";
const router = useRouter()
const page = ref({
limit: 50,
......@@ -119,37 +123,48 @@ const tableSearchItemList: any = ref([{
placeholder: '血缘关系名称',
clearable: true
}]);
const tableBtnClick = (scope, btn) => {
const tableBtnClick = async (scope, btn) => {
const type = btn.value;
let row = scope.row;
rowData.value = row
currTableData.value = row;
if (type == 'view') {
getImageContent(row.analysisReportUrl).then((res: any) => {
if (res && !res.msg) {
let name = row.analysisReportUrl;
var fileSuffix = name ? name.substring(name.lastIndexOf('.') + 1) : '';
if (fileSuffix === 'png') { //浏览器可以支持图片和pdf预览
let fileUrl = getDownloadUrl(res, name, fileSuffix);
let win = window.open(fileUrl, name);
win && (win.document.title = name);
let fileName: string = parseAndDecodeUrl(row.analysisReportUrl).fileName;
const refSignInfo: any = await getDownFileSignByUrl(fileName);
if (!refSignInfo?.data) {
refSignInfo?.msg && ElMessage.error(refSignInfo?.msg);
return;
}
obsDownloadRequest(refSignInfo?.data).then((res: any) => {
if (res && !res.msg) {
var fileSuffix = fileName ? fileName.substring(fileName.lastIndexOf('.') + 1) : '';
if (fileSuffix === 'png') { //浏览器可以支持图片和pdf预览
let fileUrl = <string>getDownloadUrl(res, name, fileSuffix);
let win = window.open(fileUrl, row.analysisReportName + fileSuffix);
win && (win.document.title = row.analysisReportName + fileSuffix);
} else {
download(res, row.analysisReportName, fileSuffix);
}
} else {
download(res, row.analysisReportName, fileSuffix);
res?.msg && ElMessage.error(res?.msg);
}
} else {
res?.msg && ElMessage.error(res?.msg);
}
});
});
} else if (type == 'export') {
getImageContent(row.analysisReportUrl).then((res: any) => {
if (res && !res.msg) {
let name = row.analysisReportUrl;
var fileSuffix = name ? name.substring(name.lastIndexOf('.') + 1) : '';
download(res, row.analysisReportName, fileSuffix);
} else {
res?.msg && ElMessage.error(res?.msg);
let fileName: string = parseAndDecodeUrl(row.analysisReportUrl).fileName;
const refSignInfo: any = await getDownFileSignByUrl(fileName);
if (!refSignInfo?.data) {
refSignInfo?.msg && ElMessage.error(refSignInfo?.msg);
return;
}
});
obsDownloadRequest(refSignInfo?.data).then((res: any) => {
if (res && !res.msg) {
// let name = row.analysisReportUrl;
var fileSuffix = fileName ? fileName.substring(fileName.lastIndexOf('.') + 1) : '';
download(res, row.analysisReportName, fileSuffix);
} else {
res?.msg && ElMessage.error(res?.msg);
}
});
} else if (type == "rename") {
dialogInfo.value.visible = true
formItems.value[0].default = row.analysisReportName
......
......@@ -22,7 +22,11 @@ import {
delLineAge,
checkTableData
} from '@/api/modules/dataMetaService';
import { getFileUrl } from "@/api/modules/queryService"
import {
parseAndDecodeUrl,
getUpFileSignByUrl,
obsUploadRequest
} from "@/api/modules/obsService";
import { useRouter, useRoute } from "vue-router";
import useDataMetaStore from "@/store/modules/dataMeta"
import { cloneDeep } from 'lodash-es'
......@@ -857,17 +861,23 @@ const pageSave = () => {
return
}
let formData = new FormData();
formData.append('file', file.value);
formData.append('fileName', `${analysisReportName}.png`);
getFileUrl(formData).then((res) => {
saveMetaReportAnalysis({
dialogInfo1.value.footer.btns[1].loading = true;
return getUpFileSignByUrl({ fileName: `${analysisReportName}.png` })
.then((res: any) => {
obsUploadRequest({
signedUrl: res.data.signedUrl,
file: file.value,
actualSignedRequestHeaders: res.data.actualSignedRequestHeaders
}).then(() => {
if (res.code == '00000') {
saveMetaReportAnalysis({
table: lastClickNode.value.tableName,
database: lastClickNode.value.databaseName,
analysisReportUrl: res.data,
analysisReportUrl: res.data?.signedUrl,
analysisReportName: analysisReportName,
databaseChName: lastClickNode.value.databaseChName
}).then((res: any) => {
dialogInfo1.value.footer.btns[1].loading = false;
if (res.code == proxy.$passCode) {
ElMessage({
type: "success",
......@@ -883,9 +893,19 @@ const pageSave = () => {
})
}
})
}).catch((res) => {
} else {
ElMessage({
type: "error",
message: res.msg,
appendTo: lineageGraph.value.containerRef
})
}
}).catch((res) => {
ElMessage.error(res.msg)
})
});
}).catch((res) => {
ElMessage.error(res.msg)
});
}
const formItems1: any = ref([
......@@ -933,7 +953,7 @@ const dialogInfo1 = ref({
footer: {
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "保存", value: "submit" },
{ type: "primary", label: "保存", value: "submit", loading: false },
],
},
});
......
......@@ -144,7 +144,7 @@ const getMetaChangeTableData = () => {
}
const activeTabName = ref('task');
const activeTabName = ref('meta');
watch(() => activeTabName.value, (val) => {
if(val==="task"){
......@@ -420,9 +420,7 @@ const metaChangeTableInfo = ref({
// { label: "状态", field: "changeTime", width: 180, },
// { label: "操作时间", field: "changeTime", width: 180, },
],
data: [{
guid: 1
}],
data: [],
page: {
type: "normal",
rows: 0,
......@@ -486,6 +484,7 @@ onBeforeMount(() => {
</div>
<div class="main_wrap">
<el-tabs v-model="activeTabName">
<!--
<el-tab-pane label="同步任务变更记录" name="task">
<div class="table_tool_wrap">
<TableTools :searchItems="tableSearchItemList" :init="false" searchId="detect-table-search"
......@@ -496,6 +495,7 @@ onBeforeMount(() => {
@tablePageChange="taskChangeTablePageChange" />
</div>
</el-tab-pane>
-->
<el-tab-pane label="元数据变更记录" name="meta">
<div class="table_tool_wrap">
<TableTools :searchItems="metaTableSearchItemList" :init="false" searchId="meta-detect-table-search"
......
......@@ -26,9 +26,13 @@ import {
saveMetaReportAnalysis,
checkTableData
} from '@/api/modules/dataMetaService';
import { getFileUrl } from "@/api/modules/queryService"
import useDataMetaStore from "@/store/modules/dataMeta"
import { TableColumnWidth } from '@/utils/enum';
import {
parseAndDecodeUrl,
getUpFileSignByUrl,
obsUploadRequest
} from "@/api/modules/obsService";
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
......@@ -556,18 +560,24 @@ const pageSave = () => {
})
return
}
let formData = new FormData();
formData.append('file', file.value);
formData.append('fileName', `${analysisReportName}.png`);
console.log(formInline1.value.pageName)
getFileUrl(formData).then((res) => {
saveMetaReportAnalysis({
dialogInfo1.value.footer.btns[1].loading = true;
getUpFileSignByUrl({ fileName: `${analysisReportName}.png` })
.then((res: any) => {
obsUploadRequest({
signedUrl: res.data.signedUrl,
file: file.value,
actualSignedRequestHeaders: res.data.actualSignedRequestHeaders
}).then(() => {
if (res.code == '00000') {
saveMetaReportAnalysis({
table: sheetInfo.value.tableName,
database: sheetInfo.value.databaseName,
analysisReportUrl: res.data,
analysisReportUrl: res.data?.signedUrl,
analysisReportName: analysisReportName,
databaseChName: sheetInfo.value.databaseChName
}).then((res: any) => {
dialogInfo1.value.footer.btns[1].loading = false;
if (res.code == proxy.$passCode) {
// ElMessage.success("保存成功")
ElMessage({
......@@ -584,13 +594,19 @@ const pageSave = () => {
})
}
})
}).catch((res) => {
ElMessage({
type: "error",
message: res.msg,
appendTo: lineageGraph.value[0].containerRef
})
})
} else {
ElMessage({
type: "error",
message: res.msg,
appendTo: lineageGraph.value.containerRef
})
}
}).catch((res) => {
ElMessage.error(res.msg)
});
}).catch((res) => {
ElMessage.error(res.msg)
});
}
const formItems1: any = ref([
......@@ -638,7 +654,7 @@ const dialogInfo1 = ref({
footer: {
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "保存", value: "submit" },
{ type: "primary", label: "保存", value: "submit", loading: false },
],
},
});
......
......@@ -238,12 +238,12 @@ const rulesDetailTableBtnClick = (scope, btn) => {
label: row.ruleName
}];
smallCategoryList.value = [{
paramValue: detailInfo.value.smallCategory,
paramName: row.smallCategory
value: detailInfo.value.smallCategory,
label: row.smallCategory
}];
largeCategoryList.value = [{
paramValue: detailInfo.value.largeCategory,
paramName: row.largeCategory
value: detailInfo.value.largeCategory,
label: row.largeCategory
}];
oneRulesDetailDialogVisible.value = true;
} else {
......@@ -268,12 +268,12 @@ const rulesDetailTableBtnClick = (scope, btn) => {
label: row.ruleName
}];
smallCategoryList.value = [{
paramValue: detailInfo.value.smallCategory,
paramName: row.smallCategory
value: detailInfo.value.smallCategory,
label: row.smallCategory
}];
largeCategoryList.value = [{
paramValue: detailInfo.value.largeCategory,
paramName: row.largeCategory
value: detailInfo.value.largeCategory,
label: row.largeCategory
}];
} else {
ElMessage.error(res.msg);
......
......@@ -135,18 +135,18 @@ const rulesListByType: any = computed(() => {
return {};
}
return {
char: checkRulesList.value.filter(r => r.paramValue == 'length_rule' || r.paramValue == 'ch_rule' || r.paramValue == 'en_rule' || r.paramValue == 'num_value_rule' || r.paramValue == 'custom_regular_rule'),
varchar: checkRulesList.value.filter(r => r.paramValue == 'length_rule' || r.paramValue == 'id_card_rule' || r.paramValue == 'phone_number_rule' || r.paramValue == 'ch_rule' || r.paramValue == 'en_rule' || r.paramValue == 'num_value_rule' || r.paramValue == 'custom_regular_rule'),
int: checkRulesList.value.filter(r => r.paramValue == 'length_rule' || r.paramValue == 'num_value_rule' || r.paramValue == 'custom_regular_rule'),
date: checkRulesList.value.filter(r => r.paramValue == 'date_format_rule' || r.paramValue == 'custom_regular_rule'),
datetime: checkRulesList.value.filter(r => r.paramValue == 'date_format_rule' || r.paramValue == 'custom_regular_rule'),
timestamp: checkRulesList.value.filter(r => r.paramValue == 'custom_regular_rule' || r.paramValue == 'custom_regular_rule'),
// text: checkRulesList.value.filter(r => r.paramValue == ''),
decimal: checkRulesList.value.filter(r => r.paramValue == 'length_rule' || r.paramValue == 'precision_rule' || r.paramValue == 'num_value_rule' || r.paramValue == 'custom_regular_rule'),
// json: checkRulesList.value.filter(r => r.paramValue == ''),
tinyint: checkRulesList.value.filter(r => r.paramValue == 'length_rule' || r.paramValue == 'num_value_rule' || r.paramValue == 'custom_regular_rule'),
time: checkRulesList.value.filter(r => r.paramValue == 'custom_regular_rule'),
bit: checkRulesList.value.filter(r => r.paramValue == 'ch_rule' || r.paramValue == 'en_rule' || r.paramValue == 'custom_regular_rule'),
char: checkRulesList.value.filter(r => r.value == 'length_rule' || r.value == 'ch_rule' || r.value == 'en_rule' || r.value == 'num_value_rule' || r.value == 'custom_regular_rule'),
varchar: checkRulesList.value.filter(r => r.value == 'length_rule' || r.value == 'id_card_rule' || r.value == 'phone_number_rule' || r.value == 'ch_rule' || r.value == 'en_rule' || r.value == 'num_value_rule' || r.value == 'custom_regular_rule'),
int: checkRulesList.value.filter(r => r.value == 'length_rule' || r.value == 'num_value_rule' || r.value == 'custom_regular_rule'),
date: checkRulesList.value.filter(r => r.value == 'date_format_rule' || r.value == 'custom_regular_rule'),
datetime: checkRulesList.value.filter(r => r.value == 'date_format_rule' || r.value == 'custom_regular_rule'),
timestamp: checkRulesList.value.filter(r => r.value == 'custom_regular_rule' || r.value == 'custom_regular_rule'),
// text: checkRulesList.value.filter(r => r.value == ''),
decimal: checkRulesList.value.filter(r => r.value == 'length_rule' || r.value == 'precision_rule' || r.value == 'num_value_rule' || r.value == 'custom_regular_rule'),
// json: checkRulesList.value.filter(r => r.value == ''),
tinyint: checkRulesList.value.filter(r => r.value == 'length_rule' || r.value == 'num_value_rule' || r.value == 'custom_regular_rule'),
time: checkRulesList.value.filter(r => r.value == 'custom_regular_rule'),
bit: checkRulesList.value.filter(r => r.value == 'ch_rule' || r.value == 'en_rule' || r.value == 'custom_regular_rule'),
}
});
......@@ -238,8 +238,8 @@ const panelList: any = ref([
default: '1',
options: props.largeCategoryList,
props: {
label: 'paramName',
value: 'paramValue'
label: 'label',
value: 'value'
},
required: true,
visible: true
......@@ -249,8 +249,8 @@ const panelList: any = ref([
placeholder: '请选择',
field: 'smallCategory',
props: {
label: 'paramName',
value: 'paramValue'
label: 'label',
value: 'value'
},
default: '',
options: props.smallCategoryList.slice(6),
......@@ -1006,7 +1006,7 @@ const setPanelListValue = (item, isSelectChange = false, init = false, radioGrou
}
}
if (isSelectChange) {
val['smallCategory'] = panelList.value[2].options[0]?.paramValue;
val['smallCategory'] = panelList.value[2].options[0]?.value;
} else if (!val['smallCategory']) {
val['smallCategory'] = getDefaultSmallCategory(formItems.value[0].default);
} else if (radioGroupChange && !init) {//切换规则类型。
......@@ -2306,8 +2306,8 @@ defineExpose({
<template #default="scope">
<el-select v-if="!props.readonly || (scope.row.dataType == 'text' || scope.row.dataType == 'json')"
v-model="scope.row['checkRule']" placeholder="请选择" filterable clearable>
<el-option v-for="opt in rulesListByType[scope.row.dataType]" :key="opt['paramValue']"
:label="opt['paramName']" :value="opt['paramValue']" />
<el-option v-for="opt in rulesListByType[scope.row.dataType]" :key="opt['value']"
:label="opt['label']" :value="opt['value']" />
</el-select>
<span v-else>{{ scope.row.checkRuleName ?? '--' }}</span>
</template>
......
......@@ -16,6 +16,9 @@ import {
getSmallCategoryList,
getLargeCategoryList,
} from '@/api/modules/dataQuality';
import {
getMetaTreeData
} from '@/api/modules/dataMetaService';
import ruleForm from "../data_quality/ruleForm.vue";
import useUserStore from "@/store/modules/user";
import useDataQualityStore from "@/store/modules/dataQuality";
......@@ -60,7 +63,7 @@ const toSubjectTables: any = ref([]);
const getSubjectTableTreeData = () => {
dsFromTreeDataLoading.value = true;
getSubjectTableTree({}).then((res: any) => {
getMetaTreeData({}).then((res: any) => {
dsFromTreeDataLoading.value = false;
if (res.code == proxy.$passCode) {
dsFromTreeData.value = res.data?.map(d => {
......@@ -428,17 +431,17 @@ const save = () => {
<div class="operator_panel is-block">
<div class="panel_title">
<div class="title_text">
<span>选择主题</span>
<span class="tips_text">选择需要添加质检规则的主题表</span>
<span>选择表</span>
<span class="tips_text">选择需要添加质检规则的表,请确保数据库为脱产环境,避免数据质检影响您的生产环境,且允许在该脱产环境建脏数据的库,请知晓!</span>
</div>
</div>
<TreeTransfer mode="transfer" :title="['主题表', '已选表']" pid="parentGuid"
:from-tree-data-loading="dsFromTreeDataLoading" :lazy="true" :checkOnClickNode="true"
<TreeTransfer mode="transfer" :title="['可选表', '已选表']" pid="parentGuid"
:from-tree-data-loading="dsFromTreeDataLoading" :checkOnClickNode="true"
:from_checked_all="false" :from_data="dsFromTreeData" :to_data="dsToTreeData" node_key="guid"
:transferOpenNode="true" width="70%" :defaultProps="{
label: 'name',
value: 'guid'
}" :lazyFn="handleSubjectTableLazyFn" @left-check-change="handleSubjectCheckedChange"
}"
height="calc(100% - 64px)">
</TreeTransfer>
</div>
......
......@@ -221,7 +221,7 @@ const tableBtnClick = async (scope, btn) => {
const row = scope.row;
currTableData.value = row;
if (type == "export_file") {
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(row.filePath).decodedPath);
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(row.filePath).fileName);
if (!refSignInfo?.data) {
refSignInfo?.msg && ElMessage.error(refSignInfo?.msg);
return;
......@@ -236,7 +236,7 @@ const tableBtnClick = async (scope, btn) => {
//downFile(row.filePath, row.fileName)
} else if (type == 'export_abnormal_data') {
//downFile(row.errorFilePath, '')
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(row.errorFilePath).decodedPath);
const refSignInfo: any = await getDownFileSignByUrl(parseAndDecodeUrl(row.errorFilePath).fileName);
if (!refSignInfo?.data) {
refSignInfo?.msg && ElMessage.error(refSignInfo?.msg);
return;
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!