feat: 区域管理
This commit is contained in:
parent
c5b4c69b82
commit
97be31a587
|
@ -91,5 +91,9 @@ export default [
|
|||
path: VideoSharePath,
|
||||
component: () => import('@/views/media/Device/Channel/Share/index.vue')
|
||||
},
|
||||
AccountMenu
|
||||
AccountMenu,
|
||||
{
|
||||
path: '/system/region',
|
||||
component: () => import('@/views/system/Region/index.vue')
|
||||
},
|
||||
]
|
|
@ -0,0 +1,92 @@
|
|||
<template>
|
||||
<j-tree
|
||||
class="draggable-tree"
|
||||
draggable
|
||||
block-node
|
||||
v-if="treeData.length"
|
||||
:tree-data="treeData"
|
||||
@dragenter="onDragEnter"
|
||||
@drop="onDrop"
|
||||
/>
|
||||
<j-empty v-else style="margin-top: 150px" />
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
|
||||
const treeData = ref([]);
|
||||
|
||||
const onDragEnter = (info) => {
|
||||
// console.log(info);
|
||||
};
|
||||
|
||||
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];
|
||||
// // 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;
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
<template>
|
||||
<j-modal
|
||||
:maskClosable="false"
|
||||
width="650px"
|
||||
:visible="true"
|
||||
:title="!!data?.id ? '编辑区域' : '新增区域'"
|
||||
@ok="handleSave"
|
||||
@cancel="handleCancel"
|
||||
:confirmLoading="loading"
|
||||
>
|
||||
<div style="margin-top: 10px">
|
||||
<j-form :layout="'vertical'" ref="formRef" :model="modelRef">
|
||||
<j-form-item name="productId" label="上级区域">
|
||||
<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-form-item>
|
||||
<j-form-item name="type" label="添加方式">
|
||||
<j-radio-group
|
||||
v-model:value="modelRef.type"
|
||||
button-style="solid"
|
||||
>
|
||||
<a-radio-button value="a">内置行政区</a-radio-button>
|
||||
<a-radio-button value="b">自定义数据</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>
|
||||
<j-form-item
|
||||
label="区域名称"
|
||||
name="name"
|
||||
:rules="[
|
||||
{
|
||||
max: 200,
|
||||
message: '最多输入200个字符',
|
||||
},
|
||||
]"
|
||||
>
|
||||
<j-textarea
|
||||
v-model:value="modelRef.describe"
|
||||
placeholder="请输入说明"
|
||||
showCount
|
||||
:maxlength="200"
|
||||
/>
|
||||
</j-form-item>
|
||||
</j-form>
|
||||
</div>
|
||||
</j-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, watch, reactive } from 'vue';
|
||||
|
||||
const emit = defineEmits(['close', 'save']);
|
||||
const props = defineProps({
|
||||
data: {
|
||||
type: Object,
|
||||
default: undefined,
|
||||
},
|
||||
});
|
||||
const productList = ref<Record<string, any>[]>([]);
|
||||
const loading = ref<boolean>(false);
|
||||
|
||||
const formRef = ref();
|
||||
|
||||
const modelRef = reactive({
|
||||
productId: undefined,
|
||||
id: undefined,
|
||||
name: '',
|
||||
describe: '',
|
||||
type: 'a',
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.data,
|
||||
(newValue) => {
|
||||
Object.assign(modelRef, newValue);
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
);
|
||||
|
||||
const handleCancel = () => {
|
||||
emit('close');
|
||||
};
|
||||
|
||||
const handleSave = () => {
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(async (_data: any) => {
|
||||
loading.value = true;
|
||||
})
|
||||
.catch((err: any) => {
|
||||
console.log('error', err);
|
||||
});
|
||||
};
|
||||
</script>
|
|
@ -0,0 +1,64 @@
|
|||
<template>
|
||||
<page-container>
|
||||
<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">
|
||||
地图
|
||||
</div>
|
||||
</div>
|
||||
<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'
|
||||
|
||||
const searchValue = ref()
|
||||
const visible = ref<boolean>(false)
|
||||
const current = ref<any>({})
|
||||
|
||||
const onSearch = () => {
|
||||
|
||||
}
|
||||
|
||||
const onAdd = () => {
|
||||
visible.value = true
|
||||
current.value = {}
|
||||
}
|
||||
|
||||
const onSave = () => {
|
||||
|
||||
}
|
||||
|
||||
const onClose = () => {
|
||||
visible.value = false
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.region {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
|
||||
.left {
|
||||
width: 300px;
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
margin: 18px 0;
|
||||
}
|
||||
}
|
||||
.right {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue