duy 1 year ago
parent
commit
bbb351efcd

+ 53 - 11
src/api/modules/other.js

@@ -1,36 +1,78 @@
-import {httpApi} from "../request/httpApi";
+import { httpApi } from '../request/httpApi'
 
 //用户配置保存
 export const userConfigSave = (form, msg = true) => httpApi({
     url: '/api/blade-business/defaultConfig/saveOrUpdate',
     method: 'post',
-    data: form
-}, msg);
+    data: form,
+}, msg)
 
 //用户配置详情
 export const userConfigInfo = (form, msg = true) => httpApi({
     url: '/api/blade-business/defaultConfig/detail',
     method: 'get',
-    params: form
-}, msg);
+    params: form,
+}, msg)
 
 //获取用户列表
 export const getContractUserList = (form, msg = true) => httpApi({
     url: '/api/blade-manager/contractInfo/get-contract-userList',
     method: 'get',
-    params: form
-}, msg);
+    params: form,
+}, msg)
 
 //获取表单的下拉框测站点数据
 export const getDapSiteData = (form, msg = true) => httpApi({
     url: '/api/blade-business/dap/site',
     method: 'get',
-    params: form
-}, msg);
+    params: form,
+}, msg)
 
 
 //获取更新信息
 export const getVersionJson = () => httpApi({
     url: 'version.json?time=' + new Date().getTime(),
-    method: 'get'
-}, false);
+    method: 'get',
+}, false)
+//懒加载区域树
+export const getLazyTree = (form, msg = true) => httpApi({
+    url: '/api/blade-land/regionTreeInfo/lazyTree',
+    method: 'get',
+    params: form,
+}, msg)
+//新增或修改树
+export const addOrUpdateTree = (form, msg = true) => httpApi({
+    url: '/api/blade-land/regionTreeInfo/addOrUpdate',
+    method: 'post',
+    data: form,
+}, msg)
+
+//获取节点详情
+export const getDetail = (form, msg = true) => httpApi({
+    url: '/api/blade-land/regionTreeInfo/detail',
+    method: 'get',
+    params: form,
+}, msg)
+
+//删除节点
+export const deleteTree = (form, msg = true) => httpApi({
+    url: '/api/blade-land/regionTreeInfo/delete',
+    method: 'get',
+    params: form,
+}, msg)
+//获取区域
+export const getAllCounty = (form, msg = true) => httpApi({
+    url: '/api/blade-land/regionTreeInfo/getAllCounty',
+    method: 'get',
+    params: form,
+}, msg)
+
+//字典数据查询接口
+export const getDictInfo = (code) => httpApi({
+    url: '/api/blade-system/dict/dictionary',
+    method: 'get',
+    params: {
+        code,
+    },
+}, false)
+

+ 63 - 0
src/components/message/index.js

@@ -0,0 +1,63 @@
+import { h } from 'vue'
+import domView from './index.vue'
+
+//删除提醒
+export const delMessageV2 = (cbk) => {
+    window?.$messageBox({
+        center: true,
+        message: () => h(domView, {
+            type: 'delete',
+            title: '确认删除提醒',
+            text: '请谨慎考虑后,确认是否需要删除?',
+        }),
+        customClass: 'hc-message-view-box',
+        showCancelButton: true,
+        confirmButtonText: '确认删除',
+        cancelButtonText: '取消操作',
+        beforeClose: (action, instance, done) => {
+            if (cbk) {
+                cbk(action, instance, done)
+            } else {
+                done()
+            }
+        },
+    })
+}
+
+//请求异常
+export const apiErrorMessage = () => {
+    setTimeout(() => {
+        const doms = document.querySelector('.hc-message-view-box.warning')
+        if (doms) return
+        window?.$messageBox({
+            center: true,
+            message: () => h(domView, {
+                type: 'warning',
+                title: '服务器异常,请稍后重试',
+                text: '服务器异常了,如有需要,请联系管理员!',
+            }),
+            customClass: 'hc-message-view-box warning',
+            showCancelButton: false,
+            confirmButtonText: '关闭',
+        })
+    }, 1000)
+}
+
+//请求异常
+export const apiWarningMessage = () => {
+    setTimeout(() => {
+        const doms = document.querySelector('.hc-message-view-box.warning')
+        if (doms) return
+        window?.$messageBox({
+            center: true,
+            message: () => h(domView, {
+                type: 'warning',
+                title: '正在升级优化,请稍后重试',
+                text: '该功能正在升级优化,请联系管理员',
+            }),
+            customClass: 'hc-message-view-box warning',
+            showCancelButton: false,
+            confirmButtonText: '关闭',
+        })
+    }, 1000)
+}

+ 71 - 0
src/components/message/index.vue

