iZaiZaiA %!s(int64=2) %!d(string=hai) anos
pai
achega
8f4b64849f

+ 1 - 1
src/config/index.js

@@ -17,7 +17,7 @@ export default {
     statusWhiteList: [],    //http的status默认放行列表
     ossUrl: 'https://bladex-test-info.oss-cn-chengdu.aliyuncs.com', //oss地址
     smsPhone: '',  //测试接受短信验证码的手机号
-    dev_version: '202209261550',    //开发版本号
+    dev_version: '202209261652',    //开发版本号
     prod_host: 'http://47.110.251.215:8090',  //线上
     dev_host: 'http://192.168.4.6', //黄键楠
     //dev_host: 'http://192.168.3.13', //祝炜

+ 22 - 94
src/views/data-fill/components/DivisionTree.vue

@@ -3,12 +3,9 @@
             :default-expanded-keys="defaultExpandedCids" @node-click="ElTreeClick" :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">
-                    <div class="cu-tree-node-popover-menu-icon" @click.prevent.stop="ElTreeLabelContextMenu($event,data,node)">关联</div>
+                <div class="label division" :class="node.level === 1?'level-name':node.level">{{ node.label }}</div>
+                <div class="menu-icon">
+                    <div class="cu-tree-node-popover-menu-icon" @click.prevent.stop="ElTreeRelationClick($event,data,node)">关联</div>
                 </div>
             </div>
         </template>
@@ -38,10 +35,6 @@ const props = defineProps({
         type: String,
         default: 'division-tree-'
     },
-    isAutoKeys: {
-        type: Boolean,
-        default: true
-    },
     isAutoClick: {
         type: Boolean,
         default: true
@@ -57,7 +50,6 @@ const ElTreeProps = ref({
     children: 'children',
     isLeaf: 'notExsitChild'
 })
-const isAutoKeys = ref(props.isAutoKeys)
 const TreeExpandKey = ref(props.autoExpandKeys)
 const projectId = ref(props.projectId);
 const contractId = ref(props.contractId);
@@ -65,17 +57,11 @@ const idPrefix = ref(props.idPrefix);
 
 //监听
 watch(() => [
-    props.menus,
-    props.isMark,
-    props.isAutoKeys,
     props.autoExpandKeys,
     props.projectId,
     props.contractId,
     props.idPrefix,
-], ([menus, isMark, AutoKeys, expandKeys, UserProjectId, UserContractId,UserIdPrefix]) => {
-    menusData.value = menus
-    menuMark.value = isMark
-    isAutoKeys.value = AutoKeys
+], ([expandKeys, UserProjectId, UserContractId,UserIdPrefix]) => {
     TreeExpandKey.value = expandKeys
     projectId.value = UserProjectId
     contractId.value = UserContractId
@@ -83,7 +69,7 @@ watch(() => [
 })
 
 //事件
-const emit = defineEmits(['menuTap','nodeTap', 'nodeLoading'])
+const emit = defineEmits(['nodeTap', 'nodeLoading', 'relationTap'])
 
 //树形结构异步加载数据
 const defaultExpandedCids = ref([])
@@ -144,77 +130,17 @@ const ElTreeLoadNode = async (node, resolve) => {
 
 //节点被点击
 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: []})
-    }
-}
-
-//处理自动展开的节点KEY
-const getNodeExpandKeys = async (node, newKeys) => {
-    const parent = node?.parent ?? []
-    const primaryKeyId = node?.data?.primaryKeyId ?? ''
-    if (primaryKeyId) {
-        newKeys.push(primaryKeyId)
-        await getNodeExpandKeys(parent, newKeys)
-    }
+    emit('nodeTap', {node, data})
 }
 
 //鼠标右键事件
-const contextMenuRef = ref(null)
-const ElTreeLabelContextMenu = (e,data,node) => {
-    const rows = menusData.value || [];
-    if (node.level !== 1 && rows.length > 0) {
+const ElTreeRelationClick = (e,data,node) => {
+    if (node.level !== 1) {
         e.preventDefault();
-        treeRefNode.value = node;
-        treeRefData.value = data;
-        //展开菜单
-        contextMenuRef.value?.showMenu(e)
+        emit('relationTap', {node, data})
     }
 }
 
-//鼠标右键菜单被点击
-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>
@@ -237,26 +163,23 @@ defineExpose({
         pointer-events: none;
         transition: opacity 0.2s;
         opacity: 0;
-        right: 0;
-        background: rgba(255, 255, 255, 0.25);
+        right: 20px;
+        cursor: pointer;
+        background: rgba(255, 255, 255, 0.9);
         border-radius: 2px;
+        padding: 2px 14px;
         .cu-tree-node-popover-menu-icon {
             display: flex;
             align-items: center;
             justify-content: center;
+            color: var(--el-color-primary);
+            cursor: pointer;
         }
     }
-    &:hover {
-        .menu-icon {
-            opacity: 1;
-            pointer-events: all;
-            cursor: context-menu;
-        }
-    }
-    .menu-icon.show {
+    &:hover .menu-icon {
         opacity: 1;
         pointer-events: all;
-        cursor: context-menu;
+        cursor: pointer;
     }
 }
 
@@ -316,4 +239,9 @@ defineExpose({
 .hc-tree-node .el-tree-node__label {
     flex: 1;
 }
+.hc-tree-node.page-division-tree.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content .el-tree-node__label .data-custom-tree-node .label.division {
+    font-size: 22px;
+    font-weight: bold;
+    color: var(--el-color-primary);
+}
 </style>

+ 214 - 0
src/views/data-fill/components/DivisionTree1.vue

@@ -0,0 +1,214 @@
+<template>
+    <ElTree class="hc-tree-node tree-line" ref="ElTreeRef" :props="ElTreeProps" :load="ElTreeLoadNode" lazy highlight-current accordion node-key="primaryKeyId"
+            show-checkbox :default-expanded-keys="defaultExpandedCids" @node-click="ElTreeClick" :indent="0">
+        <template #default="{ node, data }">
+            <div class="data-custom-tree-node" :id="`${idPrefix}${data['primaryKeyId']}`">
+                <div class="label division" :class="node.level === 1?'level-name':node.level">{{ node.label }}</div>
+            </div>
+        </template>
+    </ElTree>
+</template>
+
+<script setup>
+import {ref,nextTick,watch} from "vue";
+import dataFillQuery from '~api/data-fill/query';
+import {isItem,getArrValue,getObjValue} from "vue-utils-plus"
+
+//参数
+const props = defineProps({
+    projectId: {
+        type: [String,Number],
+        default: ''
+    },
+    contractId: {
+        type: [String,Number],
+        default: ''
+    },
+    autoExpandKeys: {
+        type: Array,
+        default: () => ([])
+    },
+    idPrefix: {
+        type: String,
+        default: 'division-tree-'
+    },
+    isAutoClick: {
+        type: Boolean,
+        default: true
+    }
+})
+
+//变量
+const ElTreeRef = ref(null)
+const ElTreeProps = ref({
+    label: 'title',
+    children: 'children',
+    isLeaf: 'notExsitChild'
+})
+const TreeExpandKey = ref(props.autoExpandKeys)
+const projectId = ref(props.projectId);
+const contractId = ref(props.contractId);
+const idPrefix = ref(props.idPrefix);
+
+//监听
+watch(() => [
+    props.autoExpandKeys,
+    props.projectId,
+    props.contractId,
+    props.idPrefix,
+], ([expandKeys, UserProjectId, UserContractId,UserIdPrefix]) => {
+    TreeExpandKey.value = expandKeys
+    projectId.value = UserProjectId
+    contractId.value = UserContractId
+    idPrefix.value = UserIdPrefix
+})
+
+//事件
+const emit = defineEmits(['nodeTap', 'nodeLoading', 'relationTap'])
+
+//树形结构异步加载数据
+const defaultExpandedCids = ref([])
+const ElTreeLoadNode = async (node, resolve) => {
+    let contractIdRelation = '', parentId = '', primaryKeyId = '';
+    if (node.level !== 0) {
+        const nodeData = getObjValue(node?.data);
+        contractIdRelation = nodeData?.contractIdRelation || ''
+        parentId = contractIdRelation ? nodeData?.primaryKeyId : nodeData?.id
+        primaryKeyId = nodeData?.id || ''
+    }
+    //获取数据
+    const {error, code, data} = await dataFillQuery.queryWbsTreeData({
+        contractId: contractId.value || '',
+        contractIdRelation,
+        primaryKeyId,
+        parentId
+    })
+    //处理数据
+    if (!error && code === 200) {
+        let clickKey = '', defaultExpandedArr = [];
+        const keys = TreeExpandKey.value || []
+        const resData = getArrValue(data)
+        if (keys.length > 0) {
+            let lastKey = keys[keys.length-1];
+            for (const item of resData) {
+                //自动展开
+                if (isItem(keys,item?.primaryKeyId)) {
+                    defaultExpandedArr.push(item?.primaryKeyId)
+                }
+                //最后一个,选中点击
+                if (item?.primaryKeyId === lastKey) {
+                    clickKey = item?.primaryKeyId
+                }
+            }
+        } else if (node.level === 0) {
+            defaultExpandedArr.push(resData[0]?.primaryKeyId)
+        }
+        //自动展开
+        defaultExpandedCids.value = defaultExpandedArr
+        if (node.level === 0) {
+            emit('nodeLoading')
+        }
+        resolve(resData)
+        //最后一个,执行点击
+        if (props.isAutoClick && clickKey) {
+            await nextTick(() => {
+                document.getElementById(`${idPrefix.value}${clickKey}`)?.click()
+            })
+        }
+    } else {
+        if (node.level === 0) {
+            emit('nodeLoading')
+        }
+        resolve([])
+    }
+}
+
+//节点被点击
+const ElTreeClick = async (data,node) => {
+    emit('nodeTap', {node, data})
+}
+
+//鼠标右键事件
+const ElTreeRelationClick = (e,data,node) => {
+    if (node.level !== 1) {
+        e.preventDefault();
+        emit('relationTap', {node, data})
+    }
+}
+
+</script>
+
+<style lang="scss" scoped>
+.data-custom-tree-node {
+    position: relative;
+    display: flex;
+    align-items: center;
+    width: 100%;
+    color: var(--ui-TC);
+    .label {
+        flex: auto;
+        font-size: 16px;
+    }
+    .label.level-name {
+        font-size: 18px;
+        font-weight: bold;
+    }
+}
+
+// 树样式
+.tree-line {
+    :deep(.el-tree-node) {
+        position: relative;
+        padding-left: 16px; // 缩进量
+    }
+    :deep(.el-tree-node__children) {
+        padding-left: 16px; // 缩进量
+    }
+    // 竖线
+    :deep(.el-tree-node::before) {
+        content:"";
+        height: 100%;
+        width: 1px;
+        position: absolute;
+        left: -3px;
+        top: -26px;
+        border-width: 1px;
+        border-left: 1px dashed #ccc;
+    }
+    // 当前层最后⼀个节点的竖线⾼度固定
+    :deep(.el-tree-node:last-child::before) {
+        height: 38px; // 可以⾃⼰调节到合适数值
+    }
+    // 横线
+    :deep(.el-tree-node::after) {
+        content:"";
+        width: 24px;
+        height: 20px;
+        position: absolute;
+        left: -3px;
+        top: 12px;
+        border-width: 1px;
+        border-top: 1px dashed #ccc;
+    }
+    // 去掉最顶层的虚线,放最下⾯样式才不会被上⾯的覆盖了
+    & > :deep(.el-tree-node::after) {
+        border-top: none;
+    }
+    & > :deep(.el-tree-node::before) {
+        border-left: none;
+    }
+    // 展开关闭的icon
+    :deep(.el-tree-node__expand-icon) {
+        font-size: 16px;
+        &.is-leaf {
+            color: transparent;
+            font-size: 0px;
+        }
+    }
+}
+</style>
+<style lang="scss">
+.hc-tree-node .el-tree-node__label {
+    flex: 1;
+}
+</style>

+ 5 - 5
src/views/data-fill/components/ListItem.vue

@@ -411,13 +411,15 @@ const uploadData = ref({})
 const uploadClick = (item) => {
     const pkeyIds = item.pkeyId ? item.pkeyId + '' : ''
     if (pkeyIds) {
-        if (isStatus.value !== '3') {
+        if (isStatus.value !== '3' && item.isTableForm) {
             uploadModal.value = true
             uploadData.value = getFormDataInit(item,pkeyIds)
             //获取文件列表
             getBussFileList(pkeyIds)
+        } else if (!item.isTableForm) {
+            window?.$message?.warning('暂无表单数据')
         } else {
-            window?.$message?.success('已上报的资料,不允许上传')
+            window?.$message?.warning('已上报的资料,不允许上传')
         }
     } else {
         window?.$message?.warning('pkeyId为空')
@@ -605,11 +607,9 @@ const renewData = () => {
 //获取表单数据
 const getFormData = () => {
     const formArr = deepClone(formData.value);
-    let xxx = formArr.filter((item) => {
+    return formArr.filter((item) => {
         return (item.pkeyId??'') !== '' && item.isCollapseLoad;
     })
-    console.log(xxx)
-    return xxx
 }
 
 // 暴露出去

+ 24 - 4
src/views/data-fill/division.vue

@@ -36,7 +36,7 @@
                     <HcIcon name="download-2"/>
                     <span>下载导入划分模板</span>
                 </el-button>
-                <el-button type="primary" hc-btn>
+                <el-button type="primary" hc-btn @click="toImportTempClick">
                     <HcIcon name="folder-upload"/>
                     <span>导入划分模板</span>
                 </el-button>
@@ -192,7 +192,7 @@
                         <div class="hc-tree-title-box">未被系统识别:手动关联</div>
                         <div class="hc-tree-bar-box">
                             <el-scrollbar>
-                                <DivisionTree :projectId="projectId" :contractId="contractId" line @nodeTap="wbsElTreeClick"/>
+                                <DivisionTree :projectId="projectId" :contractId="contractId" line @relationTap="ElTreeRelationClick"/>
                             </el-scrollbar>
                         </div>
                     </div>
@@ -221,6 +221,13 @@
             </template>
         </HcDialog>
 
+        <!--替换并关联节点-->
+        <HcDialog :show="relationModal" title="替换并关联节点" widths="47rem" ui="hc-modal-table" @close="relationModal = false">
+            <el-scrollbar>
+                <DivisionTree1 :projectId="projectId" :contractId="contractId" line/>
+            </el-scrollbar>
+        </HcDialog>
+
     </div>
 </template>
 
@@ -229,7 +236,8 @@ import {ref,watch,onMounted} from "vue";
 import {useAppStore} from "~src/store";
 import {useRouter, useRoute} from 'vue-router'
 import WbsTree from "./components/WbsTree.vue"
-import DivisionTree from "./components/WbsTree.vue"
+import DivisionTree from "./components/DivisionTree.vue"
+import DivisionTree1 from "./components/DivisionTree1.vue"
 import HcTreeNode from "./components/HcTreeNode.vue"
 import {isType, getIndex, downloadBlob, deepClone, formValidate} from "vue-utils-plus"
 import {getStoreData, setStoreData} from '~src/utils/storage'
@@ -691,7 +699,12 @@ const sortNodeClick = async () => {
 }
 
 //导入模板
-const importTempModal = ref(true)
+const importTempModal = ref(false)
+const toImportTempClick = () => {
+    importTempModal.value = true
+}
+
+//导入类型
 const importRadio = ref(1)
 const importRadioData = ref([
     {key: 1, name: '路基工程'},
@@ -705,6 +718,13 @@ const importRadioData = ref([
     {key: 9, name: '特大斜拉桥、特大悬索桥'},
 ])
 
+//关联节点
+const ElTreeRelationClick = ({node, data}) => {
+    console.log({node, data})
+    relationModal.value = true
+}
+
+const relationModal = ref(false)
 
 
 

+ 4 - 5
src/views/ledger/components/table-form.vue

@@ -113,7 +113,7 @@ import queryApi from '~api/ledger/query';
 import wbsQueryApi from '~api/data-fill/query';
 import HTableForm from "~src/plugins/HTableForm"
 import DateCalendar from "./dateCalendar/index.vue"
-import {getObjValue, getObjNullValue, isString, getArrValue, isValueNull} from "vue-utils-plus"
+import {getObjValue, getObjNullValue, isString, getArrValue, isValueNull, deepClone} from "vue-utils-plus"
 
 //参数
 const props = defineProps({
@@ -442,10 +442,9 @@ const saveExcelBussData = async () => {
 const getLinkTabIds = () => {
     let {nodeType} = menuItem.value;
     if (nodeType === 7 || nodeType === 11) {
-        const formIndex = formLogIndex.value
-        const formData = formLogDataList.value[formIndex]
-        const linkTabIds = getArrValue(formData?.linkTabIds)
-        if (linkTabIds.length > 0) {
+        const formItem = formLogDataList.value[0];
+        const linkIds = getArrValue(formItem?.linkTabIds)
+        if (linkIds.length > 0) {
             return true
         } else {
             window?.$message?.warning('请先关联工序')