f278ba6b by xukangle

fix:修改分级分类标准的相关问题

1 parent 751d9bbf
......@@ -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
});
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'
});
......@@ -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,15 +449,20 @@ 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) => {
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,
url: res.data.signedUrl,
file: file.file
};
if (item.limit === 1) {
......@@ -468,6 +478,7 @@ const uploadFile = (file, item) => {
ElMessage.error('上传失败,请重新上传!');
}
})
})
.catch(() => {
uploadRef.value['ref' + item.field].handleRemove(file);
ElMessage.error('上传失败,请重新上传');
......
......@@ -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[]
......
......@@ -6,10 +6,9 @@
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();
......@@ -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',
// placeholder: '请选择',
// field: 'gradeStandard',
// default: '',
// required: true,
// filterable: true,
// clearable: true,
// disabled: false,
// visible: true,
label: '分级标准',
type: 'input',
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->四级
......@@ -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 },
......@@ -165,7 +188,7 @@ const classEditFormItems = ref([{
type: 'select',
placeholder: '请选择',
field: 'gradeGuid',
default: 1,
default: '',
options: [], //TODO
props: {
label: "name",
......@@ -322,7 +345,9 @@ 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) {
......@@ -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);
}
......@@ -445,6 +472,39 @@ 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 {
proxy.$ElMessage.error(res.msg);
}
}
/** 导入分类。 */
const importClass = () => {
......@@ -778,6 +838,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>
......@@ -824,11 +885,11 @@ onMounted(() => {
}
.shape-main {
height: calc(100% - 58px);
height: calc(100% - 160px);
}
.table_panel {
height: calc(100% - 58px) !important;
height: calc(100% - 160px) !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.query.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: {
......@@ -328,19 +331,81 @@ const newStandard = () => {
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 {
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">
<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>
</template>
......@@ -351,11 +416,48 @@ const newStandard = () => {
.content_main {
height: calc(100% - 44px);
padding: 17px 16px 10px 16px;
padding: 10px 16px;
.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>
......
<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>
......@@ -14,7 +14,9 @@ import {
createTableSql,
getDsTableStructures,
getDbDirFieldClassifyAndGrade,
getDbDirTableSelectList
getDbDirTableSelectList,
getTaskExeTreeList,
getGradeList
} from "@/api/modules/dataInventory";
import existingTableSelect from "./existingTableSelect.vue";
......@@ -52,39 +54,109 @@ const processData = (data) => {
const gradeList: any = ref([]);
const classifyList: any = ref([]);
const getDbDirFieldClassifyAndGradeList = async () => {
const params = {
execGuid: execGuid.value,
type: 'C',
fieldName: 'classifyName',
// const getDbDirFieldClassifyAndGradeList = async () => {
// const params = {
// execGuid: execGuid.value,
// type: 'C',
// fieldName: 'classifyName',
// }
// const res: any = await getDbDirFieldClassifyAndGrade(params);
// if (res.code === proxy.$passCode) {
// console.log('分类分级数据', res.data)
// } else {
// proxy.$ElMessage.error(res.msg);
// }
// };
// 获取分类树形数据
// 定义树形选择器的属性
const treeSelectProps = {
label: "classifyName",
value: "classifyDetailGuid",
children: "children",
};
const treeSelectOptions = ref<any>([]);
// 存储引用的refGradeGuid
const refGradeGuidList = 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,不用递归,找第一层
data.forEach(item => {
if (item.refGradeGuid) {
refGradeGuidList.value.push(item.refGradeGuid);
}
});
const res: any = await getDbDirFieldClassifyAndGrade(params);
if (res.code === proxy.$passCode) {
console.log('分类分级数据', res.data)
} else {
proxy.$ElMessage.error(res.msg);
ElMessage.error(res.msg);
}
};
}).catch(() => {
ElMessage.error('获取分类树形数据失败');
})
}
// 联动查询数据getDbDirTableSelectList
const getTableSelectList = async (params) => {
const inParams = {
// 获取分类名称的方法
const matchedItem = ref<any>();
const getClassifyName = (guid) => {
const findClassify = (data, guid) => {
for (const item of data) {
if (item.guid === guid) {
matchedItem.value = item;
return item.classifyName;
}
// 确保 children 是一个数组
if (Array.isArray(item.children)) {
const childResult = findClassify(item.children, guid);
if (childResult) return childResult;
}
const res: any = await getDbDirTableSelectList(params);
if (res.code === proxy.$passCode) {
console.log('联动查询数据', res.data)
} else {
proxy.$ElMessage.error(res.msg);
}
return null;
};
const result = findClassify(treeSelectOptions.value, guid);
return result;
};
// 获取分级的数据
const gradeSelectProps = {
value: 'guid',
label: 'name',
}
const getGradeName = (guid) => {
const grade = gradeList.value.find(item => item.guid === guid);
return grade ? grade.gradeName : '';
}
// 进入编辑模式
const editRow = (row) => {
console.log('进入编辑模式', row)
// 进入编辑模式时,查找classifyDetailGuid
// 这个是指定是否能编辑的字段
editableFields.sourceFieldName = false;
row.isEdit = true
}
// 保存数据
const saveRow = (row) => {
editableFields.sourceFieldName = true;
row.isEdit = false
}
onMounted(async () => {
await getDbDirDataSourceListData();
await getDbDirFieldClassifyAndGradeList();
});
const stepsInfo = ref({
......@@ -111,19 +183,14 @@ const handlDsSelectedChange = (v, guid) => {
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",
......@@ -131,36 +198,60 @@ const nextStep = () => {
});
return;
}
getNextTableInfo();
getFieldTree();
initializeTableData();
stepsInfo.value.step = 1;
};
//下一步获取表字段信息getNextTableInfo。getDsData 入参selectedDatabaseTable.value
const getNextTableInfo = async () => {
const res: any = await getDsTableStructures(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 initializeTableData = () => {
console.log('初始化表格分级数据显示', refGradeGuidList.value)
tableDataDetailInfo.value.forEach((row) => {
if (row.refGradeGuid) {
getGradeList({ classifyGradeGuid: row.refGradeGuid, pageIndex: 1, pageSize: -1 }).then((res: any) => {
console.log('row进来了吗')
if (res.code === proxy.$passCode) {
row.gradeOptions = res.data.records || [];
} else {
ElMessage.error(res.msg);
}
});
}
});
};
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([
{
......@@ -170,22 +261,19 @@ 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, // 分类可编辑
}
const tableFieldsLoading = ref(false)
......@@ -238,15 +326,7 @@ const moveDown = () => {
}
};
// 进入编辑模式
const editRow = (row) => {
row.isEdit = true
}
// 保存数据
const saveRow = (row) => {
row.isEdit = false
}
// 删除行
const deleteRow = (index) => {
......@@ -278,10 +358,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: [],
})
}
......@@ -358,7 +444,6 @@ const data = [
const submitAsDraft = () => {
// 保存为草稿,无论有没有guid 都传入guid
saveOrUpdate({ isDraft: 'Y' }, 0)
}
......@@ -685,7 +770,11 @@ const createNewSql = () => {
<!-- 源字段英文 -->
<el-table-column prop="sourceFieldName" label="源字段英文" width="150">
<template #default="scope">
{{ scope.row.sourceFieldName ? scope.row.sourceFieldName : '--' }}
<!-- {{ 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-->
......@@ -698,10 +787,10 @@ const createNewSql = () => {
<!-- 长度(可编辑) -->
<el-table-column prop="fieldLength" label="长度" width="120" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.length">{{ scope.row.fieldLength ?
<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 -->
......@@ -725,11 +814,12 @@ const createNewSql = () => {
<!-- 数据是否唯一(可编辑) -->
<el-table-column prop="isPrimary" label="是否主键" width="150" align="center">
<template #default="scope">
<span v-if="!scope.row.isEdit || !editableFields.length">{{ scope.row.isPrimary ? scope.row.isPrimary :
<span v-if="!scope.row.isEdit || !editableFields.isPrimary">{{ scope.row.isPrimary ? scope.row.isPrimary
:
'--' }}</span>
<el-select v-else v-model="scope.row.isPrimary" placeholder="请选择">
<el-option label="是" value="是" />
<el-option label="否" value="否" />
<el-option label="Y" value="Y" />
<el-option label="N" value="N" />
</el-select>
</template>
</el-table-column>
......@@ -738,22 +828,42 @@ const createNewSql = () => {
<template #default="scope">
<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="是" value="是" />
<el-option label="否" value="否" />
<el-option label="Y" value="Y" />
<el-option label="N" value="N" />
</el-select>
</template>
</el-table-column>
<!-- 分类(不可编辑)classifyName -->
<el-table-column prop="classifyName" label="分类" width="150">
<el-table-column prop="classifyDetailGuid" label="分类" width="150">
<template #default="scope">
{{ scope.row.classifyName ? scope.row.classifyName : '--' }}
<!-- 如果当前行是编辑状态,显示 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="gradeDetailName" label="分级" width="120" align="center">
<template #default="scope">
{{ scope.row.gradeDetailName ? scope.row.gradeDetailName : '--' }}
<div v-if="scope.row.isEdit">
<el-select v-model="scope.row.gradeGuid" placeholder="请选择分级" clearable filterable
:props="gradeSelectProps">
<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>
<!-- 操作列 -->
......
......@@ -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>
......
......@@ -149,6 +149,7 @@ const handleClassDataEdit = (params) => {
// 配置分类
const handleClassDataClick = (item, des = '') => {
console.log(item, 'i111tem');
// 获取分级标准
router.push({
name: 'classStandardEdit',
......@@ -156,7 +157,8 @@ const handleClassDataClick = (item, des = '') => {
guid: item.guid,
type: des === '' ? '配置' : des,
classStandardName: item.name,
refGradeGuid: item.refGradeGuid
refGradeGuid: item.refGradeGuid,
description: item.description
}
});
}
......@@ -248,6 +250,7 @@ const newCreateClassStandardDialogInfo = ref({
newCreateClassStandardDialogInfo.value.visible = false;
},
submit: async (btn, info) => {
if (newCreateClassStandardDialogInfo.value.title === '新增分类') {
newCreateClassStandardDialogInfo.value.submitBtnLoading = true;
const params = {
......@@ -263,6 +266,22 @@ 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
}
handleClassDataClick(params, '');
}
})
newCreateClassStandardDialogInfo.value.submitBtnLoading = false;
newCreateClassStandardDialogInfo.value.visible = false;
} else {
......@@ -343,7 +362,7 @@ const newCreateGradeStandardDialogInfo = ref({
await getClassifyGradListData();
proxy.$ElMessage({
type: 'success',
message: '新增分成功'
message: '新增分成功'
})
// 拿到新增的分级数据,跳转到配置页面
......@@ -372,7 +391,7 @@ const newCreateGradeStandardDialogInfo = ref({
getClassifyGradListData();
proxy.$ElMessage({
type: 'success',
message: '修改分成功'
message: '修改分成功'
})
newCreateGradeStandardDialogInfo.value.visible = false;
} else {
......@@ -437,6 +456,7 @@ const handleClassifyGradDataClick = (item) => {
}
const newCreateGrade = () => {
newCreateGradeStandardDialogInfo.value.submitBtnLoading = false;
newCreateGradeStandardDialogInfo.value.visible = true;
newCreateGradeFormItems.value.forEach(item => item.default = '');
}
......@@ -539,7 +559,7 @@ const newCreateGrade = () => {
</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="handleClassDataEdit(item)">编辑</span> -->
<span class="levitation-li" @click="handleClassDataDel(item)">删除</span>
</div>
</el-popover>
......@@ -572,7 +592,7 @@ const newCreateGrade = () => {
</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="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!