@@ -0,0 +1,71 @@
+<template>
+    <div class="hc-message-box">
+        <div class="hc-lottie-box delete">
+            <HcLottie v-if="isType === 'delete'" type="delete" style="height: 200px" />
+            <HcLottie v-if="isType === 'warning'" type="warning" style="height: 140px" />
+        </div>
+        <div class="title">{{ titles }}</div>
+        <div class="text">{{ text }}</div>
+    </div>
+</template>
+
+<script setup>
+import { ref, watch } from 'vue'
+import { HcLottie } from 'hc-vue3-ui'
+//参数
+const props = defineProps({
+    type: {
+        type: String,
+        default: 'warning',
+    },
+    title: {
+        type: String,
+        default: '',
+    },
+    text: {
+        type: String,
+        default: '',
+    },
+})
+
+//监听
+watch(() => [
+    props.type,
+    props.title,
+    props.text,
+], ([type, title, text]) => {
+    isType.value = type
+    titles.value = title
+    texts.value = text
+})
+
+//变量
+const isType = ref(props.type)
+const titles = ref(props.title)
+const texts = ref(props.text)
+</script>
+
+<style scoped lang="scss">
+.hc-message-box {
+    position: relative;
+    .hc-lottie-box {
+        position: relative;
+        height: 200px;
+        overflow: hidden;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+    }
+    .title {
+        position: relative;
+        font-size: 20px;
+        color: var(--hc-text-color);
+        margin-bottom: 20px;
+    }
+    .text {
+        color: var(--hc-label-color);
+        font-size: 14px;
+        margin-bottom: 10px;
+    }
+}
+</style>

+ 151 - 95
src/global/components/tree-data/index.vue

@@ -1,72 +1,117 @@
 <template>
-    <HcDataTree :h-props="treeProps" :autoExpandKeys="autoExpandKeys" :treeKey="treeKey" :datas="treeLoadNode"
-                :showCheckbox="showCheckbox"
-                @nodeTap="treeNodeClick">
-        <template #default="{node, data, level}">
-            <div :class="level === 1 ? 'level-name':''" class="label flex items-center">
-                <span class="hc-tree-node-type" v-if="level !== 1">县</span>
-                <span>{{node.label }}</span>
+    <HcLazyTree
+        v-if="isShowTree"
+        :h-props="treeProps" :auto-expand-keys="autoExpandKeys" :tree-key="treeKey" :show-checkbox="showCheckbox"
+        @load="treeLoadNode"
+        @nodeTap="treeNodeClick"
+    >
+        <template #default="{ node, data, level }">
+            <div :class="level === 1 ? 'level-name' : ''" class="label flex items-center">
+                <span v-if="level !== 1" class="hc-tree-node-type">{{ getNodeTypeName(data?.nodeType) }}</span>
+                <span>{{ node.label }}</span>
             </div>
-            <!--树组件,操作菜单-->
-            <div v-if="isMenus" :class="node.showTreeMenu?'show':''" class="menu-icon1">
+            <!-- 树组件,操作菜单 -->
+            <div v-if="isMenus" :class="node.showTreeMenu ? 'show' : ''" class="menu-icon1">
                 <div class="cu-tree-node-popover-menu-icon" @click.prevent.stop="treeLabelContextMenu($event, data, node)">
-                    <HcIcon name="apps" ui="text-2xl"/>
+                    <HcIcon name="apps" ui="text-2xl" />
                 </div>
             </div>
         </template>
-    </HcDataTree>
-    <!--右键菜单-->
-    <HcContextMenu ref="contextMenuRef" :datas="treeMenu" @closed="handleMenuClosed" @item-click="handleMenuSelect" v-if="isMenus"/>
-    <!--新增/编辑-->
-    <HcDialog isToBody bgColor="white" :show="rowModal" :title="formModel.id?'编辑区域':'新增区域'" widths="30rem" @save="rowModalSave" @close="rowModalClose">
+    </HcLazyTree>
+    <!-- 右键菜单 -->
+    <HcContextMenu v-if="isMenus" ref="contextMenuRef" :datas="treeMenu" @closed="handleMenuClosed" @item-click="handleMenuSelect" />
+    <!-- 新增/编辑 -->
+    <HcDialog is-to-body bg-color="white" :show="rowModal" :title="formModel.id ? '编辑区域' : '新增区域'" widths="30rem" :loading="submitLoading" @save="rowModalSave" @close="rowModalClose">
         <el-form ref="formRef" :model="formModel" :rules="formRules" label-position="top" size="large">
             <el-form-item label="区域名称:" prop="key">
-                <el-input v-model="formModel.key"/>
+                <el-input v-model="formModel.areaName" />
             </el-form-item>
             <el-form-item label="征拆桩号:">
