Merge branch 'dev' of github.com:jetlinks/jetlinks-ui-vue into dev
This commit is contained in:
commit
f55bf06297
|
@ -34,8 +34,8 @@
|
||||||
)
|
)
|
||||||
: record.type === 'boolean'
|
: record.type === 'boolean'
|
||||||
? [
|
? [
|
||||||
{ label: '是', value: true },
|
{ label: record?.dataType?.trueText, value: record?.dataType?.trueValue },
|
||||||
{ label: '否', value: false },
|
{ label: record?.dataType?.falseText, value: record?.dataType?.falseValue },
|
||||||
]
|
]
|
||||||
: undefined
|
: undefined
|
||||||
"
|
"
|
||||||
|
|
|
@ -1,126 +1,173 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mangement-container">
|
<page-container>
|
||||||
<div class="left">
|
<div class="manager-container">
|
||||||
<j-input-search
|
<div class="left">
|
||||||
v-model:value="leftData.searchValue"
|
<j-input-search
|
||||||
placeholder="请输入"
|
v-model:value="leftData.searchValue"
|
||||||
style="margin-bottom: 24px"
|
placeholder="请输入"
|
||||||
/>
|
style="margin-bottom: 24px"
|
||||||
<!-- 使用v-if用于解决异步加载数据后不展开的问题 -->
|
/>
|
||||||
<j-tree
|
<!-- 使用v-if用于解决异步加载数据后不展开的问题 -->
|
||||||
v-if="leftData.treeData.length > 0"
|
<j-tree
|
||||||
showLine
|
v-if="leftData.treeData.length > 0"
|
||||||
defaultExpandAll
|
showLine
|
||||||
:tree-data="leftData.treeData"
|
defaultExpandAll
|
||||||
v-model:selectedKeys="leftData.selectedKeys"
|
:tree-data="leftData.treeData"
|
||||||
@select="leftData.onSelect"
|
v-model:selectedKeys="leftData.selectedKeys"
|
||||||
>
|
@select="onSelect"
|
||||||
<template #title="{ dataRef }">
|
>
|
||||||
<div
|
<template #title="{ dataRef }">
|
||||||
v-if="dataRef.root"
|
<div
|
||||||
:style="`
|
v-if="dataRef.root"
|
||||||
justify-content: space-between;
|
style="
|
||||||
display: flex;
|
justify-content: space-between;
|
||||||
align-items: center;
|
display: flex;
|
||||||
`"
|
align-items: center;
|
||||||
>
|
width: 200px;
|
||||||
<span>
|
"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
{{ dataRef.title }}
|
||||||
|
</span>
|
||||||
|
<AIcon
|
||||||
|
type="PlusOutlined"
|
||||||
|
style="color: #1d39c4"
|
||||||
|
@click="addTable"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span v-else>
|
||||||
{{ dataRef.title }}
|
{{ dataRef.title }}
|
||||||
</span>
|
</span>
|
||||||
<AIcon
|
</template>
|
||||||
type="PlusOutlined"
|
</j-tree>
|
||||||
style="color: #1d39c4"
|
|
||||||
@click="leftData.addTable"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<span v-else>
|
|
||||||
{{ dataRef.title }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</j-tree>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<div class="btns">
|
|
||||||
<j-button type="primary" @click="table.clickSave"
|
|
||||||
>保存</j-button
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<j-pro-table
|
<div class="right">
|
||||||
ref="tableRef"
|
<div class="btns">
|
||||||
:columns="table.columns"
|
<j-button type="primary" @click="clickSave">保存</j-button>
|
||||||
model="TABLE"
|
</div>
|
||||||
:dataSource="table.data"
|
<j-form ref="formRef" :model="table">
|
||||||
>
|
<j-table
|
||||||
<template #name="slotProps">
|
:columns="columns"
|
||||||
<j-input
|
:dataSource="table.data"
|
||||||
:disabled="slotProps.scale !== undefined"
|
:pagination="false"
|
||||||
v-model:value="slotProps.name"
|
:scroll="{ y: 500 }"
|
||||||
placeholder="请输入名称"
|
|
||||||
:maxlength="64"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #type="slotProps">
|
|
||||||
<j-input
|
|
||||||
v-model:value="slotProps.type"
|
|
||||||
placeholder="请输入类型"
|
|
||||||
:maxlength="64"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #length="slotProps">
|
|
||||||
<j-input-number
|
|
||||||
v-model:value="slotProps.length"
|
|
||||||
:min="0"
|
|
||||||
:max="99999"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #precision="slotProps">
|
|
||||||
<j-input-number
|
|
||||||
v-model:value="slotProps.precision"
|
|
||||||
:min="0"
|
|
||||||
:max="99999"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template #notnull="slotProps">
|
|
||||||
<j-radio-group
|
|
||||||
v-model:value="slotProps.notnull"
|
|
||||||
button-style="solid"
|
|
||||||
>
|
>
|
||||||
<j-radio-button :value="true">是</j-radio-button>
|
<template #bodyCell="{ column, record, index }">
|
||||||
<j-radio-button :value="false">否</j-radio-button>
|
<template v-if="column.key === 'name'">
|
||||||
</j-radio-group>
|
<j-form-item
|
||||||
</template>
|
:name="['data', index, 'name']"
|
||||||
<template #comment="slotProps">
|
:rules="[
|
||||||
<j-input
|
{
|
||||||
v-model:value="slotProps.comment"
|
max: 64,
|
||||||
placeholder="请输入说明"
|
message: '最多可输入64个字符',
|
||||||
/>
|
},
|
||||||
</template>
|
{
|
||||||
<template #action="slotProps">
|
required: true,
|
||||||
<PermissionButton
|
message: '请输入名称',
|
||||||
:hasPermission="`{permission}:delete`"
|
},
|
||||||
type="link"
|
]"
|
||||||
:tooltip="{ title: '删除' }"
|
>
|
||||||
:popConfirm="{
|
<j-input
|
||||||
title: `确认删除`,
|
:disabled="record.scale !== undefined"
|
||||||
onConfirm: () => table.clickDel(slotProps),
|
v-model:value="record.name"
|
||||||
}"
|
placeholder="请输入名称"
|
||||||
:disabled="slotProps.status"
|
/>
|
||||||
>
|
</j-form-item>
|
||||||
<AIcon type="DeleteOutlined" />
|
</template>
|
||||||
</PermissionButton>
|
<template v-else-if="column.key === 'type'">
|
||||||
</template>
|
<j-form-item
|
||||||
</j-pro-table>
|
:name="['data', index, 'type']"
|
||||||
<j-botton class="add-row" @click="table.addRow">
|
:rules="[
|
||||||
<AIcon type="PlusOutlined" /> 新增行
|
{
|
||||||
</j-botton>
|
max: 64,
|
||||||
|
message: '最多可输入64个字符',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入类型',
|
||||||
|
},
|
||||||
|
]"
|
||||||
|
>
|
||||||
|
<j-input
|
||||||
|
v-model:value="record.type"
|
||||||
|
placeholder="请输入类型"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'length'">
|
||||||
|
<j-form-item :name="['data', index, 'length']">
|
||||||
|
<j-input-number
|
||||||
|
v-model:value="record.length"
|
||||||
|
:min="0"
|
||||||
|
:max="99999"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'precision'">
|
||||||
|
<j-form-item
|
||||||
|
:name="['data', index, 'precision']"
|
||||||
|
>
|
||||||
|
<j-input-number
|
||||||
|
v-model:value="record.precision"
|
||||||
|
:min="0"
|
||||||
|
:max="99999"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'notnull'">
|
||||||
|
<j-form-item
|
||||||
|
:name="['data', index, 'notnull']"
|
||||||
|
>
|
||||||
|
<j-radio-group
|
||||||
|
v-model:value="record.notnull"
|
||||||
|
button-style="solid"
|
||||||
|
>
|
||||||
|
<j-radio-button :value="true"
|
||||||
|
>是</j-radio-button
|
||||||
|
>
|
||||||
|
<j-radio-button :value="false"
|
||||||
|
>否</j-radio-button
|
||||||
|
>
|
||||||
|
</j-radio-group>
|
||||||
|
</j-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'comment'">
|
||||||
|
<j-form-item
|
||||||
|
:name="['data', index, 'notnull']"
|
||||||
|
>
|
||||||
|
<j-input
|
||||||
|
v-model:value="record.comment"
|
||||||
|
placeholder="请输入说明"
|
||||||
|
/>
|
||||||
|
</j-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-else-if="column.key === 'action'">
|
||||||
|
<PermissionButton
|
||||||
|
hasPermission="system/DataSource:delete"
|
||||||
|
type="link"
|
||||||
|
:tooltip="{ title: '删除' }"
|
||||||
|
:danger="true"
|
||||||
|
:popConfirm="{
|
||||||
|
title: `确认删除`,
|
||||||
|
onConfirm: () => clickDel(record),
|
||||||
|
}"
|
||||||
|
:disabled="record.status"
|
||||||
|
>
|
||||||
|
<AIcon type="DeleteOutlined" />
|
||||||
|
</PermissionButton>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</j-table>
|
||||||
|
</j-form>
|
||||||
|
|
||||||
|
<j-button class="add-row" @click="addRow">
|
||||||
|
<AIcon type="PlusOutlined" /> 新增行
|
||||||
|
</j-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<j-modal v-model:visible="dialog.visible" title="新增" @ok="handleOk">
|
||||||
<div class="dialogs">
|
|
||||||
<j-modal
|
|
||||||
v-model:visible="dialog.visible"
|
|
||||||
title="新增"
|
|
||||||
@ok="dialog.handleOk"
|
|
||||||
>
|
|
||||||
<j-form :model="dialog.form" ref="addFormRef">
|
<j-form :model="dialog.form" ref="addFormRef">
|
||||||
<j-form-item
|
<j-form-item
|
||||||
label="名称"
|
label="名称"
|
||||||
|
@ -129,22 +176,22 @@
|
||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '请输入名称',
|
message: '请输入名称',
|
||||||
trigger: 'change',
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
max: 64,
|
max: 64,
|
||||||
message: '最多可输入64个字符',
|
message: '最多可输入64个字符',
|
||||||
trigger: 'change',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^[0-9].*$/,
|
// pattern: /^[0-9].*$/,
|
||||||
message: '不能以数字开头',
|
// message: '不能以数字开头',
|
||||||
trigger: 'change',
|
trigger: 'change',
|
||||||
|
validator: checkName,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
pattern: /^\w+$/,
|
pattern: /^\w+$/,
|
||||||
message: '名称只能由数字、字母、下划线、中划线组成',
|
message: '名称只能由数字、字母、下划线、中划线组成',
|
||||||
trigger: 'change',
|
trigger: 'blur',
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
|
@ -155,7 +202,7 @@
|
||||||
</j-form-item>
|
</j-form-item>
|
||||||
</j-form>
|
</j-form>
|
||||||
</j-modal>
|
</j-modal>
|
||||||
</div>
|
</page-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="Management">
|
<script setup lang="ts" name="Management">
|
||||||
|
@ -166,248 +213,290 @@ import {
|
||||||
saveTable_api,
|
saveTable_api,
|
||||||
delSaveRow_api,
|
delSaveRow_api,
|
||||||
} from '@/api/system/dataSource';
|
} from '@/api/system/dataSource';
|
||||||
|
import { onlyMessage } from '@/utils/comm';
|
||||||
import { FormInstance, message } from 'ant-design-vue';
|
import { FormInstance, message } from 'ant-design-vue';
|
||||||
import { DataNode } from 'ant-design-vue/lib/tree';
|
import { DataNode } from 'ant-design-vue/lib/tree';
|
||||||
|
import _ from 'lodash';
|
||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import type { dbColumnType, dictItemType, sourceItemType } from '../typing';
|
import type { dbColumnType, dictItemType, sourceItemType } from '../typing';
|
||||||
|
|
||||||
const id = useRoute().query.id as string;
|
const id = useRoute().query.id as string;
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: '列名',
|
||||||
|
dataIndex: 'name',
|
||||||
|
key: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '类型',
|
||||||
|
dataIndex: 'type',
|
||||||
|
key: 'type',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '长度',
|
||||||
|
dataIndex: 'length',
|
||||||
|
key: 'length',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '精度',
|
||||||
|
dataIndex: 'precision',
|
||||||
|
key: 'precision',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '不能为空',
|
||||||
|
dataIndex: 'notnull',
|
||||||
|
key: 'notnull',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '说明',
|
||||||
|
dataIndex: 'comment',
|
||||||
|
key: 'comment',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
dataIndex: 'action',
|
||||||
|
key: 'action',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
const formRef = ref();
|
||||||
|
|
||||||
|
const getInfo = (_id: string) => {
|
||||||
|
getDataSourceInfo_api(_id).then((resp: any) => {
|
||||||
|
info.data = resp.result;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const info = reactive({
|
const info = reactive({
|
||||||
data: {} as sourceItemType,
|
data: {} as sourceItemType,
|
||||||
init: () => {
|
|
||||||
id &&
|
|
||||||
getDataSourceInfo_api(id).then((resp: any) => {
|
|
||||||
info.data = resp.result;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const leftData = reactive({
|
const leftData = reactive({
|
||||||
searchValue: '',
|
searchValue: '',
|
||||||
sourceTree: [] as dictItemType[],
|
sourceTree: [] as dictItemType[],
|
||||||
treeData: [] as DataNode[],
|
treeData: [] as any[],
|
||||||
selectedKeys: [] as string[],
|
selectedKeys: [] as string[],
|
||||||
oldKey: '',
|
oldKey: '',
|
||||||
|
|
||||||
init: () => {
|
|
||||||
leftData.getTree();
|
|
||||||
watch(
|
|
||||||
[
|
|
||||||
() => leftData.searchValue,
|
|
||||||
() => leftData.sourceTree,
|
|
||||||
() => info.data,
|
|
||||||
],
|
|
||||||
(n) => {
|
|
||||||
if (leftData.sourceTree.length < 1 || !info.data.shareConfig)
|
|
||||||
return;
|
|
||||||
let filterArr = [];
|
|
||||||
if (leftData.searchValue) {
|
|
||||||
filterArr = leftData.sourceTree.filter((item) =>
|
|
||||||
item.name.includes(n[0]),
|
|
||||||
);
|
|
||||||
} else filterArr = leftData.sourceTree;
|
|
||||||
leftData.treeData = [
|
|
||||||
{
|
|
||||||
title: info.data.shareConfig.schema,
|
|
||||||
key: info.data.shareConfig.schema,
|
|
||||||
root: true,
|
|
||||||
children: filterArr.map((item) => ({
|
|
||||||
title: item.name,
|
|
||||||
key: item.name,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
leftData.selectedKeys = [filterArr[0].name];
|
|
||||||
leftData.onSelect([filterArr[0].name]);
|
|
||||||
},
|
|
||||||
{},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
getTree: () => {
|
|
||||||
rdbTree_api(id)
|
|
||||||
.then((resp: any) => {
|
|
||||||
leftData.sourceTree = resp.result;
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
},
|
|
||||||
onSelect: (selectedKeys: string[], e?: any) => {
|
|
||||||
if (e?.node?.root) {
|
|
||||||
leftData.selectedKeys = [leftData.oldKey];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
leftData.oldKey = selectedKeys[0];
|
|
||||||
const key = selectedKeys[0];
|
|
||||||
table.getTabelData(key);
|
|
||||||
},
|
|
||||||
addTable: (e: Event) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const table = reactive({
|
const queryTables = (key: string) => {
|
||||||
columns: [
|
if (key) {
|
||||||
{
|
|
||||||
title: '列名',
|
|
||||||
dataIndex: 'name',
|
|
||||||
key: 'name',
|
|
||||||
scopedSlots: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '类型',
|
|
||||||
dataIndex: 'type',
|
|
||||||
key: 'type',
|
|
||||||
scopedSlots: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '长度',
|
|
||||||
dataIndex: 'length',
|
|
||||||
key: 'length',
|
|
||||||
scopedSlots: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '精度',
|
|
||||||
dataIndex: 'precision',
|
|
||||||
key: 'precision',
|
|
||||||
scopedSlots: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '不能为空',
|
|
||||||
dataIndex: 'notnull',
|
|
||||||
key: 'notnull',
|
|
||||||
scopedSlots: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '说明',
|
|
||||||
dataIndex: 'comment',
|
|
||||||
key: 'comment',
|
|
||||||
scopedSlots: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '操作',
|
|
||||||
dataIndex: 'action',
|
|
||||||
key: 'action',
|
|
||||||
scopedSlots: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
data: [] as dbColumnType[],
|
|
||||||
|
|
||||||
getTabelData: (key: string) => {
|
|
||||||
rdbTables_api(id, key).then((resp: any) => {
|
rdbTables_api(id, key).then((resp: any) => {
|
||||||
table.data = resp.result.columns.map(
|
table.data = resp.result.columns.map(
|
||||||
(item: object, index: number) => ({ ...item, index }),
|
(item: object, index: number) => ({
|
||||||
|
...item,
|
||||||
|
index,
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
},
|
}
|
||||||
addRow: () => {
|
};
|
||||||
const initData: dbColumnType = {
|
|
||||||
precision: 0,
|
const handleSearch = (refresh?: boolean) => {
|
||||||
length: 0,
|
rdbTree_api(id)
|
||||||
notnull: false,
|
.then((resp: any) => {
|
||||||
type: '',
|
|
||||||
comment: '',
|
|
||||||
name: '',
|
|
||||||
};
|
|
||||||
table.data.push(initData);
|
|
||||||
},
|
|
||||||
clickSave: () => {
|
|
||||||
const columns = cloneDeep(table.data);
|
|
||||||
columns.forEach((item) => delete item.index);
|
|
||||||
const params = {
|
|
||||||
name: leftData.selectedKeys[0],
|
|
||||||
columns,
|
|
||||||
};
|
|
||||||
saveTable_api(id, params).then((resp) => {
|
|
||||||
if (resp.status === 200) {
|
if (resp.status === 200) {
|
||||||
message.success('操作成功');
|
leftData.sourceTree = resp.result;
|
||||||
table.getTabelData(params.name);
|
if (refresh) {
|
||||||
|
leftData.selectedKeys = [resp.result[0]?.name];
|
||||||
|
queryTables(resp.result[0]?.name);
|
||||||
|
} else {
|
||||||
|
queryTables(leftData.selectedKeys[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onSelect = (selectedKeys: string[], e?: any) => {
|
||||||
|
if (e?.node?.root) {
|
||||||
|
leftData.selectedKeys = [leftData.oldKey];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!selectedKeys[0]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
leftData.oldKey = selectedKeys[0];
|
||||||
|
const key = selectedKeys[0];
|
||||||
|
queryTables(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
const addTable = (e: Event) => {
|
||||||
|
e?.stopPropagation();
|
||||||
|
dialog.visible = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => id,
|
||||||
|
(newId) => {
|
||||||
|
if (newId) {
|
||||||
|
getInfo(newId);
|
||||||
|
handleSearch(true);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
clickDel: (row: any) => {
|
{
|
||||||
if (row.scale !== undefined) {
|
immediate: true,
|
||||||
delSaveRow_api(id, leftData.selectedKeys[0], [row.name]).then(
|
|
||||||
(resp: any) => {
|
|
||||||
if (resp.status === 200) table.data.splice(row.index, 1);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} else table.data.splice(row.index, 1);
|
|
||||||
},
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const table = reactive({
|
||||||
|
data: [] as dbColumnType[],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const addRow = () => {
|
||||||
|
const initData: dbColumnType = {
|
||||||
|
precision: 0,
|
||||||
|
length: 0,
|
||||||
|
notnull: false,
|
||||||
|
type: '',
|
||||||
|
comment: '',
|
||||||
|
name: '',
|
||||||
|
};
|
||||||
|
table.data.push(initData);
|
||||||
|
};
|
||||||
|
|
||||||
|
const clickDel = (row: any) => {
|
||||||
|
if (row.scale !== undefined) {
|
||||||
|
delSaveRow_api(id, leftData.selectedKeys[0], [row.name]).then(
|
||||||
|
(resp: any) => {
|
||||||
|
if (resp.status === 200) table.data.splice(row.index, 1);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else table.data.splice(row.index, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
const clickSave = () => {
|
||||||
|
formRef.value.validate().then((_data: any) => {
|
||||||
|
console.log(_data)
|
||||||
|
// const columns = cloneDeep(table.data);
|
||||||
|
// columns.forEach((item) => delete item.index);
|
||||||
|
// if (!columns.length) {
|
||||||
|
// onlyMessage('请配置数据源字段', 'error');
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// const params = {
|
||||||
|
// name: leftData.selectedKeys[0],
|
||||||
|
// columns,
|
||||||
|
// };
|
||||||
|
// saveTable_api(id, params).then((resp) => {
|
||||||
|
// if (resp.status === 200) {
|
||||||
|
// message.success('操作成功');
|
||||||
|
// queryTables(params.name);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const addFormRef = ref<FormInstance>();
|
const addFormRef = ref<FormInstance>();
|
||||||
const dialog = reactive({
|
const dialog = reactive({
|
||||||
visible: false,
|
visible: false,
|
||||||
form: {
|
form: {
|
||||||
name: '',
|
name: '',
|
||||||
},
|
},
|
||||||
handleOk: () => {
|
|
||||||
addFormRef.value &&
|
|
||||||
addFormRef.value.validate().then(() => {
|
|
||||||
const name = dialog.form.name;
|
|
||||||
leftData.sourceTree.unshift({
|
|
||||||
id: name,
|
|
||||||
name,
|
|
||||||
});
|
|
||||||
leftData.oldKey = name;
|
|
||||||
leftData.selectedKeys = [name];
|
|
||||||
table.data = [];
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
init();
|
const handleOk = () => {
|
||||||
function init() {
|
addFormRef.value &&
|
||||||
info.init();
|
addFormRef.value.validate().then(() => {
|
||||||
leftData.init();
|
const name = dialog.form.name;
|
||||||
}
|
leftData.sourceTree.unshift({
|
||||||
|
id: name,
|
||||||
|
name,
|
||||||
|
});
|
||||||
|
leftData.oldKey = name;
|
||||||
|
leftData.selectedKeys = [name];
|
||||||
|
table.data = [];
|
||||||
|
dialog.visible = false;
|
||||||
|
addFormRef.value?.resetFields();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
[() => leftData.searchValue, () => leftData.sourceTree],
|
||||||
|
([m, n]) => {
|
||||||
|
if (!!m) {
|
||||||
|
const list = n.filter((item) => {
|
||||||
|
return item.name.includes(m);
|
||||||
|
});
|
||||||
|
leftData.treeData = [
|
||||||
|
{
|
||||||
|
title: info.data.shareConfig.schema,
|
||||||
|
key: info.data.shareConfig.schema,
|
||||||
|
root: true,
|
||||||
|
children: list.map((item) => ({
|
||||||
|
title: item.name,
|
||||||
|
key: item.name,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
if (!_.map(list, 'name').includes(leftData.selectedKeys[0])) {
|
||||||
|
leftData.selectedKeys = [list[0]?.name];
|
||||||
|
queryTables(list[0]?.name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
leftData.treeData = [
|
||||||
|
{
|
||||||
|
title: info.data.shareConfig.schema,
|
||||||
|
key: info.data.shareConfig.schema,
|
||||||
|
root: true,
|
||||||
|
children: leftData.sourceTree.map((item) => ({
|
||||||
|
title: item.name,
|
||||||
|
key: item.name,
|
||||||
|
})),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
const checkName = (_: any, value: any) =>
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
if (value) {
|
||||||
|
const first = value.slice(0, 1);
|
||||||
|
if (typeof Number(first) === 'number' && !isNaN(Number(first))) {
|
||||||
|
reject('不能以数字开头');
|
||||||
|
} else {
|
||||||
|
resolve('');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.mangement-container {
|
.manager-container {
|
||||||
margin: 24px;
|
|
||||||
padding: 24px;
|
padding: 24px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
min-height: 500px;
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
flex-basis: 280px;
|
flex-basis: 280px;
|
||||||
padding-right: 24px;
|
padding: 0 24px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
:deep(.ant-tree-treenode) {
|
|
||||||
width: 100%;
|
|
||||||
.ant-tree-switcher-noop {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.ant-tree-node-content-wrapper {
|
|
||||||
width: 100%;
|
|
||||||
.ant-tree-title {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:first-child .ant-tree-node-selected {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.right {
|
.right {
|
||||||
width: calc(100% - 280px);
|
width: calc(100% - 280px);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-left: 1px solid #f0f0f0;
|
border-left: 1px solid #f0f0f0;
|
||||||
|
padding-left: 24px;
|
||||||
|
|
||||||
.btns {
|
.btns {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: right;
|
justify-content: right;
|
||||||
padding: 0px 24px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-row {
|
.add-row {
|
||||||
display: block;
|
display: block;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
margin: 24px 0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ant-form-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
:title="dialogTitle"
|
:title="dialogTitle"
|
||||||
:confirmLoading="loading"
|
:confirmLoading="loading"
|
||||||
@ok="confirm"
|
@ok="confirm"
|
||||||
@cancel="emits('update:visible', false)"
|
@cancel="emits('cancel')"
|
||||||
>
|
>
|
||||||
<j-form ref="formRef" :model="form.data" layout="vertical">
|
<j-form ref="formRef" :model="form.data" layout="vertical">
|
||||||
<j-row :gutter="24">
|
<j-row :gutter="24">
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
message: '请输入URL',
|
message: '请输入URL',
|
||||||
trigger: 'change',
|
trigger: 'change',
|
||||||
},
|
},
|
||||||
{ validator: form.checkUrl, trigger: 'blur' },
|
{ validator: checkUrl, trigger: 'blur' },
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<j-input
|
<j-input
|
||||||
|
@ -193,9 +193,8 @@ import { FormInstance, message } from 'ant-design-vue';
|
||||||
import { Rule } from 'ant-design-vue/lib/form';
|
import { Rule } from 'ant-design-vue/lib/form';
|
||||||
import type { dictItemType, optionItemType, sourceItemType } from '../typing';
|
import type { dictItemType, optionItemType, sourceItemType } from '../typing';
|
||||||
|
|
||||||
const emits = defineEmits(['confirm', 'update:visible']);
|
const emits = defineEmits(['confirm', 'cancel']);
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
visible: boolean;
|
|
||||||
data: sourceItemType;
|
data: sourceItemType;
|
||||||
}>();
|
}>();
|
||||||
// 弹窗相关
|
// 弹窗相关
|
||||||
|
@ -203,19 +202,25 @@ const dialogTitle = computed(() =>
|
||||||
props.data.id ? '编辑数据源' : '新增数据源',
|
props.data.id ? '编辑数据源' : '新增数据源',
|
||||||
);
|
);
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const confirm = () => {
|
|
||||||
loading.value = true;
|
const checkUrl = (_rule: Rule, value: string): Promise<any> => {
|
||||||
formRef.value
|
if (!value) return Promise.reject('请输入URL');
|
||||||
?.validate()
|
const arr = value.split(':');
|
||||||
.then(() => form.submit())
|
if (arr?.[0] === 'jdbc' || arr?.[0] === 'r2dbc') {
|
||||||
.then((resp: any) => {
|
return Promise.resolve();
|
||||||
if (resp.status === 200) {
|
} else {
|
||||||
message.success('操作成功');
|
return Promise.reject('请输入正确的URL');
|
||||||
emits('confirm');
|
}
|
||||||
emits('update:visible', false);
|
};
|
||||||
}
|
|
||||||
})
|
const getTypeOption = () => {
|
||||||
.finally(() => (loading.value = false));
|
getDataTypeDict_api().then((resp: any) => {
|
||||||
|
const result = resp.result as dictItemType[];
|
||||||
|
form.typeOptions = result.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const formRef = ref<FormInstance>();
|
const formRef = ref<FormInstance>();
|
||||||
|
@ -223,30 +228,38 @@ const form = reactive({
|
||||||
data: {
|
data: {
|
||||||
...props.data,
|
...props.data,
|
||||||
} as sourceItemType,
|
} as sourceItemType,
|
||||||
|
|
||||||
typeOptions: [] as optionItemType[],
|
typeOptions: [] as optionItemType[],
|
||||||
|
|
||||||
checkUrl: (_rule: Rule, value: string): Promise<any> => {
|
|
||||||
if (!value) return Promise.reject('请输入URL');
|
|
||||||
const arr = value.split(':');
|
|
||||||
if (arr?.[0] === 'jdbc' || arr?.[0] === 'r2dbc') {
|
|
||||||
return Promise.resolve();
|
|
||||||
} else {
|
|
||||||
return Promise.reject('请输入正确的URL');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getTypeOption: () => {
|
|
||||||
getDataTypeDict_api().then((resp: any) => {
|
|
||||||
const result = resp.result as dictItemType[];
|
|
||||||
form.typeOptions = result.map((item) => ({
|
|
||||||
label: item.name,
|
|
||||||
value: item.id,
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
submit: () => {
|
|
||||||
return saveDataSource_api(form.data);
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
form.getTypeOption();
|
|
||||||
|
watch(
|
||||||
|
() => props.data,
|
||||||
|
(newValue) => {
|
||||||
|
form.data = {...newValue, shareConfig: { ...newValue?.shareConfig }}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true,
|
||||||
|
deep: true
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTypeOption();
|
||||||
|
})
|
||||||
|
|
||||||
|
const confirm = () => {
|
||||||
|
loading.value = true;
|
||||||
|
formRef.value
|
||||||
|
?.validate()
|
||||||
|
.then(async (_data: any) => {
|
||||||
|
const resp = await saveDataSource_api({ ...props.data, ..._data });
|
||||||
|
if (resp.status === 200) {
|
||||||
|
message.success('操作成功');
|
||||||
|
emits('confirm');
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
loading.value = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -14,8 +14,13 @@
|
||||||
model="TABLE"
|
model="TABLE"
|
||||||
:params="queryParams"
|
:params="queryParams"
|
||||||
:defaultParams="{
|
:defaultParams="{
|
||||||
|
pageSize: 10,
|
||||||
sorts: [{ name: 'createTime', order: 'desc' }],
|
sorts: [{ name: 'createTime', order: 'desc' }],
|
||||||
}"
|
}"
|
||||||
|
:pagination="{
|
||||||
|
showSizeChanger: true,
|
||||||
|
pageSizeOptions: ['10', '20', '50', '100'],
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<template #headerTitle>
|
<template #headerTitle>
|
||||||
<PermissionButton
|
<PermissionButton
|
||||||
|
@ -31,7 +36,7 @@
|
||||||
:status="slotProps.state?.value"
|
:status="slotProps.state?.value"
|
||||||
:text="slotProps.state?.text"
|
:text="slotProps.state?.text"
|
||||||
:statusNames="{
|
:statusNames="{
|
||||||
enabled: 'success',
|
enabled: 'processing',
|
||||||
disabled: 'error',
|
disabled: 'error',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
@ -116,6 +121,7 @@
|
||||||
? '请先禁用,再删除'
|
? '请先禁用,再删除'
|
||||||
: '删除',
|
: '删除',
|
||||||
}"
|
}"
|
||||||
|
:danger="true"
|
||||||
:popConfirm="{
|
:popConfirm="{
|
||||||
title: `确认删除`,
|
title: `确认删除`,
|
||||||
onConfirm: () => table.clickDel(slotProps),
|
onConfirm: () => table.clickDel(slotProps),
|
||||||
|
@ -130,7 +136,7 @@
|
||||||
|
|
||||||
<EditDialog
|
<EditDialog
|
||||||
v-if="dialog.visible"
|
v-if="dialog.visible"
|
||||||
v-model:visible="dialog.visible"
|
@cancel="table.cancel"
|
||||||
:data="dialog.selectItem"
|
:data="dialog.selectItem"
|
||||||
@confirm="table.refresh"
|
@confirm="table.refresh"
|
||||||
/>
|
/>
|
||||||
|
@ -211,7 +217,7 @@ const columns = [
|
||||||
value: 'enabled',
|
value: 'enabled',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '已禁用',
|
label: '禁用',
|
||||||
value: 'disabled',
|
value: 'disabled',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
@ -277,7 +283,13 @@ const table = {
|
||||||
// 刷新列表
|
// 刷新列表
|
||||||
refresh: () => {
|
refresh: () => {
|
||||||
tableRef.value.reload();
|
tableRef.value.reload();
|
||||||
|
dialog.visible = false
|
||||||
|
dialog.selectItem = {}
|
||||||
},
|
},
|
||||||
|
cancel: () => {
|
||||||
|
dialog.visible = false
|
||||||
|
dialog.selectItem = {}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
table.getTypeOption();
|
table.getTypeOption();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue