c7b77154 by lxs

Merge branch 'develop' of http://117.78.60.236:8000/csbr-daop/fe-data-asset-management into develop

2 parents 429ed263 82a6de26
......@@ -36,6 +36,9 @@ VITE_APP_CHECK_BASEURL = ms-daop-zcgl-data-inventory
# 数据字典接口地址
VITE_APP_CONFIG_URL = 'ms-daop-configure-service'
# 文件上传下载接口地址
VITE_APP_COMMON_URL = 'ms-daop-common-service'
#门户接口
VITE_API_PORTALURL = https://swzl-test.zgsjzc.com/portal
......
import request from "@/utils/request";
/** 数仓目录的类型 */
export const enum clickTreeNodeType {
CATALOG = 'catalog',
LEVEL = 'level',
SUBJECTTABLE = 'subjectTable'
}
/** 分层属性类型列表 */
export const layereAttributeList = [{
value: 1,
label: '主题表层'
}, {
value: 2,
label: '维度层'
}, {
value: 4,
label: '主数据层'
}, {
value: 3,
label: '未分类'
}];
/** 表分类类型 */
export const tableCategoryList = [
{
value: 1,
label: "明细表",
},
{
value: 2,
label: "汇总表",
},
{
value: 3,
label: "应用表",
},
{
value: 6,
label: "业务表",
},
// {
// value: 4,
// label: "维度表",
// },
// {
// value: 5,
// label: "缓慢变化维",
// }
];
/** 同步策略 */
export const syncPolicys = [
{
value: 1,
label: "实时",
},
{
value: 2,
label: "增量",
},
{
value: 3,
label: "全量",
},
{
value: 4,
label: "增量加更新",
},
];
/** 维表类型 */
export const dimTypeList = [{
label: "列表",
value: 1,
},
{
label: "层级",
value: 2,
},
{
label: "螺旋",
value: 3,
},
{
label: "通用",
value: 4,
}];
/** 表模型分类 */
export const tableModels = [
{
label: "主键模型",
value: 1,
},
{
label: "聚合模型",
value: 2,
},
{
label: "明细模型",
value: 3,
}
];
/** 聚合方式 */
export const aggMethodList = [{
value: 'SUM',
}, {
value: 'MAX'
}, {
value: 'MIN'
}, {
value: 'REPLACE'
}, {
value: 'REPLACE_IF_NOT_NULL'
}, {
value: 'HLL_UNION'
}, {
value: 'BITMAP_UNION'
}];
/** 数仓目录树列表查询 */
export const getDataWareCatalogList = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-directory/tree-list`,
method: 'post',
data: params
})
/** 获取数仓目录对应的所有分层数据 */
export const getDataWareLevelData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-directory/list`,
method: 'post',
data: params
})
/** 删除数仓分层 */
export const deleteDataWareLevel = (guid) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-directory/del?guid=` + guid,
method: 'delete'
})
/** 修改数仓分层 */
export const updateDataWareLevel = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-directory/update`,
method: 'put',
data: params
})
// 新增数仓分层。
export const addDataWareLevel = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-directory/add`,
method: 'post',
data: params
});
/** 获取主题域对应的所有分层数据 */
export const getSubjectDomainByLevelData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject-domain/list`,
method: 'post',
data: params
})
/** 删除主题域 */
export const deleteSubjectDomain = (guids) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject-domain/del`,
method: 'delete',
data: guids
})
// 详情
export const getSubjectDomainDetail = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject-domain/detail/${params}`,
method: 'get'
})
/** 修改主题域 */
export const updateSubjectDomain = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject-domain/update`,
method: 'put',
data: params
})
// 新增主题域
export const addSubjectDomain = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject-domain/add`,
method: 'post',
data: params
})
/** 获取主题域对应的主题表数据 */
export const getSubjectTable = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/page-list`,
method: 'post',
data: params
})
/** 删除主题表 */
export const deleteSubjectTable = (guids) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/del`,
method: 'delete',
data: guids
})
/** 获取数据库表列表 */
// export const getDatabase = (params) => request({
// url: `${import.meta.env.VITE_APP_API_BASEURL}/data-source/get-source-list`,
// method: 'post',
// data: params
// })
export const getDatabase = (params) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/data-source/list?execGuid=${params.execGuid}`,
method: 'post',
})
/** 根据选择的连接池获取表列表 */
export const getDsTableByDs = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/schema-table-page-list`,
method: 'post',
data: params
})
/** 获取字典列表 */
export const getDictionary = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-dictionary-general/list-all?state=1`,
method: 'post'
})
/** 获取维度列表 */
export const getDimList = () => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/get-dim-list`,
method: 'get'
})
/** 获取标准集列表 */
export const getDataStandardSet = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-standard-set/list-valid`,
method: 'post',
data: params
})
/** 获取命名标准列表 */
export const getTableStandardList = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/table-name-standard/list-standard?standardSetGuid=` + params,
method: 'post'
})
/** 获取命名标准详情,用于懒加载的树形选择,显示正确的标签。 */
export const getTableStandardDetail = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/table-name-standard/detail/${params}`,
method: 'get'
})
/** 获取字段标准列表 */
export const getFieldStandardList = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/field-standard/list-standard?standardSetGuid=` + params,
method: 'post'
})
/** 获取字段标准层级 */
export const getFieldStandardTree = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-standard-set/standard-set-field-list`,
method: 'post',
data: params
});
/** 根据标准集获取字段标准列表分页。 */
export const getFileStandards = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/field-standard/page-list`,
method: 'post',
data: params
})
/** 保存主题表设置,直接入库 */
export const saveSubjectTable = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/add`,
method: 'post',
data: params
})
/** 更新主题设置,直接入库 */
export const updateSubjectTable = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/update`,
method: 'put',
data: params
})
/** 保存主题表设置,草稿 */
export const saveSubjectTableDraft = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/add-draft`,
method: 'post',
data: params
})
/** 更新主题表设置,草稿 TODO,现在无接口 */
export const updateSubjectTableDraft = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/update-draft`,
method: 'put',
data: params
})
/** 获取主题表详情 */
export const getSubjectTableDetail = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/detail/${params}`,
method: 'get'
})
/** 获取主题表详情 */
export const getSubjectTableDetail1 = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/change-detail/${params}`,
method: 'get'
})
/** 根据数据表获取前100行数据 */
export const getDsData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/table-data-preview-page-list`,
method: 'post',
data: params
});
/** 根据数据表获取表结构 */
export const getDsTableStructure = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/table-column-list`,
method: 'post',
data: params
});
/** 查询主题表的数据 */
export const queryData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/subject-data-preview-page-list/${params}`,
method: 'get'
});
// 获取数据类型的接口
export const getDataTypeList = () => request({
url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
method: 'post',
data: { paramCode: "DATA_TYPE" }
})
// 获取字符集接口。
export const getCharacterList = () => request({
url:`${import.meta.env.VITE_APP_API_BASEURL}/data-dict/get-data-list`,
method: 'post',
data: { paramCode: "mysql_charset" }
})
//已有表新建查询主题表字段
export const getSubjectFieldByTables = (params, guid) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/had-new/subject-field-list?subjectDomainGuid=` + guid,
method: 'post',
data: params
});
//已有表分类查询主题表字段
export const getSubjectFieldByTable = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/had-sort/subject-field-list`,
method: 'post',
data: params
});
// 根据文件新建表查询匹配主题表字段。
export const getSubjectFieldByFile = (params, guid) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/subject-field-by-ch-name?subjectDomainGuid=` + guid,
method: 'post',
data: params
});
//获取主题表字段。
export const getSubjectChangingFields = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/changing-fields-table-list`,
method: 'post',
data: params
});
/** 同步表结构 */
export const syncTableStructure = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/synchronization-table-structure`,
method: 'post',
data: params
});
/** 已有表分类保存 */
export const saveSortSubject = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/had-sort/save-subject`,
method: 'post',
data: params
});
/** 检查主题表是否有数据 */
export const checkSubjectTableData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/is-check-data`,
method: 'post',
data: params
});
/** 撤销流程。 */
// export const cancelSubjectFlow = (params) => request({
// url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/cancel-flow`,
// method: 'post',
// data: params
// });
/**导入文件 */
export const importData = (params) => request({
url: `${import.meta.env.VITE_APP_PLAN_BASEURL}/data-catalog-subject/import-data`,
method: 'post',
data: params
});
......@@ -172,6 +172,14 @@ export const getLargeCategoryList = (params) => request({
method: 'get',
})
/**
* 获取字段类型
*/
export const getFieldTypeList = (params) => request({
url: `${import.meta.env.VITE_APP_CONFIG_URL}/dict/data/get-by-dictType?dictType=${params.dictType}`,
method: 'get',
})
/** 分类分级模板数据 */
export const getTempleteClassifyData = (data) => request({
......@@ -595,7 +603,7 @@ export const getDictionary = (params) => request({
* @path /biz-rule-config/save
*/
export const saveBizRuleConfig = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/biz-rule-config/save`,
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/biz-rule-config/save-or-update`,
method: 'post',
data
})
......@@ -644,15 +652,46 @@ export const getDbDirFieldPageList = (data) => request({
data
})
/**
* 数据库目录-表联动查询
* @param data
* @returns
* @path /db-dir/table/select-list
*/
export const getDbDirTableSelectList = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/select-list`,
method: 'post',
data
})
/** 获取已有字段信息 */
export const getDsTableStructure= (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/field/list-by-table-guid`,
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/field/list-by-table-guid?tableGuid=${data.tableGuid}&execGuid=${data.execGuid}`,
method: 'post',
data
});
/** 获取已有数据库目录字段信息 入参是数组 */
export const getDsTableStructures= (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/field/list-by-table-guids`,
method: 'post',
data
});
/**
* 数据库目录-字段查询分类分级
* @param {Object}
* @path /db-dir/field/get-classify-and-grade
*/
export const getDbDirFieldClassifyAndGrade = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/field/get-classify-and-grade`,
method: 'post',
data
})
/** 根据选择的连接池获取表列表 */
export const getDsTableByDs = (params) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/list-by-datasource-guid`,
......
import request from "@/utils/request";
//获取下载签名
export const getDownFileSignByUrl = (params) => {
return request({
url: `${
import.meta.env.VITE_APP_COMMON_URL
}/obs/generate-download-file-signature?fileName=${params.fileName}`,
method: "get",
});
};
//obs下载
export const obsDownloadRequest = (params) => {
return request({
withCredentials: false,
headers: params.actualSignedRequestHeaders
? {
"Content-Type": params.actualSignedRequestHeaders["Content-Type"],
}
: {},
validateStatus: function (status) {
return status >= 200;
},
url: params.signedUrl,
responseType: "blob",
maxRedirects: 0,
data: { unused: 0 },
method: "get",
});
};
//获取上传签名
export const getUpFileSignByUrl = (params) => {
return request({
url: `${
import.meta.env.VITE_APP_COMMON_URL
}/obs/generate-file-signature?fileName=${params.fileName}`,
method: "get",
});
};
//obs上传
export const obsUploadRequest = (params) => {
return request({
withCredentials: false,
headers: params.actualSignedRequestHeaders ? {
"Content-Type": params.actualSignedRequestHeaders[
"Content-Type"
]
} : {},
validateStatus: function (status) {
return status >= 200;
},
url: params.signedUrl,
method: "put",
data: params.file,
});
};
export const getImageContent = (params) => request({
url: `${import.meta.env.VITE_APP_COMMON_URL}/obs/view-pic?filePath=${params.split("?")[0]}`,
method: 'get',
responseType: 'blob'
});
......@@ -24,7 +24,8 @@ const props = defineProps({
const emits = defineEmits(["expand"]);
const isExpanded = ref(true);
// const isExpanded = ref(true);
const isExpanded = ref(props.isExpand);
watch(
() => props.isExpand,
......@@ -46,14 +47,10 @@ const expandSwicthHandler = () => {
</script>
<template>
<ElCard
class="v-content-wrap"
shadow="never"
:body-style="{
padding: `0px`,
height: `${isExpanded ? contentHeight + 28 : 0}px`,
}"
>
<ElCard class="v-content-wrap" shadow="never" :body-style="{
padding: `0px`,
height: `${isExpanded ? contentHeight + 28 : 0}px`,
}">
<template v-if="title" #header>
<div class="card-title" @click="expandSwicthHandler">
<span v-if="expandSwicth" style="padding-right: 5px; cursor: pointer">
......
......@@ -19,10 +19,15 @@ import Schedule from "../Schedule/index.vue";
import { setFormFields, setItemsDisabled, getDownloadUrl, download } from '@/utils/common';
import { ElMessage, ElMessageBox } from 'element-plus';
import useUserStore from "@/store/modules/user";
// import {
// getFileUrl,
// getImageContent
// } from '@/api/modules/queryService';
import {
getFileUrl,
getImageContent
} from '@/api/modules/queryService';
getImageContent,
getUpFileSignByUrl,
obsUploadRequest
} from "@/api/modules/obsSerivice";
import { Editor, EditorExpose } from '@/components/Editor'
const userStore = useUserStore()
......@@ -444,29 +449,35 @@ const uploadFile = (file, item) => {
return Promise.resolve();
}
ruleFormRef.value?.clearValidate([item.field]);
let formData = new FormData();
formData.append('file', file.file);
formData.append('fileName', file.file.name);
return getFileUrl(formData)
// let formData = new FormData();
// formData.append('file', file.file);
// formData.append('fileName', file.file.name);
return getUpFileSignByUrl({ fileName: file.file.name })
.then((res: any) => {
if (res.code == '00000') {
let fileItem = {
name: file.file.name,
url: res.data,
file: file.file
};
if (item.limit === 1) {
formInline.value[item.field] = [fileItem];
obsUploadRequest({
signedUrl: res.data.signedUrl,
file: file.file,
actualsignedRequestHeaders: res.data.actualsignedRequestHeaders
}).then(() => {
if (res.code == '00000') {
let fileItem = {
name: file.file.name,
url: res.data.signedUrl,
file: file.file
};
if (item.limit === 1) {
formInline.value[item.field] = [fileItem];
} else {
formInline.value[item.field].push(fileItem);
}
ruleFormRef.value?.validateField([item.field]);
ElMessage.success('上传成功');
emits("uploadFileChange", formInline.value[item.field]);
} else {
formInline.value[item.field].push(fileItem);
uploadRef.value['ref' + item.field].handleRemove(file);
ElMessage.error('上传失败,请重新上传!');
}
ruleFormRef.value?.validateField([item.field]);
ElMessage.success('上传成功');
emits("uploadFileChange", formInline.value[item.field]);
} else {
uploadRef.value['ref' + item.field].handleRemove(file);
ElMessage.error('上传失败,请重新上传!');
}
})
})
.catch(() => {
uploadRef.value['ref' + item.field].handleRemove(file);
......
......@@ -99,8 +99,9 @@ onMounted(() => {
<el-form-item v-if="item.visible ?? true" :key="'item_' + index"
:class="{ 'width_auto': item.type == 'radio-button' }" :prop="item.field">
<template v-if="item.type == 'select'">
<el-select :class="{ 'is-multiple': item.multiple }" v-model="formInline[item.field]"
:placeholder="item.placeholder" :clearable="item.clearable" :filterable="item.filterable"
<el-select collapse-tags collapse-tags-tooltip :class="{ 'is-multiple': item.multiple }"
v-model="formInline[item.field]" :placeholder="item.placeholder" :clearable="item.clearable"
:filterable="item.filterable" :multiple="item.multiple" :max-collapse-tags="3"
:disabled="item.disabled ?? false" @change="(val) => selectChange(val, item)">
<el-option v-for="opt in item.options" :label="item.props?.label ? opt[item.props.label] : opt.label"
:value="item.props?.value ? opt[item.props.value] : opt.value" />
......
......@@ -206,7 +206,7 @@ export const getDbDirTreeList = {
return {
code: '00000',
message: '成功',
'data|10-30': [{
'data|10-30': {
cgDirName: '@cword(3, 5)',
'children|1-3': [{
databaseGuid: '@guid',
......@@ -218,7 +218,7 @@ export const getDbDirTreeList = {
tableChName: '@cword(3, 5)'
}]
}]
}]
}
}
}
}
......@@ -616,8 +616,221 @@ export const createTableSql = {
}
}
/** 获取已有数据库目录字段信息 入参是数组
export const getDsTableStructures= (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/field/list-by-table-guids`,
method: 'post',
data
});
* "data": [
{
"guid": "string",
"sourceTableName": "string",
"sourceDatabase": "string",
"sourceFieldName": "string",
"sourceFieldChName": "string",
"fieldGuid": "string",
"fieldName": "string",
"fieldChName": "string",
"fieldType": "string",
"fieldLength": 0,
"fieldPrecision": 0,
"dimGuid": "string",
"dictionaryGuid": "string",
"sortValue": 0,
"isPrimary": "string",
"isFk": "string",
"isNotNull": "string",
"classifyDetailGuid": "string",
"classifyDetailName": "string",
"gradeDetailGuid": "string",
"gradeDetailName": "string"
}
],
*/
// 模拟 getDsTableStructures 接口
export const getDsTableStructures = {
url: '/mock/db-dir/field/list-by-table-guids',
method: 'post',
response: ({ body }: { body: any }) => {
return {
code: '00000',
message: '成功',
'data|2-5': [
{
guid: '@guid',
sourceTableName: '@cword(3, 5)',
sourceDatabase: '@cword(3, 5)',
sourceFieldName: '@cword(3, 5)',
sourceFieldChName: '@cword(3, 5)',
fieldGuid: '@guid',
fieldName: '@cword(3, 5)',
fieldChName: '@cword(3, 5)',
fieldType: '@cword(3, 5)',
fieldLength: '@integer(1, 100)',
fieldPrecision: '@integer(1, 100)',
dimGuid: '@guid',
dictionaryGuid: '@guid',
sortValue: '@integer(1, 100)',
isPrimary: 'Y',
isFk: 'Y',
isNotNull: 'Y',
classifyDetailGuid: () => {
return Math.floor(Math.random() * 2) + 3; // 随机生成 3 或 4
},
classifyDetailName: '@cword(3, 5)',
gradeDetailGuid: '@guid',
gradeDetailName: '@cword(3, 5)'
}
]
};
}
};
// 模拟 getGradeDetails 接口
export const getGradeDetails = {
url: '/mock/grade-details',
method: 'post',
response: ({ body }: { body: any }) => {
return {
code: '00000',
message: '成功',
data: [{
}]
};
}
};
let currentGuid = 2;
// 模拟 getTaskExeTreeList 接口
export const getTaskExeTreeList = {
url: '/mock/cg-task-exec/classify/tree-list',
method: 'get',
response: ({ body }: { body: any }) => {
return {
code: '00000',
message: '成功',
data: [{
"guid": 1,
"classifyName": "听参我完",
"parentGuid": 1,
"gradeGuid":1,
"parentGuids": [
"39Ec3B98-EA2F-f5FF-Fc3b-EfAfe1fce91C",
"14be757b-8f0e-3DB9-5AaE-8cfeC18B2322"
],
"children": [
{
"classifyName": "素新议白",
"parentGuid": 4,
"gradeGuid":2,
"parentGuids": [
"de6A2ED4-Dc2f-DBf2-4d14-ceD8fd5BBa7C"
],
"children": [
{
"classifyName": "置表京革",
"parentGuid": 5,
"gradeGuid":3,
"parentGuids": [
"E2FAe9b2-3bc3-B6f7-f99a-964C6ae9dFCE",
"18EA10f2-7f1a-4ADA-cEba-d1dF44ED74cB"
],
"guid": 3
}
],
"guid": 10
}
],
},
{
"guid": 7,
"classifyName": "大头儿子",
"parentGuid": 1,
"gradeGuid":4,
"parentGuids": [
"39Ec3B98-EA2F-f5FF-Fc3b-EfAfe1fce91C",
"14be757b-8f0e-3DB9-5AaE-8cfeC18B2322"
],
"children": [
{
"classifyName": "小头把把",
"parentGuid": 4,
"gradeGuid":5,
"parentGuids": [
"de6A2ED4-Dc2f-DBf2-4d14-ceD8fd5BBa7C"
],
"children": [
{
"classifyName": "喜羊羊",
"parentGuid": 5,
"gradeGuid":6,
"parentGuids": [
"E2FAe9b2-3bc3-B6f7-f99a-964C6ae9dFCE",
"18EA10f2-7f1a-4ADA-cEba-d1dF44ED74cB"
],
"guid": 9
}
],
"guid": 8
}
],
},
]
};
}
};
// 模拟 getGradeList 分级接口 用于获取分级列表
export const getGradeList = {
url: '/mock/grade/page-list',
method: 'post',
response: ({ body }: { body: any }) => {
return {
code: '00000',
message: '成功',
data: {
records:[{
"guid": '1',
"name": "一级",
"parentGuid": 0,
},
{
"guid": '2',
"name": "二级",
"parentGuid": 1,
},
{
"guid": '3',
"name": "三级",
"parentGuid": 2,
},
{
"guid": '4',
"name": "四级",
"parentGuid": 3,
},
{
"guid": '5',
"name": "五级",
"parentGuid": 4,
},
{
"guid": '6',
"name": "六级",
"parentGuid": 5,
},
]
}}
}
};
export default [getCgDirTreeList,getCgDirFieldPageList,
getDictionary,saveBizRuleConfig, getDbDirTreeList,
getDbDirTablePageList,getDbDirDataSourceList,getDsTableByDs,
getDsTableStructure,getDbDirFieldPageList,getBizRuleConfigDetail,
updateBizRuleConfig,saveDbDirTable,createTableSql,updateDbDirTable] as MockMethod[]
updateBizRuleConfig,saveDbDirTable,createTableSql,updateDbDirTable,getDsTableStructures,getGradeDetails,getTaskExeTreeList,getGradeList] as MockMethod[]
......
......@@ -82,7 +82,7 @@ const routes: RouteRecordRaw[] = [
name: 'templateConfig',
component: () => import('@/views/data_inventory/templateConfig.vue'),
meta: {
title: '分类分级标准',
title: '分类分级规则',
breadcrumb: false,
cache: true
},
......
......@@ -6,17 +6,16 @@
import { ref, onMounted } from "vue";
import useUserStore from "@/store/modules/user";
import { useValidator } from '@/hooks/useValidator';
import { TableColumnWidth } from '@/utils/enum';
import G6 from '@antv/g6';
import { IGroup, ModelConfig } from '@antv/g6';
import { getClassifyGradList, getClassifyTreeList, getGradeList, saveClassify, updateClassify, deleteClassify } from "@/api/modules/dataInventory";
import { getClassifyGradList, getClassifyTreeList, getGradeList, saveClassify, updateClassify, deleteClassify, updateClassifyGrad } from "@/api/modules/dataInventory";
const { required, orderNum } = useValidator();
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const route = useRoute();
const fullPath = route.query.fullPath;
const fullPath = route.fullPath;
const userStore = useUserStore();
const fullscreenLoading = ref(false);
......@@ -30,19 +29,43 @@ const classStandardFormItems = ref([{
field: 'classStandardName',
default: router.currentRoute.value.query.classStandardName,
clearable: true,
disabled: true,
disabled: false,
required: true
}, {
label: '分级标准',
type: 'input',
// label: '分级标准',
// type: 'input',
// placeholder: '请选择',
// field: 'gradeStandard',
// default: '',
// required: true,
// filterable: true,
// clearable: true,
// disabled: false,
// visible: true,
label: '分级名称',
type: 'select',
placeholder: '请选择',
field: 'gradeStandard',
options: [],
props: {
label: "name",
value: "guid",
},
filterable: true,
clearable: true,
default: '',
required: true,
filterable: true,
block: false,
},
{
label: '分类描述',
type: 'textarea',
placeholder: '请输入',
field: 'description',
default: '',
clearable: true,
disabled: true,
visible: true,
required: false,
block: true
}]);
// 定义层级映射1->一级,2->二级,3->三级,4->四级
......@@ -60,7 +83,7 @@ const tableInfo = ref({
multiple: false,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "分类", field: "classifyName", width: 160, type: 'expand' },
{ label: "规则名称", field: "classifyName", width: 160, type: 'expand' },
{
label: "层级", field: "level", width: 120, getName: (scope) => {
let level = scope.row.level;
......@@ -77,7 +100,7 @@ const tableInfo = ref({
{
label: "最低安全级别参考", field: "name", width: 140, getName: (scope) => {
let dataGrade = scope.row.dataGrade;
return dataGrade + '级';
return dataGrade ? dataGrade + '级' : '--';
}
},
{ label: "修改人", field: "updateUserName", width: 140 },
......@@ -93,12 +116,12 @@ const tableInfo = ref({
btns: [
{
label: "编辑", value: "edit", click: (scope) => {
// console.log(drawerRef.value.drawerFormRef[0].ruleFormRef);
console.log(scope.row);
currentEditingGuid.value = scope.row.guid;
selectParentEdit(scope.row.guid);
currTableInfo.value = scope.row;
drawerInfo.value.visible = true;
drawerInfo.value.header.title = '编辑分类';
drawerInfo.value.header.title = '编辑规则';
classEditFormItems.value.forEach(item => {
item.default = scope.row[item.field]
})
......@@ -165,7 +188,7 @@ const classEditFormItems = ref([{
type: 'select',
placeholder: '请选择',
field: 'gradeGuid',
default: 1,
default: '',
options: [], //TODO
props: {
label: "name",
......@@ -187,7 +210,7 @@ const classEditFormItems = ref([{
}, {
label: '定义说明',
type: 'textarea',
placeholder: '请输入',
placeholder: '分类规则的描述说明',
field: 'description',
default: '',
clearable: true,
......@@ -282,7 +305,7 @@ const drawerInfo = ref({
direction: 'rtl',
size: 600,
header: {
title: '添加分类',
title: '添加规则',
},
type: '',
container: {
......@@ -301,7 +324,7 @@ const drawerBtnClick = async (btn, info) => {
if (btn.value == 'cancel') {
drawerInfo.value.visible = false;
} else {
if (drawerInfo.value.header.title == '添加分类') {
if (drawerInfo.value.header.title == '添加规则') {
drawerInfo.value.footer.btns.map((item: any) => (item.disabled = true));
const params = {
...info,
......@@ -309,7 +332,7 @@ const drawerBtnClick = async (btn, info) => {
}
const res: any = await saveClassify(params);
if (res.code == proxy.$passCode) {
proxy.$ElMessage.success('添加成功!');
proxy.$ElMessage.success('添加规则成功!');
drawerInfo.value.visible = false;
getTreeListData();
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled);
......@@ -322,11 +345,13 @@ const drawerBtnClick = async (btn, info) => {
const params = {
...info,
classifyGradeGuid: router.currentRoute.value.query.guid,
guid: currTableInfo.value.guid
guid: currTableInfo.value.guid,
gradeGuid: info.gradeGuid || '',
parentGuid: info.parentGuid || '',
}
const res: any = await updateClassify(params);
if (res.code == proxy.$passCode) {
proxy.$ElMessage.success('修改成功!');
proxy.$ElMessage.success('编辑规则成功!');
drawerInfo.value.visible = false;
drawerInfo.value.footer.btns.map((item: any) => delete item.disabled);
getTreeListData();
......@@ -350,8 +375,10 @@ const getClassifyGradListData = async () => {
const res: any = await getClassifyGradList(refGradePageParams.value);
if (res.code == proxy.$passCode) {
classifyGradListData.value = res.data.records || [];
const gradeName = findStandardName(router.currentRoute.value.query.refGradeGuid as any);
classStandardFormItems.value[1].default = gradeName;
classStandardFormItems.value[1].options = classifyGradListData.value;
// const gradeName = findStandardName(router.currentRoute.value.query.refGradeGuid as any);
classStandardFormItems.value[1].default = router.currentRoute.value.query.refGradeGuid;
classStandardFormItems.value[2].default = router.currentRoute.value.query.description;
} else {
proxy.$ElMessage.error(res.msg);
}
......@@ -360,7 +387,7 @@ const findStandardName = (guid: string) => {
const item: any = classifyGradListData.value.find((item: any) => item.guid == guid);
return item ? item.name : '';
}
const tableRef = ref(null); // 表格的 ref
// 获取分类树形列表
const treeListParams = ref({
pageIndex: 1,
......@@ -377,6 +404,7 @@ const getTreeListData = async () => {
classEditFormItems.value[2].options = treeListData.value;
shapeTreeListData.value = treeListData.value;
tableInfo.value.loading = false;
} else {
proxy.$ElMessage.error(res.msg);
}
......@@ -435,7 +463,7 @@ const newCreateClass = () => {
drawerInfo.value.visible = true;
classEditFormItems.value[2].options = treeListData.value;
drawerInfo.value.header.title = '添加分类';
drawerInfo.value.header.title = '添加规则';
classEditFormItems.value.forEach(item => {
if (item.field == 'status') {
item.default = 'Y';
......@@ -445,18 +473,66 @@ const newCreateClass = () => {
})
}
const saveLoading = ref(false);
const saveUpdate = async () => {
console.log(formRef.value.formInline);
if (!formRef.value.formInline.classStandardName) {
proxy.$ElMessage.error('分类名称不能为空');
return;
}
if (!formRef.value.formInline.gradeStandard) {
proxy.$ElMessage.error('分级名称不能为空');
return;
}
saveLoading.value = true;
const params = {
guid: router.currentRoute.value.query.guid,
name: formRef.value.formInline.classStandardName,
refGradeGuid: formRef.value.formInline.gradeStandard,
type: 'C',
description: formRef.value.formInline.description
}
console.log(params);
const res: any = await updateClassifyGrad(params);
if (res.code == proxy.$passCode) {
proxy.$ElMessage.success('修改分类成功');
router.push({
name: 'templateConfig'
});
saveLoading.value = false;
} else {
saveLoading.value = false;
proxy.$ElMessage.error(res.msg);
}
}
/** 导入分类。 */
const importClass = () => {
}
const dataShowMethod = ref('table');
// 创建聚合数据
const updatedTreeData = ref<any>();
/** 切换是图形展示,还是表格展示。 */
const changeShowMethod = () => {
dataShowMethod.value = dataShowMethod.value == 'table' ? 'shape' : 'table';
console.log(shapeTreeListData.value);
if (dataShowMethod.value == 'shape') {
const tempArr = {
classifyName: router.currentRoute.value.query.classStandardName,
guid: "1",
children: shapeTreeListData.value
}
updatedTreeData.value = [tempArr];
console.log('updatedTreeData', [tempArr]);
}
}
const cancel = () => {
console.log(userStore.tabbar);
console.log(fullPath);
proxy.$openMessageBox("当前页面尚未保存,确定放弃修改吗?", () => {
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({
......@@ -613,13 +689,14 @@ const initGraph = () => {
},
getHGap: function getHGap() {
return 80;
}
},
}
});
graph.data(shapeTreeListData.value[0]);
graph.data(updatedTreeData.value[0]);
graph.on('node:mouseenter', (e) => {
const nodeItem = e.item; // 获取鼠标进入的节点元素对象
const nodeModel = nodeItem.getModel();
if (nodeModel.guid == '1') return; // 根节点不显示
// 更新弹窗位置和显示节点详情
nodeDetails.value = nodeModel;
showNodeDetails.value = true;
......@@ -739,22 +816,30 @@ onMounted(() => {
// });
})
const isExpand = ref<boolean>(router.currentRoute.value.query.isExpand == 'true');
const isExpand1 = ref<boolean>(true);
const expand = (item) => {
console.log(item);
isExpand1.value = item
}
</script>
<template>
<div class="container_wrap" v-loading="fullscreenLoading">
<div class="content_main">
<ContentWrap id="id-baseInfo" title="基础信息" description="" style="margin-top: 8px;">
<ContentWrap id="id-baseInfo" title="基础信息" description="" style="margin-top: 8px;" :expandSwicth="true"
:isExpand="isExpand">
<Form ref="formRef" :itemList="classStandardFormItems" formId="main-model-edit" col="col3" />
</ContentWrap>
<ContentWrap id="id-classStandard" class="detail-content" title="分类标准" description=""
style="margin-top:16px; height: calc(100% - 161px)">
<ContentWrap id="id-classStandard" class="detail-content" title="分类规则" description=""
style="margin-top:16px; height: calc(100% - 161px)" :expandSwicth="true" :isExpand="isExpand1" @expand="expand">
<div class="tools_btns">
<el-button v-show="dataShowMethod == 'table'" type="primary" @click="newCreateClass">添加分类</el-button>
<el-button v-show="dataShowMethod == 'table'" type="primary" @click="newCreateClass">添加规则</el-button>
<!-- <el-button v-show="dataShowMethod == 'table'" @click="importClass">导入分类</el-button> -->
<el-button class="show-change-btn" @click="changeShowMethod">{{ '图形展示' }}</el-button>
</div>
<Table v-show="dataShowMethod == 'table'" :tableInfo="tableInfo" />
<Table v-show="dataShowMethod == 'table'" :tableInfo="tableInfo" :ref="tableRef" />
<div ref="shapeMain" class="shape-main" v-show="dataShowMethod != 'table'"></div>
<div v-if="showNodeDetails" class="node-details-popup"
:style="{ top: popupPosition.top + 'px', left: popupPosition.left + 'px' }">
......@@ -778,6 +863,7 @@ onMounted(() => {
</div>
<div class="bottom_tool_wrap">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="saveUpdate" :loading="saveLoading">保存修改</el-button>
</div>
<Drawer :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" ref="drawerRef" />
</div>
......@@ -791,6 +877,7 @@ onMounted(() => {
.content_main {
height: calc(100% - 44px);
padding: 10px 16px;
overflow: auto;
}
.bottom_tool_wrap {
......@@ -809,6 +896,7 @@ onMounted(() => {
.card-body-content {
height: 100%;
overflow: auto;
}
}
}
......@@ -824,11 +912,11 @@ onMounted(() => {
}
.shape-main {
height: calc(100% - 58px);
height: calc(100% - 44px);
}
.table_panel {
height: calc(100% - 58px) !important;
height: calc(100% - 44px) !important;
}
.node-details-popup {
......
......@@ -6,8 +6,11 @@
import router from "@/router";
import { ref } from "vue";
import { saveGrade, getGradeList, deleteGrade, getLargeCategoryList, updateGrade } from '@/api/modules/dataInventory';
import { saveGrade, getGradeList, deleteGrade, getLargeCategoryList, updateGrade, updateClassifyGrad } from '@/api/modules/dataInventory';
import useUserStore from "@/store/modules/user";
const userStore = useUserStore();
const route = useRoute();
const fullPath = route.fullPath;
onBeforeMount(() => {
getGradeListData();
getDataGrade();
......@@ -16,7 +19,6 @@ onBeforeMount(() => {
// 获取分级列表
const getGradeListData = async () => {
console.log('调用了吗~~~');
tableInfo.value.loading = true;
const params = {
pageIndex: 1,
......@@ -111,7 +113,8 @@ const tableInfo = ref({
id: "data-class-standard-table",
multiple: true,
fields: [
{ label: "序号", field: 'orderNum', width: 56, align: "center" },
{ label: "序号", type: 'index', width: 56, align: "center" },
// { label: "排序", field: 'orderNum', width: 56, align: "center" },
{
label: "数据级别", field: "dataGrade", width: 120, getName: (scope) => {
let dataGrade = scope.row.dataGrade;
......@@ -124,7 +127,7 @@ const tableInfo = ref({
return classDataRef.value.find((item: any) => item.value === dataClassify)?.label;
}
},
{ label: "分级描述", field: "gradeDesc", align: "left", width: 480 },
{ label: "规则描述", field: "gradeDesc", align: "left" },
],
actionInfo: {
......@@ -137,7 +140,7 @@ const tableInfo = ref({
console.log(scope);
filterDataGradeEdit(scope.row.dataGrade);
newCreateGradeStandardDialogInfo.value.visible = true;
newCreateGradeStandardDialogInfo.value.title = '编辑分类';
newCreateGradeStandardDialogInfo.value.title = '编辑规则';
newCreateGradeFormItems.value.forEach(item => {
item.default = scope.row[item.field];
})
......@@ -228,7 +231,7 @@ const newCreateGradeFormItems = ref([{
visible: true,
},
{
label: '序号',
label: '序号',
type: 'input',
maxlength: 19,
placeholder: '请输入',
......@@ -239,10 +242,10 @@ const newCreateGradeFormItems = ref([{
regexp: /\D/g
},
{
label: '分级描述',
label: '规则描述',
type: 'textarea',
maxlength: 500,
placeholder: '分类分级的描述说明',
placeholder: '分级规则的描述说明',
field: 'gradeDesc',
default: '',
clearable: true,
......@@ -265,7 +268,7 @@ const newCreateGradeFormRules = ref({
const newCreateGradeStandardDialogInfo = ref({
visible: false,
size: 860,
title: "添加分类",
title: "新增规则",
type: "",
formInfo: {
id: "grade-form",
......@@ -278,9 +281,8 @@ const newCreateGradeStandardDialogInfo = ref({
newCreateGradeStandardDialogInfo.value.visible = false;
},
submit: async (btn, info) => {
console.log(info, guid);
newCreateGradeStandardDialogInfo.value.submitBtnLoading = true;
if (newCreateGradeStandardDialogInfo.value.title === '编辑分类') {
if (newCreateGradeStandardDialogInfo.value.title === '编辑规则') {
const params = {
...info,
guid: editClassifyGradeGuid.value,
......@@ -291,7 +293,7 @@ const newCreateGradeStandardDialogInfo = ref({
if (res.code == proxy.$passCode) {
proxy.$ElMessage({
type: 'success',
message: '修改分类成功'
message: '编辑规则成功'
})
getGradeListData();
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
......@@ -309,7 +311,7 @@ const newCreateGradeStandardDialogInfo = ref({
if (res.code == proxy.$passCode) {
proxy.$ElMessage({
type: 'success',
message: '新增分类成功'
message: '新增规则成功'
})
getGradeListData();
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
......@@ -324,22 +326,86 @@ const newCreateGradeStandardDialogInfo = ref({
const newStandard = () => {
filterDataGrade();
newCreateGradeStandardDialogInfo.value.title = '新增规则';
newCreateGradeStandardDialogInfo.value.visible = true;
newCreateGradeFormItems.value.forEach(item => item.default = '');
}
const formRef = ref<any>();
const classStandardFormItems = ref([{
label: '分级名称',
type: 'input',
maxlength: 50,
placeholder: '请输入',
field: 'name',
default: router.currentRoute.value.query.classClassifyGradName,
block: false,
clearable: true,
required: true
}]);
const saveLoading = ref(false);
const saveUpdate = async () => {
console.log(formRef.value.formInline);
if (!formRef.value.formInline.name) {
proxy.$ElMessage.error('分级名称不能为空');
return;
}
saveLoading.value = true;
const params = {
guid: router.currentRoute.value.query.guid,
name: formRef.value.formInline.name,
type: 'G',
}
console.log(params);
const res: any = await updateClassifyGrad(params);
if (res.code == proxy.$passCode) {
proxy.$ElMessage.success('修改分级成功');
router.push({
name: 'templateConfig'
});
saveLoading.value = false;
} else {
saveLoading.value = false;
proxy.$ElMessage.error(res.msg);
}
}
const cancel = () => {
proxy.$openMessageBox("当前页面尚未保存,确定放弃修改吗?", () => {
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({
name: 'templateConfig'
});
}, () => {
proxy.$ElMessage.info("已取消");
});
}
</script>
<template>
<div class="container_wrap" v-loading="fullscreenLoading">
<div class="container_wrap">
<div class="content_main">
<div class="table-top-btns">
<el-button type="primary" @click="newStandard">新增标准</el-button>
<el-button @click="batchRemobe">批量删除</el-button>
</div>
<Table ref="tableRef" :tableInfo="tableInfo" @tableSelectionChange="onTableSelectChange" />
<ContentWrap id="id-baseInfo" title="基础信息" description="" style="margin-top: 8px;">
<Form ref="formRef" :itemList="classStandardFormItems" formId="main-model-edit" col="col3" />
</ContentWrap>
<ContentWrap id="id-grade-info" title="分级规则" class="detail-content" description="" style="margin-top: 8px;">
<div class="content" v-loading="fullscreenLoading">
<div class="table-top-btns">
<el-button type="primary" @click="newStandard">新增规则</el-button>
<el-button @click="batchRemobe">批量删除</el-button>
</div>
<Table ref="tableRef" :tableInfo="tableInfo" @tableSelectionChange="onTableSelectChange" />
</div>
</ContentWrap>
</div>
<div class="bottom_tool_wrap">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="saveUpdate" :loading="saveLoading">保存修改</el-button>
</div>
<Dialog_form :dialogConfigInfo="newCreateGradeStandardDialogInfo" />
</div>
......@@ -351,11 +417,49 @@ const newStandard = () => {
.content_main {
height: calc(100% - 44px);
padding: 17px 16px 10px 16px;
padding: 10px 16px;
overflow: auto;
.table-top-btns {
display: flex;
margin-bottom: 12px;
}
}
.bottom_tool_wrap {
height: 44px;
padding: 0 16px;
border-top: 1px solid #d9d9d9;
display: flex;
justify-content: center;
align-items: center;
}
:deep(.detail-content) {
.el-card__body {
height: calc(100% - 50px) !important;
.card-body-content {
height: 100%;
}
}
}
.tools_btns {
position: relative;
margin-bottom: 16px;
.show-change-btn {
position: absolute;
right: 0px;
}
}
.shape-main {
height: calc(100% - 40px);
}
.table_panel {
height: calc(100% - 40px) !important;
}
</style>
......
......@@ -7,7 +7,9 @@ import { Warning } from "@element-plus/icons-vue";
import TableTools from '@/components/Tools/table_tools.vue';
import {
getCgDirTreeList, getCgDirFieldPageList, getDictionary, saveBizRuleConfig,
getDbDirTreeList, getDbDirTablePageList, getDbDirFieldPageList, getExecGuidAndName
getDbDirTreeList, getDbDirTablePageList, getDbDirFieldPageList, getExecGuidAndName,
getClassifyTreeList, getCgLabelPageList, execTaskFieldList, execTaskSheetList, getTaskExeTreeList,
getDbFieldList
} from '@/api/modules/dataInventory';
import { TableColumnWidth } from "@/utils/enum";
import router from "@/router";
......@@ -20,15 +22,16 @@ const CgDirTreeList = ref();
const getCgDirTreeData = async () => {
treeInfo.value.loading = true;
const params = {
classifyName: '',
execGuid: execGuidInfo.value.execGuid
}
const res: any = await getCgDirTreeList(params);
const res: any = await getTaskExeTreeList(params);
if (res.code == proxy.$passCode) {
CgDirTreeList.value = res.data;
treeInfo.value.data = res.data;
currentPath.value = [res.data[0].classifyName];
treeInfo.value.expandedKey = [res.data[0].guid];
treeInfo.value.currentNodeKey = res.data[0].guid;
searchItemList.value[1].options = res.data;
treeInfo.value.loading = false;
} else {
proxy.$ElMessage.error(res.msg);
......@@ -41,18 +44,16 @@ const getCgDirFieldPage = async (params = {}) => {
// 在这里你可以根据需要扩展或修改 params
const defaultParams = {
pageIndex: 1,
pageSize: 10,
dirGuid: '',
label: '',
fieldName: '',
classifyName: '',
gradeDetailName: '',
tableName: '',
database: '',
dirGuids: [],
pageSize: 50,
execGuid: '',
classifyDetail: '',
gradeDetailGuid: '',
databaseGuid: '',
tableGuid: '',
fieldGuid: '',
};
const finalParams = { ...defaultParams, ...params };
const res: any = await getCgDirFieldPageList(finalParams);
const res: any = await execTaskFieldList(finalParams);
if (res.code == proxy.$passCode) {
CgDirFieldPageList.value = res.data.records;
tableInfo.value.page.rows = res.data.totalRows;
......@@ -90,11 +91,15 @@ const getExecGuid = async () => {
}
onMounted(() => {
getCgDirTreeData();
getCgDirFieldPage();
onMounted(async () => {
await getExecGuid();
await getCgDirTreeData();
await getCgDirFieldPage({
execGuid: execGuidInfo.value.execGuid
});
getDictionaryList();
getExecGuid();
getSearchTableList();
})
// 左侧tree-list
......@@ -104,12 +109,12 @@ const treeInfo = ref({
editTreeItem: false,
queryValue: "",
className: 'tree-list',
queryPlaceholder: "输入标准集名称搜索",
queryPlaceholder: "输入名称搜索",
props: {
label: "classifyName",
value: "guid",
value: "classifyDetailGuid",
},
nodeKey: 'guid',
nodeKey: 'classifyDetailGuid',
expandedKey: ['0'],
currentNodeKey: '',
expandOnNodeClick: false,
......@@ -117,6 +122,7 @@ const treeInfo = ref({
loading: false
});
const addStandardSet = () => {
console.log('addStandardSet');
}
......@@ -139,33 +145,24 @@ const searchItemList = ref([
},
clearable: true,
},
// {
// label: '字段名',
// type: 'select',
// maxlength: 19,
// placeholder: '选择字段名',
// field: 'fieldName',
// default: '',
// options: [],
// props: {
// label: 'name',
// value: 'guid',
// },
// clearable: true,
// },
{
label: '分类',
type: 'select',
maxlength: 19,
placeholder: '选择分类',
label: "",
placeholder: '分类',
field: 'classifyName',
type: 'tree-select',
default: '',
options: [],
showAllLevels: false,
checkStrictly: true,
lazy: false,
props: {
label: 'name',
value: 'guid',
label: "classifyName",
value: "classifyDetailGuid",
},
clearable: true,
block: false,
filterable: false,
clearable: false,
required: false
}, {
label: '分级',
type: 'select',
......@@ -199,8 +196,14 @@ const toSearch = (val: any, clear: boolean = false) => {
// return getTableData(params);
};
const nodeClick = (data: any) => {
const { guid, classifyName } = data
const nodeClick = async (data: any) => {
console.log('nodeClick', data);
const { guid, classifyDetailGuid } = data
searchItemList.value[1].default = data.classifyName;
await getCgDirFieldPage({
execGuid: execGuidInfo.value.execGuid,
classifyDetail: classifyDetailGuid,
});
// 递归tempData找到所有祖先元素的standardName,存入currentPath中
const path = findPath(CgDirTreeList.value, guid);
if (path) {
......@@ -210,6 +213,7 @@ const nodeClick = (data: any) => {
console.error('未找到路径');
}
}
const findPath = (data: any[], targetGuid: string, path: string[] = []) => {
for (const item of data) {
path.push(item.classifyName); // 添加当前节点名称
......@@ -292,7 +296,7 @@ const tableCheckboxSelectChange = (select, row) => {
let rulesName: any = [];
let rulesGuid: any = [];
select.forEach((item: any) => {
rulesName.push(item.classifyName);
rulesName.push(item.fieldName);
rulesGuid.push(item.guid);
});
selectedRulesData.value = {
......@@ -305,7 +309,7 @@ const tableCheckboxAllSelectChange = (select) => {
let rulesName: any = [];
let rulesGuid: any = [];
select.forEach((item: any) => {
rulesName.push(item.classifyName);
rulesName.push(item.fieldName);
rulesGuid.push(item.guid);
});
selectedRulesData.value = {
......@@ -364,9 +368,9 @@ const dataBaseTableInfo = ref({
fixedSelection: true,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "数据源", field: "cgDirName", width: 140 },
{ label: "表名称", field: "tableName", width: 180 },
{ label: "数据库表", field: "tableChName", width: 120 },
{ label: "数据源", field: "databaseChName", width: 140 },
{ label: "表名称", field: "tableChName", width: 180 },
{ label: "数据库表", field: "tableName", width: 120 },
{
label: "新建方式", field: "foundMode", width: 140, getName: (scope) => {
let dataGrade = scope.row.foundMode;
......@@ -380,7 +384,7 @@ const dataBaseTableInfo = ref({
return status == 0 ? '草稿中' : status == 1 ? '已建表' : '已有默认表';
}
},
{ label: "任务修改人", field: "damName", width: 120 },
{ label: "任务修改人", field: "updateUserName", width: 120 },
{ label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME },
{ label: "描述", field: "description", width: 120, align: 'center' },
{ label: "规划数据资产", field: "isDataAsset", type: 'switch', activeText: '是', inactiveText: '否', activeValue: 'Y', inactiveValue: 'N', switchWidth: 56, width: 120, align: 'center' },
......@@ -397,31 +401,35 @@ const dataBaseTableInfo = ref({
type: "btn",
width: 300,
fixed: 'right',
btns: [
{
label: "配置业务规则", value: "edit", click: (scope) => {
console.log('编辑', scope);
// 路由跳转configure-rules
router.push({
name: 'configureRules',
query: {
cgDirName: scope.row.cgDirName,
tableName: scope.row.tableName,
tableChName: scope.row.tableChName,
tableGuid: scope.row.tableGuid,
description: scope.row.description,
execGuid: execGuidInfo.value.execGuid
}
});
btns: (scope) => {
return [
{
label: "配置业务规则", value: "edit", click: (scope) => {
console.log('编辑', scope);
// 路由跳转configure-rules
router.push({
name: 'configureRules',
query: {
cgDirName: scope.row.cgDirName,
tableName: scope.row.tableName,
tableChName: scope.row.tableChName,
tableGuid: scope.row.tableGuid,
description: scope.row.description,
execGuid: execGuidInfo.value.execGuid
}
});
}
},
{
label: "编辑表结构", value: "edit", click: (scope) => {
console.log('复制', scope);
},
disabled: scope.row.state !== 2 ? false : true
}
},
]
}
{
label: "编辑表结构", value: "copy", click: (scope) => {
console.log('复制', scope);
}
}
]
},
loading: false
......@@ -595,17 +603,31 @@ const drawerBtnClick = async (btn, info) => {
proxy.$ElMessage.error('字段取值范围结束值不能小于开始值');
return;
}
fieldValueRange = [numberStart, numberEnd];
}
const params = {
fieldPrecision,
dictionaryGuid,
isUnique,
isNotNull,
fieldLengthCondition,
fieldValueRange,
fieldGuid: selectedRulesData.value.guids
fieldValueRange = numberStart + '#' + numberEnd;
}
const params: any = [];
selectedRulesData.value.guids.forEach((item: any) => {
params.push({
fieldPrecision,
dictionaryGuid,
isUnique,
isNotNull,
fieldLengthCondition,
fieldValueRange,
fieldGuid: item,
execGuid: execGuidInfo.value.execGuid
})
});
// const params = {
// fieldPrecision,
// dictionaryGuid,
// isUnique,
// isNotNull,
// fieldLengthCondition,
// fieldValueRange,
// fieldGuid: selectedRulesData.value.guids,
// execGuid: execGuidInfo.value.execGuid
// }
const res: any = await saveBizRuleConfig(params);
if (res.code == proxy.$passCode) {
btn.loading = false;
......@@ -613,6 +635,7 @@ const drawerBtnClick = async (btn, info) => {
drawerInfo.value.visible = false;
getCgDirFieldPage();
} else {
btn.loading = false;
proxy.$ElMessage.error(res.msg);
}
......@@ -687,7 +710,7 @@ const getDataBaseTableData = async (params = {}) => {
pageIndex: 1,
pageSize: 10,
databaseGuid: "",
isDataAsset: checked.value ? 'Y' : 'N',
isDataAsset: '',
execGuid: execGuidInfo.value.execGuid,
};
const finalParams = { ...dataBaseParams, ...params };
......@@ -727,7 +750,9 @@ const getDataBaseFieldData = async (params = {}) => {
tableGuid: "",
execGuid: execGuidInfo.value.execGuid,
databaseGuid: "",
isDataAsset: checked.value ? 'Y' : 'N',
isDataAsset: '',
fieldName: '',
gradeDetailName: '',
};
const finalParams = { ...dataBaseParams, ...params };
......@@ -773,11 +798,14 @@ const tableFieldsDataInfo = ref({
const showTableOrDatabase = ref(true);
const isShowCreateBtn = ref(false);
// 定义tableGuid
const tableGuid = ref('');
const dataBaseGuid = ref('');
const dataBaseInfo = ref<any>({});
const dataBasenodeClick = (data: any) => {
isShowCreateBtn.value = false;
console.log('dataBasenodeClick', data);
if (data.cgDirName) {
tableGuid.value = '';
......@@ -786,7 +814,9 @@ const dataBasenodeClick = (data: any) => {
getDataBaseTableData();
}
if (data.databaseGuid) {
dataBaseInfo.value = data;
dataBaseGuid.value = data.databaseGuid;
isShowCreateBtn.value = true;
tableGuid.value = '';
getDataBaseFieldData({
databaseGuid: data.databaseGuid
......@@ -801,9 +831,9 @@ const dataBasenodeClick = (data: any) => {
getDataBaseFieldData({
tableGuid: data.tableGuid
});
getDataBaseTableData({
tableGuid: data.tableGuid
});
// getDataBaseTableData({
// tableGuid: data.tableGuid
// });
}
if (data.databaseGuid || data.cgDirName) {
......@@ -826,7 +856,8 @@ const handleSubjectTableCommand = (command: string) => {
router.push({
name: 'tableCreateFile',
query: {
type: 'tableCreateFile'
type: 'tableCreateFile',
foundMode: 2
}
});
} else if (command === 'existingCreate') {
......@@ -834,7 +865,11 @@ const handleSubjectTableCommand = (command: string) => {
router.push({
name: 'tableCreateExisting',
query: {
execGuid: execGuidInfo.value.execGuid
execGuid: execGuidInfo.value.execGuid,
foundMode: 1,
database: dataBaseInfo.value.database,
databaseChName: dataBaseInfo.value.databaseChName,
databaseGuid: dataBaseInfo.value.databaseGuid,
}
});
}
......@@ -860,53 +895,27 @@ const setActiveTab = (tab) => {
};
// 模拟后端接口
const fetchOptionsA = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve([
{ label: "选项 A1", value: "a1" },
{ label: "选项 A2", value: "a2" },
]);
}, 500);
});
};
// 获取查询的数据库名 execTaskSheetList
const fetchOptionsB = (aValue) => {
return new Promise((resolve) => {
setTimeout(() => {
const data = {
a1: [
{ label: "B1-1", value: "b1" },
{ label: "B1-2", value: "b2" },
],
a2: [
{ label: "B2-1", value: "b3" },
{ label: "B2-2", value: "b4" },
],
};
resolve(data[aValue] || []);
}, 500);
});
};
const getSearchTableList = async (type = 1, dbGuid = '') => {
const fetchOptionsC = (bValue) => {
return new Promise((resolve) => {
setTimeout(() => {
const data = {
b1: [
{ label: "C1-1", value: "c1" },
{ label: "C1-2", value: "c2" },
],
b3: [
{ label: "C2-1", value: "c3" },
{ label: "C2-2", value: "c4" },
],
};
resolve(data[bValue] || []);
}, 500);
const res: any = await getDbFieldList({
execGuid: execGuidInfo.value.execGuid,
dbGuid,
type,
});
if (res.code == proxy.$passCode) {
if (type == 1) {
optionsA.value = res.data;
} else if (type == 2) {
optionsB.value = res.data;
} else {
optionsC.value = res.data;
}
} else {
proxy.$ElMessage.error(res.msg);
}
};
const selectedA = ref<any>(null);
const selectedB = ref<any>(null);
const selectedC = ref<any>(null);
......@@ -915,29 +924,33 @@ const optionsA = ref<any>([]);
const optionsB = ref<any>([]);
const optionsC = ref<any>([]);
// 初始化加载第一个下拉框的选项
const loadOptionsA = async () => {
optionsA.value = await fetchOptionsA();
};
// 第一个下拉框值改变时
const onAChange = async () => {
selectedB.value = null;
selectedC.value = null;
optionsB.value = [];
optionsC.value = [];
optionsB.value = await fetchOptionsB(selectedA.value); // 根据 A 动态加载 B 的选项
await getSearchTableList(2, selectedA.value); // 根据 A 动态加载 B 的选项
};
// 第二个下拉框值改变时
const onBChange = async () => {
console.log('onBChange', selectedB.value);
selectedC.value = null;
optionsC.value = [];
optionsC.value = await fetchOptionsC(selectedB.value); // 根据 B 动态加载 C 的选项
await getSearchTableList(3, selectedB.value); // 根据 B 动态加载 C 的选项
};
// 页面加载时初始化 A 的数据
loadOptionsA();
// 导出
const btnClick = async () => {
};
// 分类选择
const treeSelectNodeChange = (node, item) => {
console.log('treeSelectNodeChange', node, item);
}
</script>
......@@ -946,23 +959,25 @@ loadOptionsA();
<div class="v-table-tools">
<el-select v-model="selectedA" placeholder="选择数据库名" @change="onAChange" style="width: 140px; margin-right: 8px"
clearable>
<el-option v-for="item in optionsA" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in optionsA" :key="item.dbGuid" :label="item.name" :value="item.dbGuid" />
</el-select>
<el-select v-model="selectedB" placeholder="选择表名" :disabled="!selectedA" @change="onBChange"
style="width: 140px; margin-right: 8px" clearable>
<el-option v-for="item in optionsB" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in optionsB" :key="item.dbGuid" :label="item.name" :value="item.dbGuid" />
</el-select>
<el-select v-model="selectedC" placeholder="选择字段名" :disabled="!selectedB" style="width: 140px;margin-right: 8px"
clearable>
<el-option v-for="item in optionsC" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in optionsC" :key="item.dbGuid" :label="item.name" :value="item.dbGuid" />
</el-select>
<TableTools :searchItems="searchItemList" :init="false" :searchId="'files-standard-search'" @search="toSearch" />
<TableTools :searchItems="searchItemList" :init="false" :searchId="'files-standard-search'" @search="toSearch"
@treeSelectNodeChange="treeSelectNodeChange" />
</div>
<div class="container_wrap full flex">
<div class="aside_wrap">
<el-tabs v-model="activeName" class="v-tabs" @tab-click="handleClick">
<el-tab-pane label="分类分级目录" name="first">
<Tree :treeInfo="treeInfo" @nodeClick="nodeClick" @itemMenuClick="handleTreeItemMenuClick" />
<!-- <Tree ref="treeInfoRef" :treeInfo="treeInfo" @nodeClick="nodeClick" /> -->
</el-tab-pane>
<el-tab-pane label="数据库目录" name="second">
<Tree :treeInfo="dataBaseTreeInfo" @nodeClick="dataBasenodeClick" @nodeSelectChange='nodeSelectChange' />
......@@ -992,7 +1007,7 @@ loadOptionsA();
<div class="btns-area">
<div class="left-btns">
<el-button type="primary" @click="addStandardSet">查看已生产报告</el-button>
<el-button>导出</el-button>
<el-button @click="btnClick()">导出</el-button>
<el-button @click="batchControlRules">批量配置业务规则</el-button>
</div>
</div>
......@@ -1033,7 +1048,7 @@ loadOptionsA();
<div class="btns-area" v-if="!tableGuid && activeTab === 'table'">
<div class="left-btns">
<div class="dropdown_btn">
<div class="dropdown_btn" v-if="isShowCreateBtn">
<el-dropdown popper-class="table-create-menu" @command="handleSubjectTableCommand"
placement="bottom-start" trigger="click">
<span class="el-dropdown-link">
......
......@@ -6,7 +6,6 @@
import { ref } from "vue";
import router from "@/router";
import { getBizRuleConfigDetail, updateBizRuleConfig } from '@/api/modules/dataInventory'
const { proxy } = getCurrentInstance() as any;
const bizRuleConfigData = ref<any>()
const getBizRuleConfigDetailData = async () => {
......@@ -105,9 +104,25 @@ const moveDown = () => {
// 编辑行
const editRow = (row) => {
if (!row.isEdit) {
const [symbol, value] = row.fieldLengthCondition.split('#');
row.lengthSymbol = symbol; // 初始化符号部分
row.lengthValue = value; // 初始化数值部分
// 编辑fieldLengthCondition
if (row.fieldLengthCondition) {
const [symbol, value] = row.fieldLengthCondition.split('#');
row.lengthSymbol = symbol; // 初始化符号部分
row.lengthValue = value; // 初始化数值部分
} else {
row.lengthSymbol = ''; // 默认值
row.lengthValue = ''; // 默认值
}
//编辑fieldValueRange
if (row.fieldValueRange) {
const [start, end] = row.fieldValueRange.split('-');
row.rangeStart = start; // 初始化符号部分
row.rangeEnd = end; // 初始化数值部分
} else {
row.rangeStart = ''; // 默认值
row.rangeEnd = ''; // 默认值
}
row.isEdit = true; // 进入编辑模式
}
};
......@@ -115,6 +130,7 @@ const editRow = (row) => {
// 保存数据
const saveRow = (row) => {
row.fieldLengthCondition = `${row.lengthSymbol}#${row.lengthValue}`;
row.fieldValueRange = [row.rangeStart || '', row.rangeEnd || ''];
row.isEdit = false
}
......@@ -213,19 +229,23 @@ const saveData = async () => {
"isNotNull": "string",
"fieldValueRange": "string"
*/
const params = tableData.value.map((item: any) => {
return {
guid: item.guid,
const inParams = [] as any
tableData.value.forEach((item: any) => {
const obj = {
guid: router.currentRoute.value.query.tableGuid,
fieldGuid: item.fieldGuid,
fieldLengthCondition: item.fieldLengthCondition,
fieldPrecision: item.fieldPrecision,
dictionaryGuid: item.dictionaryGuid,
isUnique: item.isUnique,
isNotNull: item.isNotNull,
isNotNull: item.isRequired,
fieldValueRange: item.fieldValueRange
}
inParams.push(obj)
})
const res: any = await updateBizRuleConfig(params)
console.log('finalParams', inParams)
const res: any = await updateBizRuleConfig(inParams)
if (res.code === proxy.$passCode) {
proxy.$message.success('修改配置规则成功!')
router.back()
......@@ -270,29 +290,29 @@ const cancel = () => {
<!-- 排序列(不可编辑) -->
<el-table-column type="index" label="排序" width="80" align="center" />
<!-- 字段中文名(不可编辑)fieldChName -->
<el-table-column prop="fieldName" label="字段中文名" width="120">
<el-table-column prop="fieldChName" label="字段中文名" width="120">
<template #default="scope">
{{ scope.row.fieldName ? scope.row.fieldName : '--' }}
{{ scope.row.fieldChName ? scope.row.fieldChName : '--' }}
</template>
</el-table-column>
<!-- 字段英文名(不可编辑) -->
<el-table-column prop="fieldEnglish" label="字段英文名" width="120">
<el-table-column prop="fieldName" label="字段英文名" width="120">
<template #default="scope">
{{ scope.row.fieldEnglish ? scope.row.fieldEnglish : '--' }}
{{ scope.row.fieldName ? scope.row.fieldName : '--' }}
</template>
</el-table-column>
<!-- 分类(不可编辑)classifyName -->
<el-table-column prop="fieldEnglish" label="分类" width="120">
<!-- <el-table-column prop="fieldEnglish" label="分类" width="120">
<template #default="scope">
{{ scope.row.fieldEnglish ? scope.row.fieldEnglish : '--' }}
</template>
</el-table-column>
</el-table-column> -->
<!-- 分级(不可编辑) -->
<el-table-column prop="gradeDetailName" label="分级" width="120" align="center">
<!-- <el-table-column prop="gradeDetailName" label="分级" width="120" align="center">
<template #default="scope">
{{ scope.row.gradeDetailName ? scope.row.gradeDetailName : '--' }}
</template>
</el-table-column>
</el-table-column> -->
<!-- 字段类型fieldType (不可编辑) -->
<el-table-column prop="fieldType" label="字段类型" width="150" align="center">
<template #default="scope">
......@@ -367,11 +387,20 @@ const cancel = () => {
</el-select>
</template>
</el-table-column>
<!-- 字段取值范围 fieldValueRange(可编辑)-->
<el-table-column prop="fieldValueRange" label="字段取值范围" width="150" align="center">
<el-table-column prop="fieldValueRange" label="字段取值范围" width="260" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit">{{ scope.row.fieldValueRange ? scope.row.fieldValueRange : '--' }}</span>
<el-input v-else v-model="scope.row.fieldValueRange" placeholder="请输入字段取值范围" />
<!-- 非编辑模式,展示取值范围 -->
<span v-if="!scope.row.isEdit">
{{ scope.row.fieldValueRange ? scope.row.fieldValueRange.join('-') : '--' }}
</span>
<!-- 编辑模式,显示两个输入框 -->
<div v-else style="display: flex; gap: 5px; align-items: center;">
<el-input v-model="scope.row.rangeStart" placeholder="最小值" style="width: 45%;" type="number" />
<span>-</span>
<el-input v-model="scope.row.rangeEnd" placeholder="最大值" style="width: 45%;" type="number" />
</div>
</template>
</el-table-column>
......
......@@ -9,6 +9,7 @@ import { getLabelList, getClassifyGradeTreeList, saveLabel, getLabelPageList, de
import { CirclePlus, Delete } from "@element-plus/icons-vue";
const { proxy } = getCurrentInstance() as any;
const dialogLabelFormRef = ref();
......@@ -74,6 +75,7 @@ const transformDataForTree = (data: any[]) => {
const labelPageList = ref<any>()
const getLabelPageData = async () => {
refCount.value++;
tableInfo.value.loading = true;
const params = {
pageIndex: page.value.curr,
......@@ -111,7 +113,7 @@ const getLabelListData = async () => {
}
}
onMounted(async () => {
onBeforeMount(async () => {
await getClassifyGradeTree();
await getLabelPageData();
await getLabelListData();
......@@ -136,8 +138,46 @@ const treeInfo = ref<any>({
loading: false
});
// 点击树节点修改分类guid 和 分类明细guid
const nodeClick = (data: any) => {
console.log('nodeClick', data);
// 存储大类的数据。
const findNodeDetails = ref<any>('');
const isLastLayer = ref<boolean>(false);
// 所在层级的info
const atGradeinfo = ref<any>('');
const findTopParentNode = (node: any) => {
if (!node) return;
// 判断是否为最后一层
isLastLayer.value = node.childNodes.length === 0;
if (isLastLayer.value) {
atGradeinfo.value = node.data;
}
// 递归向上查找符合条件的祖先节点
const findCParent = (currentNode: any): any => {
if (!currentNode?.parent) return null; // 没有父节点,停止递归
if (currentNode.parent.data?.type === 'C') {
return currentNode.parent; // 找到符合条件的节点
}
return findCParent(currentNode.parent); // 继续向上查找
};
// 查找最接近的符合条件的祖先节点
const topParent = findCParent(node);
// 更新结果
if (topParent) {
findNodeDetails.value = topParent.data;
}
};
const nodeClick = (data, node) => {
findTopParentNode(node);
newCreateGradeFormItems.value[1].options = transformDataForTree([findNodeDetails.value])
// 分类guid
if (Object.keys(data).includes("type")) {
classifyGuid.value = data.guid;
......@@ -180,8 +220,13 @@ const tableInfo = ref({
fixedSelection: true,
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "标签名", field: "label", type: 'text_btn', class: 'drawer-detail-cell', width: 120, value: 'detail', columClass: 'text_btn' },
{ label: "分类", field: "classifyDetailName", width: 140 },
{ label: "标签名", field: "label", type: 'text_btn', class: 'drawer-detail-cell', width: 160, value: 'detail', columClass: 'text_btn' },
{
label: "分类", field: "classifyNames", getName: (scope) => {
let tempInfo = scope.row.classifyNames;
return tempInfo.join('/')
},
},
{ label: "分级", field: "gradeDetailName", width: 140 },
{
label: '状态', field: 'bizState', type: 'switch', activeText: '启用', inactiveText: '停用', activeValue: 'Y', inactiveValue: 'N', switchWidth: 56, width: 100, align: 'center'
......@@ -280,7 +325,6 @@ const batchRemobe = async () => {
message: '已取消删除'
});
});
};
const tableSwitchBeforeChange = (scope, field, callback) => {
......@@ -410,7 +454,7 @@ const newCreateGradeFormItems = ref<any>([{
{
label: '精确匹配',
type: 'textarea',
maxlength: 500,
maxlength: 260,
placeholder: '请输入字段中文,中间用英文“,”分号隔开',
field: 'matchChValue',
default: '',
......@@ -421,7 +465,7 @@ const newCreateGradeFormItems = ref<any>([{
{
label: '',
type: 'textarea',
maxlength: 500,
maxlength: 260,
placeholder: '请输入字段中文,中间用英文“,”分号隔开',
field: 'matchEnValue',
default: '',
......@@ -459,7 +503,18 @@ const newCreateGradeStandardDialogInfo = ref({
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
},
submit: async (btn, info) => {
console.log(info);
for (let i = 0; i < formRows.value.length; i++) {
const row = formRows.value[i];
// 如果某一条数据的 matchValue, position, name 都为空,则跳过,不校验
if (!row.matchValue && !row.position && !row.name) {
continue; // 如果全为空,跳过这一行的校验
}
if (!row.matchValue || !row.position || !row.name) {
proxy.$ElMessage.error('请填写完整的模糊匹配规则');
return;
}
}
newCreateGradeStandardDialogInfo.value.submitBtnLoading = true;
if (newCreateGradeStandardDialogInfo.value.title === "添加标签") {
const tempParams = formRows.value.map((item) => ({
......@@ -482,6 +537,7 @@ const newCreateGradeStandardDialogInfo = ref({
getLabelPageData();
getLabelListData();
} else {
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
proxy.$ElMessage.error(res.msg);
}
}
......@@ -508,6 +564,7 @@ const newCreateGradeStandardDialogInfo = ref({
getLabelPageData();
getLabelListData();
} else {
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
proxy.$ElMessage.error(res.msg);
}
}
......@@ -516,30 +573,63 @@ const newCreateGradeStandardDialogInfo = ref({
})
// 新增标签
const addNewLabel = () => {
console.log('addNewLabel');
const addNewLabel = async () => {
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
newCreateGradeFormItems.value.forEach(item => {
item.default = '';
item.disabled = false;
});
formRows.value = [{ matchValue: '', position: '', name: '', disabled: false }];
//
if (isLastLayer.value) {
// 选择了最后一级
newCreateGradeFormItems.value[1].default = atGradeinfo.value.guid;
treeInfo.value.expandedKey = [];
treeInfo.value.currentNodeKey = atGradeinfo.value.guid;
treeInfo.value.expandedKey.push(atGradeinfo.value.classifyGradeGuid);
if (atGradeinfo.value?.classifyGradeGuid) {
classifyGuid.value = atGradeinfo.value.classifyGradeGuid;
tempName.value = atGradeinfo.value.name;
classifyDetailGuid.value = atGradeinfo.value.guid;
}
// 遍历classGradeTreeData 找到对应的guid item的refGradeGuid
classGradeTreeData.value.forEach((element: any) => {
if (element.guid === classifyGuid.value) {
tempRefGradeGuid.value = element.refGradeGuid;
}
});
if (tempRefGradeGuid.value) {
await getGradeListData(tempRefGradeGuid.value);
const matchedGrade = gradeListData.value.find(
(element: any) => element.name === tempName.value
);
if (matchedGrade) {
newCreateGradeFormItems.value[2].default = matchedGrade.guid;
}
}
}
newCreateGradeStandardDialogInfo.value.title = '添加标签';
newCreateGradeStandardDialogInfo.value.visible = true;
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
}
const classSearchItemList = ref<any>([
{
type: 'select-slots',
type: 'select',
multiple: true,
label: '',
field: 'labelName',
default: [],
options: [],
placeholder: '请选择标签名称',
clearable: false,
clearable: true,
filterable: true,
visible: true
}
]);
......@@ -551,6 +641,7 @@ const selectChange = async (val: any, row: any) => {
};
/** 搜索查询分类标准 */
const refCount = ref(0);
const searchClass = async (val: any, clear: boolean = false) => {
console.log('searchClass', val, clear);
if (clear) {
......@@ -559,7 +650,7 @@ const searchClass = async (val: any, clear: boolean = false) => {
getLabelPageData();
return;
}
if (val?.labelName?.length !== 0) {
if (val?.labelName?.length !== 0 || refCount.value >= 1) {
tableInfo.value.loading = true;
const params = {
pageIndex: page.value.curr,
......@@ -579,7 +670,6 @@ const searchClass = async (val: any, clear: boolean = false) => {
}
}
};
......@@ -601,12 +691,13 @@ const handleSelectChange = async (val, row, info) => {
newCreateGradeFormItems.value[2].default = matchedGrade.guid;
newCreateGradeFormItems.value[0].default = tempFormData.value.label;
newCreateGradeFormItems.value[1].default = tempFormData.value.classifyDetailGuid;
newCreateGradeFormItems.value[3].default = tempFormData.value.matchChValue;
newCreateGradeFormItems.value[4].default = tempFormData.value.matchEnValue;
}
}
};
const handleTreeSelectNodeChange = (node, item, nodeObj) => {
console.log('handleTreeSelectNodeChange', node, item, nodeObj);
treeInfo.value.expandedKey = [];
treeInfo.value.currentNodeKey = node.guid;
treeInfo.value.expandedKey.push(node.classifyGradeGuid);
......@@ -702,8 +793,8 @@ const deleteRow = (index: number) => {
</div>
<div>
<el-button type="primary" class="v-add" @click="addNewLabel">新增</el-button>
<el-button class="v-import">导入</el-button>
<el-button>导出</el-button>
<!-- <el-button class="v-import">导入</el-button>
<el-button>导出</el-button> -->
</div>
<div class="table_panel_wrap">
<Table :tableInfo="tableInfo" @tableSwitchBeforeChange="tableSwitchBeforeChange"
......@@ -868,6 +959,11 @@ const deleteRow = (index: number) => {
line-height: 24px;
font-weight: 600;
}
.el-dialog__body {
height: 510px;
overflow: auto;
}
}
}
</style>
......
......@@ -196,13 +196,16 @@ const getPreviewData = () => {
const getTableStructure = () => {
let tableName = currDatasourceSelect.value.tableName;
console.log('tableName', currDatasourceSelect.value);
currDsTableStructureLoading.value = true;
currDsTableStructure.value = [];
getDsTableStructure({
tableName: tableName,
dataSourceGuid: databaseInfo.value.guid,
database: databaseInfo.value.databaseNameEn,
databaseType: databaseInfo.value.databaseType
// tableName: tableName,
// dataSourceGuid: databaseInfo.value.guid,
// database: databaseInfo.value.databaseNameEn,
// databaseType: databaseInfo.value.databaseType,
tableGuid: currDatasourceSelect.value.tableGuid,
execGuid: props.execGuid
}).then((res: any) => {
currDsTableStructureLoading.value = false;
if (res.code == proxy.$passCode) {
......@@ -318,7 +321,7 @@ watch(
if (val?.length && !currDatasourceSelect.value?.tableName) {
currDatasourceSelect.value = val[0];
}
emits("datasourceSelectedChange", val);
emits("datasourceSelectedChange", val, databaseGuid.value);
},
{
deep: true,
......
<script lang="ts" setup name="existingTableSelect">
import { ref } from "vue";
import Dialog from "@/components/Dialog/index.vue";
const emits = defineEmits([
"expandValueChange"
]);
const props = defineProps({
tableCreateInfo: {
type: Object,
default: {},
},
partitionAttribute: {
type: Object,
default: {},
},
isLook: {
type: Boolean,
default: false
}
});
const expandProperties: any = computed(() => {
let partitionAttribute = props.tableCreateInfo.partitionAttribute;
return {
partitionMode: partitionAttribute?.partitionMode || 'dynamic',
staticPartitionType: partitionAttribute?.staticPartitionType || 'Range',
partitionCol: partitionAttribute?.partitionCol || "",
partitionTimeUnit: partitionAttribute?.partitionTimeUnit || "DAY",
dynamicPartitionEnd: partitionAttribute?.dynamicPartitionEnd == null ? 3 : partitionAttribute?.dynamicPartitionEnd,
staticPartitionRange: partitionAttribute?.staticPartitionRangeBegin ? [partitionAttribute?.staticPartitionRangeBegin,
partitionAttribute?.staticPartitionRangeEnd] : null,
dynamicPartitionHistory: partitionAttribute?.dynamicPartitionHistory === "Y",
dynamicPartitionHistoryNum: partitionAttribute?.dynamicPartitionHistoryNum,
staticPartitionEnum: partitionAttribute?.staticPartitionEnum,
}
})
const formItems: any = ref([
{
label: "分区模式",
type: "radio-panel",
placeholder: "",
field: "partitionMode",
default: "dynamic",
options: [
{ label: "动态分区", value: "dynamic" },
{ label: "静态分区", value: "static" },
],
children: [],
required: true,
block: true,
col: "no-wrap col2",
},
{
label: "分区类型",
type: "select",
placeholder: "请选择",
options: [
{
label: "Range",
value: "Range",
},
{
label: "List",
value: "List",
},
],
field: "staticPartitionType",
default: 'Range',
required: true,
visible: false,
},
{
label: "分区字段",
type: "select",
placeholder: "请选择",
options: [],
field: "partitionCol",
default: "",
props: {
label: 'chName',
value: 'enName'
},
tooltip: true,
tooltipContent: '分区字段为日期、日期时间类型且为主键的字段。',
clearable: true,
required: true,
visible: true,
},
{
label: "分区单位",
type: "select",
placeholder: "请选择",
options: [
{
value: "DAY",
label: "按天",
},
{
value: "WEEK",
label: "按星期",
},
{
value: "MONTH",
label: "按月",
},
{
value: "YEAR",
label: "按年",
},
],
default: "DAY",
field: "partitionTimeUnit",
required: true,
visible: false,
},
{
type: "select-group",
field: "dynamicPartitionTimeUnit",
children: [
{
label: "分区单位",
type: "select",
placeholder: "请选择",
options: [
{
value: "HOUR",
label: "按小时",
},
{
value: "DAY",
label: "按天",
},
{
value: "WEEK",
label: "按星期",
},
{
value: "MONTH",
label: "按月",
},
{
value: "YEAR",
label: "按年",
},
],
default: "DAY",
field: "partitionTimeUnit",
required: true,
visible: true,
},
{
label: " ",
type: "input",
placeholder: "结束偏移量",
default: 3,
field: "dynamicPartitionEnd",
required: true,
visible: true,
},
],
col: "col2",
visible: true
},
{
label: "分区范围",
type: "date-picker",
field: "staticPartitionRange",
default: null,
placeholder: "开始时间~截止时间",
clearable: true,
required: true,
visible: false,
},
{
type: "checkbox-input",
placeholder: "创建历史分区",
field: "dynamicPartitionHistory",
default: false,
children: [
{
label: "",
type: "input",
placeholder: "历史分区数量",
field: "dynamicPartitionHistoryNum",
default: 1,
required: false,
visible: false,
},
],
class: "dialog-checkbox-input",
visible: true,
required: false,
},
{
label: "分区枚举值",
type: "textarea",
placeholder: "请使用“,”号分隔",
field: "staticPartitionEnum",
default: "",
clearable: true,
required: true,
block: true,
visible: false,
},
]);
const formRules = ref({
staticPartitionType: [
{
validator: (rule: any, value: any, callback: any) => {
if (!value) {
callback(new Error("分区类型不为空"));
} else {
callback();
}
},
trigger: "blur",
},
],
partitionCol: [{
validator: (rule: any, value: any, callback: any) => {
if (!value) {
callback(new Error("分区字段不为空"));
} else {
callback();
}
},
trigger: "blur",
}],
staticPartitionRange: [{
validator: (rule: any, value: any, callback: any) => {
if (!value?.length) {
callback(new Error("分区范围不为空"));
} else {
callback();
}
},
trigger: "blur",
}],
staticPartitionEnum: [{
trigger: "blur",
required: true,
message: '分区枚举值不能为空'
}],
dynamicPartitionHistoryNum: {
validator: (rule: any, value: any, callback: any) => {
const r = /(^[0-9]([0-9]*)$|^[0-9]$)/; // 正整数(可以以0打头)
if (value && !r.test(value)) {
callback(new Error('请填写大于或等于零整数'));
return;
}
if ((value + '').length > 6) {
callback(new Error('请填写小于7位的整数'));
return;
}
callback();
},
trigger: "blur",
},
dynamicPartitionEnd: {
validator: (rule: any, value: any, callback: any) => {
const r = /(^[0-9]([0-9]*)$|^[0-9]$)/; // 正整数(可以以0打头)
if (value && !r.test(value)) {
callback(new Error('请填写大于或等于零整数'));
return;
}
if ((value + '').length > 6) {
callback(new Error('请填写小于7位的整数'));
return;
}
callback();
},
trigger: "blur",
},
});
const expandPropertyDialogInfo = ref({
readonly: false,
visible: false,
size: 700,
height: "270px",
header: {
title: "扩展属性",
},
direction: "column",
type: "",
contents: [
{
type: "form",
title: "",
formInfo: {
readonly: false,
id: "edit-expand-property",
items: formItems.value,
rules: formRules.value,
},
},
],
footer: {
visible: true,
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "确定", value: "submit" },
],
},
});
/** 记录对话框编辑过程中的扩展属性。提交之后才会记录在expandProperties */
const editExpandProperties: any = ref({});
/** 扩展属性弹出对话框 */
const handleClickExpand = () => {
expandPropertyDialogInfo.value.visible = true;
if (props.isLook || props.tableCreateInfo.isCreate) {
expandPropertyDialogInfo.value.contents[0].formInfo.readonly = true;
expandPropertyDialogInfo.value.footer.visible = false;
} else {
expandPropertyDialogInfo.value.contents[0].formInfo.readonly = false;
expandPropertyDialogInfo.value.footer.visible = true;
}
if (expandProperties.value.partitionMode === 'dynamic') {
formItems.value[1].visible = false;
formItems.value[2].visible = true;
formItems.value[3].visible = false;
formItems.value[4].visible = true;
formItems.value[5].visible = false;
formItems.value[6].visible = true;
formItems.value[7].visible = false;
formItems.value[6].children[0].visible = expandProperties.value.dynamicPartitionHistory;
formItems.value[2].options = props.tableCreateInfo.tableFields?.filter(field => field.isPrimary === 'Y' && (field.dataType === 'date' || field.dataType === 'datetime')) || [];
formItems.value[2].tooltipContent = '分区字段为日期、日期时间类型且为主键的字段。';
} else {
formItems.value[1].visible = true;
formItems.value[2].visible = true;
formItems.value[3].visible = true;
formItems.value[4].visible = false;
formItems.value[5].visible = true;
formItems.value[6].visible = false;
formItems.value[7].visible = false;
let val = expandProperties.value.staticPartitionType;
formItems.value[3].visible = val !== 'List';
formItems.value[5].visible = val !== 'List';
formItems.value[7].visible = val === 'List';
if (val !== 'List') {
formItems.value[2].options = props.tableCreateInfo.tableFields?.filter(field => field.isPrimary === 'Y' && (field.dataType === 'date' || field.dataType === 'datetime')) || [];
formItems.value[2].tooltipContent = '分区字段为日期、日期时间类型且为主键的字段。';
} else {
formItems.value[2].options = props.tableCreateInfo.tableFields?.filter(field => field.isPrimary === 'Y') || [];
formItems.value[2].tooltipContent = '分区字段为主键字段。';
}
}
expandPropertyDialogInfo.value.contents[0].formInfo.items = formItems.value;
editExpandProperties.value = Object.assign({}, expandProperties.value);
setFormItems(editExpandProperties.value);
};
/** 重置formItems的值 */
const setFormItems = (row: any = null) => {
formItems.value.forEach(item => {
if (item.field === 'dynamicPartitionTimeUnit') {
item.children.forEach(child => {
child.default = row[child.field];
});
} else if (item.field === 'dynamicPartitionHistory') {
item.default = row[item.field];
item.children.forEach(child => {
child.default = row[child.field];
});
} else {
item.default = row[item.field];
}
})
}
const radioGroupChange = (val, info) => {
formItems.value[0].default = val;
if (val == "dynamic") {
formItems.value[1].visible = false;
formItems.value[2].visible = true;
formItems.value[3].visible = false;
formItems.value[4].visible = true;
formItems.value[5].visible = false;
formItems.value[6].visible = true;
formItems.value[7].visible = false;
} else if (val == "static") {
formItems.value[1].visible = true;
formItems.value[2].visible = true;
formItems.value[3].visible = true;
formItems.value[4].visible = false;
formItems.value[5].visible = true;
formItems.value[6].visible = false;
formItems.value[7].visible = false;
}
expandPropertyDialogInfo.value.contents[0].formInfo.items = formItems.value;
editExpandProperties.value = Object.assign({}, editExpandProperties.value, info)
setFormItems(editExpandProperties.value);
};
const dialogCheckboxChange = (val, info) => {
let opts: any = formItems.value[6].children;
opts[0].visible = val;
editExpandProperties.value = Object.assign({}, editExpandProperties.value, info)
setFormItems(editExpandProperties.value);
};
const dialogSelectChange = (val, row, info) => {
if (row.field == 'staticPartitionType') {
formItems.value[3].visible = val !== 'List';
formItems.value[5].visible = val !== 'List';
formItems.value[7].visible = val === 'List';
if (val !== 'List') {
formItems.value[2].options = props.tableCreateInfo.tableFields?.filter(field => field.isPrimary === 'Y' && (field.dataType === 'date' || field.dataType === 'datetime')) || [];
formItems.value[2].tooltipContent = '分区字段为日期、日期时间类型且为主键的字段。';
} else {
formItems.value[2].options = props.tableCreateInfo.tableFields?.filter(field => field.isPrimary === 'Y') || [];
formItems.value[2].tooltipContent = '分区字段为主键字段。';
}
}
editExpandProperties.value = Object.assign({}, editExpandProperties.value, info)
setFormItems(editExpandProperties.value);
}
const expandPropertyDialogBtnClick = (btn, info) => {
if (btn.value == 'submit') {
emits('expandValueChange', info);
expandPropertyDialogInfo.value.visible = false;
} else if (btn.value == 'cancel') {
expandPropertyDialogInfo.value.visible = false;
}
};
defineExpose({
handleClickExpand
});
</script>
<template>
<Dialog ref="expandPropertyDialogRef" :dialogInfo="expandPropertyDialogInfo" @radioGroupChange="radioGroupChange"
@checkboxChange="dialogCheckboxChange" @selectChange="dialogSelectChange"
@btnClick="expandPropertyDialogBtnClick" />
</template>
<style scoped lang="scss"></style>
......@@ -9,10 +9,15 @@ import StepBar from "@/components/StepBar/index.vue";
import {
getDbDirDataSourceList,
getDsData,
getDsTableStructure,
saveDbDirTable,
updateDbDirTable,
createTableSql,
getDsTableStructures,
getDbDirFieldClassifyAndGrade,
getDbDirTableSelectList,
getTaskExeTreeList,
getGradeList,
getFieldTypeList,
} from "@/api/modules/dataInventory";
import existingTableSelect from "./existingTableSelect.vue";
......@@ -45,8 +50,111 @@ const processData = (data) => {
databaseGuid: undefined, // 删除旧键 "databaseGuid"
})).map(({ databaseGuid, ...rest }) => rest); // 过滤掉 undefined 键
};
const classifyList: any = ref([]);
// 获取分类树形数据
// 定义树形选择器的属性
const treeSelectProps = {
label: "classifyName",
value: "classifyDetailGuid",
children: "children",
};
const treeSelectOptions = ref<any>([]);
// 存储引用的refGradeGuid
const refGradeGuid = ref<any>();
const getFieldTree = () => {
getTaskExeTreeList({ execGuid: execGuid.value }).then((res: any) => {
if (res.code == proxy.$passCode) {
const data = res.data || [];
classifyList.value = data;
treeSelectOptions.value = data;
// 遍历data,找到refGradeGuid,不用递归,找第一层
} else {
ElMessage.error(res.msg);
}
}).catch(() => {
ElMessage.error('获取分类树形数据失败');
})
}
// 分级的数据props
const gradeSelectProps = {
value: 'guid',
label: 'name',
}
// 字段类型props
const fieldTypeProps = {
value: 'value',
label: 'label',
}
// 获取字段类型
const fieldData = ref<any>();
const getFieldTypeData = async () => {
const params = {
dictType: "字段类型"
}
const res: any = await getFieldTypeList(params);
if (res.code == proxy.$passCode) {
fieldData.value = res.data;
} else {
proxy.$ElMessage.error(res.msg);
}
}
// 进入编辑模式
const findRefGradeGuid = (data, targetClassifyDetailGuid) => {
// 遍历当前数据
for (const item of data) {
// 判断当前节点是否匹配
if (item.classifyDetailGuid === targetClassifyDetailGuid) {
return item.refGradeGuid; // 找到匹配的,返回 refGradeGuid
}
// 如果当前节点有 children,则递归查找子节点
if (Array.isArray(item.children) && item.children.length > 0) {
const result = findRefGradeGuid(item.children, targetClassifyDetailGuid);
if (result) {
return result; // 如果子节点中找到匹配,返回结果
}
}
}
return null; // 没有找到匹配项时返回 null
};
const editRow = (row) => {
// 进入编辑模式时,查找classifyDetailGuid所在的refGradeGuid
let refGradeGuid = findRefGradeGuid(treeSelectOptions.value, row.classifyDetailGuid);
getGradeList({ classifyGradeGuid: refGradeGuid, pageIndex: 1, pageSize: -1 }).then((res: any) => {
if (res.code === proxy.$passCode) {
row.gradeOptions = res.data.records || [];
} else {
ElMessage.error(res.msg);
}
});
// 这个是指定是否能编辑的字段
editableFields.sourceFieldName = false;
row.isEdit = true
}
const handleGradeChange = (row) => {
console.log('分级改变', row)
const gradeOptions = row.gradeOptions || [];
const matchedItem = gradeOptions.find((item) => item.guid === row.gradeDetailGuid);
if (matchedItem) {
row.gradeDetailName = matchedItem.name;
}
};
// 保存数据
const saveRow = (row) => {
console.log('保存数据', row)
editableFields.sourceFieldName = true;
row.isEdit = false
}
onMounted(async () => {
await getDbDirDataSourceListData();
await getFieldTypeData();
});
const stepsInfo = ref({
......@@ -60,32 +168,24 @@ const stepsInfo = ref({
const datasourceSelectedRows: Ref<any> = ref([]);
//记录下一步时选中的库表信息。
const selectedDatabaseTable: Ref<any> = ref([]);
const handlDsSelectedChange = (v) => {
// 记录数据库databaseGuid
const handlDsSelectedChange = (v, guid) => {
datasourceSelectedRows.value = v || [];
const params: any = [];
v.forEach((item) => {
params.push({
tableName: item.tableName,
database: item.database,
tableGuid: item.tableGuid,
execGuid: execGuid.value,
});
});
selectedDatabaseTable.value = params;
console.log('params', params)
// if (isPrevious.value) {
// tableCreateInfo.value.tableFields = [];
// tableCreateInfo.value.inputNameValue = '';
// tableCreateInfo.value.tableData[0].chName = '';
// }
getNextTableInfo(params);
};
const fullscreenLoading = ref(false);
/** 下一步 */
const nextStep = () => {
const nextStep = async () => {
if (!datasourceSelectedRows.value.length) {
ElMessage({
type: "error",
......@@ -93,36 +193,44 @@ const nextStep = () => {
});
return;
}
getNextTableInfo();
getFieldTree();
stepsInfo.value.step = 1;
};
//下一步获取表字段信息getNextTableInfo。getDsData 入参selectedDatabaseTable.value
const getNextTableInfo = async () => {
const res: any = await getDsTableStructure(selectedDatabaseTable.value);
const getNextTableInfo = async (params) => {
const res: any = await getDsTableStructures(params);
if (res.code === proxy.$passCode) {
tableDataDetailInfo.value = res.data;
} else {
proxy.$ElMessage.error(res.msg);
}
};
const isPrevious = ref(false);
const handleClassifyChange = (row) => {
if (!row.classifyDetailGuid) {
row.gradeGuid = null;
row.gradeOptions = [];
return;
}
getGradeList({ classifyGradeGuid: row.classifyDetailGuid, pageIndex: 1, pageSize: -1 }).then((res: any) => {
if (res.code === 200) {
row.gradeOptions = res.data.records || [];
} else {
ElMessage.error(res.msg);
}
});
};
const isPrevious = ref(false);
/** 上一步 */
const previousStep = () => {
stepsInfo.value.step = 0;
isPrevious.value = true;
};
//记录当前正在编辑的表创建信息。
const tableCreateInfo: Ref<any> = ref({
guid: "",
isCreate: false,
inputNameValue: '',
tableData: [],
partitionAttribute: {},
tableFields: [], // 字段标准数组。
});
const tableDataInfo = ref([
{
......@@ -132,22 +240,21 @@ const tableDataInfo = ref([
},
])
// 表格数据
const tableDataDetailInfo = ref([
{ id: 1, fieldName: '系统唯一标识', fieldEnglish: 'ID', length: '<200', isUnique: '是', isEdit: false },
{ id: 2, fieldName: '姓名', fieldEnglish: 'NAME', length: '<=200', isUnique: '否', isEdit: false },
{ id: 3, fieldName: '年纪', fieldEnglish: 'AGE', length: '=200', isUnique: '否', isEdit: false },
{ id: 4, fieldName: '系统唯一标识', fieldEnglish: 'ID', length: '<200', isUnique: '是', isEdit: false },
{ id: 5, fieldName: '姓名', fieldEnglish: 'NAME', length: '<=200', isUnique: '否', isEdit: false },
{ id: 6, fieldName: '年纪', fieldEnglish: 'AGE', length: '=200', isUnique: '否', isEdit: false },
])
const tableDataDetailInfo = ref<any>([])
// 配置哪些字段可编辑
const editableFields = {
fieldName: true, // 字段中文名可编辑
length: true, // 长度可编辑
fieldLength: true, // 长度可编辑
isUnique: true, // 数据是否唯一可编辑
isPrimary: true, // 是否主键可编辑
fieldPrecision: true, // 精度可编辑
dictionaryGuid: true, // 关联字典可编辑
classifyName: true, // 分类可编辑
gradeDetailName: true, // 分级可编辑
sourceFieldName: true, // 源字段英文名可编辑
classifyDetailGuid: true, // 分类可编辑
fieldType: true, // 字段类型可编辑
fieldChName: true, // 字段中文名可编辑
}
const tableFieldsLoading = ref(false)
......@@ -200,15 +307,7 @@ const moveDown = () => {
}
};
// 进入编辑模式
const editRow = (row) => {
row.isEdit = true
}
// 保存数据
const saveRow = (row) => {
row.isEdit = false
}
// 删除行
const deleteRow = (index) => {
......@@ -240,10 +339,16 @@ const addRow = () => {
tableDataDetailInfo.value.push({
id: tableDataDetailInfo.value.length + 1,
fieldName: '',
fieldEnglish: '', // 英文名不可编辑
fieldEnglish: '',
fieldType: '',
length: '',
fieldPrecision: '',
isUnique: '',
isEdit: true, // 新增时默认进入编辑模式
isRequired: '',
fieldValueRange: '',
dictionaryGuid: '',
isEdit: true,
gradeOptions: [],
})
}
......@@ -320,7 +425,6 @@ const data = [
const submitAsDraft = () => {
// 保存为草稿,无论有没有guid 都传入guid
saveOrUpdate({ isDraft: 'Y' }, 0)
}
......@@ -331,37 +435,42 @@ const submitAsDraft = () => {
* 2、tableDataDetailInfo.value 每一项中的字段名称、字段英文名、字段类型、长度、精度、是否唯一、是否必填、字段取值范围、关联字典、不能为空
*/
const checkTableData = (tableDataInfo, tableDataDetailInfo) => {
const tableDataInfoKeys = ['tableName', 'tableChName']
const tableDataDetailInfoKeys = ['fieldName', 'fieldEnglish', 'fieldType', 'length', 'fieldPrecision', 'isUnique', 'isRequired', 'fieldValueRange', 'dictionaryGuid']
let flag = true
tableDataInfo.forEach(item => {
tableDataInfoKeys.forEach(key => {
if (!item[key]) {
flag = false
proxy.$ElMessage.error('表名称、数据库表不能为空')
}
})
})
tableDataDetailInfo.forEach(item => {
tableDataDetailInfoKeys.forEach(key => {
if (!item[key]) {
flag = false
proxy.$ElMessage.error('字段名称、字段英文名、字段类型、长度、精度、是否唯一、是否必填、字段取值范围、关联字典不能为空')
}
})
})
return flag
}
// const checkTableData = (tableDataInfo, tableDataDetailInfo) => {
// const tableDataInfoKeys = ['tableName', 'tableChName']
// const tableDataDetailInfoKeys = ['fieldName', 'fieldEnglish', 'fieldType', 'length', 'fieldPrecision', 'isUnique', 'isRequired', 'fieldValueRange', 'dictionaryGuid']
// let flag = true
// tableDataInfo.forEach(item => {
// tableDataInfoKeys.forEach(key => {
// if (!item[key]) {
// flag = false
// proxy.$ElMessage.error('表名称、数据库表不能为空')
// }
// })
// })
// tableDataDetailInfo.forEach(item => {
// tableDataDetailInfoKeys.forEach(key => {
// if (!item[key]) {
// flag = false
// proxy.$ElMessage.error('字段名称、字段英文名、字段类型、长度、精度、是否唯一、是否必填、字段取值范围、关联字典不能为空')
// }
// })
// })
// return flag
// }
const guid = ref('')
const submit = async () => {
console.log('提交', tableDataDetailInfo.value, tableDataInfo.value)
// 校验表格数据是否填写完整
if (!checkTableData(tableDataDetailInfo.value, tableDataInfo.value)) {
return
const params = {
tableName: tableDataInfo.value[0].tableName,
tableChName: tableDataInfo.value[0].tableChName,
foundMode: route.query.foundMode,
}
// 校验表格数据是否填写完整
// if (!checkTableData(tableDataDetailInfo.value, tableDataInfo.value)) {
// return
// }
/**
"guid": "string",
"cgDirName": "string",
......@@ -407,7 +516,15 @@ const submit = async () => {
*/
// 如果提交时没有 guid 则为新增type 0,否则为修改 type 1, 也要传参
if (!guid.value) {
saveOrUpdate({}, 0)
saveOrUpdate({
tableName: tableDataInfo.value[0].tableName,
tableChName: tableDataInfo.value[0].tableChName,
databaseGuid: route.query.databaseGuid || '',
database: route.query.database || '',
databaseChName: route.query.databaseChName || '',
foundMode: route.query.foundMode,
isDraft: 'N',
}, 0)
} else {
saveOrUpdate({}, 1)
}
......@@ -425,10 +542,8 @@ const saveOrUpdate = async (params: any = {}, type) => {
tableChName: '',
databaseGuid: '',
database: '',
dbType: '',
databaseChName: '',
foundMode: 0,
state: 0,
isDraft: '',
fieldRQVOList: tableDataDetailInfo.value
}
......@@ -519,6 +634,10 @@ const newCreateSqlDialogInfo = ref({
newCreateSqlDialogInfo.value.submitBtnLoading = true;
const params = {
...info,
tableName: tableDataInfo.value[0].tableName,
tableChName: tableDataInfo.value[0].tableChName,
foundMode: route.query.foundMode,
isDraft: 'N',
};
await saveOrUpdate(params, 2);
newCreateSqlDialogInfo.value.submitBtnLoading = false;
......@@ -597,44 +716,78 @@ const createNewSql = () => {
}">
<el-table-column type="selection" :width="32" align="center" />
<!-- 排序列(不可编辑) -->
<el-table-column prop="id" label="排序" width="80" align="center" />
<!-- 字段中文名(不可编辑)fieldChName -->
<el-table-column prop="fieldName" label="字段中文名" width="150">
<el-table-column type="index" label="排序" width="80" align="center" />
<!-- 字段中文名(可编辑)fieldChName -->
<el-table-column prop="fieldChName" label="目标字段中文名" width="150">
<!-- 可以编辑 -->
<template #default="scope">
{{ scope.row.fieldName ? scope.row.fieldName : '--' }}
<span v-if="!scope.row.isEdit || !editableFields.fieldChName">{{ scope.row.fieldChName ?
scope.row.fieldChName
: '--' }}</span>
<el-input v-else v-model="scope.row.fieldChName" placeholder="请输入" />
</template>
</el-table-column>
<!-- 字段英文名(可编辑) -->
<el-table-column prop="fieldEnglish" label="字段英文名" width="150">
<!-- 字段英文名(可编辑) -->
<el-table-column prop="fieldName" label="目标字段英文名" width="150">
<template #default="scope">
{{ scope.row.fieldEnglish ? scope.row.fieldEnglish : '--' }}
<span v-if="!scope.row.isEdit || !editableFields.fieldName">{{ scope.row.fieldName ?
scope.row.fieldName
: '--' }}</span>
<el-input v-else v-model="scope.row.fieldName" placeholder="请输入" />
</template>
</el-table-column>
<!-- 分类(不可编辑)classifyName -->
<el-table-column prop="classifyName" label="分类" width="150">
<!-- 源数据库 -->
<el-table-column prop="sourceDatabase" label="源数据库" width="150">
<template #default="scope">
{{ scope.row.classifyName ? scope.row.classifyName : '--' }}
{{ scope.row.sourceDatabase ? scope.row.sourceDatabase : '--' }}
</template>
</el-table-column>
<!-- 分级(不可编辑) -->
<el-table-column prop="gradeDetailName" label="分级" width="120" align="center">
<!-- 源数据表 -->
<el-table-column prop="sourceTableName" label="源数据表" width="150">
<template #default="scope">
{{ scope.row.gradeDetailName ? scope.row.gradeDetailName : '--' }}
{{ scope.row.sourceTableName ? scope.row.sourceTableName : '--' }}
</template>
</el-table-column>
<!-- 字段类型fieldType (不可编辑) -->
<el-table-column prop="fieldType" label="字段类型" width="150" align="center">
<!-- 源字段中文 -->
<el-table-column prop="sourceFieldChName" label="源字段中文" width="150">
<template #default="scope">
{{ scope.row.fieldType ? scope.row.fieldType : '--' }}
{{ scope.row.sourceFieldChName ? scope.row.sourceFieldChName : '--' }}
</template>
</el-table-column>
<!-- 源字段英文 -->
<el-table-column prop="sourceFieldName" label="源字段英文" width="150">
<template #default="scope">
<!-- {{ scope.row.sourceFieldName ? scope.row.sourceFieldName : '--' }} -->
<span v-if="!scope.row.isEdit || !editableFields.sourceFieldName">{{ scope.row.sourceFieldName ?
scope.row.sourceFieldName : '--' }}</span>
<el-input v-else v-model="scope.row.sourceFieldName" placeholder="请输入长度" />
</template>
</el-table-column>
<!-- 源端字段 fieldType fieldTypeProps-->
<el-table-column prop="fieldType" label="源端字段类型" width="150">
<template #default="scope">
<div v-if="scope.row.isEdit">
<el-select v-model="scope.row.fieldType" placeholder="选择类型" clearable filterable
:props="fieldTypeProps">
<el-option v-for="(item, index) in fieldData" :key="index" :label="item.label"
:value="item.value"></el-option>
</el-select>
</div>
<div v-else>
{{ fieldData.find(item => item.value === scope.row.fieldType)?.label || '--' }}
</div>
</template>
</el-table-column>
<!-- 长度(可编辑) -->
<el-table-column prop="length" label="长度" width="120" align="center">
<el-table-column prop="fieldLength" label="长度" width="120" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.length">{{ scope.row.length ? scope.row.length
<span v-if="!scope.row.isEdit || !editableFields.fieldLength">{{ scope.row.fieldLength ?
scope.row.fieldLength
: '--' }}</span>
<el-input v-else v-model="scope.row.length" placeholder="请输入长度" />
<el-input v-else v-model="scope.row.fieldLength" placeholder="请输入长度" />
</template>
</el-table-column>
<!-- 精度(可编辑)fieldPrecision -->
......@@ -656,34 +809,60 @@ const createNewSql = () => {
</el-table-column>
<!-- 数据是否唯一(可编辑) -->
<el-table-column prop="isUnique" label="数据是否唯一" width="150" align="center">
<el-table-column prop="isPrimary" label="是否主键" width="150" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.isUnique">{{ scope.row.isUnique ? scope.row.isUnique :
<span v-if="!scope.row.isEdit || !editableFields.isPrimary">{{ scope.row.isPrimary ? scope.row.isPrimary
:
'--' }}</span>
<el-select v-else v-model="scope.row.isUnique" placeholder="请选择">
<el-option label="是" value="是" />
<el-option label="否" value="否" />
<el-select v-else v-model="scope.row.isPrimary" placeholder="请选择">
<el-option label="Y" value="Y" />
<el-option label="N" value="N" />
</el-select>
</template>
</el-table-column>
<!-- 是否必填(可编辑) -->
<el-table-column prop="isRequired" label="是否必填" width="120" align="center">
<el-table-column prop="isNotNull" label="是否必填" width="120" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit">{{ scope.row.isRequired ? scope.row.isRequired : '--' }}</span>
<el-select v-else v-model="scope.row.isRequired" placeholder="请选择">
<el-option label="是" value="是" />
<el-option label="否" value="否" />
<span v-if="!scope.row.isEdit">{{ scope.row.isNotNull ? scope.row.isNotNull : '--' }}</span>
<el-select v-else v-model="scope.row.isNotNull" placeholder="请选择">
<el-option label="Y" value="Y" />
<el-option label="N" value="N" />
</el-select>
</template>
</el-table-column>
<!-- 字段取值范围 fieldValueRange(可编辑)-->
<el-table-column prop="fieldValueRange" label="字段取值范围" width="150" align="center">
<!-- 分类(不可编辑)classifyName -->
<el-table-column prop="classifyDetailGuid" label="分类" width="150">
<template #default="scope">
<span v-if="!scope.row.isEdit">{{ scope.row.fieldValueRange ? scope.row.fieldValueRange : '--' }}</span>
<el-input v-else v-model="scope.row.fieldValueRange" placeholder="请输入字段取值范围" />
<!-- 如果当前行是编辑状态,显示 tree-select -->
<div v-if="scope.row.isEdit">
<el-tree-select v-model="scope.row.classifyDetailGuid" :data="treeSelectOptions"
:props="treeSelectProps" placeholder="请选择分类" clearable filterable
@change="handleClassifyChange(scope.row)">
</el-tree-select>
</div>
<!-- 否则直接显示分类名称 -->
<div v-else>
{{ scope.row.classifyDetailName || '--' }}
</div>
</template>
</el-table-column>
<!-- 分级(不可编辑) -->
<el-table-column prop="gradeDetailGuid" label="分级" width="120" align="center">
<template #default="scope">
<div v-if="scope.row.isEdit">
<el-select v-model="scope.row.gradeDetailGuid" placeholder="请选择分级" clearable filterable
:props="gradeSelectProps" @change="handleGradeChange(scope.row)">
<el-option v-for="(item, index) in scope.row.gradeOptions || []" :key="index" :label="item.name"
:value="item.guid"></el-option>
</el-select>
</div>
<div v-else>
{{ scope.row.gradeDetailName || '--' }}
</div>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="scope">
......
<route lang="yaml">
name: tableCreateFile
</route>
name: tableCreateFile
</route>
<script lang="ts" setup name="tableCreateFile">
......@@ -10,29 +10,29 @@ import useUserStore from "@/store/modules/user";
import useDataCatalogStore from "@/store/modules/dataCatalog";
import expandPropertyDialog from "./expandPropertyDialog.vue";
import tableDefaultValue from "./components/tableDefaultValue.vue";
// import {
// getDatabase,
// getFileStandards,
// getDictionary,
// getSubjectFieldByFile,
// tableCategoryList,
// syncPolicys,
// getDataTypeList,
// tableModels,
// aggMethodList,
// getCharacterList,
// saveSubjectTable,
// updateSubjectTable,
// getTableStandardDetail,
// getSubjectDomainDetail,
// saveSubjectTableDraft,
// updateSubjectTableDraft,
// getFieldStandardTree,
// dimTypeList,
// getDimList,
// getSubjectTableDetail,
// checkSubjectTableData
// } from "@/api/modules/dataCatalogService";
import {
getDatabase,
getFileStandards,
getDictionary,
getSubjectFieldByFile,
tableCategoryList,
syncPolicys,
getDataTypeList,
tableModels,
aggMethodList,
getCharacterList,
saveSubjectTable,
updateSubjectTable,
getTableStandardDetail,
getSubjectDomainDetail,
saveSubjectTableDraft,
updateSubjectTableDraft,
getFieldStandardTree,
dimTypeList,
getDimList,
getSubjectTableDetail,
checkSubjectTableData
} from "@/api/modules/dataCatalogService";
import { useDefault } from "@/hooks/useDefault";
import uploadExcelFile from "./components/uploadExcelFile.vue";
......@@ -109,23 +109,23 @@ const handleFileDataChange = (fileFields, files, sheetName, data) => {
const uploadFileRef = ref();
// const getSubjectField = () => {
// tableFieldsLoading.value = true;
// getSubjectFieldByFile(fileTableFields.value.map(f => f.chName), tableCreateInfo.value.tableData[0].subjectDomainGuid).then((res: any) => {
// tableFieldsLoading.value = false;
// if (res.code == proxy.$passCode) {
// tableCreateInfo.value.tableFields = res.data?.map((field, i) => {
// field.dimOrdictionaryGuid = field.dictionaryGuid;
// field.fileFieldName = fileTableFields.value[i].chName;
// field.isEdit = true;
// !field.notNull && (field.notNull = 'N');
// return field;
// }) || [];
// } else {
// ElMessage.error(res.msg);
// }
// });
// }
const getSubjectField = () => {
tableFieldsLoading.value = true;
getSubjectFieldByFile(fileTableFields.value.map(f => f.chName), tableCreateInfo.value.tableData[0].subjectDomainGuid).then((res: any) => {
tableFieldsLoading.value = false;
if (res.code == proxy.$passCode) {
tableCreateInfo.value.tableFields = res.data?.map((field, i) => {
field.dimOrdictionaryGuid = field.dictionaryGuid;
field.fileFieldName = fileTableFields.value[i].chName;
field.isEdit = true;
!field.notNull && (field.notNull = 'N');
return field;
}) || [];
} else {
ElMessage.error(res.msg);
}
});
}
const nextStep = () => {
uploadFileRef.value.fileFormRef.ruleFormRef.validate((valid) => {
......@@ -143,19 +143,19 @@ const nextStep = () => {
tableCreateInfo.value.isSync = 'Y';
}
stepsInfo.value.step = 1;
// getDictionaryList();
// getDimListData();
// if (!fieldTypes.value.length) {
// getFieldTypeList();
// getCharacterListData();
// }
// if (!databaseList.value.length) {
// getDatabaseList();
// }
// getDomainDetail(subjectDomainGuid.value);
// if (!tableCreateInfo.value.tableFields.length) {
// getSubjectField();
// }
getDictionaryList();
getDimListData();
if (!fieldTypes.value.length) {
getFieldTypeList();
getCharacterListData();
}
if (!databaseList.value.length) {
getDatabaseList();
}
getDomainDetail(subjectDomainGuid.value);
if (!tableCreateInfo.value.tableFields.length) {
getSubjectField();
}
}
});
};
......@@ -216,11 +216,1242 @@ const fullscreenLoading = ref(false);
/** 表里有数据时不能修改字段类型,长度,精度 */
const hasSubjectData = ref(false);
onBeforeMount(() => {
if (route.query.guid) {
init.value = false;
fullscreenLoading.value = true;
getSubjectTableDetail(route.query.guid).then((res: any) => {
fullscreenLoading.value = false;
if (res?.code == proxy.$passCode) {
let data = res.data;
standardSetGuids.value = data.fieldStandardSetGuids
if (data.isCreate === 'Y') {
checkSubjectTableData({
databaseType: data.dbType,
dataSourceGuid: data.dataSourceGuid,
databaseNameEn: data.dataServerName,
enName: data.enName
}).then((res: any) => {
if (res?.code == proxy.$passCode) {
hasSubjectData.value = res.data;
} else {
ElMessage.error(res.msg);
}
})
}
init.value = true;
let domainVO = data?.dataCatalogSubjectDomainTableVOS || {};
let subjectDomainName = domainVO.subjectDomainName;
if (fullPath === route.fullPath) {
document.title = `编辑-${data.chName}(${subjectDomainName})`;
}
let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === fullPath);
if (tab) {
tab.meta.title = `编辑-${data.chName}(${subjectDomainName})`;
}
subjectDomainGuid.value = data.subjectDomainGuid;
getFieldStandardOptions(domainVO.fieldStandardSetGuids || []);
tableStandardGuid.value = domainVO.tableStandardGuid || '';
fieldStandardSetGuids.value = domainVO.fieldStandardSetGuids || [];
isOpenStandard.value = domainVO.isOpenStandard === 'Y';
dbType.value = data.dbType;
originTableCreateInfo.value = tableCreateInfo.value = {
guid: data.guid,
isCreate: data.isCreate === 'Y',
partitionAttribute: data.partitionAttribute || {},
tableCreateType: data.tableCreateType,
inputNameValue: data.enName,
isSync: data.isSync,
sheetName: data.subjectTableAttachmentsVO?.sheetName,
tableData: [
{
dataSourceGuid: data.dataSourceGuid,
dataServerName: data.dataServerName,
dataServerChName: data.dataServerChName,
enName: data.enName,
chName: data.chName,
subjectDomain: subjectDomainName,
subjectDomainGuid: subjectDomainGuid.value,
tableCategory: data.tableCategory,
dimType: data.dimType,
syncPolicy: data.syncPolicy,
characterSet: data.characterSet,
tableModel: data.tableModel, //若是聚合模型,下方出现一列聚合方式选择。处了主键列,其余列都需要选择。每个表里都要有主键。
description: data.description,
},
],
tableFields: data.subjectFieldVOS?.map((fieldVO, i) => {
return {
orderNum: fieldVO.orderNum,
guid: fieldVO.guid,
chName: fieldVO.chName,
enName: fieldVO.enName,
isPrimary: fieldVO.isPrimary,
notNull: fieldVO.notNull,
fieldLength: fieldVO.fieldLength,
fieldPrecision: fieldVO.fieldPrecision,
fileFieldName: fieldVO.fileFieldName,
fieldStandardGuid: fieldVO.fieldStandardGuid,
fieldStandardCode: fieldVO.fieldStandardCode,
fieldStandardName: fieldVO.fieldStandardName,
dataType: fieldVO.dataType,
aggWay: fieldVO.aggWay,
dataTypeChName: fieldVO.dataTypeChName,
dictionaryGuid: fieldVO.dictionaryGuid || "",
dictionaryChName: fieldVO.dictionaryChName || "",
dimGuid: fieldVO.dimGuid,
dimChName: fieldVO.dimChName,
dimOrdictionaryGuid: (fieldVO.dictionaryGuid ? fieldVO.dictionaryGuid : fieldVO.dimGuid) || '',
isCreate: fieldVO.isCreate,
defaultValue: fieldVO.defaultValue,
}
}) || [], // 字段标准数组。
};
let subjectTableAttachmentsVO = data.subjectTableAttachmentsVO || {};
let file = subjectTableAttachmentsVO?.fileUrl ? [{
name: subjectTableAttachmentsVO?.fileName,
url: subjectTableAttachmentsVO?.fileUrl
}] : [];
uploadFileRef.value.setFormValue({
file: file,
sheetName: subjectTableAttachmentsVO.sheetName
});
uploadDataFileInfo.value = file;
fileTableFields.value = tableCreateInfo.value.tableFields?.map((f, i) => {
return {
index: i,
enName: f.fileFieldName,
chName: f.fileFieldName,
dataType: f.dataType
}
}) || [];
let partitionAttribute = data.partitionAttribute;
expandProperties.value = {
partitionMode: partitionAttribute?.partitionMode || 'dynamic',
staticPartitionType: partitionAttribute?.staticPartitionType || 'Range',
partitionCol: partitionAttribute?.partitionCol || "",
partitionTimeUnit: partitionAttribute?.partitionTimeUnit || "DAY",
dynamicPartitionEnd: partitionAttribute?.dynamicPartitionEnd == null ? 3 : partitionAttribute?.dynamicPartitionEnd,
staticPartitionRange: partitionAttribute?.staticPartitionRangeBegin ? [partitionAttribute?.staticPartitionRangeBegin,
partitionAttribute?.staticPartitionRangeEnd] : null,
dynamicPartitionHistory: partitionAttribute?.dynamicPartitionHistory === "Y",
dynamicPartitionHistoryNum: partitionAttribute?.dynamicPartitionHistoryNum,
staticPartitionEnum: partitionAttribute?.staticPartitionEnum,
};
} else {
ElMessage.error(res.msg);
}
});
}
})
onActivated(() => {
if (init.value) {
let tab: any = userStore.tabbar.find((tab: any) => tab.fullPath === fullPath);
if (tab) {
if (route.query.guid) {
let chName = tableCreateInfo.value.tableData[0].chName;
let subjectDomainName = tableCreateInfo.value.tableData[0].subjectDomain;
tab.meta.title = `编辑-${chName}(${subjectDomainName})`;
}
if (fullPath === route.fullPath) {
document.title = tab.meta.title;
}
}
getDomainDetail(subjectDomainGuid.value);
}
});
watch(() => tableStandardGuid.value, (val) => {
if (val) {
getTableStandardDetail(val).then((res: any) => {
if (res.code == proxy.$passCode) {
tableStandardDetail.value = res.data || {};
} else {
ElMessage.error(res.msg);
}
});
} else {
tableStandardDetail.value = {}
}
});
watch(() => tableStandardDetail.value, (val) => {
let enName = tableCreateInfo.value.tableData[0].enName;
if (!val.abbreviation) {
tableCreateInfo.value.inputNameValue = enName;
return;
}
let strLen = val.abbreviation.length;
if (val.standardType === 1) {
tableCreateInfo.value.inputNameValue = enName.indexOf(val.abbreviation) === 0 ? enName.slice(strLen) : enName;
} else if (val.standardType === 2) {
tableCreateInfo.value.inputNameValue = enName.lastIndexOf(val.abbreviation) !== -1 ? enName.substring(0, enName.length - strLen) : enName;
}
});
const getDomainDetail = (domainGuid) => {
getSubjectDomainDetail(domainGuid).then((res: any) => {
if (res.code == proxy.$passCode) {
tableStandardGuid.value = res.data.tableStandardGuid || '';
fieldStandardSetGuids.value = res.data.fieldStandardSetGuids || [];
standardSetGuids.value = res.data.fieldStandardSetGuids || [];
getFieldStandardOptions(fieldStandardSetGuids.value || []);
isOpenStandard.value = res.data.isOpenStandard === 'Y';
} else {
ElMessage.error(res.msg);
}
});
}
const getFieldStandardOptions = (guids) => {
if (!guids?.length) {
standardListOptions.value = [];
batchAddDialogInfo.value.contents[0].treeInfo.data = [];
return;
}
getFieldStandardTree(guids).then((res: any) => {
if (res.code == proxy.$passCode) {
standardListOptions.value = res.data || [];
batchAddDialogInfo.value.contents[0].treeInfo.data = standardListOptions.value?.map(s => {
return {
guid: s.guid,
chName: s.chName
}
})
} else {
ElMessage.error(res.msg);
}
})
}
const getDatabaseList = () => {
getDatabase({ connectStatus: 1 }).then((res: any) => {
databaseList.value = [];
if (res.code == proxy.$passCode) {
databaseList.value = res.data || [];
} else {
ElMessage.error(res.msg);
}
})
};
//字典列表
const dictionaryList: any = ref([]);
const getDictionaryList = () => {
getDictionary({}).then((res: any) => {
dictionaryList.value = [];
if (res.code == proxy.$passCode) {
dictionaryList.value = res.data || [];
dimOrDictList.value[0].children = dictionaryList.value;
dimOrDictList.value[0].disabled = !dictionaryList.value.length;
} else {
ElMessage.error(res.msg);
}
})
};
// 可选择的关联维度的列表。
const dimListData: any = ref([]);
const getDimListData = () => {
getDimList().then((res: any) => {
dimListData.value = [];
if (res.code == proxy.$passCode) {
dimListData.value = res.data?.map(r => {
return {
guid: r.guid,
chName: r.chName,
subjectDomainName: r.subjectDomainName,
parentGuid: '2'
}
}) || [];
dimOrDictList.value[1].children = dimListData.value;
dimOrDictList.value[1].disabled = !dimListData.value.length;
} else {
ElMessage.error(res.msg);
}
})
};
const getFieldTypeList = () => {
getDataTypeList().then((res: any) => {
fieldTypes.value = [];
if (res.code == proxy.$passCode) {
fieldTypes.value = res.data || [];
} else {
ElMessage.error(res.msg);
}
})
}
const getCharacterListData = () => {
getCharacterList().then((res: any) => {
characterList.value = [];
if (res.code == proxy.$passCode) {
characterList.value = res.data || [];
} else {
ElMessage.error(res.msg);
}
})
}
const getBatchAddFileStandardList = () => {
batchAddDialogInfo.value.contents[1].tableInfo.data = [];
if (!batchAddFieldStandardPage.value.standardSetLevelCode) {
batchAddDialogInfo.value.contents[1].tableInfo.page.rows = 0;
return;
}
let tableInfo: any = batchAddDialogInfo.value.contents[1].tableInfo;
tableInfo.loading = true;
getFileStandards(batchAddFieldStandardPage.value).then((res: any) => {
tableInfo.loading = false;
if (res.code == proxy.$passCode) {
let tableData: any = [];
batchAddDialogInfo.value.contents[1].tableInfo.data = tableData = res.data.records || [];
batchAddDialogInfo.value.contents[1].tableInfo.page.rows = res.data.totalRows || 0;
nextTick(() => {
let rows: any = [];
batchAddDialogInfo.value.contents[2].tagInfo.data?.forEach((d) => {
let row = tableData.find((v: any) => v.guid == d.guid);
if (row) {
rows.push(row);
}
});
batchAddDialogRef.value?.setTableRowSelected(rows, true);
});
} else {
ElMessage.error(res.msg);
}
})
};
/** 第二步的相关代码逻辑 */
const fieldStandardTableRef = ref<InstanceType<typeof ElTable>>();
/** 表模型,只有doris数据库才有 */
const dbType = ref('');
const tableFieldsLoading = ref(false);
/*** 以下是处理数据字典或维表的树形选择框。 */
const dimOrDictList: any = ref([{
guid: '1',
chName: '数据字典',
children: dictionaryList.value,
isLeaf: false,
disabled: !dictionaryList.value.length,
}, {
guid: '2',
chName: '维度',
isLeaf: false,
disabled: !dimListData.value.length,
children: dimListData.value
}]);
const dimOrDictInputFilterMethod = (v, data) => {
return data.label?.includes(v) || data.chName?.includes(v);
};
const dimOrDictSelectRef = ref();
const dimOrDictSelectNode = ref();
const handleDictSelectNodeChange = (node) => {
dimOrDictSelectNode.value = node;
}
const handleDictionaryChange = (val, scope) => {
if (!val) {
scope.row.dictionaryGuid = '';
scope.row.dimGuid = '';
scope.row.dictionaryChName = '';
scope.row.dimChName = '';
return;
}
let info = dimOrDictSelectNode.value;
if (!info) {
return;
}
if (info.parentGuid == '2') {
scope.row.dimGuid = val;
scope.row.dimChName = dimListData.value.find(d => d.guid === val)?.chName;
scope.row.dictionaryGuid = '';
scope.row.dictionaryChName = '';
} else {
scope.row.dictionaryGuid = val;
scope.row.dictionaryChName = dictionaryList.value.find(d => d.guid === val)?.chName;
scope.row.dimGuid = '';
scope.row.dimChName = '';
}
}
//数据库选择改变,对应的表名称是否需要变化。需要根据此属性带出表名前缀,以及是否是doris数据库。
const selectDatabaseChange = (val) => {
let d = databaseList.value.find(d => d.guid === val);
if (d) {
dbType.value = d.databaseType;
tableCreateInfo.value.tableData[0].dataSourceGuid = d.guid;
tableCreateInfo.value.tableData[0].dataServerName = d.databaseNameEn;
} else {
dbType.value = '';
tableCreateInfo.value.tableData[0].dataSourceGuid = '';
tableCreateInfo.value.tableData[0].dataServerName = '';
}
};
const batchAddDialogRef = ref();
const batchAddDialogInfo: any = ref({
visible: false,
size: 960,
modalClass: 'batchDialog',
height: "534px",
header: {
title: "批量新增字段",
headerSearchInputVisible: true,
headerSearchInputPlaceholder: "模糊搜索中文名称/英文名称",
},
type: "grid",
contents: [
{
type: "tree",
title: "",
style: {
width: '223px',
padding: 0,
},
treeInfo: {
id: "standard_tree",
filter: true,
// showCheckbox: true,
queryPlaceholder: "搜索名称",
showAllLevels: false,
props: {
label: "chName",
value: "guid",
children: "children"
},
nodeKey: "guid",
expandedKey: [],
data: standardListOptions.value?.map(s => {
return {
guid: s.guid,
chName: s.chName,
children: s.children
}
})
},
},
{
type: "table",
title: "",
style: {
width: '508px',
padding: 0,
},
col: "border",
tableInfo: {
id: "batchAddFields",
loading: false,
maxHeight: "calc(100% - 40px)",
multiple: true,
fields: [
{
label: "序号",
type: "index",
width: 56
},
{ label: "标准编码", field: "fieldStandardCode", width: 150 },
{ label: "中文名称", field: "chName", width: 120 },
{ label: "英文名称", field: "enName", width: 120 },
{ label: "数据类型", field: "dataTypeValue", width: 85 },
{ label: "字段长度", field: "fieldLength", width: 85 },
{ label: "字段精度", field: "fieldPrecision", width: 85 },
],
data: [],
page: {
type: "concise",
rows: 0,
curr: 1,
limit: 50,
showCount: true
},
actionInfo: {
show: false,
},
},
},
{
type: "tags",
title: "",
style: {
width: '227px',
padding: 0,
},
tagInfo: {
id: "field_tag_list",
closable: true,
effect: "plain",
data: [],
labelFields: (tag) => {
return tag['chName'] + '(' + tag['enName'] + ')';
}
},
tools: {
posit: "top",
btns: [{ label: "清空", value: "clear" }],
},
},
],
footer: {
btns: [
{ type: "default", label: "取消", value: "cancel" },
{ type: "primary", label: "确认", value: "submit" },
],
},
});
watch(() => batchAddFieldStandardPage.value.pageSize, (val) => {
batchAddDialogInfo.value.contents[1].tableInfo.page.limit = val || 50;
})
watch(() => batchAddFieldStandardPage.value.pageIndex, (val) => {
batchAddDialogInfo.value.contents[1].tableInfo.page.curr = val || 1;
})
const deepStandardListOptions = (arr) => {
const list: any = []
for (let i = 0; i < arr.length; i++) {
const { children, ...obj } = arr[i]
if (children) {
if (arr[i].standardSetGuid) {
list.push(obj)
} else {
list.push({ ...obj, children: deepStandardListOptions(children) })
}
}
}
return list
}
/** 批量添加字段标准 */
const batchAddFields = () => {
batchAddDialogInfo.value.visible = true;
let treeInfo = batchAddDialogInfo.value.contents[0].treeInfo;
treeInfo && (treeInfo.data = deepStandardListOptions(standardListOptions.value));
treeInfo && (treeInfo.currentKey = standardListOptions.value?.[0]?.guid);
let tags: any = batchAddDialogInfo.value.contents[2];
tags.tagInfo.data = [];
batchAddFieldStandardPage.value.pageIndex = 1;
//batchAddFieldStandardPage.value.standardSetGuid = standardListOptions.value[0]?.guid;
batchAddFieldStandardPage.value.standardSetLevelCode = standardListOptions.value[0]?.standardSetLevelCode;
batchAddFieldStandardPage.value.standardSetGuids = standardSetGuids.value
getBatchAddFileStandardList();
};
// 批量新增字段的对话框中的分页改变。
const bacthAddTablePageChange = (info) => {
console.log(info);
batchAddFieldStandardPage.value.pageSize = info.size;
getBatchAddFileStandardList();
};
/** 批量新增对话框搜索输入改变 */
const batchDialogHeaderSearchInputChanged = (v) => {
batchAddFieldStandardPage.value.pageIndex = 1;
batchAddFieldStandardPage.value.name = v;
getBatchAddFileStandardList();
};
const bacthAddTreeNodeClick = (node) => {
batchAddFieldStandardPage.value.pageIndex = 1;
batchAddFieldStandardPage.value.standardSetLevelCode = node.standardSetLevelCode;
getBatchAddFileStandardList();
}
/** 添加字段标准 */
const addField = () => {
let len = tableCreateInfo.value.tableFields.length;
tableCreateInfo.value.tableFields.push({
orderNum: len + 1,
isDim: "N",
isPrimary: "N",
notNull: "N",
isEdit: true
});
//设置选中表格当前新增行。
fieldStandardTableRef.value?.setCurrentRow(
tableCreateInfo.value.tableFields[tableCreateInfo.value.tableFields.length - 1]
);
nextTick(() => {
let bodyWrapper = fieldStandardTableRef.value?.$el.querySelector('.el-table__body');
let domScroll = bodyWrapper.parentElement.parentElement;
let rect = domScroll.getBoundingClientRect();
let maxNum = len + 1;
if (maxNum * 36 > rect.height + domScroll.scrollTop) {
fieldStandardTableRef.value?.setScrollTop(maxNum * 36 - rect.height + 2)
}
})
};
/** 勾选字段标准选中变化。 */
const selectionFieldsChange = (val) => {
selectTableFieldRows.value = val;
};
/**
* 上移规则:
* 勾选多个时先从最上面开始逐个上移一行,若已经移到最上面一行,则不处理。
*/
const moveUp = () => {
let selectRows = fieldStandardTableRef.value?.getSelectionRows();
if (!selectRows.length) {
ElMessage.error('请先选择需要勾选的数据进行上移');
return;
}
let data = tableCreateInfo.value.tableFields;
let selectRowIndexs: number[] = [];
let minNum: number = 0;
selectRows.forEach((row, i) => {
let orderNum = data.findIndex(d => d === row) + 1;
if (orderNum == 1) {
selectRowIndexs.push(orderNum);
minNum = orderNum;
return;
}
if (selectRowIndexs.includes(orderNum - 1)) {
//下一行也是选中的,则不做转换。
return;
}
let topNum = orderNum - 1;
if (i === 0) {
minNum = topNum;
}
row.orderNum = topNum;
let changeRow = data[topNum - 1];
changeRow.orderNum = orderNum;
selectRowIndexs.push(topNum);
data[topNum] = changeRow;
data[topNum - 1] = row;
});
nextTick().then(() => {
let bodyWrapper = fieldStandardTableRef.value?.$el.querySelector('.el-table__body');
let domScroll = bodyWrapper.parentElement.parentElement;
if ((minNum * 36 - 36 - 2) < domScroll.scrollTop) {
fieldStandardTableRef.value?.setScrollTop((domScroll.scrollTop - 36 - 2) < 0 ? 0 : (domScroll.scrollTop - 36 - 2))
}
});
}
/**
* 下移规则:
* 勾选多个时先从最下面开始逐个下移一行,若已经移到最下面一行,则不处理。
*/
const moveDown = () => {
let selectRows = fieldStandardTableRef.value?.getSelectionRows();
if (!selectRows.length) {
ElMessage.error('请先选择需要勾选的数据进行下移');
return;
}
let data = tableCreateInfo.value.tableFields;
let selectRowIndexs: number[] = [];
let maxNum: number = 0;
selectRows.slice(0).reverse().forEach((row, i) => {
let orderNum = data.findIndex(d => d === row) + 1;
if (orderNum === data.length) {
maxNum = orderNum;
selectRowIndexs.push(orderNum);
return;
}
if (selectRowIndexs.includes(orderNum + 1)) {
//下一行也是选中的,则不做转换。
return;
}
let bottomNum = orderNum + 1;
row.orderNum = bottomNum;
if (i === 0) {
maxNum = bottomNum;
}
let changeRow = data[bottomNum - 1];
changeRow.orderNum = orderNum;
selectRowIndexs.push(bottomNum);
data[orderNum - 1] = changeRow;
data[bottomNum - 1] = row;
});
nextTick(() => {
let bodyWrapper = fieldStandardTableRef.value?.$el.querySelector('.el-table__body');
let domScroll = bodyWrapper.parentElement.parentElement;
let rect = domScroll.getBoundingClientRect();
if (maxNum * 36 > rect.height + domScroll.scrollTop) {
fieldStandardTableRef.value?.setScrollTop(maxNum * 36 - rect.height + 2)
}
})
}
/** 批量删除字段标准 */
const delFeilds = () => {
if (selectTableFieldRows.value.length == 0) {
ElMessage({
type: "info",
message: "请选择需要删除的字段",
});
return;
}
ElMessageBox.confirm("此操作将永久删除, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
//此删除是直接从库里删除,还是点击保存后再删除呢??如果是入库删除,后,调用接口获取数据。
let tableFields = tableCreateInfo.value.tableFields;
let tableData = tableCreateInfo.value.tableData[0];
selectTableFieldRows.value.forEach((r) => {
let index = tableFields.findIndex((t: any) => t === r);
if (index !== -1) {
let row = tableFields[index];
tableFields.splice(index, 1);
if (tableData.codeName == row.enName) {
tableData.codeName = "";
}
if (tableData.codeColumn == row.enName) {
tableData.codeColumn = "";
}
}
});
fieldStandardTableRef.value?.clearSelection();
ElMessage({
type: "success",
message: "删除成功",
});
})
.catch(() => {
ElMessage({
type: "info",
message: "已取消删除",
});
});
};
/** 跳转到新建字段标准 */
const createFieldsStandard = () => {
//先判断当前内容,与数据库里的是否相同,不通则需要提示是否存为草稿,或者放弃修改。
ElMessageBox.confirm(
"当前页面存在尚未保存的修改,确定跳转到字段标准吗?",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
router.push({
name: "structure"
});
})
.catch(() => {
ElMessage({
type: "info",
message: "已取消",
});
});
};
//点击编辑按钮
const handleFieldClickEdit = (scope) => {
scope.row['isEdit'] = true;
};
//点击保存按钮
const handleFieldClickSave = (scope) => {
if (isOpenStandard.value && !scope.row.fieldStandardCode) {
ElMessage({
type: "error",
message: "该主题域开启了字段标准,当前行字段标准不能为空!",
});
return;
}
if (!scope.row.enName) {
ElMessage({
type: "error",
message: "字段英文名不能为空!",
});
return;
}
if (checkDefault[scope.row.dataType]) {
if (!scope.row.fieldLength) { }
if (!checkDefault[scope.row.dataType](scope)) {
return
}
}
scope.row['isEdit'] = false;
};
const handleFieldDelete = (scope) => {
ElMessageBox.confirm("此操作将永久删除, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
//此删除是直接从库里删除,还是点击保存后再删除呢??如果是入库删除,后,调用接口获取数据。
let tableFields = tableCreateInfo.value.tableFields;
tableFields.splice(scope.$index, 1);
tableCreateInfo.value.tableFields.forEach((field, i) => {
field.orderNum = i + 1;
});
let row = scope.row;
let tableData = tableCreateInfo.value.tableData[0];
if (tableData.codeName == row.enName) {
tableData.codeName = "";
}
if (tableData.codeColumn == row.enName) {
tableData.codeColumn = "";
}
ElMessage({
type: "success",
message: "删除成功",
});
})
.catch(() => {
ElMessage({
type: "info",
message: "已取消删除",
});
});
}
const standardInputFilterMethod = (v, data) => {
return data.label?.includes(v) || data.fieldStandardCode?.includes(v) ||
data.chName?.includes(v) ||
data.enName?.includes(v);
};
const standardSelectNode = ref();
const handleStandardNodeChange = (node) => {
standardSelectNode.value = node;
}
/** 通过字段标准自动带出相关信息。 */
const handleStandardValueChange = (v, scope) => {
console.log(v);
if (!v) {
return;
}
let info = standardSelectNode.value;
if (!info) {
return;
}
scope.row.fieldStandardGuid = info.guid;
scope.row.fieldStandardCode = info.fieldStandardCode;
scope.row.fieldStandardName = info.chName;
scope.row.chName = info.chName;
scope.row.enName = info.enName;
scope.row.dataType = info.dataTypeCode;
if (!scope.row.dimGuid) {
scope.row.dictionaryGuid = info.isDataDic === 'Y' ? info.dataDicGuid : scope.row.dictionaryGuid;
scope.row.dictionaryChName = info.isDataDic === 'Y' ? dictionaryList.value.find(d => d.guid === info.dataDicGuid)?.chName : scope.row.dictionaryChName;
}
scope.row.fieldLength = info["fieldLength"];
scope.row.fieldPrecision = info.fieldPrecision;
};
/** 通过中文字段名称匹配到标准,若已有标准,则不匹配 */
const handleFieldChineseNameChange = (v, scope) => {
if (!v) {
return;
}
let info: any = null;
for (const stand of standardListOptions.value) {
info = stand.children?.find((s) => s.chName === v);
if (info) {
break;
}
}
if (!info) {
scope.row.fieldStandardGuid = '';
scope.row.fieldStandardCode = '';
scope.row.fieldStandardName = '';
scope.row.fieldStandardEnName = '';
return;
}
scope.row.fieldStandardGuid = info.guid;
scope.row.fieldStandardCode = info.fieldStandardCode;
scope.row.fieldStandardName = info.chName;
scope.row.chName = info.chName;
scope.row.enName = info.enName;
scope.row.dataType = info.dataTypeCode;
if (!scope.row.dimGuid) {
scope.row.dictionaryGuid = info.isDataDic === 'Y' ? info.dataDicGuid : scope.row.dictionaryGuid;
scope.row.dictionaryChName = info.isDataDic === 'Y' ? dictionaryList.value.find(d => d.guid === info.dataDicGuid)?.chName : scope.row.dictionaryChName;
}
scope.row.fieldLength = info["fieldLength"];
scope.row.fieldPrecision = info.fieldPrecision;
};
const dataTypeChange = (val, scope) => {
scope.row['defaultValue'] = ''
scope.row['fieldLength'] = undefined
scope.row['fieldPrecision'] = undefined
}
/** 限制长度输入框只能输入整型数字,表,字段英文名称,限制输入字符,数字和下划线。 */
const inputLengthKeyUp = (regexp, scope, field, max: any = null, min: any = null) => {
scope.row[field] = scope.row[field].replace(regexp, '');
if (field == 'fieldLength' && scope.row.dataType == 'decimal') {
max = 65;
}
/** 最大值设置2000 */
if (max && scope.row[field] > max) {
scope.row[field] = max;
}
if (min !== null && scope.row[field] != '' && scope.row[field] <= min) {
scope.row[field] = min;
}
}
/** 保存表 */
const saveTable = () => {
let tableData = tableCreateInfo.value.tableData[0];
if (!tableData.chName) {
ElMessage({
type: "error",
message: "主题表名称不能为空!",
});
return;
}
if (!tableData.dataServerName) {
ElMessage({
type: "error",
message: "数据源不能为空!",
});
return;
}
if (tableData.dataServerName.indexOf('-') > -1) {
ElMessage.error('数据库表名称不能包含中划线,可以改为下划线!');
return;
}
if (isDimTable && !tableData.codeColumn) {
ElMessage({
type: "error",
message: "编码字段不能为空",
});
return;
}
if (isDimTable && !tableData.codeName) {
ElMessage({
type: "error",
message: "编码名称不能为空",
});
return;
}
if (!tableCreateInfo.value.inputNameValue) {
ElMessage({
type: "error",
message: "主题表名称不能为空!",
});
return;
}
let tableFields = tableCreateInfo.value.tableFields;
if (!tableFields.length) {
ElMessage({
type: "error",
message: "表字段不能为0行",
});
return;
}
// 若开启了字段标准,则不能为空。
// 必须含有主键。若是聚合模型,则除了主键必须有聚合方式。
let isSumModel = tableData.tableModel === 2;
let hasPrimary = false;
let enNames: any = [];
let chNames: any = [];
const regex = /^[a-zA-Z]/;
let index = 1;
for (const field of tableFields) {
if (!field.enName) {
ElMessage.error(`第 ${index} 个字段的英文名称不能为空!`);
return;
}
if (!regex.test(field.enName)) {
ElMessage.error(`第 ${index} 个字段的英文名称必须以英文字符开头`);
return;
}
if (enNames.indexOf(field.enName) > -1) {
ElMessage.error(`字段的英文名称 ${field.enName} 不能重复!`);
return;
}
if (chNames.indexOf(field.chName) > -1) {
ElMessage.error(`字段的英文名称 ${field.chName} 不能重复!`);
return;
}
if (isOpenStandard.value && !field.fieldStandardCode) {
ElMessage.error(`开启了字段强标准,第 ${index} 个字段的标准不能为空!`);
return;
}
if (field.dataType === "decimal" && (!field.fieldPrecision && field.fieldPrecision != 0)) {
ElMessage.error(`第 ${index} 个字段的字段类型为浮点型时,精度不能为空`);
return;
}
if (field.dataType === "varchar" && (!field.fieldLength && field.fieldLength != 0)) {
ElMessage.error(`第 ${index} 个字段的字段类型为字符型时,长度不能为空`);
return;
}
if (field.dataType === "char" && (!field.fieldLength && field.fieldLength != 0)) {
ElMessage.error(`第 ${index} 个字段的字段类型为单字符型时,长度不能为空`);
return;
}
if (field.dataType === "decimal" && (!field.fieldLength && field.fieldLength != 0)) {
ElMessage.error(`第 ${index} 个字段的字段类型为浮点符型时,长度不能为空`);
return;
}
if (field.isPrimary === 'Y') {
hasPrimary = true;
if (field.notNull != 'Y') {
ElMessage.error(`第 ${field.orderNum} 个字段为主键,应设置为必填`);
return;
}
if (field.dataType == 'text') {
ElMessage.error(`第 ${field.orderNum} 个字段为主键,字段类型不能设置为‘大字段型’`);
return;
}
if (field.dataType == 'json') {
ElMessage.error(`第 ${field.orderNum} 个字段为主键,字段类型不能设置为‘JSON类型’`);
return;
}
if (field.dataType == 'bit') {
ElMessage.error(`第 ${field.orderNum} 个字段为主键,字段类型不能设置为‘布尔类型’`);
return;
}
} else {
if (!field.aggWay && isSumModel) {
ElMessage.error(`聚合模型的非主键字段必须设置聚合方式!`);
return;
}
}
if (tableCreateInfo.value.isSync == 'Y' && field.notNull == 'Y' && !field.fileFieldName && (field.defaultValue === "" || field.defaultValue == null)) {
ElMessage.error(`第 ${index} 个字段为必填且建表勾选同步数据时,文件字段名和默认值不能同时为空`);
return;
}
if (field.isEdit) {
if (field.dataType && checkDefault[field.dataType]) {
if (!field.fieldLength) { }
if (!checkDefault[field.dataType]({ row: field })) {
return;
}
}
}
enNames.push(field.enName);
chNames.push(field.chName);
index++;
}
if (!hasPrimary) {
ElMessage.error(`字段至少有一个主键字段!`);
return;
}
let abbreviation = tableStandardDetail.value.abbreviation;
let uploadDataFileInfos = uploadDataFileInfo.value;
let addInfo = Object.assign({}, tableCreateInfo.value.tableData[0], {
enName: !abbreviation ? tableCreateInfo.value.inputNameValue : (tableStandardDetail.value.standardType === 1 ? abbreviation.concat(tableCreateInfo.value.inputNameValue) : tableCreateInfo.value.inputNameValue.concat(abbreviation)),
tableCreateType: 4,//根据文件新建表
saveFlag: 1,
dbType: dbType.value,
layereAttribute: route.query.layereAttribute,
dataState: 1,
tableCategory: isDimTable ? 4 : tableCreateInfo.value.tableData[0].tableCategory,
partitionAttribute: !Object.keys(tableCreateInfo.value.partitionAttribute).length ? null : Object.assign({}, tableCreateInfo.value.partitionAttribute, {
dynamicPartitionHistory: tableCreateInfo.value.partitionAttribute ? "Y" : 'N'
}),
subjectFieldAddDTOS: tableCreateInfo.value.tableFields.map((field, i) => {
return Object.assign({}, field, { orderNum: i + 1 });
}),
standardGuid: tableStandardDetail.value.guid,
standardCode: tableStandardDetail.value.standardCode,
standardDataVersion: tableStandardDetail.value.dataVersion,
abbreviation: abbreviation,
isSync: tableCreateInfo.value.isSync,
attachmentsDTO: {
fileName: uploadDataFileInfos[0]?.name,
sheetName: tableCreateInfo.value.sheetName,
fileUrl: uploadDataFileInfos[0].url || "",
staffGuid: userData.staffGuid
}
})
if (!tableCreateInfo.value.guid) { //添加
fullscreenLoading.value = true;
saveSubjectTable(addInfo).then((res: any) => {
fullscreenLoading.value = false;
if (res.code == proxy.$passCode) {
ElMessage.success('手动新建表保存成功!');
router.push({
name: 'dataWarehouse'
});
dataCatalogStore.set(subjectDomainGuid.value);
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== route.fullPath));
} else {
ElMessage.error(res.msg);
}
});
} else { //更新
addInfo.guid = tableCreateInfo.value.guid;
addInfo.isCreate = tableCreateInfo.value.isCreate ? 'Y' : 'N';
fullscreenLoading.value = true;
updateSubjectTable(addInfo).then((res: any) => {
fullscreenLoading.value = false;
if (res.code == proxy.$passCode) {
ElMessage.success('编辑更新成功!');
router.push({
name: 'dataWarehouse'
});
dataCatalogStore.set(subjectDomainGuid.value);
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== route.fullPath));
} else {
ElMessage.error(res.msg);
}
});
}
};
const saveDraftTable = () => {
let tableData = tableCreateInfo.value.tableData[0];
if (!tableData.chName) {
ElMessage({
type: "error",
message: "主题表名称不能为空!",
});
return;
}
let abbreviation = tableStandardDetail.value.abbreviation;
let uploadDataFileInfos = uploadDataFileInfo.value;
let addInfo = Object.assign({}, tableCreateInfo.value.tableData[0], {
enName: !abbreviation ? tableCreateInfo.value.inputNameValue : (tableStandardDetail.value.standardType === 1 ? abbreviation.concat(tableCreateInfo.value.inputNameValue) : tableCreateInfo.value.inputNameValue.concat(abbreviation)),
tableCreateType: 4,//根据文件新建表
saveFlag: 0,
layereAttribute: route.query.layereAttribute,
dbType: dbType.value,
dataState: 0,
partitionAttribute: !Object.keys(tableCreateInfo.value.partitionAttribute).length ? null : Object.assign({}, tableCreateInfo.value.partitionAttribute, {
dynamicPartitionHistory: tableCreateInfo.value.partitionAttribute ? "Y" : 'N'
}),
subjectFieldAddDTOS: tableCreateInfo.value.tableFields.map((field, i) => {
return Object.assign({}, field, { orderNum: i + 1 });
}),
standardGuid: tableStandardDetail.value.guid,
standardCode: tableStandardDetail.value.standardCode,
standardDataVersion: tableStandardDetail.value.dataVersion,
abbreviation: abbreviation,
isSync: tableCreateInfo.value.isSync,
attachmentsDTO: {
fileName: uploadDataFileInfos[0]?.name,
sheetName: tableCreateInfo.value.sheetName,
fileUrl: uploadDataFileInfos[0].url || "",
staffGuid: userData.staffGuid
}
})
if (!tableCreateInfo.value.guid) { //添加
fullscreenLoading.value = true;
saveSubjectTableDraft(addInfo).then((res: any) => {
fullscreenLoading.value = false;
if (res.code == proxy.$passCode) {
ElMessage.success('手动新建表保存草稿成功!');
router.push({
name: 'dataWarehouse'
});
dataCatalogStore.set(subjectDomainGuid.value);
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== route.fullPath));
} else {
ElMessage.error(res.msg);
}
})
} else {
addInfo.isCreate = tableCreateInfo.value.isCreate ? 'Y' : 'N';
addInfo.guid = tableCreateInfo.value.guid;
fullscreenLoading.value = true;
updateSubjectTableDraft(addInfo).then((res: any) => {
fullscreenLoading.value = false;
if (res.code == proxy.$passCode) {
ElMessage.success('编辑保存草稿成功!');
router.push({
name: 'dataWarehouse'
});
dataCatalogStore.set(subjectDomainGuid.value);
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== route.fullPath));
} else {
ElMessage.error(res.msg);
}
});
}
};
const batchAddDialogBtnClick = (btn, info) => {
if (btn.value == "submit") {
if (!info.length) {
ElMessage.error('已选标准不能为空!');
return;
}
batchAddDialogInfo.value.visible = false;
if (info.length) {
let len = tableCreateInfo.value.tableFields.length;
info.forEach((i) => {
tableCreateInfo.value.tableFields.push({
orderNum: ++len,
fieldStandardGuid: i.guid,
fieldStandardCode: i.fieldStandardCode,
fieldStandardName: i.chName,
chName: i.chName,
enName: i.enName,
dataType: i.dataTypeCode,
dictionaryGuid: i.isDataDic === 'Y' ? i.dataDicGuid : "",
dictionaryChName: i.isDataDic === 'Y' ? dictionaryList.value.find(d => d.guid === i.dataDicGuid)?.chName : "",
fieldLength: i.fieldLength,
fieldPrecision: i.fieldPrecision,
isPrimary: "N",
notNull: "N",
});
});
nextTick(() => {
let bodyWrapper = fieldStandardTableRef.value?.$el.querySelector('.el-table__body');
let domScroll = bodyWrapper.parentElement.parentElement;
let rect = domScroll.getBoundingClientRect();
if (len * 36 > rect.height + domScroll.scrollTop) {
fieldStandardTableRef.value?.setScrollTop(len * 36 - rect.height + 2)
}
})
}
} else if (btn.value == "cancel") {
batchAddDialogInfo.value.visible = false;
}
};
const expandProperties = ref({});
/** 扩展属性弹出对话框 */
const expandPropertyDialogRef = ref();
/** 扩展属性弹出对话框 */
const handleClickExpand = () => {
expandPropertyDialogRef.value?.handleClickExpand();
}
const expandDialogValueChange = (val) => {
tableCreateInfo.value.partitionAttribute = val;
expandProperties.value = val;
}
const tableSelectFields = computed(() => {
return tableCreateInfo.value.tableFields.filter(t => !!t.enName);
})
</script>
<template>
......@@ -232,7 +1463,295 @@ const saveTable = () => {
<uploadExcelFile ref="uploadFileRef" v-show="stepsInfo.step === 0" @fileDataChange="handleFileDataChange">
</uploadExcelFile>
<div class="second-step-content" v-show="stepsInfo.step === 1">
aaa
<el-table ref="tableRef" :data="tableCreateInfo.tableData" :highlight-current-row="true" stripe border
height="100%" tooltip-effect="light" row-key="guid" :style="{
width: '100%',
height: 'auto',
display: 'inline-block',
}">
<el-table-column prop="dataSourceGuid" label="数据源" width="200px" align="left" show-overflow-tooltip>
<template #header>
<span>数据源</span>
<span style="color:red;margin-left: 2px;">*</span>
</template>
<template #default="scope">
<el-select v-model="scope.row['dataSourceGuid']" placeholder="请选择" :disabled="tableCreateInfo.isCreate"
@change="(val) => selectDatabaseChange(val)" clearable filterable>
<el-option v-for="opt in databaseList" :key="opt['guid']" :label="opt['databaseNameZh']"
:value="opt['guid']" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="enName" label="数据库表" width="200px" align="left" show-overflow-tooltip>
<template #header>
<span>数据库表</span>
<span style="color:red;margin-left: 2px;">*</span>
</template>
<template #default="scope">
<div class="prefix-or-suffix-cell">
<div v-if="tableStandardDetail.standardType === 1">{{ tableStandardDetail.abbreviation }}</div>
<el-input :disabled="tableCreateInfo.isCreate" v-model.trim="tableCreateInfo.inputNameValue"
:maxlength="50" placeholder="必填" />
<div v-if="tableStandardDetail.standardType === 2">{{ tableStandardDetail.abbreviation }}</div>
</div>
</template>
</el-table-column>
<el-table-column prop="chName" label="主题表名称" width="200px" align="left" show-overflow-tooltip>
<template #header>
<span>主题表名称</span>
<span style="color:red;margin-left: 2px;">*</span>
</template>
<template #default="scope">
<el-input v-model.trim="scope.row['chName']" placeholder="必填" :maxlength="50" />
</template>
</el-table-column>
<el-table-column prop="subjectDomain" label="主题域" width="180px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-input disabled v-model.trim="scope.row['subjectDomain']" />
</template>
</el-table-column>
<el-table-column prop="tableModel" label="表模型" width="150px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-select v-if="dbType == 'doris'" v-model="scope.row['tableModel']" placeholder="请选择"
:disabled="tableCreateInfo.isCreate">
<el-option v-for="opt in tableModels" :key="opt['value']" :label="opt['label']" :value="opt['value']" />
</el-select>
<span v-else>--</span>
</template>
</el-table-column>
<el-table-column prop="tableCategory" v-if="!isDimTable" label="表分类" width="150px" align="left"
show-overflow-tooltip>
<template #default="scope">
<el-select v-model="scope.row['tableCategory']" placeholder="请选择" :disabled="tableCreateInfo.isCreate">
<el-option v-for="opt in tableCategoryList" :key="opt['value']" :label="opt['label']"
:value="opt['value']" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="dimType" v-if="isDimTable" label="维表类型" width="150px" align="left"
show-overflow-tooltip>
<template #default="scope">
<el-select v-model="scope.row['dimType']" placeholder="请选择">
<el-option v-for="opt in dimTypeList" :key="opt['value']" :label="opt['label']" :value="opt['value']" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="codeColumn" v-if="isDimTable" label="编码字段" width="150px" align="left"
show-overflow-tooltip>
<template #header>
<span>编码字段</span>
<span style="color:red;margin-left: 2px;">*</span>
</template>
<template #default="scope">
<el-select v-model="scope.row['codeColumn']" placeholder="请选择">
<el-option v-for="opt in tableSelectFields" :key="opt['enName']" :label="opt['chName']"
:value="opt['enName']" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="codeName" v-if="isDimTable" label="编码名称" width="150px" align="left"
show-overflow-tooltip>
<template #header>
<span>编码名称</span>
<span style="color:red;margin-left: 2px;">*</span>
</template>
<template #default="scope">
<el-select v-model="scope.row['codeName']" placeholder="请选择">
<el-option v-for="opt in tableSelectFields" :key="opt['enName']" :label="opt['chName']"
:value="opt['enName']" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="syncPolicy" label="同步策略" width="150px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-select v-model="scope.row['syncPolicy']" placeholder="请选择" :disabled="tableCreateInfo.isCreate">
<el-option v-for="opt in syncPolicys" :key="opt['value']" :label="opt['label']" :value="opt['value']" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="characterSet" label="字符集" width="150px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-select v-model="scope.row['characterSet']" placeholder="请选择" :disabled="tableCreateInfo.isCreate">
<el-option v-for="opt in characterList" :key="opt['paramValue']" :label="opt['paramName']"
:value="opt['paramValue']" />
</el-select>
</template>
</el-table-column>
<el-table-column prop="description" label="描述" width="220px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-input v-model.trim="scope.row['description']" />
</template>
</el-table-column>
<el-table-column label="操作" width="100px" align="left" fixed="right" show-overflow-tooltip>
<template #default="scope">
<span class="text_btn" :class="{ 'is-disabled': tableCreateInfo.isCreate }" @click="handleClickExpand()"
v-preReClick>扩展属性</span>
</template>
</el-table-column>
</el-table>
<div class="tools_btns">
<el-button v-if="fieldStandardSetGuids?.length" type="primary" @click="batchAddFields"
v-preReClick>批量新增</el-button>
<el-button type="primary" @click="addField" v-preReClick>新增</el-button>
<el-button @click="moveUp">上移</el-button>
<el-button @click="moveDown">下移</el-button>
<el-button @click="delFeilds" v-preReClick>批量删除</el-button>
<el-button v-if="fieldStandardSetGuids?.length" type="primary" @click="createFieldsStandard"
v-preReClick>新建字段标准</el-button>
</div>
<div class="table_panel">
<el-table ref="fieldStandardTableRef" :data="tableCreateInfo.tableFields" v-loading="tableFieldsLoading"
:highlight-current-row="true" stripe border height="100%" @selection-change="selectionFieldsChange"
tooltip-effect="light" :style="{
width: '100%',
'max-height': '100%',
display: 'inline-block',
}">
<el-table-column type="selection" :width="32" align="center" />
<el-table-column label="排序" type="index" width="56px" align="center" show-overflow-tooltip>
</el-table-column>
<el-table-column v-if="fieldStandardSetGuids?.length" prop="fieldStandardGuid" label="标准名称" width="160px"
align="left" show-overflow-tooltip>
<template #default="scope">
<el-tree-select ref="treeSelectRef" v-if="scope.row['isEdit']" filterable clearable
:data="standardListOptions" v-model="scope.row['fieldStandardGuid']" placeholder="请选择"
:filter-node-method="standardInputFilterMethod" :props="{
label: 'chName',
value: 'guid',
children: 'children',
isLeaf: 'isLeaf'
}" @change="(v) => handleStandardValueChange(v, scope)" @current-change="handleStandardNodeChange">
<template #default="{ node, data }">
<template v-if="node.level > 1 && !node.data.children && node.data.standardSetGuid">
<span>{{ data["chName"] + `(${data["enName"]})` }}</span>
</template>
<span v-else>{{ data['chName'] }}</span>
</template>
</el-tree-select>
<span v-else>{{ scope.row["fieldStandardName"] || "--" }}</span>
</template>
</el-table-column>
<el-table-column prop="chName" label="目标字段名" width="150px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-input v-if="scope.row['isEdit'] && !isOpenStandard"
:placeholder="fieldStandardSetGuids?.length ? '输入匹配标准' : ''" v-model.trim="scope.row['chName']"
@change="(v) => handleFieldChineseNameChange(v, scope)" />
<span v-else>{{ scope.row["chName"] || '--' }}</span>
</template>
</el-table-column>
<el-table-column prop="enName" label="目标字段英文名" width="150px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-input v-if="scope.row['isEdit'] && !isOpenStandard" v-model.trim="scope.row['enName']"
placeholder="必填" @input="inputLengthKeyUp(/[^a-zA-Z0-9_]/g, scope, 'enName')" />
<span v-else>{{ scope.row["enName"] || '--' }}</span>
</template>
</el-table-column>
<el-table-column prop="fileFieldName" label="文件字段名" width="150px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-select v-if="scope.row['isEdit']" v-model="scope.row['fileFieldName']" clearable filterable
placeholder="请选择">
<el-option v-for="opt in fileTableFields" :key="opt['index']" :label="opt['chName']"
:value="opt['enName']" />
</el-select>
<span v-else>{{ scope.row['fileFieldName'] || "--" }}</span>
</template>
</el-table-column>
<el-table-column prop="dataType" label="字段类型" width="120px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-select v-if="scope.row['isEdit'] && !isOpenStandard" v-model="scope.row['dataType']"
@change="(val) => dataTypeChange(val, scope)" placeholder="请选择">
<el-option v-for="opt in fieldTypes" :key="opt['paramValue']" :label="opt['paramName']"
:value="opt['paramValue']" />
</el-select>
<span v-else>{{ fieldTypes.find(f => f.paramValue === scope.row["dataType"])?.paramName || "--"
}}</span>
</template>
</el-table-column>
<el-table-column prop="fieldLength" label="长度" width="115px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-input
v-if="scope.row['isEdit'] && !isOpenStandard && (scope.row['dataType'] == 'varchar' || scope.row['dataType'] == 'decimal' || scope.row['dataType'] == 'char')"
v-model.trim="scope.row['fieldLength']" placeholder="必填"
@input="inputLengthKeyUp(/\D/g, scope, 'fieldLength', 2000, 1)" />
<span v-else>{{ scope.row["fieldLength"] == null ? '--' : scope.row["fieldLength"] }}</span>
</template>
</el-table-column>
<el-table-column prop="fieldPrecision" label="精度" width="115px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-input v-if="scope.row['isEdit'] && !isOpenStandard && scope.row['dataType'] == 'decimal'"
v-model.trim="scope.row['fieldPrecision']" placeholder="必填"
@input="inputLengthKeyUp(/\D/g, scope, 'fieldPrecision', 30, 1)" />
<span v-else>{{ scope.row["fieldPrecision"] == null ? '--' : scope.row["fieldPrecision"] }}</span>
</template>
</el-table-column>
<el-table-column prop="dimOrdictionaryGuid" v-if="!isDimTable" label="关联维度/字典" width="130px" align="left"
show-overflow-tooltip>
<template #default="scope">
<el-tree-select ref="dimOrDictSelectRef" v-if="scope.row['isEdit']" filterable clearable
:data="dimOrDictList" v-model="scope.row['dimOrdictionaryGuid']" node-key="guid"
:default-expanded-keys="scope.row['dictionaryGuid'] ? ['1'] : (scope.row['dimGuid'] ? ['2'] : [])"
placeholder="请选择" :filter-node-method="dimOrDictInputFilterMethod" :props="{
label: 'chName',
value: 'guid',
children: 'children',
isLeaf: 'isLeaf'
}" @change="(v) => handleDictionaryChange(v, scope)" @current-change="handleDictSelectNodeChange">
<template #default="{ node, data }">
<template v-if="node.level > 1 && data.parentGuid == '2'">
<span>{{ data["chName"] + `(${data["subjectDomainName"]})` }}</span>
</template>
<span v-else>{{ data['chName'] }}</span>
</template>
</el-tree-select>
<span v-else>{{ (scope.row['dictionaryGuid'] ? scope.row["dictionaryChName"] : (scope.row['dimGuid'] ?
scope.row['dimChName'] : '--')) || '--' }}</span>
</template>
</el-table-column>
<el-table-column prop="isPrimary" label="是否主键" width="90px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-select v-if="scope.row['isEdit']" v-model="scope.row['isPrimary']" placeholder="请选择">
<el-option v-for="opt in isNotList" :key="opt['value']" :label="opt['label']" :value="opt['value']" />
</el-select>
<span v-else>{{ scope.row["isPrimary"] || '--' }}</span>
</template>
</el-table-column>
<el-table-column v-if="tableCreateInfo.tableData[0].tableModel == 2" prop="aggWay" label="聚合方式"
width="120px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-select v-if="scope.row['isEdit']" v-model="scope.row['aggWay']" placeholder="请选择">
<el-option v-for="opt in aggMethodList" :key="opt['value']" :label="opt['label']"
:value="opt['value']" />
</el-select>
<span v-else>{{ scope.row["aggWay"] || '--' }}</span>
</template>
</el-table-column>
<el-table-column prop="notNull" label="是否必填" width="90px" align="left" show-overflow-tooltip>
<template #default="scope">
<el-select v-if="scope.row['isEdit'] && !(scope.row.isCreate == 'Y' && scope.row['notNull'] == 'N')"
v-model="scope.row['notNull']" placeholder="请选择">
<el-option v-for="opt in isNotList" :key="opt['value']" :label="opt['label']" :value="opt['value']" />
</el-select>
<span v-else>{{ scope.row["notNull"] || '--' }}</span>
</template>
</el-table-column>
<el-table-column prop="defaultValue" label="默认值" width="205px" align="left" show-overflow-tooltip>
<template #default="scope">
<tableDefaultValue :scope="scope" :dbType="dbType"></tableDefaultValue>
</template>
</el-table-column>
<el-table-column label="操作" width="100px" align="left" fixed="right" show-overflow-tooltip>
<template #default="scope">
<span class="text_btn" v-if="!scope.row['isEdit']" @click="handleFieldClickEdit(scope)"
v-preReClick>编辑</span>
<span class="text_btn" v-else @click="handleFieldClickSave(scope)" v-preReClick>保存</span>
<el-divider direction="vertical" />
<span class="text_btn" @click="handleFieldDelete(scope)">删除</span>
</template>
</el-table-column>
</el-table>
</div>
<Dialog ref="batchAddDialogRef" :dialogInfo="batchAddDialogInfo" @btnClick="batchAddDialogBtnClick"
@tablePageChange="bacthAddTablePageChange" @headerSearchInputChanged="batchDialogHeaderSearchInputChanged" />
</div>
</div>
<div class="bottom_tool_wrap">
......@@ -243,11 +1762,15 @@ const saveTable = () => {
<el-checkbox v-model="tableCreateInfo.isSync" true-label="Y" :disabled="!fileTableData?.length"
false-label="N">同步数据(说明:勾选代表建表同时写入表格数据。)</el-checkbox>
<el-button @click="previousStep">上一步</el-button>
<el-button type="primary">保存为草稿</el-button>
<el-button type="primary" @click="saveDraftTable">保存为草稿</el-button>
<el-button type="primary" @click="saveTable">提交</el-button>
</template>
</div>
<Dialog ref="batchAddDialogRef" :dialogInfo="batchAddDialogInfo" @btnClick="batchAddDialogBtnClick"
@tablePageChange="bacthAddTablePageChange" @treeNodeClick="bacthAddTreeNodeClick"
@headerSearchInputChanged="batchDialogHeaderSearchInputChanged" />
<expandPropertyDialog ref="expandPropertyDialogRef" :partitionAttribute="expandProperties"
:table-create-info="tableCreateInfo" @expandValueChange="expandDialogValueChange" />
</div>
</template>
......
......@@ -57,9 +57,18 @@ const getClassifyGradListData = async () => {
}
//获取分类列表
const getClassListData = async () => {
const getClassListData = async (params = {}) => {
const inParams = {
type: 'C',
pageIndex: 1,
pageSize: -1
}
const finalParams = {
...inParams,
...params
}
classListDataLoading.value = true;
const res: any = await getClassifyGradList(refClassifyPageParams.value);
const res: any = await getClassifyGradList(finalParams);
if (res.code == proxy.$passCode) {
classListData.value = res.data.records || [];
classListDataLoading.value = false;
......@@ -70,7 +79,7 @@ const getClassListData = async () => {
onMounted(() => {
getClassifyGradListData();
getClassListData();
// getClassListData();
})
......@@ -108,24 +117,30 @@ const cardBtnVisible: any = ref(false);
/** 搜索查询分类标准 */
const searchClass = async (val: any, clear: boolean = false) => {
console.log(val, 'val');
if (clear) {
classSearchItemList.value.map(item => item.default = '')
getClassListData();
return;
}
const params = {
type: 'C',
name: val.classStandardName,
pageIndex: 1,
pageSize: -1
}
const res: any = await getClassifyGradList(params);
if (res.code == proxy.$passCode) {
classListData.value = res.data.records || [];
} else {
proxy.$ElMessage.error(res.msg);
}
// const params = {
// type: 'C',
// name: val.classStandardName,
// pageIndex: 1,
// pageSize: -1
// }
// const res: any = await getClassifyGradList(params);
// if (res.code == proxy.$passCode) {
// classListData.value = res.data.records || [];
// } else {
// proxy.$ElMessage.error(res.msg);
// }
getClassListData(
{
name: val.classStandardName
}
);
};
/** 编辑分类 */
......@@ -149,6 +164,7 @@ const handleClassDataEdit = (params) => {
// 配置分类
const handleClassDataClick = (item, des = '') => {
console.log(item, 'i111tem');
// 获取分级标准
router.push({
name: 'classStandardEdit',
......@@ -156,7 +172,9 @@ const handleClassDataClick = (item, des = '') => {
guid: item.guid,
type: des === '' ? '配置' : des,
classStandardName: item.name,
refGradeGuid: item.refGradeGuid
refGradeGuid: item.refGradeGuid,
description: item.description,
isExpand: item.isExpand || false
}
});
}
......@@ -229,7 +247,7 @@ const classStandardFormItems = ref([{
const classStandardFormRules = ref({
classStandardName: [required('请填写分类名称')],
gradeStandard: [required('请选择分级标准')]
refGradeGuid: [required('请选择分级标准')]
});
const newCreateClassStandardDialogInfo = ref({
......@@ -248,6 +266,7 @@ const newCreateClassStandardDialogInfo = ref({
newCreateClassStandardDialogInfo.value.visible = false;
},
submit: async (btn, info) => {
if (newCreateClassStandardDialogInfo.value.title === '新增分类') {
newCreateClassStandardDialogInfo.value.submitBtnLoading = true;
const params = {
......@@ -263,9 +282,26 @@ const newCreateClassStandardDialogInfo = ref({
type: 'success',
message: '新增分类成功'
})
nextTick(() => {
// 拿到新增的分类数据,跳转到配置页面
const item = classListData.value.find(item => item.name === info.classStandardName);
console.log(item, 'item---------------');
if (item) {
const params = {
name: item.name,
guid: item.guid,
refGradeGuid: item.refGradeGuid,
description: item.description,
isExpand: true
}
handleClassDataClick(params, '');
}
})
newCreateClassStandardDialogInfo.value.submitBtnLoading = false;
newCreateClassStandardDialogInfo.value.visible = false;
} else {
newCreateClassStandardDialogInfo.value.submitBtnLoading = false;
proxy.$ElMessage.error(res.msg);
}
} else {
......@@ -293,6 +329,7 @@ const newCreateClassStandardDialogInfo = ref({
})
const newCreateClass = () => {
newCreateClassStandardDialogInfo.value.submitBtnLoading = false;
newCreateClassStandardDialogInfo.value.visible = true;
classStandardFormItems.value.forEach(item => item.default = '');
}
......@@ -343,12 +380,10 @@ const newCreateGradeStandardDialogInfo = ref({
await getClassifyGradListData();
proxy.$ElMessage({
type: 'success',
message: '新增分成功'
message: '新增分成功'
})
// 拿到新增的分级数据,跳转到配置页面
const item = classifyGradListData.value.find(item => item.name === info.name);
if (item) {
const params = {
name: item.name,
......@@ -359,6 +394,7 @@ const newCreateGradeStandardDialogInfo = ref({
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
newCreateGradeStandardDialogInfo.value.visible = false;
} else {
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
proxy.$ElMessage.error(res.msg);
}
} else {
......@@ -372,7 +408,7 @@ const newCreateGradeStandardDialogInfo = ref({
getClassifyGradListData();
proxy.$ElMessage({
type: 'success',
message: '修改分成功'
message: '修改分成功'
})
newCreateGradeStandardDialogInfo.value.visible = false;
} else {
......@@ -437,6 +473,7 @@ const handleClassifyGradDataClick = (item) => {
}
const newCreateGrade = () => {
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
newCreateGradeStandardDialogInfo.value.visible = true;
newCreateGradeFormItems.value.forEach(item => item.default = '');
}
......@@ -538,8 +575,8 @@ const newCreateGrade = () => {
</el-icon>
</template>
<div class="levitation-ul">
<span class="levitation-li" @click="handleClassDataClick(item)">配置</span>
<span class="levitation-li" @click="handleClassDataEdit(item)">编辑</span>
<span class="levitation-li" @click="handleClassDataClick(item)">编辑</span>
<!-- <span class="levitation-li" @click="handleClassDataEdit(item)">编辑</span> -->
<span class="levitation-li" @click="handleClassDataDel(item)">删除</span>
</div>
</el-popover>
......@@ -571,8 +608,8 @@ const newCreateGrade = () => {
</el-icon>
</template>
<div class="levitation-ul">
<span class="levitation-li" @click="handleClassifyGradDataClick(item)">配置</span>
<span class="levitation-li" @click="handleClassifyGradDataEdit(item)">编辑</span>
<span class="levitation-li" @click="handleClassifyGradDataClick(item)">编辑</span>
<!-- <span class="levitation-li" @click="handleClassifyGradDataEdit(item)">编辑</span> -->
<span class="levitation-li" @click="handleClassifyGradDataDel(item)">删除</span>
</div>
</el-popover>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!