-                <el-input v-model="formModel.key1"/>
+                <el-input v-model="formModel.stakeMark" />
             </el-form-item>
             <el-form-item label="节点类型:">
-                <el-select block v-model="formModel.key2">
-                    <el-option label="选项1" value="选项1"/>
-                    <el-option label="选项2" value="选项2"/>
+                <el-select v-model="formModel.nodeType" block>
+                    <el-option v-for="item in nodeTypeData" :key="item.id" :label="item.dictValue" :value="item.dictKey" />
                 </el-select>
             </el-form-item>
             <el-form-item label="备注:">
-                <el-input type="textarea" v-model="formModel.key3" :autosize="{ minRows: 3, maxRows: 5 }"/>
+                <el-input v-model="formModel.remark" type="textarea" :autosize="{ minRows: 3, maxRows: 5 }" />
             </el-form-item>
         </el-form>
     </HcDialog>
 </template>
 
 <script setup>
-import {ref,watch,onMounted} from "vue";
-import {isNullES} from "js-fast-way";
-
+import { onMounted, ref, watch } from 'vue'
+import { formValidate, getArrValue, getObjValue, isNullES } from 'js-fast-way'
+import { addOrUpdateTree, getDictInfo, getLazyTree } from '~api/other'
+import { useAppStore } from '~src/store'
+import { getStoreValue, setStoreValue } from '~src/utils/storage'
+import { delMessageV2 } from '~com/message/index.js'
 //参数
 const props = defineProps({
     isMenu: {
         type: Boolean,
-        default: true
+        default: true,
     },
     showCheckbox: {
         type: Boolean,
-        default: false
+        default: false,
     },
 })
+//事件
+const emit = defineEmits(['menuTap', 'nodeTap'])
+const useAppState = useAppStore()
+const projectId = ref(useAppState.getProjectId)
 
 //渲染完成
 onMounted(()=> {
-
+    getNodeTypeData()
 })
 
 //事件
 
