Merge remote-tracking branch 'origin/dev-dictionary' into dev-dictionary
# Conflicts: # src/views/system/Region/index.vue
This commit is contained in:
commit
c5d70916dd
|
@ -0,0 +1,22 @@
|
|||
import server from '@/utils/request';
|
||||
|
||||
// 获取全部地区(树结构)
|
||||
export const getRegionTree = (): Promise<any> => server.post(`/area/_all/tree`);
|
||||
|
||||
// 校验名称是否存在
|
||||
export const validateName = (name: string, id?: string): Promise<any> => server.get(`/area/name/_validate?name=${name}${id ? `&id=${id}` : ''}`);
|
||||
|
||||
//校验行政区划代码是否存在
|
||||
export const validateCode = (code: string, id?: string): Promise<any> => server.get(`/area/code/_validate?code=${code}${id ? `&id=${id}` : ''}`);
|
||||
|
||||
// 删除
|
||||
export const delRegion = (id: string): Promise<any> => server.remove(`/area/${id}`);
|
||||
|
||||
// 保存
|
||||
export const saveRegion = (data: any): Promise<any> => server.post(`/area`, data);
|
||||
|
||||
// 更新
|
||||
export const updateRegion = (data: any): Promise<any> => server.patch(`/area`, data);
|
||||
|
||||
// 获取全部内置地区(树结构)
|
||||
export const getBuiltinRegionTree = (data: any): Promise<any> => server.post(`/area/builtin/_all/tree`, data);
|
|
@ -1,92 +1,237 @@
|
|||
<template>
|
||||
<j-input
|
||||
placeholder="请输入区域名称或行政区划代码"
|
||||
class="search-input"
|
||||
v-model:value="searchValue"
|
||||
@change="(e) => onSearch(e.target.value)"
|
||||
>
|
||||
<template #prefix>
|
||||
<AIcon type="SearchOutlined" style="color: rgba(0, 0, 0, 0.45)" />
|
||||
</template>
|
||||
</j-input>
|
||||
<j-button @click="onAdd" type="primary" class="btn">新增区域</j-button>
|
||||
<j-tree
|
||||
class="draggable-tree"
|
||||
draggable
|
||||
block-node
|
||||
v-if="treeData.length"
|
||||
:tree-data="treeData"
|
||||
@dragenter="onDragEnter"
|
||||
:tree-data="_treeData"
|
||||
@drop="onDrop"
|
||||
/>
|
||||
:defaultExpandAll="true"
|
||||
:height="700"
|
||||
:show-line="{ showLeafIcon: false }"
|
||||
:show-icon="true"
|
||||
>
|
||||
<template #title="_data">
|
||||
<div class="tree-box">
|
||||
<div class="name">
|
||||
<j-ellipsis>{{ _data?.name }}</j-ellipsis>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<j-space :size="8">
|
||||
<j-tooltip title="重命名">
|
||||
<j-button
|
||||
@click.stop="onEdit(_data?.data)"
|
||||
class="actions-btn"
|
||||
type="link"
|
||||
><AIcon type="EditOutlined"
|
||||
/></j-button>
|
||||
</j-tooltip>
|
||||
<j-tooltip title="新增子区域">
|
||||
<j-button
|
||||
@click.stop="onAdd(_data?.data)"
|
||||
class="actions-btn"
|
||||
type="link"
|
||||
><AIcon type="PlusCircleOutlined"
|
||||
/></j-button>
|
||||
</j-tooltip>
|
||||
<j-tooltip title="删除">
|
||||
<j-popconfirm @confirm="onRemove(_data?.id)">
|
||||
<j-button
|
||||
@click.stop
|
||||
class="actions-btn"
|
||||
type="link"
|
||||
danger
|
||||
><AIcon type="DeleteOutlined"
|
||||
/></j-button>
|
||||
</j-popconfirm>
|
||||
</j-tooltip>
|
||||
</j-space>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</j-tree>
|
||||
<j-empty v-else style="margin-top: 150px" />
|
||||
<Save
|
||||
:mode="mode"
|
||||
v-if="visible"
|
||||
:data="current"
|
||||
@save="onSave"
|
||||
@close="onClose"
|
||||
/>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { onlyMessage } from '@/utils/comm';
|
||||
import { debounce } from 'lodash-es';
|
||||
import { onMounted, ref, watch } from 'vue';
|
||||
import Save from '../Save/index.vue';
|
||||
import { getRegionTree, delRegion } from '@/api/system/region';
|
||||
|
||||
const treeData = ref([]);
|
||||
const treeData = ref<any[]>([]);
|
||||
const _treeData = ref<any[]>([]);
|
||||
const visible = ref<boolean>(false);
|
||||
const current = ref<any>({});
|
||||
const mode = ref<'add' | 'edit'>('add');
|
||||
const searchValue = ref<string>();
|
||||
|
||||
const onDragEnter = (info) => {
|
||||
// console.log(info);
|
||||
const filterTreeNodes = (tree: any[], condition: string) => {
|
||||
return tree.filter((item) => {
|
||||
if (item?.title && item.title.includes(condition)) {
|
||||
return true;
|
||||
}
|
||||
if (item?.code && item.code.includes(condition)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (item.children) {
|
||||
item.children = filterTreeNodes(item.children, condition);
|
||||
return !!item.children.length;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
const onDrop = (info) => {
|
||||
// console.log(info);
|
||||
// const dropKey = info.node.key;
|
||||
// const dragKey = info.dragNode.key;
|
||||
// const dropPos = info.node.pos.split('-');
|
||||
// const dropPosition =
|
||||
// info.dropPosition - Number(dropPos[dropPos.length - 1]);
|
||||
// const loop = (data: any, key: string | number, callback: any) => {
|
||||
// data.forEach((item, index) => {
|
||||
// if (item.key === key) {
|
||||
// return callback(item, index, data);
|
||||
// }
|
||||
// if (item.children) {
|
||||
// return loop(item.children, key, callback);
|
||||
// }
|
||||
// });
|
||||
// };
|
||||
// const data = [...gData.value];
|
||||
const onSearch = debounce((v: string) => {
|
||||
_treeData.value = filterTreeNodes(treeData.value, v);
|
||||
});
|
||||
|
||||
const onSave = () => {};
|
||||
|
||||
const onClose = () => {
|
||||
visible.value = false;
|
||||
};
|
||||
|
||||
const onEdit = (_data: any) => {
|
||||
mode.value = 'edit';
|
||||
current.value = _data;
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
const onRemove = async (id: string) => {
|
||||
const resp = await delRegion(id);
|
||||
if (resp.success) {
|
||||
onlyMessage('操作成功!');
|
||||
handleSearch();
|
||||
}
|
||||
};
|
||||
|
||||
const onAdd = (_data?: any) => {
|
||||
mode.value = 'add';
|
||||
current.value = _data ? _data : {};
|
||||
visible.value = true;
|
||||
};
|
||||
|
||||
const onDrop = (info: any) => {
|
||||
const dropKey = info.node.key;
|
||||
const dragKey = info.dragNode.key;
|
||||
const dropPos = info.node.pos.split('-');
|
||||
const dropPosition =
|
||||
info.dropPosition - Number(dropPos[dropPos.length - 1]);
|
||||
const loop = (data: any, key: string | number, callback: any) => {
|
||||
data.forEach((item: any, index: number) => {
|
||||
if (item.key === key) {
|
||||
return callback(item, index, data);
|
||||
}
|
||||
if (item.children) {
|
||||
return loop(item.children, key, callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
const data = [...treeData.value];
|
||||
// // Find dragObject
|
||||
// let dragObj: TreeDataItem;
|
||||
// loop(
|
||||
// data,
|
||||
// dragKey,
|
||||
// (item: TreeDataItem, index: number, arr: TreeProps['treeData']) => {
|
||||
// arr.splice(index, 1);
|
||||
// dragObj = item;
|
||||
// },
|
||||
// );
|
||||
// if (!info.dropToGap) {
|
||||
// // Drop on the content
|
||||
// loop(data, dropKey, (item: TreeDataItem) => {
|
||||
// item.children = item.children || [];
|
||||
// /// where to insert 示例添加到头部,可以是随意位置
|
||||
// item.children.unshift(dragObj);
|
||||
// });
|
||||
// } else if (
|
||||
// (info.node.children || []).length > 0 && // Has children
|
||||
// info.node.expanded && // Is expanded
|
||||
// dropPosition === 1 // On the bottom gap
|
||||
// ) {
|
||||
// loop(data, dropKey, (item: TreeDataItem) => {
|
||||
// item.children = item.children || [];
|
||||
// // where to insert 示例添加到头部,可以是随意位置
|
||||
// item.children.unshift(dragObj);
|
||||
// });
|
||||
// } else {
|
||||
// let ar: TreeProps['treeData'] = [];
|
||||
// let i = 0;
|
||||
// loop(
|
||||
// data,
|
||||
// dropKey,
|
||||
// (
|
||||
// _item: TreeDataItem,
|
||||
// index: number,
|
||||
// arr: TreeProps['treeData'],
|
||||
// ) => {
|
||||
// ar = arr;
|
||||
// i = index;
|
||||
// },
|
||||
// );
|
||||
// if (dropPosition === -1) {
|
||||
// ar.splice(i, 0, dragObj);
|
||||
// } else {
|
||||
// ar.splice(i + 1, 0, dragObj);
|
||||
// }
|
||||
// }
|
||||
// gData.value = data;
|
||||
let dragObj: any;
|
||||
loop(data, dragKey, (item: any, index: number, arr: any[]) => {
|
||||
arr.splice(index, 1);
|
||||
dragObj = item;
|
||||
});
|
||||
if (!info.dropToGap) {
|
||||
// Drop on the content
|
||||
loop(data, dropKey, (item: any) => {
|
||||
item.children = item.children || [];
|
||||
/// where to insert 示例添加到头部,可以是随意位置
|
||||
item.children.unshift(dragObj);
|
||||
});
|
||||
} else if (
|
||||
(info.node.children || []).length > 0 && // Has children
|
||||
info.node.expanded && // Is expanded
|
||||
dropPosition === 1 // On the bottom gap
|
||||
) {
|
||||
loop(data, dropKey, (item: any) => {
|
||||
item.children = item.children || [];
|
||||
// where to insert 示例添加到头部,可以是随意位置
|
||||
item.children.unshift(dragObj);
|
||||
});
|
||||
} else {
|
||||
let ar: any[] = [];
|
||||
let i = 0;
|
||||
loop(data, dropKey, (_item: any, index: number, arr: any[]) => {
|
||||
ar = arr;
|
||||
i = index;
|
||||
});
|
||||
if (dropPosition === -1) {
|
||||
ar.splice(i, 0, dragObj);
|
||||
} else {
|
||||
ar.splice(i + 1, 0, dragObj);
|
||||
}
|
||||
}
|
||||
treeData.value = data;
|
||||
};
|
||||
|
||||
watch(
|
||||
() => treeData.value,
|
||||
() => {
|
||||
if (searchValue.value) {
|
||||
onSearch(searchValue.value);
|
||||
} else {
|
||||
_treeData.value = treeData.value;
|
||||
}
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
immediate: true,
|
||||
},
|
||||
);
|
||||
|
||||
const handleSearch = async () => {
|
||||
const resp = await getRegionTree();
|
||||
if (resp.success) {
|
||||
treeData.value = resp?.result || [];
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
handleSearch();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.btn {
|
||||
width: 100%;
|
||||
margin: 18px 0;
|
||||
}
|
||||
.tree-box {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.actions {
|
||||
.actions-btn {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
<template>
|
||||
<j-tree-select
|
||||
showSearch
|
||||
placeholder="1级区域不需要选择"
|
||||
:tree-data="builtInAreaList"
|
||||
:value="_value"
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'code',
|
||||
}"
|
||||
tree-node-filter-prop="name"
|
||||
@select="onSelect"
|
||||
>
|
||||
<template #title="{ name, code }">
|
||||
<span v-if="code">{{ name }} | {{ code }}</span>
|
||||
</template>
|
||||
</j-tree-select>
|
||||
<j-checkbox
|
||||
@change="onCheckChange"
|
||||
v-model:checked="_checked"
|
||||
style="margin-top: 5px"
|
||||
>同步添加下一级区域</j-checkbox
|
||||
>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { getBuiltinRegionTree } from '@/api/system/region';
|
||||
import { omit } from 'lodash-es';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits(['update:value']);
|
||||
|
||||
const features = ref<any>();
|
||||
const _value = ref<string>('100000')
|
||||
const builtInAreaList = ref<Record<string, any>[]>([]);
|
||||
const _checked = ref<boolean>(false);
|
||||
|
||||
const queryBuiltinRegionTree = async () => {
|
||||
const resp = await getBuiltinRegionTree({
|
||||
paging: false,
|
||||
sorts: [{ name: 'sortIndex', order: 'asc' }],
|
||||
});
|
||||
if (resp.success) {
|
||||
builtInAreaList.value = resp?.result || [];
|
||||
}
|
||||
};
|
||||
|
||||
const onCheckChange = (e: any) => {
|
||||
if (e.target.checked) {
|
||||
emits('update:value', features.value);
|
||||
} else {
|
||||
emits('update:value', omit(features.value, 'children'));
|
||||
}
|
||||
};
|
||||
|
||||
const onSelect = (val: string, node: any) => {
|
||||
features.value = node;
|
||||
_value.value = val
|
||||
if (_checked.value) {
|
||||
emits('update:value', node);
|
||||
} else {
|
||||
emits('update:value', omit(node, 'children'));
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
queryBuiltinRegionTree();
|
||||
});
|
||||
</script>
|
|
@ -0,0 +1,21 @@
|
|||
<template>
|
||||
<j-button v-if="_value.length" type="link">请在地图上描点</j-button>
|
||||
<div v-else>
|
||||
已完成描点<j-button type="link">编辑</j-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue"
|
||||
|
||||
const props = defineProps({
|
||||
value: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['update:value'])
|
||||
|
||||
const _value = ref<any[]>([])
|
||||
</script>
|
|
@ -10,95 +10,136 @@
|
|||
>
|
||||
<div style="margin-top: 10px">
|
||||
<j-form :layout="'vertical'" ref="formRef" :model="modelRef">
|
||||
<j-form-item name="productId" label="上级区域">
|
||||
<j-select
|
||||
<j-form-item name="parentId" label="上级区域">
|
||||
<j-tree-select
|
||||
showSearch
|
||||
v-model:value="modelRef.productId"
|
||||
v-model:value="modelRef.parentId"
|
||||
placeholder="1级区域不需要选择"
|
||||
>
|
||||
<j-select-option
|
||||
:value="item.id"
|
||||
v-for="item in productList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
>{{ item.name }}</j-select-option
|
||||
>
|
||||
</j-select>
|
||||
:tree-data="areaList"
|
||||
allowClear
|
||||
:field-names="{
|
||||
children: 'children',
|
||||
label: 'name',
|
||||
value: 'id',
|
||||
}"
|
||||
tree-node-filter-prop="name"
|
||||
/>
|
||||
</j-form-item>
|
||||
<j-form-item name="type" label="添加方式">
|
||||
<j-radio-group
|
||||
v-model:value="modelRef.type"
|
||||
button-style="solid"
|
||||
@change="onChange"
|
||||
>
|
||||
<a-radio-button value="a">内置行政区</a-radio-button>
|
||||
<a-radio-button value="b">自定义数据</a-radio-button>
|
||||
<a-radio-button value="builtIn"
|
||||
>内置行政区</a-radio-button
|
||||
>
|
||||
<a-radio-button value="Custom"
|
||||
>自定义数据</a-radio-button
|
||||
>
|
||||
</j-radio-group>
|
||||
</j-form-item>
|
||||
<j-form-item>
|
||||
<j-select
|
||||
showSearch
|
||||
v-model:value="modelRef.productId"
|
||||
placeholder="1级区域不需要选择"
|
||||
>
|
||||
<j-select-option
|
||||
:value="item.id"
|
||||
v-for="item in productList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
>{{ item.name }}</j-select-option
|
||||
>
|
||||
</j-select>
|
||||
<j-checkbox v-model:checked="modelRef.productId">同步添加下一级区域</j-checkbox>
|
||||
<j-form-item v-if="modelRef.type === 'builtIn'">
|
||||
<BuildIn v-model:value="modelRef.features" />
|
||||
</j-form-item>
|
||||
<j-form-item
|
||||
label="区域名称"
|
||||
name="name"
|
||||
required
|
||||
:rules="[
|
||||
{
|
||||
max: 200,
|
||||
message: '最多输入200个字符',
|
||||
required: true,
|
||||
message: '请输入区域名称',
|
||||
},
|
||||
{
|
||||
max: 64,
|
||||
message: '最多输入64个字符',
|
||||
},
|
||||
{
|
||||
validator: vailName,
|
||||
trigger: 'blur',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<j-textarea
|
||||
v-model:value="modelRef.describe"
|
||||
placeholder="请输入说明"
|
||||
showCount
|
||||
:maxlength="200"
|
||||
<j-input
|
||||
v-model:value="modelRef.name"
|
||||
placeholder="请输入区域名称"
|
||||
/>
|
||||
</j-form-item>
|
||||
<j-form-item
|
||||
label="行政区划代码"
|
||||
name="code"
|
||||
required
|
||||
:rules="[
|
||||
{
|
||||
required: true,
|
||||
message: '请输入行政区划代码',
|
||||
},
|
||||
{
|
||||
validator: vailCode,
|
||||
trigger: 'blur',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<j-input-number
|
||||
v-model:value="modelRef.code"
|
||||
style="width: 100%"
|
||||
placeholder="请输入行政区划代码"
|
||||
/>
|
||||
</j-form-item>
|
||||
<j-form-item
|
||||
v-if="modelRef.type !== 'builtIn'"
|
||||
label="区划划分"
|
||||
required
|
||||
name="features"
|
||||
>
|
||||
<TracePoint v-model:value="modelRef.features" />
|
||||
</j-form-item>
|
||||
</j-form>
|
||||
</div>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, reactive } from 'vue';
|
||||
import { ref, watch, reactive, PropType, onMounted } from 'vue';
|
||||
import TracePoint from './TracePoint.vue';
|
||||
import BuildIn from './BuildIn.vue';
|
||||
import {
|
||||
validateName,
|
||||
getRegionTree,
|
||||
validateCode,
|
||||
} from '@/api/system/region';
|
||||
|
||||
const emit = defineEmits(['close', 'save']);
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
default: () => {},
|
||||
},
|
||||
mode: {
|
||||
type: String as PropType<'add' | 'edit'>,
|
||||
default: 'add',
|
||||
},
|
||||
});
|
||||
const productList = ref<Record<string, any>[]>([]);
|
||||
const areaList = ref<Record<string, any>[]>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
|
||||
const formRef = ref();
|
||||
|
||||
const modelRef = reactive({
|
||||
productId: undefined,
|
||||
parentId: undefined,
|
||||
id: undefined,
|
||||
name: '',
|
||||
describe: '',
|
||||
type: 'a',
|
||||
name: undefined,
|
||||
code: undefined,
|
||||
type: 'builtIn',
|
||||
features: undefined,
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(newValue) => {
|
||||
Object.assign(modelRef, newValue);
|
||||
() => {
|
||||
console.log(props.data);
|
||||
Object.assign(modelRef, props.data);
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
);
|
||||
|
@ -117,4 +158,46 @@ const handleSave = () => {
|
|||
console.log('error', err);
|
||||
});
|
||||
};
|
||||
|
||||
const vailName = async (_: Record<string, any>, value: string) => {
|
||||
if (!props?.data?.id && value) {
|
||||
const resp = await validateName(value, props.data.id);
|
||||
if (resp.status === 200 && resp.result) {
|
||||
return Promise.reject('区域名称重复');
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
const vailCode = async (_: Record<string, any>, value: string) => {
|
||||
if (!props?.data?.id && value) {
|
||||
const resp = await validateCode(value, props.data.id);
|
||||
if (resp.status === 200 && resp.result) {
|
||||
return Promise.reject('行政区域代码重复');
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
const onChange = () => {
|
||||
// console.log(e.target.value)
|
||||
modelRef.features = undefined
|
||||
}
|
||||
|
||||
const handleSearch = async () => {
|
||||
const resp = await getRegionTree();
|
||||
if (resp.success) {
|
||||
areaList.value = resp?.result || [];
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
handleSearch();
|
||||
});
|
||||
</script>
|
|
@ -3,12 +3,6 @@
|
|||
<full-page>
|
||||
<div class="region">
|
||||
<div class="left">
|
||||
<j-input-search
|
||||
v-model:value="searchValue"
|
||||
placeholder="请输入区域名称或行政区划代码"
|
||||
@search="onSearch"
|
||||
/>
|
||||
<j-button @click="onAdd" type="primary" class="btn">新增区域</j-button>
|
||||
<LeftTree />
|
||||
</div>
|
||||
<div class="right">
|
||||
|
@ -16,37 +10,22 @@
|
|||
</div>
|
||||
</div>
|
||||
</full-page>
|
||||
<Save v-if="visible" :data="current" @save="onSave" @close="onClose" />
|
||||
</page-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RegionMange">
|
||||
import LeftTree from './LeftTree/index.vue'
|
||||
import Save from './Save/index.vue'
|
||||
import Map from './MapTool/map.vue'
|
||||
import FullPage from "components/Layout/FullPage.vue";
|
||||
|
||||
const searchValue = ref()
|
||||
const visible = ref<boolean>(false)
|
||||
const current = ref<any>({})
|
||||
const path = ref([[121.5273285, 31.21515044], [121.5293285, 31.21515044], [121.5293285, 31.21915044], [121.5273285, 31.21515044]])
|
||||
|
||||
const onSearch = () => {
|
||||
|
||||
}
|
||||
|
||||
const onAdd = () => {
|
||||
visible.value = true
|
||||
current.value = {}
|
||||
}
|
||||
|
||||
const onSave = () => {
|
||||
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
visible.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
Loading…
Reference in New Issue