feat: 区域管理

This commit is contained in:
100011797 2023-10-25 11:18:40 +08:00
parent c5b4c69b82
commit 97be31a587
4 changed files with 281 additions and 1 deletions

View File

@ -91,5 +91,9 @@ export default [
path: VideoSharePath, path: VideoSharePath,
component: () => import('@/views/media/Device/Channel/Share/index.vue') component: () => import('@/views/media/Device/Channel/Share/index.vue')
}, },
AccountMenu AccountMenu,
{
path: '/system/region',
component: () => import('@/views/system/Region/index.vue')
},
] ]

View File

@ -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>

View File

@ -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>

View File

@ -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>