iZaiZaiA 2 лет назад
Родитель
Сommit
8e24d6ae95

+ 13 - 0
src/styles/app/main.scss

@@ -190,6 +190,19 @@ html, body, #app {
             padding: 15px 20px;
             height: calc(100% - 80px);
         }
+        .hc-tree-search-box {
+            position: relative;
+            padding: 15px 20px;
+            height: calc(100% - 187px);
+            .hc-search-tree-val {
+                position: relative;
+                margin-bottom: 24px;
+            }
+            .hc-tree-scrollbar {
+                position: relative;
+                height: calc(100% - 68px);
+            }
+        }
     }
     .hc-page-content-box {
         flex: 1;

+ 13 - 176
src/views/tentative/collect/components/HcTreeData.vue

@@ -1,209 +1,46 @@
 <template>
-    <ElTree class="hc-tree-node tree-line" ref="ElTreeRef" :props="ElTreeProps" :data="datas" highlight-current accordion node-key="primaryKeyId"
-            :default-expanded-keys="TreeExpandKey" @node-click="ElTreeClick" @node-contextmenu="ElTreeLabelContextMenu" :indent="0">
-        <template #default="{ node, data }">
-            <div class="data-custom-tree-node" :id="`${idPrefix}${data['primaryKeyId']}`">
-                <!--树组件,节点名称-->
-                <div class="label" :class="node.level === 1?'level-name':''">
-                    <span :class="data?.colorStatus === 2?'text-blue':data?.colorStatus === 3?'text-orange':data?.colorStatus === 4?'text-green':''" v-if="isColor">{{ node.label }}</span>
-                    <span v-else>{{ node.label }}</span>
-                </div>
-                <!--树组件,操作菜单-->
-                <div class="menu-icon" :class="node.showTreeMenu?'show':''" v-if="node.level !== 1 && menusData.length > 0" @click.stop>
-                    <div class="cu-tree-node-popover-menu-icon" @click.prevent.stop="ElTreeLabelContextMenu($event,data,node)">
-                        <HcIcon name="menu" ui="text-2xl"/>
-                    </div>
-                </div>
-                <!--树组件,操作菜单 END-->
-            </div>
-        </template>
-    </ElTree>
-    <!--右键菜单-->
-    <HcContextMenu ref="contextMenuRef" :datas="menusData" @item-click="handleMenuSelect" v-if="menusData.length > 0">
-        <template #mark="{item}">
-            <HcIcon :name="item.icon" :fill="treeRefData?.isFirst" class="menu-item-icon"/>
-            <span class="menu-item-name">{{treeRefData?.isFirst ? '取消标记为首件' : '标记为首件'}}</span>
-        </template>
-        <template #sort="{item}">
-            <HcIcon :name="item.icon" :line="false" class="menu-item-icon"/>
-            <span class="menu-item-name">{{item.label}}</span>
-        </template>
-    </HcContextMenu>
+    <ElTree class="hc-tree-node tree-line" :class="ui" ref="ElTreeRef" :props="ElTreeProps" :data="datas" show-checkbox accordion node-key="primaryKeyId" :indent="0" @check="ElTreeCheckChange"></ElTree>
 </template>
 
 <script setup>
 import {ref,watch} from "vue";
-import {getArrValue,getObjValue} from "vue-utils-plus"
 //参数
 const props = defineProps({
-    menus: {
-        type: Array,
-        default: () => ([])
+    ui: {
+        type: String,
+        default: ''
     },
     datas: {
         type: Array,
         default: () => ([])
     },
-    autoExpandKeys: {
-        type: Array,
-        default: () => ([])
-    },
-    isMark: {
-        type: Boolean,
-        default: false
-    },
-    idPrefix: {
-        type: String,
-        default: 'tree-data-'
-    },
-    isAutoKeys: {
-        type: Boolean,
-        default: true
-    },
-    isAutoClick: {
-        type: Boolean,
-        default: true
-    },
-    isColor: {
-        type: Boolean,
-        default: false
-    },
 })
 
 //变量
 const ElTreeRef = ref(null)
-const treeRefNode = ref(null)
-const treeRefData = ref(null)
+const treeData = ref(props.datas)
 const ElTreeProps = ref({
     label: 'title',
     children: 'children',
     isLeaf: 'notExsitChild'
 })
-const menusData = ref(props.menus)
-const menuMark = ref(props.isMark)
-const isAutoKeys = ref(props.isAutoKeys)
-const TreeExpandKey = ref(props.autoExpandKeys)
-const idPrefix = ref(props.idPrefix);
 
 //监听
 watch(() => [
-    props.menus,
-    props.isMark,
-    props.isAutoKeys,
-    props.autoExpandKeys,
-    props.idPrefix,
-], ([menus, isMark, AutoKeys, expandKeys, UserIdPrefix]) => {
-    menusData.value = menus
-    menuMark.value = isMark
-    isAutoKeys.value = AutoKeys
-    TreeExpandKey.value = expandKeys
-    idPrefix.value = UserIdPrefix
+    props.datas,
+], ([ datas ]) => {
+    treeData.value = datas
 })
 
 //事件
-const emit = defineEmits(['menuTap','nodeTap'])
+const emit = defineEmits(['change'])
 
-//节点被点击
-const ElTreeClick = async (data,node) => {
-    if (isAutoKeys.value) {
-        let autoKeysArr = []
-        await getNodeExpandKeys(node, autoKeysArr)
-        const autoKeys = autoKeysArr.reverse()
-        emit('nodeTap', {node, data, keys: autoKeys})
-    } else {
-        emit('nodeTap', {node, data, keys: []})
-    }
+//节点勾选
+const ElTreeCheckChange = (data, checkeds) => {
+    emit('change', {data, checkeds})
 }
-
-//处理自动展开的节点KEY
-const getNodeExpandKeys = async (node, newKeys) => {
-    const parent = getArrValue(node?.parent)
-    const nodeData = getObjValue(node?.data);
-    const primaryKeyId = nodeData?.primaryKeyId ?? ''
-    if (primaryKeyId) {
-        newKeys.push(primaryKeyId)
-        await getNodeExpandKeys(parent, newKeys)
-    }
-}
-
-//鼠标右键事件
-const contextMenuRef = ref(null)
-const ElTreeLabelContextMenu = (e,data,node) => {
-    const rows = menusData.value || [];
-    if (node.level !== 1 && rows.length > 0) {
-        e.preventDefault();
-        treeRefNode.value = node;
-        treeRefData.value = data;
-        //展开菜单
-        contextMenuRef.value?.showMenu(e)
-    }
-}
-
-//鼠标右键菜单被点击
-const handleMenuSelect = ({key}) => {
-    const node = treeRefNode.value;
-    const data = treeRefData.value;
-    //如果为标记菜单
-    if (key === 'mark' && menuMark.value) {
-        if (data.isFirst === true) {
-            emit('menuTap', {key: 'cancel_mark', node, data})
-        } else {
-            emit('menuTap', {key: 'mark', node, data})
-        }
-    } else {
-        emit('menuTap', {key, node, data})
-    }
-}
-//设置树菜单的标记数据
-const setElTreeMenuMark = (keys,isFirst) => {
-    keys.forEach(item => {
-        //根据 data 或者 key 拿到 Tree 组件中的 node
-        let node = ElTreeRef.value.getNode(item)
-        if (!!node) node.data.isFirst = isFirst;
-    })
-}
-
-//设置树菜单的标记数据
-const removeElTreeNode = (key) => {
-    //根据 data 或者 key 拿到 Tree 组件中的 node
-    let node = ElTreeRef.value.getNode(key)
-    //删除 Tree 中的一个节点,使用此方法必须设置 node-key 属性
-    ElTreeRef.value.remove(node)
-}
-
-// 暴露出去
-defineExpose({
-    setElTreeMenuMark,
-    removeElTreeNode
-})
 </script>
 
 <style lang="scss" scoped>
-@import "../../../styles/app/tree.scss";
-.data-custom-tree-node {
-    .menu-icon {
-        position: relative;
-        font-size: 20px;
-        opacity: 0;
-        pointer-events: none;
-        transition: opacity 0.2s;
-        .cu-tree-node-popover-menu-icon {
-            display: flex;
-            align-items: center;
-            justify-content: center;
-        }
-    }
-    &:hover {
-        .menu-icon {
-            opacity: 1;
-            pointer-events: all;
-            cursor: context-menu;
-        }
-    }
-    .menu-icon.show {
-        opacity: 1;
-        pointer-events: all;
-        cursor: context-menu;
-    }
-}
+@import "../../../../styles/app/tree.scss";
 </style>

+ 0 - 137
src/views/tentative/collect/components/HcTreeNode.vue

@@ -1,137 +0,0 @@
-<template>
-    <ElTree class="hc-tree-node-box hc-tree-node tree-line" ref="ElTreeRef" :props="ElTreeProps" :data="ElTreeData" :node-key="nodeKey" highlight-current accordion show-checkbox
-            :check-strictly="isStrictly" :expand-on-click-node="false" @check="ElTreeCheckChange" :indent="0">
-        <template #default="{ node, data }">
-            <div class="custom-tree-node">
-                <div class="label" @dblclick="ElTreeDblClick(data)">
-                    <el-input v-model="data.title" size="small" @keyup="keyUpEvent($event,data)" v-if="data.isInputName" @blur="ElTreeBtnClick(data)">
-                        <template #append>
-                            <el-button type="primary" plain size="small" @click="ElTreeBtnClick(data)">
-                                <HcIcon name="check"/>
-                            </el-button>
-                        </template>
-                    </el-input>
-                    <span v-else>{{data.title}}</span>
-                </div>
-            </div>
-        </template>
-    </ElTree>
-</template>
-
-<script setup>
-import {nextTick, onMounted, ref, watch} from "vue";
-import {getArrValue} from "vue-utils-plus"
-import wbsApi from '~api/data-fill/wbs';
-
-//参数
-const props = defineProps({
-    projectId: {
-        type: [String,Number],
-        default: ''
-    },
-    nodeKey: {
-        type: String,
-        default: 'primaryKeyId'
-    },
-    nodeId: {
-        type: [String,Number],
-        default: ''
-    },
-    oldId: {
-        type: [String,Number],
-        default: ''
-    },
-    strictly: {
-        type: Boolean,
-        default: false
-    },
-})
-
-//变量
-const ElTreeRef = ref(null)
-const projectId = ref(props.projectId)
-const isStrictly = ref(props.strictly)
-const ElTreeProps = ref({label: 'title', children: 'children', isLeaf: 'notExsitChild'})
-
-//监听
-watch(() => [
-    props.projectId,
-    props.strictly,
-], ([pid,strictly]) => {
-    projectId.value = pid
-    isStrictly.value = strictly
-})
-
-//渲染完成
-onMounted(() => {
-    ElTreeLoadNode()
-})
-
-//事件
-const emit = defineEmits(['check-change'])
-
-//树形结构异步加载数据
-const ElTreeData = ref([])
-const ElTreeLoadNode = async () => {
-    let nodeId = props.oldId || props.nodeId || ''
-    const {error, code, data} = await wbsApi.queryWbsTreePrivateByProjectIdAndId({
-        id: nodeId,
-        projectId: projectId.value
-    })
-    if (!error && code === 200) {
-        ElTreeData.value = getArrValue(data)
-        await nextTick(() => {
-            ElTreeCheckedKeys()
-        })
-    }
-}
-
-//被选择的
-const ElTreeCheckChange = (_,nodes) => {
-    emit('check-change', nodes)
-}
-
-//处理节点
-const ElTreeCheckedKeys = () => {
-    const Nodes = ElTreeRef.value.getCheckedNodes() || []
-    const HalfNodes = ElTreeRef.value.getHalfCheckedNodes() || []
-    emit('check-change', {
-        checkedNodes: Nodes,
-        halfCheckedNodes: HalfNodes
-    })
-}
-
-//更改节点名称
-const ElTreeDblClick = (item) => {
-    item.isInputName = true;
-}
-//回车
-const keyUpEvent = (e,item) => {
-    if (e.key === "Enter") {
-        ElTreeBtnClick(item)
-    }
-}
-//更改节点名称完成
-const ElTreeBtnClick = (item) => {
-    if (!item?.title) {
-        window?.$message?.warning('节点名称不能为空')
-    } else {
-        item.isInputName = false;
-        ElTreeCheckedKeys()
-    }
-}
-</script>
-
-<style lang="scss" scoped>
-@import "../../../styles/app/tree.scss";
-.custom-tree-node {
-    position: relative;
-    width: 100%;
-}
-</style>
-
-<style lang="scss">
-.hc-tree-node-box .el-tree-node__content {
-    height: 32px !important;
-}
-</style>

+ 3 - 3
src/views/tentative/collect/components/TestTree.vue

@@ -1,6 +1,6 @@
 <template>
     <ElTree class="hc-tree-node tree-line" :class="ui" ref="ElTreeRef" :props="ElTreeProps" :load="ElTreeLoadNode" lazy show-checkbox accordion node-key="primaryKeyId"
-            :default-expanded-keys="defaultExpandedCids" :indent="0" @check-change="ElTreeCheckChange">
+            :default-expanded-keys="defaultExpandedCids" :indent="0" @check="ElTreeCheckChange">
     </ElTree>
 </template>
 
@@ -75,8 +75,8 @@ const ElTreeLoadNode = async (node, resolve) => {
 }
 
 //节点勾选
-const ElTreeCheckChange = (data, checked, indeterminate) => {
-    emit('change', {data, checked, indeterminate})
+const ElTreeCheckChange = (data, checkeds) => {
+    emit('change', {data, checkeds})
 }
 </script>
 

+ 80 - 7
src/views/tentative/collect/monthly.vue

@@ -10,10 +10,26 @@
                     <div class="text-xs text-cut project-name">{{projectInfo['name']}}</div>
                 </div>
             </div>
-            <div class="hc-tree-box">
-                <el-scrollbar>
-                    <TestTree :projectId="projectId" :contractId="contractId" @change="testTreeCheckChange"/>
-                </el-scrollbar>
+            <div class="hc-tree-search-box">
+                <div class="hc-search-tree-val">
+                    <el-input v-model="searchTreeVal" block size="large" placeholder="请输入名称关键词检索" clearable @keyup="searchTreeKeyUp">
+                        <template #suffix>
+                            <HcIcon name="search-2" ui="text-xl"/>
+                        </template>
+                    </el-input>
+                </div>
+                <div class="hc-tree-scrollbar" v-loading="treeLoading" element-loading-text="获取数据中...">
+                    <el-scrollbar>
+                        <KeepAlive>
+                            <template v-if="isSearchTree">
+                                <HcTreeData :datas="searchTreeData" @change="testTreeCheckChange"/>
+                            </template>
+                            <template v-else>
+                                <TestTree :projectId="projectId" :contractId="contractId" @change="testTreeCheckChange"/>
+                            </template>
+                        </KeepAlive>
+                    </el-scrollbar>
+                </div>
             </div>
             <!--左右拖动-->
             <div class="horizontal-drag-line" @mousedown="onmousedown"/>
@@ -71,7 +87,7 @@
                             <template #default="scope">
                                 <!--scope.row scope.$index-->
                                 <HcTooltip keys="tentative_material_approach_annex">
-                                    <el-button type="primary" size="small" plain>编辑备注</el-button>
+                                    <el-button type="primary" size="small" plain @click="editorsNoteModalClick(scope.row)">编辑备注</el-button>
                                 </HcTooltip>
                             </template>
                         </el-table-column>
@@ -82,6 +98,12 @@
                 </template>
             </HcCard>
         </div>
+
+        <!--编辑备注-->
+        <HcDialog :show="editorsNoteModal" title="编辑备注信息" widths="45rem" :loading="editorsNoteLoading" @close="editorsNoteModalClose" @save="editorsNoteModalSave">
+            <el-input v-model="editorsNoteVal" type="textarea" placeholder="编辑备注信息" :autosize="{ minRows: 5}"/>
+        </HcDialog>
+
     </div>
 </template>
 
@@ -90,6 +112,9 @@ import {ref, onMounted, watch} from "vue";
 import {useAppStore} from "~src/store";
 import {useRouter, useRoute} from 'vue-router'
 import TestTree from "./components/TestTree.vue"
+import HcTreeData from "./components/HcTreeData.vue"
+import queryApi from "~api/data-fill/query";
+import {getArrValue} from "vue-utils-plus"
 
 //初始变量
 const router = useRouter()
@@ -114,10 +139,40 @@ onMounted(() => {
 
 })
 
+//树搜索
+const isSearchTree = ref(false)
+const searchTreeVal = ref('')
+const searchTreeData = ref([])
+
+//回车
+const treeLoading = ref(false)
+const searchTreeKeyUp = (e) => {
+    if (e.key === "Enter") {
+        searchTreeClick()
+    }
+}
+
+const searchTreeClick = async () => {
+    if (searchTreeVal.value) {
+        isSearchTree.value = true
+        treeLoading.value = true
+        const {data} = await queryApi.searchContractTree({
+            contractId: contractId.value,
+            queryValue: searchTreeVal.value
+        })
+        //判断状态
+        treeLoading.value = false
+        searchTreeData.value = getArrValue(data)
+    } else {
+        treeLoading.value = false
+        isSearchTree.value = false
+    }
+}
+
 //树被勾选
 const nodeItemInfo = ref({})
-const testTreeCheckChange = ({data, checked, indeterminate}) => {
-    console.log(data, checked, indeterminate)
+const testTreeCheckChange = ({data, checkeds}) => {
+    console.log(data, checkeds)
     //nodeItemInfo.value = data
     //searchForm.value.current = 1;
     //getTableData()
@@ -225,6 +280,24 @@ const getTableData = () => {
 
 }
 
+
+//新增/编辑
+const editorsNoteModal = ref(false)
+const editorsNoteVal = ref('')
+const editorsNoteModalClick = (row) => {
+    editorsNoteModal.value = true
+}
+
+//保存
+const editorsNoteLoading = ref(false)
+const editorsNoteModalSave = () => {
+    editorsNoteModal.value = true
+}
+const editorsNoteModalClose = () => {
+    editorsNoteModal.value = false
+}
+
+
 //左右拖动,改变树形结构宽度
 const leftWidth = ref(382);
 const onmousedown = () => {