-const treeKey = ref('label')
-const treeRefNode = ref({});
-const treeRefData = ref({});
-const isMenus = ref(props.isMenu);
-const autoExpandKeys = ref([]);
+//节点类型字典
+const nodeTypeData = ref([])
+const getNodeTypeData = async () => {
+    const { error, code, data } = await getDictInfo('region_node_type')
+    //判断状态
+    if (!error && code === 200) {
+        nodeTypeData.value = getArrValue(data)
+        nodeTypeData.value.forEach((ele)=>{
+            ele.dictKey = parseInt(ele.dictKey)
+        })
+    } else {
+        nodeTypeData.value = []
+    }
+}
+//获取节点类型名称
+const getNodeTypeName = (val)=>{
+    switch (val) {
+            case 1:
+                return '省'
+            case 2:
+                return '市'
+            case 3:
+                return '区'
+            case 4:
+                return '县'
+            case 5:
+                return '乡/镇'
+            case 6:
+            return '村'
+            case 7:
+            return '组'
+            default:
+                return ''
+        }
+}
+const treeKey = ref('id')
+const treeRefNode = ref({})
+const treeRefData = ref({})
+const isMenus = ref(props.isMenu)
+const autoExpandKeys = ref(getStoreValue('autoExpandKeys') || [])
+const isShowTree = ref(true)
 
 //监听
 watch(() => [
@@ -75,79 +120,57 @@ watch(() => [
     isMenus.value = isMenu
 })
 
-//事件
-const emit = defineEmits(['menuTap', 'nodeTap'])
-
 //数据格式
 const treeProps = {
-    label: 'label',
-    children: 'children'
+    label: 'areaName',
+    children: 'children',
+    isLeaf:'notExsitChild',
 }
 
 
-//数据
-const treeLoadNode = ref([
-    {
-        label: '征拆区域',
-        children: [
-            {
-                label: 'Level two 1-1',
-                children: [
-                    {label: 'Level three 1-1-1'}
-                ]
-            },
-            {
-                label: 'Level two 2-1',
-                children: [
-                    {label: 'Level three 2-1-1'}
-                ]
-            },
-            {
-                label: 'Level two 2-2',
-                children: [
-                    {label: 'Level three 2-2-1'}
-                ]
-            },
-            {
-                label: 'Level two 3-1',
-                children: [
-                    {label: 'Level three 3-1-1'}
-                ]
-            },
-            {
-                label: 'Level two 3-2',
-                children: [
-                    {label: 'Level three 3-2-1'}
-                ]
-            }
-        ]
-    }
-])
 
+//懒加载的数据
+const treeLoadNode = async ({ node, item, level }, resolve) => {
+    let id = 0
+    if (level !== 0) {
+        const nodeData = getObjValue(item)
+        id = nodeData?.id || ''
+    }
+    //获取数据
+    const { data } = await getLazyTree({
+        // projectId: projectId.value || '',
+        projectId: '123' || '',
+        id,
+    })
+    resolve(getArrValue(data))
+}
 //树被点击
-const treeNodeClick = async ({node, data, keys}) => {
+const treeNodeClick = async ({ node, data, keys }) => {
     treeRefNode.value = node
     treeRefData.value = data
-    emit('nodeTap', {node, data})
+    emit('nodeTap', { node, data })
+    autoExpandKeys.value = keys
+    setStoreValue('autoExpandKeys', keys)
 }
 
 //标题的鼠标右键
 const treeMenu = ref([])
 const contextMenuRef = ref(null)
-const treeLabelContextMenu = (e, data, node) => {
+const treeLabelContextMenu = async (e, data, node) => {
+
     if (!isMenus.value) {
-        return;
+        return
     }
-    e.preventDefault();
-    treeRefNode.value = node;
-    treeRefData.value = data;
+    e.preventDefault()
+    treeRefNode.value = node
+    treeRefData.value = data
     if (node.level === 1) {
-        treeMenu.value =  [{icon: 'add-circle', label: '新增节点', key: "add"}]
+        treeMenu.value = [{ icon: 'add-circle', label: '新增节点', key: 'add' }]
     } else {
         treeMenu.value = [
-            {icon: 'add-circle', label: '新增节点', key: "add"},
-            {icon: 'draft', label: '编辑节点', key: "edit"},
-            {icon: 'delete-bin', label: '删除节点', key: "del"}
+            { icon: 'add-circle', label: '新增节点', key: 'add' },
+            { icon: 'draft', label: '编辑节点', key: 'edit' },
+            { icon: 'delete-bin', label: '删除节点', key: 'del' },
         ]
     }
     node.showTreeMenu = true
@@ -156,7 +179,7 @@ const treeLabelContextMenu = (e, data, node) => {
 
 
 const handleMenuClosed = () => {
-    const node = treeRefNode.value;
+    const node = treeRefNode.value
     if (!isNullES(node)) {
         treeRefNode.value['showTreeMenu'] = false
     }
@@ -167,16 +190,17 @@ const rowModal = ref(false)
 const formRef = ref(null)
 const formModel = ref({})
 const formRules = {
-    key: [{required: true, message: '请输入区域名称', trigger: 'blur'}],
+    areaName: [{ required: true, message: '请输入区域名称', trigger: 'blur' }],
 }
 
 
 //鼠标右键菜单被点击
-const handleMenuSelect = async ({key}) => {
-    const node = treeRefNode.value;
-    console.log(node)
+const handleMenuSelect = async ({ key }) => {
+    const node = treeRefNode.value
     if (key === 'add') {
         formModel.value = {}
+        formModel.value.parentId = node?.data.id
+        formModel.value.projectId = node?.data.projectId
         rowModal.value = true
     } else if (key === 'edit') {
         formModel.value = node?.data
@@ -186,12 +210,44 @@ const handleMenuSelect = async ({key}) => {
     }
     console.log(key)
 }
-
+const submitLoading = ref(false)
 //保存
-const rowModalSave = () => {
-
+const rowModalSave = async () => {
+    const res = await formValidate(formRef.value)
+    if (res) {
+        console.log( formModel.value, ' formModel.value')
+        submitLoading.value = true
+        //发起请求
+        const form = formModel.value
+        const { error, code, msg } = await addOrUpdateTree(form)
+        //判断状态
+        submitLoading.value = false
+        if (!error && code === 200) {
+            window.$message?.success(msg)
+            rowModal.value = false
+            isShowTree.value = false
+            setTimeout(() => {
+                isShowTree.value = true
+            }, 100)
+            
+        } 
+        
+    }
 }
+//删除节点
+const delModalClick = () => {
 
+delMessageV2(async (action, instance, done) => {
+        if (action === 'confirm') {
+            instance.confirmButtonLoading = true
+            // removeContractTreeNode()
+            instance.confirmButtonLoading = false
+            done()
+        } else {
+            done()
+        }
+ })
+}
 //关闭弹窗
 const rowModalClose = () => {
     rowModal.value = false
@@ -206,7 +262,7 @@ const getAutoKeys = async (node) => {
     await getNodeExpandKeys(node, autoKeysArr)
     return autoKeysArr.reverse()
 }
-const getNodeExpandKeys = async ({parent, data}, newKeys) => {
+const getNodeExpandKeys = async ({ parent, data }, newKeys) => {
     const nodeKey = data[treeKey.value] ?? ''
     if (nodeKey) {
         newKeys.push(nodeKey)