9a3281b5 by xukangle

Merge branch 'dev_20241202_xukangle' into develop

2 parents f47b695c d329ecf5
......@@ -764,8 +764,8 @@ export const createTableSql = (data) => request({
* @param {no params}
* @path /cg-dir/export
*/
export const exportCgDir = () => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/cg-dir/export`,
export const exportCgDir = (params) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/cg-dir/export?execGuid=${params.execGuid}`,
method: 'post',
responseType: 'blob',
})
......@@ -792,6 +792,21 @@ export const getDbDirDetail = (params) => request({
method: 'get',
})
/**
* 数据库目录修改规划数据资产
* @param {Object}
* @path /db-dir/table/update-data-asset
*
*/
export const updateDataAsset = (data) => request({
url: `${import.meta.env.VITE_APP_CHECK_BASEURL}/db-dir/table/update-data-asset`,
method: 'post',
data
})
/*********************业务规则配置 ************数据库目录************************* */
/**
......
......@@ -235,8 +235,8 @@ const routes: RouteRecordRaw[] = [
reuse: true
},
beforeEnter: (to, from) => {
if (to.query.domainName) {
to.meta.title = `已有表新建(${to.query.domainName})`;
if (to.query.editOpt) {
to.meta.title = `编辑-(${to.query.tableChName})`;
to.meta.editPage = true;
}
}
......
......@@ -23,7 +23,8 @@ import {
exportDbDirTable,
getDbDirDetail,
getDbDirTableSelectList,
getDbDirFieldSelectList
getDbDirFieldSelectList,
updateDataAsset
} from '@/api/modules/dataInventory';
import { TableColumnWidth } from "@/utils/enum";
import router from "@/router";
......@@ -32,7 +33,7 @@ import { getLabelList } from "@/api/modules/dataLabel";
const currentPath = ref<string[]>([]);
const { proxy } = getCurrentInstance() as any;
const route = useRoute();
// 分级分类树形列表
const CgDirTreeList = ref();
const getCgDirTreeData = async () => {
......@@ -121,7 +122,7 @@ onMounted(async () => {
// 左侧tree-list
const treeInfo = ref({
id: "data-pickup-tree",
id: "data-tree",
filter: true,
editTreeItem: false,
queryValue: "",
......@@ -179,7 +180,7 @@ const searchItemList = ref([
},
block: false,
filterable: false,
clearable: false,
clearable: true,
required: false
}, {
label: '分级',
......@@ -219,20 +220,24 @@ const toSearch = (val: any, clear: boolean = false) => {
fieldGuid: selectedC.value,
});
}
if (activeName.value === 'second') {
getDataBaseFieldData({
if (activeName.value === 'second' && activeTab.value === 'table') {
getDataBaseTableData({
pageIndex: 1,
pageSize: 50,
execGuid: execGuidInfo.value.execGuid,
databaseGuid: selectedA.value,
tableGuid: selectedB.value,
fieldGuid: selectedC.value,
databaseGuid: selectedA.value || '',
tableGuid: selectedB.value || '',
fieldGuid: selectedC.value || '',
});
}
if (activeName.value === 'second' && activeTab.value === 'word') {
getSearchTableList(1, selectedA.value);
getSearchTableList(2, selectedB.value);
getSearchTableList(3, selectedC.value);
getDataBaseFieldData({
pageIndex: 1,
pageSize: 50,
execGuid: execGuidInfo.value.execGuid,
databaseGuid: selectedA.value || '',
tableGuid: selectedB.value || '',
});
}
};
......@@ -297,7 +302,9 @@ const checked = ref(false);
const changeCheck = (val) => {
checked.value = val;
getDataBaseTableData();
getDataBaseTableData({
isDataAsset: val ? 'Y' : ''
});
}
//下方表格配置
......@@ -414,7 +421,7 @@ const dataBaseTreeInfo = ref<any>({
});
const dataBasePage = ref({
limit: 10,
limit: 50,
curr: 1,
sizes: [
{ label: "10", value: 10 },
......@@ -432,7 +439,7 @@ const dataBaseTableInfo = ref({
fields: [
{ label: "序号", type: "index", width: 56, align: "center" },
{ label: "数据源", field: "databaseChName", width: 140 },
{ label: "表名称", field: "tableChName", width: 180 },
{ label: "表名称", field: "tableChName", width: 120 },
{ label: "数据库表", field: "tableName", width: 120 },
{
label: "新建方式", field: "foundMode", width: 140, getName: (scope) => {
......@@ -445,13 +452,13 @@ const dataBaseTableInfo = ref({
}
},
{
label: "状态", field: "state", type: 'tag', width: 180, getName: (scope) => {
label: "状态", field: "state", type: 'tag', width: 120, getName: (scope) => {
let status = scope.row.state;
// 0 草稿中 1 已建表 2 已有默认表
return status == 0 ? '草稿中' : status == 1 ? '已建表' : '已有默认表';
}
},
{ label: "任务修改人", field: "updateUserName", width: 120 },
{ label: "任务修改人", field: "updateUserName", width: 100 },
{ label: "修改时间", field: "updateTime", width: TableColumnWidth.DATETIME },
{ label: "描述", field: "description", width: 120, align: 'center' },
{ label: "规划数据资产", field: "isDataAsset", type: 'switch', activeText: '是', inactiveText: '否', activeValue: 'Y', inactiveValue: 'N', switchWidth: 56, width: 120, align: 'center' },
......@@ -466,13 +473,13 @@ const dataBaseTableInfo = ref({
actionInfo: {
label: "操作",
type: "btn",
width: 300,
width: 200,
fixed: 'right',
btns: (scope) => {
return [
{
label: "配置业务规则", value: "edit", click: (scope) => {
console.log('编辑', scope);
console.log('配置', scope);
// 路由跳转configure-rules
router.push({
name: 'configureRules',
......@@ -490,30 +497,37 @@ const dataBaseTableInfo = ref({
{
label: "编辑表结构", value: "edit", click: (scope) => {
console.log('复制', scope);
getDbDirDetail({
tableGuid: scope.row.tableGuid
}).then((res: any) => {
if (res.code == proxy.$passCode) {
console.log('res', res);
// foundMode 1 已有表新建 2 根据文件新建
if (scope.row.foundMode === 1) {
// 已有表新建编辑 editOpt 代表时编辑
router.push({
name: 'tableCreateExisting',
query: {
execGuid: execGuidInfo.value.execGuid,
foundMode: 1,
database: res.data.database,
databaseChName: res.data.databaseChName,
databaseGuid: res.data.databaseGuid,
foundMode: '1',
editOpt: '1',
tableGuid: scope.row.tableGuid,
tableName: scope.row.tableName,
execGuid: execGuidInfo.value.execGuid,
tableChName: scope.row.tableChName,
description: scope.row.description,
database: dataBaseInfo.value.database,
databaseChName: dataBaseInfo.value.databaseChName,
databaseGuid: dataBaseInfo.value.databaseGuid,
}
});
} else {
proxy.$ElMessage.error(res.msg);
router.push({
name: 'tableCreateExisting',
query: {
foundMode: '2',
editOpt: '1',
tableGuid: scope.row.tableGuid,
execGuid: execGuidInfo.value.execGuid,
tableChName: scope.row.tableChName,
database: dataBaseInfo.value.database,
databaseChName: dataBaseInfo.value.databaseChName,
databaseGuid: dataBaseInfo.value.databaseGuid,
}
});
}
})
},
disabled: scope.row.state !== 2 ? false : true
}
......@@ -526,7 +540,48 @@ const dataBaseTableInfo = ref({
loading: false
});
const tableSwitchBeforeChange = (scope, field, callback) => {
// 弹窗确认
proxy.$confirm('是否修改状态?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
let params = {};
const state = scope.row.isDataAsset === 'Y' ? 'N' : 'Y';
if (scope.row.foundMode) {
params = {
tableGuid: scope.row.tableGuid,
isDataAsset: state,
foundMode: scope.row.foundMode
}
} else {
params = {
tableGuid: scope.row.tableGuid,
isDataAsset: state
}
}
const res: any = await updateDataAsset(params);
const tableGuid = ref('');
const dataBaseGuid = ref('');
if (res.code == proxy.$passCode) {
getDataBaseTableData({
dataBaseGuid: dataBaseGuid.value,
tableGuid: tableGuid.value,
pageIndex: dataBasePage.value.curr,
pageSize: dataBasePage.value.limit
});
callback();
} else {
proxy.$ElMessage.error(res.msg);
}
}).catch(() => {
proxy.$ElMessage({
type: 'info',
message: '已取消修改'
});
});
}
......@@ -743,6 +798,8 @@ const handleTreeItemMenuClick = (data: any, type) => {
// tab切换
const activeName = ref('first');
const handleClick = (tab: any) => {
// 切换时选中的配置业务规则清空
selectedRulesData.value = {};
console.log(tab.props.name);
activeName.value = tab.props.name;
if (tab.props.name === 'second') {
......@@ -848,19 +905,17 @@ const dataBaseTablePageChange = (info) => {
const tableFieldsLoading = ref(false);
const tableFieldsData = ref([]);
const getDataBaseFieldData = async (params = {}) => {
tableFieldsLoading.value = true;
tableFieldsDataInfo.value.loading = true;
const dataBaseParams = {
pageIndex: 1,
pageSize: 50,
tableGuid: "",
execGuid: execGuidInfo.value.execGuid,
databaseGuid: "",
isDataAsset: '',
fieldName: '',
gradeDetailName: '',
};
const finalParams = { ...dataBaseParams, ...params };
const res: any = await getDbDirFieldPageList(finalParams);
if (res.code == proxy.$passCode) {
tableFieldsData.value = res.data.records;
......@@ -868,7 +923,7 @@ const getDataBaseFieldData = async (params = {}) => {
} else {
proxy.$ElMessage.error(res.msg);
}
tableFieldsLoading.value = false;
tableFieldsDataInfo.value.loading = false;
};
const tableFieldsDataInfo = ref({
......@@ -964,6 +1019,9 @@ const handleSubjectTableCommand = (command: string) => {
type: 'tableCreateFile',
foundMode: 2,
execGuid: execGuidInfo.value.execGuid,
database: dataBaseInfo.value.database,
databaseChName: dataBaseInfo.value.databaseChName,
databaseGuid: dataBaseInfo.value.databaseGuid,
}
});
} else if (command === 'existingCreate') {
......@@ -988,8 +1046,12 @@ const addIsShowClassifyTip = () => {
isShowClassifyTip.value = false;
}
const tipHeight = ref(200);
const tipHeight1 = ref(220);
const addIsShowDatabaseTip = () => {
isShowDatabaseTip.value = false;
tipHeight.value = 148;
tipHeight1.value = 168;
}
// 表信息和字段信息切换
......@@ -1075,7 +1137,7 @@ const getDbDirTableSelectData = async (type, params = {}) => {
const finalParams = { ...inParams, ...params };
const res: any = await getDbDirTableSelectList(finalParams);
if (res.code == proxy.$passCode) {
console.log('getDbDirTableSelectData', res);
if (type == 1) {
optionsA.value = res.data.map((item) => ({
dbGuid: item.database, // 数据库标识
......@@ -1083,15 +1145,16 @@ const getDbDirTableSelectData = async (type, params = {}) => {
}));
}
if (type == 2) {
console.log('进来了吗', res);
optionsB.value = res.data.map((item) => ({
dbGuid: item.tableName, // 表标识
name: item.tableName, // 表名称
dbGuid: item.database, // 表标识
name: item.database, // 表名称
}));
}
if (type == 3) {
optionsC.value = res.data.map((item) => ({
dbGuid: item.fieldName, // 字段标识
name: item.fieldName, // 字段名称
dbGuid: item.database, // 字段标识
name: item.database, // 字段名称
}));
}
......@@ -1142,7 +1205,9 @@ const onBChange = async () => {
// 导出
const btnClick = async () => {
exportCgDir().then((res: any) => {
exportCgDir({
execGuid: execGuidInfo.value.execGuid,
}).then((res: any) => {
download(res, '分类分级目录数据.xlsx', 'excel')
});
......@@ -1161,6 +1226,26 @@ const treeSelectNodeChange = (node, item) => {
const { refGradeGuid } = node;
getGradeData(refGradeGuid);
}
// 这里应该是onActivated 钩子,路由从configure-路由从configure-rules跳转过来要重新请求数据、
onActivated(async () => {
if (route.query.reload === 'true') {
console.log('重新请求数据');
await getExecGuid();
activeName.value = 'second';
getDataBaseTreeData();
getDataBaseTableData({
exexGuid: execGuidInfo.value.execGuid
});
getDataBaseFieldData(
{
exexGuid: execGuidInfo.value.execGuid
}
);
getDbDirTableSelectData(1, {});
}
});
</script>
<template>
......@@ -1295,11 +1380,14 @@ const treeSelectNodeChange = (node, item) => {
<el-checkbox v-model="checked" label="仅看规划数据资产表" size="large" @change="changeCheck" />
</div>
</div>
<div class="table_panel_wrap_database" v-if="!tableGuid && activeTab === 'table'">
<Table :tableInfo="dataBaseTableInfo" @tablePageChange="dataBaseTablePageChange" />
<div class="table_panel_wrap_database" v-if="!tableGuid && activeTab === 'table'"
:style="{ height: `calc(100% - ${tipHeight1}px)`, minHeight: '210px' }">
<Table :tableInfo="dataBaseTableInfo" @tablePageChange="dataBaseTablePageChange"
@tableSwitchBeforeChange="tableSwitchBeforeChange" />
</div>
<div class="table_field" v-if="tableGuid || activeTab === 'word'">
<Table :tableInfo="tableFieldsDataInfo" :loading="tableFieldsLoading" />
<div class="table_field" v-if="tableGuid || activeTab === 'word'"
:style="{ height: `calc(100% - ${tipHeight}px)`, minHeight: '210px' }">
<Table :tableInfo="tableFieldsDataInfo" />
</div>
</div>
<Drawer :drawerInfo="drawerInfo" @drawerBtnClick="drawerBtnClick" class="v-drawer" />
......@@ -1442,14 +1530,12 @@ const treeSelectNodeChange = (node, item) => {
.table_panel_wrap_database {
width: 100%;
height: calc(100% - 155px);
min-height: 210px;
overflow: visible;
}
.table_field {
width: 100%;
height: calc(100% - 150px);
min-height: 210px;
overflow: visible;
}
......
......@@ -13,6 +13,7 @@ const fullPath = route.fullPath;
const userStore = useUserStore();
const bizRuleConfigData = ref<any>()
const getBizRuleConfigDetailData = async () => {
tableFieldsLoading.value = true
const params = {
tableGuid: router.currentRoute.value.query.tableGuid,
execGuid: router.currentRoute.value.query.execGuid
......@@ -25,6 +26,7 @@ const getBizRuleConfigDetailData = async () => {
item.isEdit = false
})
tableData.value = bizRuleConfigData.value
tableFieldsLoading.value = false
} else {
proxy.$message.error(res.msg)
}
......
......@@ -798,7 +798,7 @@ const positionOptions = [
];
// 语言options
const languageOptions = [
{ label: '中文名', value: 'zhName' },
{ label: '中文名', value: 'chName' },
{ label: '英文名', value: 'enName' },
];
// 当前悬停的行索引
......
......@@ -18,16 +18,18 @@ import {
getTaskExeTreeList,
getGradeList,
getNewDataTypeList,
getDbDirDetail,
} from "@/api/modules/dataInventory";
import existingTableSelect from "./existingTableSelect.vue";
import { ro } from "element-plus/es/locale";
import useUserStore from "@/store/modules/user";
/** 草稿中未建表时就可以编辑表相关信息。如果建表之后就只能编辑字段。 不能修改字段英文名称,数据库修改英文名就相当于删除再添加。都可以直接跳转到*/
const { proxy } = getCurrentInstance() as any;
const router = useRouter();
const route = useRoute();
const isDimTable = route.query.isDim;
const fullPath = route.fullPath;
const userStore = useUserStore();
const execGuid: any = ref(route.query.execGuid);
// 获取数据库列表
......@@ -160,8 +162,34 @@ const saveRow = (row) => {
}
const editInfoData = ref<any>({
guid: ''
});
onMounted(async () => {
if (route.query.editOpt && route.query.editOpt === '1') {
tableFieldsLoading.value = true;
stepsInfo.value.step = 1;
getDbDirDetail({
tableGuid: route.query.tableGuid
}).then((res: any) => {
if (res.code == proxy.$passCode) {
editInfoData.value = res.data;
tableDataInfo.value = [{
tableName: editInfoData.value.tableName,
tableChName: editInfoData.value.tableChName,
description: editInfoData.value.description,
}];
console.log('tableDataInfo', res.data.fieldRSVOS)
tableDataDetailInfo.value = res.data.fieldRSVOS;
tableFieldsLoading.value = false;
} else {
proxy.$ElMessage.error(res.msg);
}
})
getFieldTree();
} else {
await getDbDirDataSourceListData();
}
await getFieldTypeData();
});
......@@ -345,6 +373,7 @@ const batchDelete = () => {
// 新增一行
const addRow = () => {
console.log('新增一行')
refGradeGuid.value = '';
tableDataDetailInfo.value.push({
id: tableDataDetailInfo.value.length + 1,
......@@ -435,53 +464,153 @@ const data = [
},
]
const submitAsDraft = () => {
// 保存为草稿,无论有没有guid 都传入guid
saveOrUpdate({ isDraft: 'Y' }, 0)
const saveBtnDraft = ref(false)
const submitAsDraft = async () => {
// 保存为草稿,
if (!tableDataInfo.value[0].tableName) {
proxy.$ElMessage.error('请填写数据库名称');
return;
}
if (!tableDataInfo.value[0].tableChName) {
proxy.$ElMessage.error('请填写数据库表');
return;
}
saveBtnDraft.value = true
if (!editInfoData.value.guid) {
try {
await saveOrUpdate({
tableName: tableDataInfo.value[0].tableName,
tableChName: tableDataInfo.value[0].tableChName,
databaseGuid: route.query.databaseGuid || '',
database: route.query.database || '',
databaseChName: route.query.databaseChName || '',
foundMode: route.query.foundMode,
isDraft: 'Y',
}, 0)
saveBtnDraft.value = false
} catch (error) {
saveBtnDraft.value = false
}
} else {
try {
await saveOrUpdate({
guid: editInfoData.value.guid,
tableName: tableDataInfo.value[0].tableName,
tableChName: tableDataInfo.value[0].tableChName,
databaseGuid: editInfoData.value.databaseGuid || '',
database: editInfoData.value.database || '',
databaseChName: editInfoData.value.databaseChName || '',
foundMode: editInfoData.value.foundMode,
isDraft: 'Y',
tableGuid: route.query.tableGuid,
}, 1)
saveBtnDraft.value = false
} catch (error) {
saveBtnDraft.value = false
}
}
}
/**
* 需求写一个校验函数,校验表格数据是否填写完整
* 1、表名称、数据库表、为空
* 2、tableDataDetailInfo.value 每一项中的字段名称、字段英文名、字段类型、长度、精度、是否唯一、是否必填、字段取值范围、关联字典、不能为空
*/
// const checkTableData = (tableDataInfo, tableDataDetailInfo) => {
// const tableDataInfoKeys = ['tableName', 'tableChName']
// const tableDataDetailInfoKeys = ['fieldName', 'fieldEnglish', 'fieldType', 'length', 'fieldPrecision', 'isUnique', 'isRequired', 'fieldValueRange', 'dictionaryGuid']
// let flag = true
// tableDataInfo.forEach(item => {
// tableDataInfoKeys.forEach(key => {
// if (!item[key]) {
// flag = false
// proxy.$ElMessage.error('表名称、数据库表不能为空')
// }
// })
// })
// tableDataDetailInfo.forEach(item => {
// tableDataDetailInfoKeys.forEach(key => {
// if (!item[key]) {
// flag = false
// proxy.$ElMessage.error('字段名称、字段英文名、字段类型、长度、精度、是否唯一、是否必填、字段取值范围、关联字典不能为空')
// }
// })
// })
// return flag
// }
const guid = ref('')
const checkTableData = (tableDataDetailInfo) => {
let hasPrimary = false; // 是否有主键字段
const enNames: any[] = []; // 用于校验英文名称重复
const chNames: any[] = []; // 用于校验中文名称重复
const regex = /^[a-zA-Z]/; // 校验英文名称必须以字母开头
let index = 1; // 记录字段序号
console.log('tableDataInfo', tableDataDetailInfo)
if (!tableDataInfo.value[0].tableName) {
proxy.$ElMessage.error('请填写数据库名称');
return;
}
if (!tableDataInfo.value[0].tableChName) {
proxy.$ElMessage.error('请填写数据库表');
return;
}
// 校验列表数组
for (const field of tableDataDetailInfo) {
// 校验字段英文名称不能为空
if (!field.fieldName) {
ElMessage.error(`第 ${index} 个字段的英文名称不能为空!`);
return false;
}
// 校验英文名称必须以字母开头
if (!regex.test(field.fieldName)) {
ElMessage.error(`第 ${index} 个字段的英文名称必须以英文字符开头!`);
return false;
}
// 校验英文名称不能重复
if (enNames.includes(field.fieldName)) {
ElMessage.error(`字段的英文名称 ${field.fieldName} 不能重复!`);
return false;
}
// 校验中文名称不能重复
if (chNames.includes(field.fieldChName)) {
ElMessage.error(`字段的中文名称 ${field.fieldChName} 不能重复!`);
return false;
}
// 校验字段类型和相应属性
if (field.fieldType === 'decimal') {
if (field.fieldPrecision == null) {
ElMessage.error(`第 ${index} 个字段的字段类型为浮点型时,精度不能为空!`);
return false;
}
if (field.fieldLength == null) {
ElMessage.error(`第 ${index} 个字段的字段类型为浮点型时,长度不能为空!`);
return false;
}
}
if ((field.fieldType === 'varchar' || field.fieldType === 'char') && field.fieldLength == null) {
ElMessage.error(`第 ${index} 个字段的字段类型为字符型时,长度不能为空!`);
return false;
}
// 校验主键字段
if (field.isPrimary === 'Y') {
hasPrimary = true;
if (field.isNotNull !== 'Y') {
ElMessage.error(`第 ${index} 个字段为主键,应设置为必填!`);
return false;
}
if (['text', 'json', 'bit'].includes(field.fieldType)) {
ElMessage.error(`第 ${index} 个字段为主键,字段类型不能设置为 ${field.fieldType} 类型!`);
return false;
}
}
// 更新英文和中文名称集合
enNames.push(field.fieldName);
chNames.push(field.fieldChName);
index++;
}
// 校验是否至少有一个主键字段
if (!hasPrimary) {
ElMessage.error(`字段至少有一个主键字段!`);
return false;
}
return true; // 校验通过
};
const saveBtn = ref(false)
const submit = async () => {
console.log('提交', tableDataDetailInfo.value, tableDataInfo.value)
saveBtn.value = true
// 校验表格数据是否填写完整
// if (!checkTableData(tableDataDetailInfo.value, tableDataInfo.value)) {
// return
// }
if (!checkTableData(tableDataDetailInfo.value)) {
saveBtn.value = false
return
}
// 如果提交时没有 guid 则为新增type 0,否则为修改 type 1, 也要传参
if (!guid.value) {
if (!editInfoData.value.guid) {
try {
await saveOrUpdate({
tableName: tableDataInfo.value[0].tableName,
......@@ -500,14 +629,15 @@ const submit = async () => {
// 修改 saveOrUpdate({}, 1)
try {
await saveOrUpdate({
guid: guid.value,
guid: editInfoData.value.guid,
tableName: tableDataInfo.value[0].tableName,
tableChName: tableDataInfo.value[0].tableChName,
databaseGuid: route.query.databaseGuid || '',
database: route.query.database || '',
databaseChName: route.query.databaseChName || '',
foundMode: route.query.foundMode,
databaseGuid: editInfoData.value.databaseGuid || '',
database: editInfoData.value.database || '',
databaseChName: editInfoData.value.databaseChName || '',
foundMode: editInfoData.value.foundMode,
isDraft: 'N',
tableGuid: route.query.tableGuid,
}, 1)
saveBtn.value = false
} catch (error) {
......@@ -519,6 +649,34 @@ const submit = async () => {
// 单独将保存和修改函数提取出来 type 0 保存 1 修改 2 生成建表语句
const saveOrUpdate = async (params: any = {}, type) => {
// 要对tableDataDetailInfo.value 进行处理,将其转换为后台需要的格式
let TepmTableDataDetailInfo = tableDataDetailInfo.value.map(item => {
return {
classifyDetailGuid: item.classifyDetailGuid,
classifyDetailName: item.classifyDetailName,
database: item.database || editInfoData.value.database,
databaseChName: item.databaseChName || editInfoData.value.databaseChName,
databaseGuid: item.databaseGuid || editInfoData.value.databaseGuid,
dictionaryGuid: item.dictionaryGuid,
dimGuid: item.dimGuid,
fieldChName: item.fieldChName,
fieldGuid: item.fieldGuid,
fieldLength: item.fieldLength,
fieldName: item.fieldName,
fieldPrecision: item.fieldPrecision,
fieldType: item.fieldType,
gradeDetailGuid: item.gradeDetailGuid,
gradeDetailName: item.gradeDetailName,
guid: item.guid,
isFk: item.isFk,
isNotNull: item.isNotNull,
isPrimary: item.isPrimary,
sortValue: item.sortValue,
tableChName: tableDataInfo.value[0].tableChName,
tableGuid: route.query.tableGuid || '',
tableName: tableDataInfo.value[0].tableName,
}
})
const InParams = {
guid: '',
cgDirName: '',
......@@ -531,21 +689,27 @@ const saveOrUpdate = async (params: any = {}, type) => {
databaseChName: '',
foundMode: 0,
isDraft: '',
fieldRQVOList: tableDataDetailInfo.value
fieldRQVOList: TepmTableDataDetailInfo
}
const finalParams = { ...InParams, ...params }
// 使用switch case 语句
switch (type) {
case 0:
// 保存/保存为草稿
saveBtn.value = true
const res: any = await saveDbDirTable(finalParams);
if (res.code === proxy.$passCode) {
if (params.isDraft === 'Y') {
proxy.$ElMessage.success('保存为草稿成功!');
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({ name: 'classifyGradeCatalogue', query: { reload: 'true' } });
return
}
proxy.$ElMessage.success('保存成功!');
router.push({ name: 'classifyGradeCatalogue' });
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({ name: 'classifyGradeCatalogue', query: { reload: 'true' } });
} else {
saveBtn.value = false
proxy.$ElMessage.error(res.msg);
}
break;
......@@ -553,9 +717,11 @@ const saveOrUpdate = async (params: any = {}, type) => {
// 修改
const res1: any = await updateDbDirTable(finalParams);
if (res1.code === proxy.$passCode) {
proxy.$ElMessage.success('修改成功!');
router.push({ name: 'classifyGradeCatalogue' });
proxy.$ElMessage.success('编辑成功!');
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({ name: 'classifyGradeCatalogue', query: { reload: 'true' } });
} else {
saveBtn.value = false
proxy.$ElMessage.error(res1.msg);
}
break;
......@@ -672,9 +838,14 @@ const inputLengthKeyUp = (regexp, scope, field, max: any = null, min: any = null
<template>
<div class="container_wrap full" v-loading.fullscreen.lock="fullscreenLoading">
<div class="content_main">
<div class="top_tool_wrap">
<div class="top_tool_wrap" v-if="!(route.query.editOpt && route.query.editOpt === '1')">
<StepBar :steps-info="stepsInfo" />
</div>
<div class="edit-btn-wrap" v-show="(route.query.editOpt && route.query.editOpt === '1')">
<el-button type="primary" @click="submitAsDraft" :loading="saveBtnDraft">保存为草稿</el-button>
<el-button type="primary" @click="submit" :loading="saveBtn">保存</el-button>
</div>
<existingTableSelect v-show="stepsInfo.step === 0" :databaseList="databaseList" :table-create-type="2"
:execGuid="execGuid" @datasource-selected-change="handlDsSelectedChange"></existingTableSelect>
<div class="second-step-content" v-show="stepsInfo.step === 1">
......@@ -754,31 +925,31 @@ const inputLengthKeyUp = (regexp, scope, field, max: any = null, min: any = null
</template>
</el-table-column>
<!-- 源数据库 -->
<el-table-column prop="sourceDatabase" label="源数据库" width="150">
<el-table-column prop="databaseChName" label="源数据库" width="150">
<template #default="scope">
{{ scope.row.sourceDatabase ? scope.row.sourceDatabase : '--' }}
{{ scope.row.databaseChName ? scope.row.databaseChName : '--' }}
</template>
</el-table-column>
<!-- 源数据表 -->
<el-table-column prop="sourceTableName" label="源数据表" width="150">
<el-table-column prop="tableName" label="源数据表" width="150">
<template #default="scope">
{{ scope.row.sourceTableName ? scope.row.sourceTableName : '--' }}
{{ scope.row.tableName ? scope.row.tableName : '--' }}
</template>
</el-table-column>
<!-- 源字段中文 -->
<el-table-column prop="sourceFieldChName" label="源字段中文" width="150">
<el-table-column prop="fieldChName" label="源字段中文" width="150">
<template #default="scope">
{{ scope.row.sourceFieldChName ? scope.row.sourceFieldChName : '--' }}
{{ scope.row.fieldChName ? scope.row.fieldChName : '--' }}
</template>
</el-table-column>
<!-- 源字段英文 -->
<el-table-column prop="sourceFieldName" label="源字段英文" width="150">
<el-table-column prop="fieldName" label="源字段英文" width="150">
<template #default="scope">
<!-- {{ scope.row.sourceFieldName ? scope.row.sourceFieldName : '--' }} -->
<span v-if="!scope.row.isEdit || !editableFields.sourceFieldName">{{ scope.row.sourceFieldName ?
scope.row.sourceFieldName : '--' }}</span>
<el-input v-else v-model="scope.row.sourceFieldName" placeholder="请输入长度" />
<span v-if="!scope.row.isEdit || !editableFields.fieldName">{{ scope.row.fieldName ?
scope.row.fieldName : '--' }}</span>
<el-input v-else v-model="scope.row.fieldName" placeholder="请输入长度" />
</template>
</el-table-column>
<!-- 源端字段 fieldType fieldTypeProps-->
......@@ -792,7 +963,7 @@ const inputLengthKeyUp = (regexp, scope, field, max: any = null, min: any = null
</el-select>
</div>
<div v-else>
{{ fieldData.find(item => item.value === scope.row.fieldType)?.label || '--' }}
{{ fieldData ? fieldData.find(item => item.value === scope.row.fieldType)?.label : '--' }}
</div>
</template>
</el-table-column>
......@@ -897,17 +1068,6 @@ const inputLengthKeyUp = (regexp, scope, field, max: any = null, min: any = null
<!-- 操作列 -->
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="scope">
<!-- <el-button v-if="!scope.row.isEdit" type="primary" size="small" @click="editRow(scope.row)">
编辑
</el-button> -->
<!-- <el-button v-else type="success" size="small" @click="saveRow(scope.row)">
保存
</el-button>
<el-button type="danger" size="small" @click="deleteRow(scope.$index)">
删除
</el-button> -->
<span class="text_btn" v-if="!scope.row.isEdit" @click="editRow(scope.row)">编辑</span>
<span class="text_btn" v-else @click="saveRow(scope.row)">保存</span>
<el-divider direction="vertical" />
......@@ -918,14 +1078,14 @@ const inputLengthKeyUp = (regexp, scope, field, max: any = null, min: any = null
</div>
</div>
</div>
<div class="bottom_tool_wrap">
<div class="bottom_tool_wrap" v-show="!(route.query.editOpt && route.query.editOpt === '1')">
<template v-if="stepsInfo.step == 0">
<el-button type="primary" @click="nextStep">下一步</el-button>
</template>
<template v-else>
<el-button @click="previousStep">上一步</el-button>
<el-button type="primary" @click="submitAsDraft">保存为草稿</el-button>
<el-button type="primary" @click="submit" v-loading="saveBtn">提交</el-button>
<el-button type="primary" @click="submitAsDraft" :loading="saveBtnDraft">保存为草稿</el-button>
<el-button type="primary" @click="submit" :loading="saveBtn">提交</el-button>
</template>
</div>
<Dialog_form :dialogConfigInfo="newCreateSqlDialogInfo" />
......@@ -949,6 +1109,11 @@ const inputLengthKeyUp = (regexp, scope, field, max: any = null, min: any = null
.content_main {
height: calc(100% - 40px);
.edit-btn-wrap {
display: flex;
padding: 16px 16px 0 16px;
}
.second-step-content {
height: calc(100% - 80px);
width: 100%;
......
......@@ -33,9 +33,10 @@ import {
getSubjectTableDetail,
checkSubjectTableData
} from "@/api/modules/dataCatalogService";
import { getFidldEnName, getGradeList, getNewDataTypeList, getTaskExeTreeList } from "@/api/modules/dataInventory";
import { getFidldEnName, getGradeList, getNewDataTypeList, getTaskExeTreeList, saveDbDirTable } from "@/api/modules/dataInventory";
import { useDefault } from "@/hooks/useDefault";
import uploadExcelFile from "./components/uploadExcelFile.vue";
import { add } from "lodash-es";
const userStore = useUserStore();
const dataCatalogStore = useDataCatalogStore();
......@@ -63,6 +64,7 @@ const tableCreateInfo: Ref<any> = ref({
{
//数据库表信息。
dataSourceGuid: '',
databaseChName: route.query.databaseChName,
dataServerName: "",
dataServerChName: "",
enName: "",
......@@ -161,10 +163,10 @@ const handleClassifyChange = (row, value) => {
}
});
console.log("选中的节点信息:", selectedNode);
row.classifyName = selectedNode.classifyName; // 假设树节点的 `label` 是分类名
row.classifyDetailName = selectedNode.classifyName; // 假设树节点的 `label` 是分类名
} else {
console.error("未找到对应的节点");
row.classifyName = ""; // 重置分类名
row.classifyDetailName = ""; // 重置分类名
}
};
const getTreeNode = (tree, value) => {
......@@ -211,16 +213,16 @@ const nextStep = () => {
tableCreateInfo.value.isSync = 'Y';
}
stepsInfo.value.step = 1;
getDictionaryList();
getDimListData();
// getDictionaryList();
// getDimListData();
if (!fieldTypes.value.length) {
getFieldTypeList();
getCharacterListData();
// getCharacterListData();
}
if (!databaseList.value.length) {
getDatabaseList();
}
getDomainDetail(subjectDomainGuid.value);
// getDomainDetail(subjectDomainGuid.value);
if (!tableCreateInfo.value.tableFields.length) {
getSubjectField();
}
......@@ -428,7 +430,7 @@ onActivated(() => {
document.title = tab.meta.title;
}
}
getDomainDetail(subjectDomainGuid.value);
// getDomainDetail(subjectDomainGuid.value);
}
});
......@@ -461,19 +463,19 @@ watch(() => tableStandardDetail.value, (val) => {
});
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 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) {
......@@ -1193,7 +1195,7 @@ const inputLengthKeyUp = (regexp, scope, field, max: any = null, min: any = null
}
/** 保存表 */
const saveTable = () => {
const saveTable = async () => {
let tableData = tableCreateInfo.value.tableData[0];
if (!tableData.chName) {
ElMessage({
......@@ -1359,42 +1361,95 @@ const saveTable = () => {
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);
console.log(addInfo, '--------------------------------------');
let TepmTableDataDetailInfo = addInfo.subjectFieldAddDTOS.map(item => {
return {
classifyDetailGuid: item.classifyDetailGuid,
classifyDetailName: item.classifyDetailName,
database: route.query.database,
databaseChName: route.query.databaseChName,
databaseGuid: route.query.databaseGuid,
dictionaryGuid: item.dictionaryGuid,
dimGuid: item.dimGuid,
fieldChName: item.fieldChName,
fieldGuid: item.fieldGuid,
fieldLength: item.fieldLength,
fieldName: item.fieldName,
fieldPrecision: item.fieldPrecision,
fieldType: item.dataType,
gradeDetailGuid: item.gradeDetailGuid,
gradeDetailName: item.gradeDetailName,
guid: item.guid,
isFk: item.isFk,
isNotNull: item.isNotNull,
isPrimary: item.isPrimary,
sortValue: item.sortValue,
tableChName: addInfo.chName,
tableGuid: route.query.tableGuid || '',
tableName: addInfo.enName,
}
});
} 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));
})
const InParams = {
guid: '',
cgDirName: '',
dirGuid: '',
tableGuid: route.query.tableGuid || '',
tableName: addInfo.enName,
tableChName: addInfo.chName,
databaseGuid: route.query.databaseGuid || '',
database: route.query.database || '',
databaseChName: addInfo.databaseChName,
foundMode: 2,
isDraft: 'N',
fieldRQVOList: TepmTableDataDetailInfo
}
console.log(InParams, '--------------------------------------');
const res: any = await saveDbDirTable(InParams);
if (res.code === proxy.$passCode) {
proxy.$ElMessage.success('保存成功!');
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({ name: 'classifyGradeCatalogue', query: { reload: 'true' } });
} else {
ElMessage.error(res.msg);
}
});
proxy.$ElMessage.error(res.msg);
}
// 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 = () => {
const saveDraftTable = async () => {
let tableData = tableCreateInfo.value.tableData[0];
if (!tableData.chName) {
ElMessage({
......@@ -1430,39 +1485,90 @@ const saveDraftTable = () => {
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);
let TepmTableDataDetailInfo = addInfo.subjectFieldAddDTOS.map(item => {
return {
classifyDetailGuid: item.classifyDetailGuid,
classifyDetailName: item.classifyDetailName,
database: route.query.database,
databaseChName: route.query.databaseChName,
databaseGuid: route.query.databaseGuid,
dictionaryGuid: item.dictionaryGuid,
dimGuid: item.dimGuid,
fieldChName: item.fieldChName,
fieldGuid: item.fieldGuid,
fieldLength: item.fieldLength,
fieldName: item.fieldName,
fieldPrecision: item.fieldPrecision,
fieldType: item.dataType,
gradeDetailGuid: item.gradeDetailGuid,
gradeDetailName: item.gradeDetailName,
guid: item.guid,
isFk: item.isFk,
isNotNull: item.isNotNull,
isPrimary: item.isPrimary,
sortValue: item.sortValue,
tableChName: addInfo.chName,
tableGuid: route.query.tableGuid || '',
tableName: addInfo.enName,
}
})
const InParams = {
guid: '',
cgDirName: '',
dirGuid: '',
tableGuid: route.query.tableGuid || '',
tableName: addInfo.enName,
tableChName: addInfo.chName,
databaseGuid: route.query.databaseGuid || '',
database: route.query.database || '',
databaseChName: addInfo.databaseChName,
foundMode: 2,
isDraft: 'Y',
fieldRQVOList: TepmTableDataDetailInfo
}
console.log(InParams, '--------------------------------------');
const res: any = await saveDbDirTable(InParams);
if (res.code === proxy.$passCode) {
proxy.$ElMessage.success('保存草稿成功!');
userStore.setTabbar(userStore.tabbar.filter((tab: any) => tab.fullPath !== fullPath));
router.push({ name: 'classifyGradeCatalogue', query: { reload: 'true' } });
} 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);
}
});
}
proxy.$ElMessage.error(res.msg);
}
// 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) => {
......@@ -1541,17 +1647,18 @@ const tableSelectFields = computed(() => {
height: 'auto',
display: 'inline-block',
}">
<el-table-column prop="dataSourceGuid" label="数据源" width="200px" align="left" show-overflow-tooltip>
<el-table-column prop="databaseChName" 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"
<!-- <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>
</el-select> -->
<el-input v-model.trim="scope.row['databaseChName']" :disabled="true" />
</template>
</el-table-column>
<el-table-column prop="enName" label="数据库表" width="200px" align="left" show-overflow-tooltip>
......@@ -1654,12 +1761,12 @@ const tableSelectFields = computed(() => {
<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>
<!-- <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-column> -->
</el-table>
<div class="tools_btns">
<el-button v-if="fieldStandardSetGuids?.length" type="primary" @click="batchAddFields"
......@@ -1734,7 +1841,7 @@ const tableSelectFields = computed(() => {
<el-option v-for="opt in fieldTypes" :key="opt['value']" :label="opt['label']"
:value="opt['value']" />
</el-select>
<span v-else>{{ fieldTypes.find(f => f.paramValue === scope.row["dataType"])?.paramName || "--"
<span v-else>{{ fieldTypes.find(f => f.value === scope.row["dataType"])?.label || "--"
}}</span>
</template>
</el-table-column>
......@@ -1816,7 +1923,7 @@ const tableSelectFields = computed(() => {
</el-tree-select>
</div>
<!-- 显示treeSelectOptions classifyDetailGuid所在itemclassifyName-->
<div v-else>{{ scope.row.classifyName || '--' }}</div>
<div v-else>{{ scope.row.classifyDetailName || '--' }}</div>
</template>
</el-table-column>
......@@ -1862,8 +1969,8 @@ const tableSelectFields = computed(() => {
<el-button type="primary" @click="nextStep">下一步</el-button>
</template>
<template v-else>
<el-checkbox v-model="tableCreateInfo.isSync" true-label="Y" :disabled="!fileTableData?.length"
false-label="N">同步数据(说明:勾选代表建表同时写入表格数据。)</el-checkbox>
<!-- <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" @click="saveDraftTable">保存为草稿</el-button>
<el-button type="primary" @click="saveTable">提交</el-button>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!