Эх сурвалжийг харах

Merge branch 'v8' of web/for_client into master

huangfh 1 жил өмнө
parent
commit
3bdb360297

+ 0 - 5
src/App.vue

@@ -28,11 +28,6 @@ watch(() => [
 
 
 nextTick(() => {
 nextTick(() => {
     setUserTheme(appStore.getThemeVal, appStore.getColor)
     setUserTheme(appStore.getThemeVal, appStore.getColor)
-    //当屏幕分辨率宽度低于1920时,自动折叠菜单
-    const width = document.body.clientWidth
-    if (width < 1920) {
-        appStore.setCollapse(true)
-    }
     //生产环境下,检测更新
     //生产环境下,检测更新
     if (import.meta.env.PROD && appStore.isSource !== 'app') {
     if (import.meta.env.PROD && appStore.isSource !== 'app') {
         getVersionJsonApi()
         getVersionJsonApi()

+ 1 - 1
src/config/theme.js

@@ -13,7 +13,7 @@ import bg11 from '~src/assets/home/fd8d568edf61d6824a5a2e3e8e4a0ec4.jpg'
 //主题配置
 //主题配置
 export default {
 export default {
     color: [
     color: [
-        { name: 'green', color: '#1ECC95', label: '森绿' }, { name: 'blue', color: '#0081ff', label: '蓝' },
+        { name: 'green', color: '#1ECC95', label: '森绿' }, { name: 'blue', color: '#204DA0', label: '蓝' },
         { name: 'cyan', color: '#37c0fe', label: '天青' }, { name: 'purple', color: '#8044de', label: '姹紫' },
         { name: 'cyan', color: '#37c0fe', label: '天青' }, { name: 'purple', color: '#8044de', label: '姹紫' },
         { name: 'mauve', color: '#b745cb', label: '木槿' }, { name: 'pink', color: '#e03997', label: '桃粉' },
         { name: 'mauve', color: '#b745cb', label: '木槿' }, { name: 'pink', color: '#e03997', label: '桃粉' },
         { name: 'red', color: '#e54d42', label: '嫣红' }, { name: 'orange', color: '#f37b1d', label: '橘橙' },
         { name: 'red', color: '#e54d42', label: '嫣红' }, { name: 'orange', color: '#f37b1d', label: '橘橙' },

+ 156 - 0
src/global/components/hc-new-card/hc-new-card.vue

@@ -0,0 +1,156 @@
+<template>
+    <HcCard class="hc-new-card-box" :class="padding ? 'is-padding' : ''">
+        <template v-if="isSlotHeader || titles || isSlotExtra || extraText">
+            <div class="hc-card-header-box">
+                <div class="hc-card-header">
+                    <div v-if="!isSlotHeader && titles" class="title">{{ titles }}</div>
+                    <slot v-if="isSlotHeader" name="header" />
+                </div>
+                <div v-if="isSlotExtra || extraText" class="hc-card-header-extra">
+                    <div v-if="!isSlotExtra && extraText" class="extra">{{ extraText }}</div>
+                    <slot v-if="isSlotExtra" name="extra" />
+                </div>
+            </div>
+        </template>
+        <div v-if="isSlotSearchBar" class="hc-card-search-bar">
+            <slot name="search" />
+        </div>
+        <div class="hc-card-main">
+            <div class="hc-card-main-body">
+                <template v-if="scrollbar">
+                    <el-scrollbar>
+                        <slot />
+                    </el-scrollbar>
+                </template>
+                <template v-else>
+                    <slot />
+                </template>
+            </div>
+        </div>
+        <div v-if="isSlotAction" class="hc-card-action">
+            <slot name="action" />
+        </div>
+    </HcCard>
+</template>
+
+<script setup>
+import { ref, useSlots, watch } from 'vue'
+const props = defineProps({
+    ui: {
+        type: String,
+        default: '',
+    },
+    title: {
+        type: [String, Number],
+        default: '',
+    },
+    extraText: {
+        type: [String, Number],
+        default: '',
+    },
+    scrollbar: {
+        type: Boolean,
+        default: false,
+    },
+    actionSize: {
+        type: [String, Number],
+        default: 'lg',
+    },
+    idRef: {
+        type: [String, Number],
+        default: '',
+    },
+    bodyUi: {
+        type: String,
+        default: '',
+    },
+    actionUi: {
+        type: String,
+        default: '',
+    },
+    padding: {
+        type: Boolean,
+        default: false,
+    },
+})
+
+const titles = ref(props.title)
+
+//监听
+watch(() => props.title, (val) => {
+    titles.value = val ?? ''
+})
+
+//判断<slot>是否有传值
+const slots = useSlots()
+const isSlotHeader = ref(!!slots.header)
+const isSlotExtra = ref(!!slots.extra)
+const isSlotAction = ref(!!slots.action)
+const isSlotSearchBar = ref(!!slots.search)
+</script>
+
+<style lang="scss">
+.el-card.hc-new-card-box {
+    background: white;
+    --el-card-padding: 10px;
+    .hc-card-main-box {
+        display: flex;
+        flex-direction: column;
+    }
+    .hc-card-header-box {
+        position: relative;
+        display: flex;
+        align-items: center;
+        flex-shrink: 0;
+        height: auto;
+        border-bottom: 1px solid #E9E9E9;
+        margin-bottom: 10px;
+        .hc-card-header {
+            position: relative;
+            flex: 1;
+            display: flex;
+            align-items: center;
+            .title {
+
+            }
+        }
+        .hc-card-header-extra {
+            position: relative;
+            display: flex;
+            align-items: center;
+            margin-left: 24px;
+            .extra {
+
+            }
+        }
+    }
+    .hc-card-search-bar {
+        position: relative;
+        display: flex;
+        align-items: center;
+        flex-shrink: 0;
+        margin-bottom: 10px;
+    }
+    .hc-card-main {
+        position: relative;
+        flex: 1;
+        flex-basis: auto;
+        .hc-card-main-body {
+            position: absolute;
+            inset: 0;
+        }
+    }
+    .hc-card-action {
+        position: relative;
+        flex-shrink: 0;
+    }
+    &.is-padding {
+        .hc-card-header-box {
+            padding-bottom: 8px;
+        }
+        .hc-card-action {
+            padding-top: 8px;
+        }
+    }
+}
+</style>

+ 106 - 0
src/global/components/hc-tab-card/hc-tab-card.vue

@@ -0,0 +1,106 @@
+<template>
+    <HcNewCard :scrollbar="scrollbar" class="hc-tab-card-box">
+        <template #header>
+            <div class="tab-card-header-tabs">
+                <template v-for="item in tabsData" :key="item.key">
+                    <div class="item" :class="item.key === tabsKey ? 'cur' : ''" @click="tabsClick(item)">{{ item.name }}</div>
+                </template>
+            </div>
+        </template>
+        <template v-if="isSlotExtra" #extra>
+            <slot name="extra" />
+        </template>
+        <slot />
+        <template v-if="isSlotAction" #action>
+            <slot name="action" />
+        </template>
+    </HcNewCard>
+</template>
+
+<script setup>
+import { ref, useSlots, watch } from 'vue'
+
+const props = defineProps({
+    tabs: {
+        type: Array,
+        default: () => ([]),
+    },
+    tabKey: {
+        type: [String, Number],
+        default: '1',
+    },
+    scrollbar: {
+        type: Boolean,
+        default: false,
+    },
+})
+
+const emit = defineEmits(['change'])
+
+//判断<slot>是否有传值
+const slots = useSlots()
+const isSlotExtra = ref(!!slots.extra)
+const isSlotAction = ref(!!slots.action)
+
+//监听表头
+const tabsData = ref(props.tabs)
+watch(() => props.tabs, (val) => {
+    tabsData.value = val
+}, { deep: true })
+
+//选项卡
+const tabsKey = ref(props.tabKey)
+watch(() => props.tabKey, (val) => {
+    tabsKey.value = val
+}, { deep: true })
+const tabsClick = (item) => {
+    tabsKey.value = item.key
+    if (item.key !== props.tabKey) {
+        emit('change', item)
+    }
+}
+</script>
+
+<style lang="scss">
+.el-card.hc-tab-card-box {
+    .hc-card-header-box {
+        border-color: #d4d4d4;
+        margin-top: -5px;
+    }
+    .tab-card-header-tabs {
+        position: relative;
+        display: flex;
+        align-items: center;
+        flex: 1;
+        .item {
+            position: relative;
+            height: 38px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            padding: 0 8px;
+            color: #747474;
+            cursor: pointer;
+            border: 1px solid white;
+            border-bottom: 0;
+            transition: .2s;
+        }
+        .item.cur {
+            cursor: default;
+            color: var(--el-color-primary);
+            background: white;
+            border-color: #d4d4d4;
+            &::after {
+                position: absolute;
+                content: '';
+                left: 0;
+                right: 0;
+                bottom: -1px;
+                height: 1px;
+                background: white;
+                z-index: 1;
+            }
+        }
+    }
+}
+</style>

+ 4 - 0
src/global/components/index.js

@@ -5,6 +5,8 @@ import HcTasksUser from './hc-tasks-user/index.vue'
 import HcTableForm from './table-form/index.vue'
 import HcTableForm from './table-form/index.vue'
 import HcUploads from './hc-uploads/index.vue'
 import HcUploads from './hc-uploads/index.vue'
 import HcSmsAuth from './hc-sms-auth/index.vue'
 import HcSmsAuth from './hc-sms-auth/index.vue'
+import HcNewCard from './hc-new-card/hc-new-card.vue'
+import HcTabCard from './hc-tab-card/hc-tab-card.vue'
 
 
 //注册全局组件
 //注册全局组件
 export const setupComponents = (App) => {
 export const setupComponents = (App) => {
@@ -15,4 +17,6 @@ export const setupComponents = (App) => {
     App.component('HcTableForm', HcTableForm)
     App.component('HcTableForm', HcTableForm)
     App.component('HcUploads', HcUploads)
     App.component('HcUploads', HcUploads)
     App.component('HcSmsAuth', HcSmsAuth)
     App.component('HcSmsAuth', HcSmsAuth)
+    App.component('HcNewCard', HcNewCard)
+    App.component('HcTabCard', HcTabCard)
 }
 }

+ 444 - 0
src/layout/index.scss

@@ -0,0 +1,444 @@
+.hc-layout-box {
+    position: relative;
+    height: 100vh;
+    width: 100%;
+    .hc-layout-header {
+        position: relative;
+        display: flex;
+        align-items: center;
+        flex-direction: row;
+        --el-header-padding: 0;
+        --el-header-height: 44px;
+        background: var(--el-color-primary);
+        color: white;
+        .hc-layout-header-logo {
+            position: relative;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            transition: opacity 0.3s;
+            cursor: pointer;
+            height: 100%;
+            box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.4);
+            z-index: 222;
+            #logo-icon {
+                height: 28px;
+                width: 28px;
+                filter: invert(85%) sepia(91%) saturate(0%) hue-rotate(233deg) brightness(114%) contrast(101%)
+            }
+            #logo-name {
+                height: 32px;
+                margin-left: 4px;
+                filter: invert(85%) sepia(91%) saturate(0%) hue-rotate(233deg) brightness(114%) contrast(101%)
+            }
+            &:hover {
+                opacity: .8;
+            }
+        }
+        .header-top-collapse-bar {
+            position: relative;
+            height: 100%;
+            font-size: 20px;
+            display: flex;
+            justify-content: center;
+            align-items: center;
+            padding: 0 10px;
+            cursor: pointer;
+            transition: opacity .2s;
+            &:hover {
+                opacity: 0.7;
+            }
+        }
+        .header-top-menu-bar {
+            position: relative;
+            padding: 0 4px;
+            height: 100%;
+            flex: 1;
+            .el-scrollbar__view {
+                height: 100%;
+            }
+        }
+        .header-content-bar {
+            position: relative;
+            padding: 0 20px;
+            height: 100%;
+            display: flex;
+            align-items: center;
+            .header-icon-bar {
+                position: relative;
+                height: 100%;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                cursor: pointer;
+                font-size: 25px;
+                margin-right: 8px;
+                color: #efefef;
+                transition: color .2s;
+                &:hover {
+                    color: white;
+                }
+            }
+        }
+    }
+    .hc-layout-container {
+        position: relative;
+        .hc-layout-aside {
+            position: relative;
+            color: white;
+            padding: 8px 0;
+            background: var(--el-color-primary);
+        }
+        .hc-layout-main {
+            position: relative;
+            overflow: hidden;
+            height: 100%;
+            --el-main-padding: 0;
+            .hc-router-menu-bar {
+                position: relative;
+                height: 36px;
+                padding: 0 10px;
+                background: white;
+                box-shadow: 0 2px 6px 0 rgba(0, 0, 0, .1);
+                z-index: 222;
+            }
+            .hc-main-page {
+                position: relative;
+                height: calc(100% - 36px);
+                overflow: hidden;
+                .hc-main-body {
+                    position: absolute;
+                    padding: 12px;
+                    inset: 0;
+                }
+            }
+        }
+    }
+}
+
+//左侧菜单
+.hc-layout-box .hc-layout-container .hc-layout-aside .el-menu {
+    --el-menu-bg-color: transparent;
+    --el-menu-text-color: #ffffff;
+    --el-menu-active-color: var(--el-menu-text-color);
+    --el-menu-hover-text-color: var(--el-menu-text-color);
+    --el-menu-hover-bg-color: var(--el-color-primary);
+    --el-menu-item-font-size: 16px;
+    --el-menu-item-height: 48px;
+    border-right: 0;
+    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item,
+    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item-group__title,
+    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
+        white-space: nowrap;
+        padding-left: 0;
+    }
+    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
+        padding-right: 1px;
+        border: 0;
+    }
+    .el-sub-menu__title {
+        padding: 0;
+    }
+    .el-menu-item, .el-sub-menu {
+        min-width: initial;
+        transition: 0.2s;
+        .hc-aside-menu-item {
+            flex: 1;
+            position: relative;
+            padding: 0 20px;
+            display: flex;
+            align-items: center;
+            transition: 0.2s;
+            .menu---item {
+                display: contents;
+            }
+            .hc-menu-icon {
+                position: relative;
+                font-size: 18px;
+                margin-right: 8px;
+                line-height: initial;
+            }
+            .name {
+                flex: 1;
+                width: 0;
+            }
+        }
+    }
+    .el-sub-menu .el-menu .el-menu-item {
+        padding-left: 24px !important;
+        padding-right: 1px;
+        font-size: 14px;
+        height: 46px;
+        line-height: initial;
+        .hc-aside-menu-item .hc-menu-icon {
+            margin-right: 6px;
+            font-size: 14px;
+        }
+    }
+    .el-sub-menu .el-icon {
+        display: none;
+    }
+    .el-sub-menu .el-icon.hc-icon-i {
+        position: relative;
+        display: inline-block;
+        font-size: 16px;
+        right: 15px;
+        top: initial;
+        height: initial;
+        width: initial;
+        margin-top: 0;
+        vertical-align: initial;
+    }
+    .el-sub-menu.is-active > .el-sub-menu__title {
+        background-color: var(--el-color-primary-light-3);
+    }
+    .el-menu-item.is-active {
+        background-color: var(--el-color-primary-dark-2);
+        &::after {
+            content: '';
+            position: absolute;
+            right: 0;
+            top: 0;
+            width: 3px;
+            height: 100%;
+            background-color: white;
+        }
+    }
+    .el-sub-menu .el-sub-menu__title:hover,
+    .el-menu-item:not(.is-active):hover {
+        background-color: var(--el-color-primary-dark-2);
+    }
+    //折叠状态
+    &.el-menu--collapse {
+        margin-left: 0;
+        width: 90px;
+        .el-sub-menu__title {
+            height: inherit;
+            line-height: initial;
+            width: 90px;
+            justify-content: center;
+            transition: 0.2s;
+        }
+        .el-menu-item, .el-sub-menu {
+            padding: 0 !important;
+            height: 60px;
+            line-height: initial;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            width: 90px;
+            transition: 0.2s;
+            .hc-aside-menu-item {
+                display: inline-flex;
+                align-items: center;
+                justify-content: center;
+                width: 60px;
+                height: 60px;
+                text-align: center;
+                border-radius: 10px;
+                padding: 5px;
+                flex: initial;
+                transition: 0.2s;
+                .menu---item {
+                    position: relative;
+                    display: block;
+                }
+                .hc-menu-icon {
+                    margin-right: 0;
+                }
+                .name {
+                    flex: initial;
+                    width: 100%;
+                }
+                .el-badge, .el-badge .el-badge__content {
+                    vertical-align: initial;
+                }
+                .el-badge {
+                    position: absolute;
+                    top: -20px;
+                    right: -24px;
+                }
+            }
+        }
+        .el-sub-menu .el-icon.hc-icon-i {
+            display: none;
+        }
+        .el-menu-item + .el-menu-item,
+        .el-menu-item + .el-sub-menu,
+        .el-sub-menu + .el-menu-item,
+        .el-sub-menu + .el-sub-menu {
+            margin-top: 12px;
+        }
+        .el-sub-menu.is-active > .el-sub-menu__title {
+            background-color: initial;
+        }
+        .el-menu-item.is-active {
+            background-color: initial;
+        }
+        .el-sub-menu .el-sub-menu__title:hover,
+        .el-menu-item:not(.is-active):hover {
+            background-color: initial;
+        }
+        .el-sub-menu:not(.is-active):hover,
+        .el-menu-item:not(.is-active):hover {
+            .hc-aside-menu-item {
+                background-color: var(--el-color-primary-light-9);
+                color: var(--el-color-primary);
+            }
+        }
+        .el-menu-item.is-active, .el-sub-menu.is-active {
+            .hc-aside-menu-item {
+                color: #ffffff !important;
+                background: var(--el-color-primary-dark-2);
+            }
+        }
+    }
+}
+
+//菜单路由
+.hc-layout-box .hc-layout-container .hc-layout-main .hc-router-menu-bar {
+    .el-scrollbar__view {
+        height: 100%;
+    }
+    .hc-router-tab-item {
+        position: relative;
+        height: 100%;
+        padding: 0 8px;
+        display: inline-flex;
+        align-items: center;
+        cursor: pointer;
+        color: #8F8F8F;
+        user-select: none;
+        transition: .3s;
+        .close-icon {
+            height: 30px;
+            width: 18px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            margin-left: 6px;
+            font-size: 16px;
+            cursor: pointer;
+            transition: color 0.3s;
+            &:hover {
+                color: var(--el-color-primary);
+            }
+        }
+        &::after{
+            content: '';
+            left: 0;
+            bottom: 0;
+            height: 2.5px;
+            width: 100%;
+            position: absolute;
+            background-size: 200%;
+        }
+        &:hover:not([class*='cur']) {
+            color: var(--el-color-primary);
+        }
+        &.cur {
+            color: var(--el-color-primary-dark-2);
+            &::after {
+                background: linear-gradient(to right, var(--el-color-primary-light-5), var(--el-color-primary), var(--el-color-primary-dark-2));
+            }
+        }
+    }
+    .el-scrollbar__bar.is-horizontal {
+        bottom: -10px;
+    }
+    .el-scrollbar__bar.is-vertical {
+        display: none;
+    }
+}
+
+
+.aside-menu-popper.el-popper.is-light {
+    background: initial !important;
+    border: 0 !important;
+    outline: none;
+}
+.aside-menu-popper.el-popper .el-menu--vertical .el-menu {
+    --el-menu-bg-color: #f1f5f8;
+    --el-menu-text-color: #838791;
+    --el-menu-active-color: #ffffff;
+    --el-menu-hover-bg-color: initial;
+    --el-menu-item-font-size: 16px;
+    background-color: #f1f5f8;
+    color: #838791;
+    .el-sub-menu__title {
+        padding: 0;
+        justify-content: center;
+        transition: 0.2s;
+    }
+    .el-menu-item, .el-sub-menu {
+        color: inherit;
+        padding: 0;
+        transition: 0.2s;
+        .hc-aside-menu-item {
+            flex: 1;
+            position: relative;
+            padding: 0 16px;
+            display: flex;
+            align-items: center;
+            transition: 0.2s;
+            .menu---item {
+                display: contents;
+            }
+            .hc-menu-icon {
+                font-size: 22px;
+                margin-right: 10px;
+                line-height: initial;
+            }
+            .name {
+                flex: 1;
+                width: 0;
+            }
+            .el-badge, .el-badge .el-badge__content {
+                vertical-align: initial;
+            }
+        }
+        &.is-active {
+            color: white;
+        }
+    }
+    .el-sub-menu .el-icon {
+        display: none;
+    }
+    .el-sub-menu .el-icon.hc-icon-i {
+        position: relative;
+        display: inline-block;
+        font-size: 16px;
+        right: 10px;
+        top: initial;
+        height: initial;
+        width: initial;
+        margin-top: 0;
+        vertical-align: initial;
+    }
+    .el-sub-menu:not(.is-active) .el-sub-menu__title:hover {
+        background-color: var(--el-color-primary-light-9);
+        color: var(--el-color-primary);
+    }
+    .el-menu-item:not(.is-active):hover {
+        .hc-aside-menu-item {
+            background-color: var(--el-color-primary-light-9);
+            color: var(--el-color-primary);
+        }
+    }
+    .el-menu-item.is-active {
+        .hc-aside-menu-item {
+            background-color: var(--el-color-primary);
+        }
+    }
+    .el-sub-menu.is-active .el-sub-menu__title {
+        background-color: var(--el-color-primary-light-9);
+        color: var(--el-color-primary);
+    }
+}
+
+.aside-menu-popper.el-popper .el-menu--vertical.home-index .el-menu {
+    --el-menu-bg-color: initial;
+    --el-menu-text-color: initial;
+    color: white;
+    background-color: var(--el-color-primary-dark-2);
+}

+ 92 - 344
src/layout/index.vue

@@ -1,292 +1,115 @@
 <template>
 <template>
     <el-container class="hc-layout-box">
     <el-container class="hc-layout-box">
-        <div v-show="MenuBarKey === 'home-index'" class="hc-layout-bg-box">
-            <img v-if="HomeTheme.bg" id="imagebox" :src="HomeTheme.bg" alt="" crossOrigin="anonymous">
-        </div>
-        <el-aside
-            :class="[isCollapse ? 'is-collapse' : '', MenuBarKey]" :width="isCollapse ? '90px' : '250px'"
-            class="hc-aside-box"
-        >
-            <div class="hc-aside-logo-box" @click="logoClick">
+        <el-header class="hc-layout-header">
+            <div class="hc-layout-header-logo" :style="`width: ${isCollapse ? '90px' : '200px'};`" @click="logoClick">
                 <img id="logo-icon" :src="appLogoIcon" alt="">
                 <img id="logo-icon" :src="appLogoIcon" alt="">
                 <img v-show="!isCollapse" id="logo-name" :src="appLogoName" alt="">
                 <img v-show="!isCollapse" id="logo-name" :src="appLogoName" alt="">
             </div>
             </div>
-            <div class="hc-aside-menu-box">
-                <el-scrollbar>
-                    <MenuBar
-                        :collapse="isCollapse" :cur="MenuBarKey" :datas="MenuBarData" :msg-count="msgCount"
-                        @change="MenuBarChange"
-                    />
-                </el-scrollbar>
+            <div class="header-top-collapse-bar" @click="collapseChange">
+                <HcIcon v-if="isCollapse" name="menu-unfold" />
+                <HcIcon v-else name="menu-fold" />
             </div>
             </div>
-            <div class="hc-aside-bar-box">
-                <div :class="isCollapse ? '' : 'active'" @click="collapseChange(false)">
-                    <HcIcon name="menu-unfold" />
-                </div>
-                <div v-show="!isCollapse" :class="isCollapse ? 'active' : ''" @click="collapseChange(true)">
-                    <HcIcon name="menu-fold" />
-                </div>
+            <div class="header-top-menu-bar">
+                <HcTopMenuBar @load="topMenuLoad" @change="topMenuChange" />
             </div>
             </div>
-        </el-aside>
-        <el-container :class="MenuBarKey === 'home-index' ? 'home' : ''" class="hc-container-view">
-            <el-header class="hc-header-view">
-                <div id="hc-header-page-name" class="hc-header-page-name">
-                    {{ RoutesTitle }}
-                </div>
-                <div class="hc-header-top-menu-bar">
-                    <TopMenuBar />
+            <div class="header-content-bar">
+                <HcCascader @send="cascaderSend" @change="cascaderChange" />
+                <HelpInfoBar />
+                <ConfigBar />
+                <UserInfoBar @load="userInfoLoad" />
+            </div>
+        </el-header>
+        <el-container class="hc-layout-container">
+            <el-aside v-if="isAsideMenu" class="hc-layout-aside" :class="[isCollapse ? 'is-collapse' : '']" :width="isCollapse ? '90px' : '200px'">
+                <MenuBar :collapse="isCollapse" :cur="menuBarKey" :datas="menuBarData" :msg-count="msgCount" @change="menuBarChange" />
+            </el-aside>
+            <el-main class="hc-layout-main">
+                <div class="hc-router-menu-bar">
+                    <RouterMenu @load="routerMenuLoad" />
                 </div>
                 </div>
-                <div class="hc-header-content">
-                    <div class="hc-header-cascader-box">
-                        <div class="project-name-box">
-                            {{ projectInfo.projectAlias }} / {{ contractInfo.name }}
-                        </div>
-                        <el-cascader
-                            ref="ElCascaderRef" v-model="projectValue"
-                            :clearable="userInfo?.role_id === '1123598816738675201'"
-                            :filterable="userInfo?.role_id === '1123598816738675201'"
-                            :options="projectContract"
-                            :props="projectProps" placeholder="请选择项目"
-                            @change="projectContractChange"
-                        />
+                <div id="hc-main-box" class="hc-main-page">
+                    <div class="hc-main-body">
+                        <router-view v-if="reloadRouter" v-slot="{ Component }">
+                            <transition name="fade-transform">
+                                <keep-alive :max="10">
+                                    <component :is="Component" :msg-count="msgCount" />
+                                </keep-alive>
+                            </transition>
+                        </router-view>
                     </div>
                     </div>
-                    <HelpInfoBar />
-                    <ConfigBar />
-                    <UserInfoBar />
                 </div>
                 </div>
-            </el-header>
-            <el-main id="hc-main-box" class="hc-main-box">
-                <router-view v-if="reloadRouter" v-slot="{ Component }">
-                    <transition name="fade-transform">
-                        <keep-alive :max="10" exclude="home,home-index,home-config,other-file-view,other-file-form">
-                            <component :is="Component" :msg-count="msgCount" />
-                        </keep-alive>
-                    </transition>
-                </router-view>
             </el-main>
             </el-main>
         </el-container>
         </el-container>
     </el-container>
     </el-container>
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { nextTick, onMounted, ref, watch } from 'vue'
-import { useRoute, useRouter } from 'vue-router'
+import { nextTick, onMounted, ref } from 'vue'
 import { useAppStore } from '~src/store'
 import { useAppStore } from '~src/store'
-import MenuBar from './modules/MenuBar.vue'
-import HelpInfoBar from './modules/HelpInfoBar.vue'
-import UserInfoBar from './modules/UserInfoBar.vue'
-import ConfigBar from './modules/ConfigBar.vue'
-import TopMenuBar from './modules/TopMenuBar.vue'
-import { initButtons, initProjectContract } from '~sto/app'
-import website from '~src/config/index'
-import { setImageColorStyle } from 'js-fast-way'
-import { setAppName } from '~uti/tools'
+import { useRouter } from 'vue-router'
+import { initButtons } from '~sto/app'
+import HcSocket from '~src/plugins/HcSocket'
+import { getObjValue, isNullES } from 'js-fast-way'
 
 
 //初始组合式
 //初始组合式
 const router = useRouter()
 const router = useRouter()
-const useRoutes = useRoute()
-const useAppState = useAppStore()
+const store = useAppStore()
 
 
-//路由参数
-const routerQuery = useRoutes?.query
 const reloadRouter = ref(true)
 const reloadRouter = ref(true)
-const BarMenuKey = useRoutes?.name ?? 'home-index'
-const BarMenuTitle = useRoutes?.meta?.title ?? ''
-
-//系统信息
-const appTitle = ref(useAppState.getTitle)
-const appLogoIcon = ref(useAppState.getLogoIcon)
-const appLogoName = ref(useAppState.getLogoName)
-
-//主题和色调变量
-const HomeTheme = ref(useAppState.getHomeTheme)
-const AppColor = ref(useAppState.getColor)
 
 
+//子组件
+import HcTopMenuBar from './modules/HcTopMenu.vue'
+import HcCascader from './modules/Cascader.vue'
+import UserInfoBar from './modules/UserInfoBar.vue'
+import HelpInfoBar from './modules/HelpInfoBar.vue'
+import ConfigBar from './modules/ConfigBar.vue'
+import RouterMenu from './modules/RouterMenu.vue'
+import MenuBar from '~src/layout/modules/MenuBar.vue'
 
 
-//顶部菜单数据和相关处理
-const MenuBarKey = ref(BarMenuKey)
-const RoutesName = ref(BarMenuKey)
-const RoutesTitle = ref(BarMenuTitle)
-const MenuBarData = ref(useAppState.getMenus)
-const isCollapse = ref(useAppState.getCollapse)
-const userInfo = ref(useAppState.getUserInfo)
+// logo
+const appLogoIcon = ref(store.getLogoIcon)
+const appLogoName = ref(store.getLogoName)
 
 
-//项目合同段
-const projectInfo = ref({})
-const contractInfo = ref({})
-const projectContract = ref([])
-const projectValue = ref(null)
-const projectProps = ref({
-    value: 'id',
-    label: 'projectAlias',
-    children: 'contractInfoList',
-})
+//菜单数据
+const menuBarKey = ref('')
+const menuBarData = ref([])
 
 
 //渲染完成
 //渲染完成
 onMounted(() => {
 onMounted(() => {
     initButtons()
     initButtons()
-    initProjectContract()
-    const info = useAppState.getProjectContract || []
-    projectContractData(info)
-    useAppState.barMenuName = BarMenuTitle
-    setIsCollapse(RoutesName.value)
-    setInitSocket()
-    setLogoImageColor()
-    setLogoNameColor(useAppState.getTheme)
-})
-
-//监听
-watch(() => [
-    useAppState.getProjectContract,
-    useAppState.getMenus,
-    useAppState.getHomeTheme,
-    useRoutes?.name,
-    useRoutes?.meta?.title,
-    useAppState.getCollapse,
-], ([projectContractArr, userMenus, theme, RouteName, RouteTitle, collapse]) => {
-    HomeTheme.value = theme
-    MenuBarData.value = userMenus
-    RoutesName.value = RouteName ?? 'home-index'
-    MenuBarKey.value = RouteName ?? 'home-index'
-    RoutesTitle.value = RouteTitle ?? ''
-    isCollapse.value = collapse
-    setIsCollapse(RoutesName.value)
-    projectContractData(projectContractArr || [])
-    useAppState.barMenuName = RouteTitle ?? ''
-    setAppName(appTitle.value)
-})
-
-//监听
-watch(() => [
-    useAppState.getTitle,
-    useAppState.getLogoIcon,
-    useAppState.getLogoName,
-    useAppState.getColor,
-], ([Title, LogoIcon, LogoName, ColorVal]) => {
-    appTitle.value = Title
-    appLogoIcon.value = LogoIcon
-    appLogoName.value = LogoName
-    AppColor.value = ColorVal
-    setLogoImageColor()
 })
 })
 
 
-//设置Logo图片颜色
-const setLogoImageColor = () => {
-    setImageColorStyle('logo-icon', AppColor.value?.color)
+//路由信息
+const routerMenuLoad = ({ key }) => {
+    menuBarKey.value = key
 }
 }
 
 
-const setLogoNameColor = (theme) => {
-    try {
-        let filter = 'invert(85%) sepia(91%) saturate(0%) hue-rotate(233deg) brightness(114%) contrast(101%)'
-        if (theme === 'light') {
-            filter = 'invert(0%) sepia(100%) saturate(0%) hue-rotate(235deg) brightness(107%) contrast(103%)'
-        }
-        document.getElementById('logo-name').style.filter = filter
-    } catch {
-    }
-}
-
-//设置折叠
-const setIsCollapse = (key) => {
-    if (key === 'data-fill-wbs') {
-        isCollapse.value = true
-        useAppState.setCollapse(true)
-    }
-}
-
-//是否折叠
-const collapseChange = (bool) => {
+// 是否折叠
+const isCollapse = ref(false)
+const collapseChange = () => {
+    const bool = !isCollapse.value
     isCollapse.value = bool
     isCollapse.value = bool
-    useAppState.setCollapse(bool)
+    store.setCollapse(bool)
 }
 }
 
 
-//处理项目合同段数据
-const projectContractData = (projectContractData) => {
-    if (projectContractData.length > 0) {
-        //处理别名
-        projectContractData.forEach(item => {
-            let contractArr = item['contractInfoList'] || []
-            contractArr.forEach(items => {
-                items['projectAlias'] = items['name']
-            })
-        })
-        //处理其他数据
-        projectContract.value = projectContractData
-        const projectId = useAppState.getProjectId //项目ID
-        const contractId = useAppState.getContractId //合同段ID
-        const UserProjectInfo = useAppState.getProjectInfo
-        const UserContractInfo = useAppState.getContractInfo
-        //查询缓存的选中ID是否存在
-        const pid = projectContractData.findIndex(item => Number(item.id) === Number(projectId))
-        const contractList = projectContractData[pid]?.contractInfoList || []
-        const cid = contractList.findIndex(item => Number(item.id) === Number(contractId))
-        //如果缓存的选中ID不存在
-        if (cid === -1) {
-            //取项目数组中的第一个数据
-            let letProjectInfo = projectContractData[0]
-            let contractInfoList = letProjectInfo?.contractInfoList || []
-            let letContractInfo = contractInfoList[0] || {}
-            projectValue.value = letContractInfo?.id
-            projectInfo.value = letProjectInfo
-            contractInfo.value = letContractInfo
-            //设置缓存
-            useAppState.setProjectInfo(letProjectInfo)
-            useAppState.setContractInfo(letContractInfo)
-            useAppState.setProjectId(letProjectInfo?.id)
-            useAppState.setContractId(letContractInfo?.id)
-            //发送消息
-            socketSend(letProjectInfo?.id + ',' + letContractInfo?.id)
-        } else {
-            projectValue.value = String(contractId)
-            projectInfo.value = UserProjectInfo
-            contractInfo.value = UserContractInfo
-            //发送消息
-            socketSend(projectId + ',' + contractId)
-        }
-    } else {
-        projectContract.value = []
-        projectValue.value = null
-        projectInfo.value = {}
-        contractInfo.value = {}
-    }
+//顶部菜单导航
+const isAsideMenu = ref(true)
+const topMenuLoad = () => {
+    isAsideMenu.value = false
 }
 }
 
 
-//项目被选择
-const ElCascaderRef = ref(null)
-const projectContractChange = (val) => {
-    if (val) {
-        const Nodes = ElCascaderRef.value.getCheckedNodes()
-        const UserProjectInfo = Nodes[0].parent.data
-        const UserContractInfo = Nodes[0].data
-        //缓存项目数据
-        useAppState.setProjectId(val[0])
-        useAppState.setContractId(val[1])
-        useAppState.setProjectInfo(UserProjectInfo)
-        useAppState.setContractInfo(UserContractInfo)
-        //更改界面更新
-        projectInfo.value = UserProjectInfo
-        contractInfo.value = UserContractInfo
-        window.$message?.info('切换了项目,数据更新中')
-        //发送消息
-        socketSend(val[0] + ',' + val[1])
-        //刷新路由
-        reloadRouter.value = false
-        nextTick(() => {
-            reloadRouter.value = true
-        })
+//顶部菜单导航被点击
+const topMenuChange = (data) => {
+    if (!isNullES(data)) {
+        menuBarData.value = data
+        isAsideMenu.value = true
     }
     }
 }
 }
 
 
 //菜单被点击
 //菜单被点击
-const MenuBarChange = (item) => {
-    MenuBarKey.value = item?.code
-    setIsCollapse(item?.code)
-    router.push({ name: item?.code })
-}
-
-//首页
-const logoClick = () => {
-    router.push({ name: 'home-index' })
+const menuBarChange = ({ code }) => {
+    menuBarKey.value = code
+    router.push({ name: code })
 }
 }
 
 
 //消息数量
 //消息数量
@@ -301,107 +124,32 @@ const msgCount = ref({
     messageCount_5: 0,
     messageCount_5: 0,
 })
 })
 
 
-//推送系统
-let socket
-const setInitSocket = () => {
-    const user_id = userInfo.value.user_id
-    socket = new WebSocket(website.socket + user_id)
-    try {
-        socket.onopen = function (evt) {
-            console.log('websocket链接成功')
-        }
-        socket.onclose = function (evt) {
-            console.log('websocket连接已断开')
-        }
-        socket.onmessage = function ({ data }) {
-            if (data) {
-                msgCount.value = JSON.parse(data)
-            }
-            console.log(data, '消息信息')
-        }
-        socket.onerror = function ({ data }) {
-            console.log('发生错误:', data)
-        }
-    } catch {
-    }
+//用户信息
+const userInfoLoad = ({ user_id }) => {
+    HcSocket.create(user_id, (data) => {
+        msgCount.value = getObjValue(data)
+    })
 }
 }
 
 
-//发送消息
-const socketSend = (msg) => {
-    try {
-        if (socket) {
-            socket.send(msg)
-        } else {
-            setTimeout(() => {
-                socket.send(msg)
-            }, 1000)
-        }
-    } catch {
-    }
+//项目合同段的ID
+const cascaderSend = ({ projectId, contractId }) => {
+    HcSocket.send(projectId + ',' + contractId)
 }
 }
-</script>
 
 
-<style lang="scss" scoped>
-@import "./layout.scss";
-</style>
+// 项目切换
+const cascaderChange = () => {
+    reloadRouter.value = false
+    nextTick(() => {
+        reloadRouter.value = true
+    })
+}
 
 
-<style lang="scss">
-.hc-layout-box .hc-container-view {
-    .hc-header-view .hc-header-content .hc-header-cascader-box {
-        .el-cascader {
-            width: 100%;
-        }
-        .el-cascader .el-input .el-input__wrapper {
-            padding: 4px 15px;
-            border: 1px solid #00000000;
-            border-radius: 100px;
-            background: #f1f5f8;
-            color: #202532;
-            box-shadow: var(--hc-shadow);
-            .el-input__inner, .el-input__suffix {
-                color: #202532;
-            }
-        }
-        .el-cascader .el-input.is-focus .el-input__wrapper {
-            box-shadow: 4px 4px 8px 0 rgba(54, 92, 167, 0.15), -4px -4px 8px 0px #ffffff;
-        }
-        .el-cascader .el-input .icon-arrow-down {
-            font-size: 18px;
-            font-weight: bold;
-        }
-    }
-    &.home {
-        .hc-header-view .hc-header-content .hc-header-cascader-box {
-            .el-cascader .el-input .el-input__wrapper {
-                background-color: #00000000;
-                border: 1px solid white;
-                box-shadow: initial;
-                .el-input__inner, .el-input__suffix {
-                    color: white;
-                }
-            }
-            .el-cascader .el-input.is-focus .el-input__wrapper {
-                box-shadow: initial;
-            }
-        }
-        .hc-header-view .hc-header-top-menu-bar {
-            padding-left: 0;
-            .hc-top-menu-bar .bar-menu-content .bar-menu-btn {
-                background: rgba(255, 255, 255, .2);
-                border-color: rgba(255, 255, 255, .2);
-                color: rgba(255, 255, 255, .7);
-                backdrop-filter: blur(20px);
-                -webkit-backdrop-filter: blur(20px);
-                &:hover:not([class*='cur']) {
-                    background: var(--el-color-primary-light-9);
-                    color: #838791;
-                }
-                &:active:not([class*='cur']) {
-                    background: var(--el-color-primary-light-8);
-                    color: #838791;
-                }
-            }
-        }
-    }
+//首页
+const logoClick = () => {
+    router.push({ name: 'home-index' })
 }
 }
+</script>
+
+<style lang="scss">
+@import "./index.scss";
 </style>
 </style>

+ 407 - 0
src/layout/index_bak.vue

@@ -0,0 +1,407 @@
+<template>
+    <el-container class="hc-layout-box">
+        <div v-show="MenuBarKey === 'home-index'" class="hc-layout-bg-box">
+            <img v-if="HomeTheme.bg" id="imagebox" :src="HomeTheme.bg" alt="" crossOrigin="anonymous">
+        </div>
+        <el-aside
+            :class="[isCollapse ? 'is-collapse' : '', MenuBarKey]" :width="isCollapse ? '90px' : '250px'"
+            class="hc-aside-box"
+        >
+            <div class="hc-aside-logo-box" @click="logoClick">
+                <img id="logo-icon" :src="appLogoIcon" alt="">
+                <img v-show="!isCollapse" id="logo-name" :src="appLogoName" alt="">
+            </div>
+            <div class="hc-aside-menu-box">
+                <el-scrollbar>
+                    <MenuBar
+                        :collapse="isCollapse" :cur="MenuBarKey" :datas="MenuBarData" :msg-count="msgCount"
+                        @change="MenuBarChange"
+                    />
+                </el-scrollbar>
+            </div>
+            <div class="hc-aside-bar-box">
+                <div :class="isCollapse ? '' : 'active'" @click="collapseChange(false)">
+                    <HcIcon name="menu-unfold" />
+                </div>
+                <div v-show="!isCollapse" :class="isCollapse ? 'active' : ''" @click="collapseChange(true)">
+                    <HcIcon name="menu-fold" />
+                </div>
+            </div>
+        </el-aside>
+        <el-container :class="MenuBarKey === 'home-index' ? 'home' : ''" class="hc-container-view">
+            <el-header class="hc-header-view">
+                <div id="hc-header-page-name" class="hc-header-page-name">
+                    {{ RoutesTitle }}
+                </div>
+                <div class="hc-header-top-menu-bar">
+                    <TopMenuBar />
+                </div>
+                <div class="hc-header-content">
+                    <div class="hc-header-cascader-box">
+                        <div class="project-name-box">
+                            {{ projectInfo.projectAlias }} / {{ contractInfo.name }}
+                        </div>
+                        <el-cascader
+                            ref="ElCascaderRef" v-model="projectValue"
+                            :clearable="userInfo?.role_id === '1123598816738675201'"
+                            :filterable="userInfo?.role_id === '1123598816738675201'"
+                            :options="projectContract"
+                            :props="projectProps" placeholder="请选择项目"
+                            @change="projectContractChange"
+                        />
+                    </div>
+                    <HelpInfoBar />
+                    <ConfigBar />
+                    <UserInfoBar />
+                </div>
+            </el-header>
+            <el-main id="hc-main-box" class="hc-main-box">
+                <router-view v-if="reloadRouter" v-slot="{ Component }">
+                    <transition name="fade-transform">
+                        <keep-alive :max="10" exclude="home,home-index,home-config,other-file-view,other-file-form">
+                            <component :is="Component" :msg-count="msgCount" />
+                        </keep-alive>
+                    </transition>
+                </router-view>
+            </el-main>
+        </el-container>
+    </el-container>
+</template>
+
+<script setup>
+import { nextTick, onMounted, ref, watch } from 'vue'
+import { useRoute, useRouter } from 'vue-router'
+import { useAppStore } from '~src/store'
+import MenuBar from './modules/MenuBar.vue'
+import HelpInfoBar from './modules/HelpInfoBar.vue'
+import UserInfoBar from './modules/UserInfoBar.vue'
+import ConfigBar from './modules/ConfigBar.vue'
+import TopMenuBar from './modules/TopMenuBar.vue'
+import { initButtons, initProjectContract } from '~sto/app'
+import website from '~src/config/index'
+import { setImageColorStyle } from 'js-fast-way'
+import { setAppName } from '~uti/tools'
+
+//初始组合式
+const router = useRouter()
+const useRoutes = useRoute()
+const useAppState = useAppStore()
+
+//路由参数
+const routerQuery = useRoutes?.query
+const reloadRouter = ref(true)
+const BarMenuKey = useRoutes?.name ?? 'home-index'
+const BarMenuTitle = useRoutes?.meta?.title ?? ''
+
+//系统信息
+const appTitle = ref(useAppState.getTitle)
+const appLogoIcon = ref(useAppState.getLogoIcon)
+const appLogoName = ref(useAppState.getLogoName)
+
+//主题和色调变量
+const HomeTheme = ref(useAppState.getHomeTheme)
+const AppColor = ref(useAppState.getColor)
+
+
+//顶部菜单数据和相关处理
+const MenuBarKey = ref(BarMenuKey)
+const RoutesName = ref(BarMenuKey)
+const RoutesTitle = ref(BarMenuTitle)
+const MenuBarData = ref(useAppState.getMenus)
+const isCollapse = ref(useAppState.getCollapse)
+const userInfo = ref(useAppState.getUserInfo)
+
+//项目合同段
+const projectInfo = ref({})
+const contractInfo = ref({})
+const projectContract = ref([])
+const projectValue = ref(null)
+const projectProps = ref({
+    value: 'id',
+    label: 'projectAlias',
+    children: 'contractInfoList',
+})
+
+//渲染完成
+onMounted(() => {
+    initButtons()
+    initProjectContract()
+    const info = useAppState.getProjectContract || []
+    projectContractData(info)
+    useAppState.barMenuName = BarMenuTitle
+    setIsCollapse(RoutesName.value)
+    setInitSocket()
+    setLogoImageColor()
+    setLogoNameColor(useAppState.getTheme)
+})
+
+//监听
+watch(() => [
+    useAppState.getProjectContract,
+    useAppState.getMenus,
+    useAppState.getHomeTheme,
+    useRoutes?.name,
+    useRoutes?.meta?.title,
+    useAppState.getCollapse,
+], ([projectContractArr, userMenus, theme, RouteName, RouteTitle, collapse]) => {
+    HomeTheme.value = theme
+    MenuBarData.value = userMenus
+    RoutesName.value = RouteName ?? 'home-index'
+    MenuBarKey.value = RouteName ?? 'home-index'
+    RoutesTitle.value = RouteTitle ?? ''
+    isCollapse.value = collapse
+    setIsCollapse(RoutesName.value)
+    projectContractData(projectContractArr || [])
+    useAppState.barMenuName = RouteTitle ?? ''
+    setAppName(appTitle.value)
+})
+
+//监听
+watch(() => [
+    useAppState.getTitle,
+    useAppState.getLogoIcon,
+    useAppState.getLogoName,
+    useAppState.getColor,
+], ([Title, LogoIcon, LogoName, ColorVal]) => {
+    appTitle.value = Title
+    appLogoIcon.value = LogoIcon
+    appLogoName.value = LogoName
+    AppColor.value = ColorVal
+    setLogoImageColor()
+})
+
+//设置Logo图片颜色
+const setLogoImageColor = () => {
+    setImageColorStyle('logo-icon', AppColor.value?.color)
+}
+
+const setLogoNameColor = (theme) => {
+    try {
+        let filter = 'invert(85%) sepia(91%) saturate(0%) hue-rotate(233deg) brightness(114%) contrast(101%)'
+        if (theme === 'light') {
+            filter = 'invert(0%) sepia(100%) saturate(0%) hue-rotate(235deg) brightness(107%) contrast(103%)'
+        }
+        document.getElementById('logo-name').style.filter = filter
+    } catch {
+    }
+}
+
+//设置折叠
+const setIsCollapse = (key) => {
+    if (key === 'data-fill-wbs') {
+        isCollapse.value = true
+        useAppState.setCollapse(true)
+    }
+}
+
+//是否折叠
+const collapseChange = (bool) => {
+    isCollapse.value = bool
+    useAppState.setCollapse(bool)
+}
+
+//处理项目合同段数据
+const projectContractData = (projectContractData) => {
+    if (projectContractData.length > 0) {
+        //处理别名
+        projectContractData.forEach(item => {
+            let contractArr = item['contractInfoList'] || []
+            contractArr.forEach(items => {
+                items['projectAlias'] = items['name']
+            })
+        })
+        //处理其他数据
+        projectContract.value = projectContractData
+        const projectId = useAppState.getProjectId //项目ID
+        const contractId = useAppState.getContractId //合同段ID
+        const UserProjectInfo = useAppState.getProjectInfo
+        const UserContractInfo = useAppState.getContractInfo
+        //查询缓存的选中ID是否存在
+        const pid = projectContractData.findIndex(item => Number(item.id) === Number(projectId))
+        const contractList = projectContractData[pid]?.contractInfoList || []
+        const cid = contractList.findIndex(item => Number(item.id) === Number(contractId))
+        //如果缓存的选中ID不存在
+        if (cid === -1) {
+            //取项目数组中的第一个数据
+            let letProjectInfo = projectContractData[0]
+            let contractInfoList = letProjectInfo?.contractInfoList || []
+            let letContractInfo = contractInfoList[0] || {}
+            projectValue.value = letContractInfo?.id
+            projectInfo.value = letProjectInfo
+            contractInfo.value = letContractInfo
+            //设置缓存
+            useAppState.setProjectInfo(letProjectInfo)
+            useAppState.setContractInfo(letContractInfo)
+            useAppState.setProjectId(letProjectInfo?.id)
+            useAppState.setContractId(letContractInfo?.id)
+            //发送消息
+            socketSend(letProjectInfo?.id + ',' + letContractInfo?.id)
+        } else {
+            projectValue.value = String(contractId)
+            projectInfo.value = UserProjectInfo
+            contractInfo.value = UserContractInfo
+            //发送消息
+            socketSend(projectId + ',' + contractId)
+        }
+    } else {
+        projectContract.value = []
+        projectValue.value = null
+        projectInfo.value = {}
+        contractInfo.value = {}
+    }
+}
+
+//项目被选择
+const ElCascaderRef = ref(null)
+const projectContractChange = (val) => {
+    if (val) {
+        const Nodes = ElCascaderRef.value.getCheckedNodes()
+        const UserProjectInfo = Nodes[0].parent.data
+        const UserContractInfo = Nodes[0].data
+        //缓存项目数据
+        useAppState.setProjectId(val[0])
+        useAppState.setContractId(val[1])
+        useAppState.setProjectInfo(UserProjectInfo)
+        useAppState.setContractInfo(UserContractInfo)
+        //更改界面更新
+        projectInfo.value = UserProjectInfo
+        contractInfo.value = UserContractInfo
+        window.$message?.info('切换了项目,数据更新中')
+        //发送消息
+        socketSend(val[0] + ',' + val[1])
+        //刷新路由
+        reloadRouter.value = false
+        nextTick(() => {
+            reloadRouter.value = true
+        })
+    }
+}
+
+//菜单被点击
+const MenuBarChange = (item) => {
+    MenuBarKey.value = item?.code
+    setIsCollapse(item?.code)
+    router.push({ name: item?.code })
+}
+
+//首页
+const logoClick = () => {
+    router.push({ name: 'home-index' })
+}
+
+//消息数量
+const msgCount = ref({
+    allCount: 0,
+    taskCount: 0,
+    messageCount: 0,
+    messageCount_1: 0,
+    messageCount_2: 0,
+    messageCount_3: 0,
+    messageCount_4: 0,
+    messageCount_5: 0,
+})
+
+//推送系统
+let socket
+const setInitSocket = () => {
+    const user_id = userInfo.value.user_id
+    socket = new WebSocket(website.socket + user_id)
+    try {
+        socket.onopen = function (evt) {
+            console.log('websocket链接成功')
+        }
+        socket.onclose = function (evt) {
+            console.log('websocket连接已断开')
+        }
+        socket.onmessage = function ({ data }) {
+            if (data) {
+                msgCount.value = JSON.parse(data)
+            }
+            console.log(data, '消息信息')
+        }
+        socket.onerror = function ({ data }) {
+            console.log('发生错误:', data)
+        }
+    } catch {
+    }
+}
+
+//发送消息
+const socketSend = (msg) => {
+    try {
+        if (socket) {
+            socket.send(msg)
+        } else {
+            setTimeout(() => {
+                socket.send(msg)
+            }, 1000)
+        }
+    } catch {
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+@import "./layout.scss";
+</style>
+
+<style lang="scss">
+.hc-layout-box .hc-container-view {
+    .hc-header-view .hc-header-content .hc-header-cascader-box {
+        .el-cascader {
+            width: 100%;
+        }
+        .el-cascader .el-input .el-input__wrapper {
+            padding: 4px 15px;
+            border: 1px solid #00000000;
+            border-radius: 100px;
+            background: #f1f5f8;
+            color: #202532;
+            box-shadow: var(--hc-shadow);
+            .el-input__inner, .el-input__suffix {
+                color: #202532;
+            }
+        }
+        .el-cascader .el-input.is-focus .el-input__wrapper {
+            box-shadow: 4px 4px 8px 0 rgba(54, 92, 167, 0.15), -4px -4px 8px 0px #ffffff;
+        }
+        .el-cascader .el-input .icon-arrow-down {
+            font-size: 18px;
+            font-weight: bold;
+        }
+    }
+    &.home {
+        .hc-header-view .hc-header-content .hc-header-cascader-box {
+            .el-cascader .el-input .el-input__wrapper {
+                background-color: #00000000;
+                border: 1px solid white;
+                box-shadow: initial;
+                .el-input__inner, .el-input__suffix {
+                    color: white;
+                }
+            }
+            .el-cascader .el-input.is-focus .el-input__wrapper {
+                box-shadow: initial;
+            }
+        }
+        .hc-header-view .hc-header-top-menu-bar {
+            padding-left: 0;
+            .hc-top-menu-bar .bar-menu-content .bar-menu-btn {
+                background: rgba(255, 255, 255, .2);
+                border-color: rgba(255, 255, 255, .2);
+                color: rgba(255, 255, 255, .7);
+                backdrop-filter: blur(20px);
+                -webkit-backdrop-filter: blur(20px);
+                &:hover:not([class*='cur']) {
+                    background: var(--el-color-primary-light-9);
+                    color: #838791;
+                }
+                &:active:not([class*='cur']) {
+                    background: var(--el-color-primary-light-8);
+                    color: #838791;
+                }
+            }
+        }
+    }
+}
+</style>

+ 159 - 0
src/layout/modules/Cascader.vue

@@ -0,0 +1,159 @@
+<template>
+    <div class="hc-header-cascader-box">
+        <div class="project-name-box">
+            {{ projectInfo.projectAlias }} / {{ contractInfo.name }}
+        </div>
+        <el-cascader
+            ref="ElCascaderRef"
+            v-model="projectValue" class="hc-header-cascader"
+            :clearable="userInfo?.role_id === '1123598816738675201'"
+            :filterable="userInfo?.role_id === '1123598816738675201'"
+            :options="projectContract"
+            :props="projectProps" placeholder="请选择项目"
+            @change="projectContractChange"
+        />
+    </div>
+</template>
+
+<script setup>
+import { onMounted, ref, watch } from 'vue'
+import { useAppStore } from '~src/store'
+import { getArrValue } from 'js-fast-way'
+import { initProjectContract } from '~sto/app'
+
+//事件
+const emit = defineEmits(['change', 'send'])
+
+//状态
+const store = useAppStore()
+const userInfo = ref(store.getUserInfo)
+
+//项目合同段
+const projectInfo = ref({})
+const contractInfo = ref({})
+const projectContract = ref([])
+const projectValue = ref(null)
+const projectProps = ref({
+    value: 'id',
+    label: 'projectAlias',
+    children: 'contractInfoList',
+})
+
+//监听
+watch(() => store.getProjectContract, (val) => {
+    projectContractData(getArrValue(val))
+})
+
+//渲染完成
+onMounted(() => {
+    initProjectContract()
+    const info = store.getProjectContract || []
+    projectContractData(info)
+})
+
+//处理项目合同段数据
+const projectContractData = (projectContractData) => {
+    if (projectContractData.length > 0) {
+        //处理别名
+        projectContractData.forEach(item => {
+            let contractArr = item['contractInfoList'] || []
+            contractArr.forEach(items => {
+                items['projectAlias'] = items['name']
+            })
+        })
+        //处理其他数据
+        projectContract.value = projectContractData
+        const projectId = store.getProjectId //项目ID
+        const contractId = store.getContractId //合同段ID
+        const UserProjectInfo = store.getProjectInfo
+        const UserContractInfo = store.getContractInfo
+        //查询缓存的选中ID是否存在
+        const pid = projectContractData.findIndex(item => Number(item.id) === Number(projectId))
+        const contractList = projectContractData[pid]?.contractInfoList || []
+        const cid = contractList.findIndex(item => Number(item.id) === Number(contractId))
+        //如果缓存的选中ID不存在
+        if (cid === -1) {
+            //取项目数组中的第一个数据
+            let letProjectInfo = projectContractData[0]
+            let contractInfoList = letProjectInfo?.contractInfoList || []
+            let letContractInfo = contractInfoList[0] || {}
+            projectValue.value = letContractInfo?.id
+            projectInfo.value = letProjectInfo
+            contractInfo.value = letContractInfo
+            //设置缓存
+            store.setProjectInfo(letProjectInfo)
+            store.setContractInfo(letContractInfo)
+            store.setProjectId(letProjectInfo?.id)
+            store.setContractId(letContractInfo?.id)
+            emit('send', {
+                projectId: letProjectInfo?.id,
+                contractId: letContractInfo?.id,
+            })
+        } else {
+            projectValue.value = String(contractId)
+            projectInfo.value = UserProjectInfo
+            contractInfo.value = UserContractInfo
+            emit('send', {
+                projectId: projectId,
+                contractId: contractId,
+            })
+        }
+    } else {
+        projectContract.value = []
+        projectValue.value = null
+        projectInfo.value = {}
+        contractInfo.value = {}
+        emit('send', {
+            projectId: '',
+            contractId: '',
+        })
+    }
+}
+
+//项目被选择
+const ElCascaderRef = ref(null)
+const projectContractChange = (val) => {
+    if (val) {
+        const Nodes = ElCascaderRef.value.getCheckedNodes()
+        const UserProjectInfo = Nodes[0].parent.data
+        const UserContractInfo = Nodes[0].data
+        //缓存项目数据
+        store.setProjectId(val[0])
+        store.setContractId(val[1])
+        store.setProjectInfo(UserProjectInfo)
+        store.setContractInfo(UserContractInfo)
+        //更改界面更新
+        projectInfo.value = UserProjectInfo
+        contractInfo.value = UserContractInfo
+        window.$message?.info('切换了项目,数据更新中')
+        emit('send', {
+            projectId: val[0],
+            contractId: val[1],
+        })
+        emit('change')
+    }
+}
+</script>
+
+<style lang="scss">
+.hc-header-cascader-box {
+    position: relative;
+    margin-right: 20px;
+    .project-name-box {
+        position: relative;
+        max-width: 340px;
+        padding-right: 20px;
+        overflow: hidden;
+        z-index: -1;
+    }
+    .el-cascader.hc-header-cascader {
+        position: absolute;
+        top: 2px;
+        width: 100%;
+        .el-input .el-input__wrapper {
+            border-radius: 104px;
+            height: 28px;
+        }
+    }
+}
+</style>

+ 0 - 26
src/layout/modules/ConfigBar.vue

@@ -6,7 +6,6 @@
 
 
 <script setup>
 <script setup>
 import { useRouter } from 'vue-router'
 import { useRouter } from 'vue-router'
-
 const router = useRouter()
 const router = useRouter()
 
 
 //跳转到系统设置页面
 //跳转到系统设置页面
@@ -16,28 +15,3 @@ const toConfigClick = () => {
     })
     })
 }
 }
 </script>
 </script>
-
-<style lang="scss" scoped>
-.header-icon-bar {
-    position: relative;
-    height: 40px;
-    width: 40px;
-    border-radius: 100px;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    cursor: pointer;
-    margin-right: 30px;
-    font-size: 26px;
-    border: 1px solid #00000000;
-    background: #f1f5f8;
-    color: #202532;
-    box-shadow: var(--hc-shadow);
-}
-.hc-layout-box .hc-container-view.home .hc-header-view .hc-header-content .header-icon-bar {
-    border: 1px solid white;
-    color: inherit;
-    box-shadow: initial;
-    background: initial;
-}
-</style>

+ 84 - 0
src/layout/modules/HcTopMenu.vue

@@ -0,0 +1,84 @@
+<template>
+    <el-scrollbar>
+        <div class="hc-header-top-menu-bar">
+            <template v-for="(item, index) in topMenuData" :key="index">
+                <div class="item" :class="curKey === item?.code ? 'cur' : '' " @click="topMenuClick(item)">{{ item?.name }}</div>
+            </template>
+        </div>
+    </el-scrollbar>
+</template>
+
+<script setup>
+import { ref, watch } from 'vue'
+import { useRoute } from 'vue-router'
+import { useAppStore } from '~src/store'
+import HcTopMenu from '~src/plugins/HcTopMenu'
+import { getArrValue } from 'js-fast-way'
+
+const emit = defineEmits(['change', 'load'])
+
+//初始组合式
+const useRoutes = useRoute()
+const store = useAppStore()
+
+//处理菜单数据
+const setMenuItem = async (item) => {
+    emit('change', await HcTopMenu.setMenuItem(item))
+}
+
+//监听菜单数据
+const topMenuData = ref([])
+watch(() => store.getMenus, (val) => {
+    topMenuData.value = getArrValue(val)
+}, { immediate: true, deep: true })
+
+//监听路由数据
+const curKey = ref('')
+watch(() => useRoutes, (val) => {
+    HcTopMenu.initMenu({
+        routes: val,
+        menu: topMenuData.value,
+        load: (key) => {
+            curKey.value = key
+            emit('load', key)
+        },
+        change: (key, item) => {
+            curKey.value = key
+            setMenuItem(item)
+        },
+    })
+}, { immediate: true, deep: true })
+
+//菜单被点击
+const topMenuClick = (item) => {
+    setMenuItem(item)
+}
+</script>
+
+<style lang="scss">
+.hc-header-top-menu-bar {
+    position: relative;
+    height: 100%;
+    display: flex;
+    align-items: center;
+    .item {
+        position: relative;
+        cursor: pointer;
+        padding: 6px 8px;
+        border-radius: 3px;
+        color: #efefef;
+        transition: background .2s, color .2s;
+        &:hover {
+            color: white;
+            background: var(--el-color-primary-dark-2);
+        }
+        &.cur {
+            color: white;
+            background: var(--el-color-primary-dark-2);
+        }
+    }
+    .item + .item {
+        margin-left: 2px;
+    }
+}
+</style>

+ 0 - 24
src/layout/modules/HelpInfoBar.vue

@@ -112,7 +112,6 @@ const screenShortClick = () => {
             completeCallback: getScreenShotImg,
             completeCallback: getScreenShotImg,
             noScroll: false,
             noScroll: false,
         })
         })
-        /*setTimeout(() => {}, 800)*/
     })
     })
 }
 }
 
 
@@ -155,29 +154,6 @@ const excelPreviewClick = () => {
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
-.header-icon-bar {
-    position: relative;
-    height: 40px;
-    width: 40px;
-    border-radius: 100px;
-    display: flex;
-    justify-content: center;
-    align-items: center;
-    font-size: 26px;
-    cursor: pointer;
-    margin-right: 30px;
-    border: 1px solid #00000000;
-    background: #f1f5f8;
-    color: #202532;
-    box-shadow: var(--hc-shadow);
-}
-.hc-layout-box .hc-container-view.home .hc-header-view .hc-header-content .header-icon-bar {
-    border: 1px solid white;
-    color: inherit;
-    box-shadow: initial;
-    background: initial;
-}
-
 .header-pover-menu-list {
 .header-pover-menu-list {
     position: relative;
     position: relative;
     margin: -5px -12px;
     margin: -5px -12px;

+ 17 - 333
src/layout/modules/MenuBar.vue

@@ -1,38 +1,14 @@
 <template>
 <template>
-    <el-menu :collapse="isCollapse" :default-active="curKey" class="hc-aside-menu" unique-opened>
-        <el-menu-item v-if="indexModel === '1'" index="home-index" @click="MenuClick({ code: 'home-index' })">
-            <div class="hc-aside-menu-item">
-                <div class="menu---item">
-                    <HcIcon :fill="curKey === 'home-index'" class="hc-menu-icon" name="home-3" />
-                    <div class="name">
-                        首页
-                    </div>
-                </div>
-            </div>
-        </el-menu-item>
-        <el-menu-item v-if="indexModel === '2'" index="home-index" @click="MenuClick({ code: 'home-index-static' })">
-            <div class="hc-aside-menu-item">
-                <div class="menu---item">
-                    <HcIcon :fill="curKey === 'home-index-static'" class="hc-menu-icon" name="home-3" />
-                    <div class="name">
-                        首页
-                    </div>
-                </div>
-            </div>
-        </el-menu-item>
-        <MenuItem :collapse="isCollapse" :cur="curKey" :datas="datas" :msg-count="msgCount" @change="MenuClick" />
-    </el-menu>
+    <el-scrollbar>
+        <el-menu :collapse="isCollapse" :default-active="curKey" class="hc-aside-menu" unique-opened text-color="#fff">
+            <MenuItem :collapse="isCollapse" :cur="curKey" :datas="datas" :msg-count="msgCount" @change="MenuClick" />
+        </el-menu>
+    </el-scrollbar>
 </template>
 </template>
 
 
 <script setup>
 <script setup>
 import { ref, watch } from 'vue'
 import { ref, watch } from 'vue'
 import MenuItem from './MenuItem.vue'
 import MenuItem from './MenuItem.vue'
-import { getToken } from '~src/api/util/auth'
-import { getStoreValue } from '~uti/storage'
-import { getTenantDetail } from '~api/other'
-import { getObjValue } from 'js-fast-way'
-import { useAppStore } from '~src/store'
-import { isPathUrl } from '~uti/tools'
 
 
 const props = defineProps({
 const props = defineProps({
     datas: {
     datas: {
@@ -52,323 +28,31 @@ const props = defineProps({
         default: () => ({}),
         default: () => ({}),
     },
     },
 })
 })
+
 //事件
 //事件
 const emit = defineEmits(['change'])
 const emit = defineEmits(['change'])
-const useAppState = useAppStore()
+
 //初始变量
 //初始变量
 const curKey = ref(props.cur)
 const curKey = ref(props.cur)
 const isCollapse = ref(props.collapse)
 const isCollapse = ref(props.collapse)
-//首页模式
-const indexModel = ref(useAppState.getIndexModel)
+
 //监听
 //监听
 watch(() => [
 watch(() => [
     props.cur,
     props.cur,
     props.collapse,
     props.collapse,
-    useAppState.getIndexModel,
-], ([cur, collapse, IndexModel]) => {
+], ([cur, collapse]) => {
     curKey.value = cur
     curKey.value = cur
     isCollapse.value = collapse
     isCollapse.value = collapse
-    indexModel.value = IndexModel
 })
 })
 
 
-
-const MenuClick = async (item) => {
-    if (isPathUrl(item?.path)) {
-        let token = getToken(), domain = item?.path
-        if (item?.code === 'to-archives-url') {
-            const tenantId = getStoreValue('tenantId')
-            if (tenantId === '000000' || !tenantId) {
-                domain = item?.path
-            } else {
-                const { error, code, data } = await getTenantDetail(tenantId)
-                if (!error && code === 200) {
-                    const url = getObjValue(data).domainUrl
-                    domain = url ? url : item?.path
-                }
-            }
-        }
-        window.open(domain + '/#/auth?token=' + token, '_blank')
-    } else {
-        curKey.value = item?.code || ''
-        emit('change', item)
-    }
+//处理菜单数据
+const setMenuItem = async (item) => {
+    curKey.value = item?.code || ''
+    emit('change', item)
 }
 }
-</script>
 
 
-<style lang="scss">
-.hc-aside-menu.el-menu {
-    --el-menu-bg-color: initial;
-    --el-menu-text-color: #838791;
-    --el-menu-active-color: #ffffff;
-    --el-menu-hover-text-color: var(--el-color-primary);
-    --el-menu-hover-bg-color: initial;
-    --el-menu-item-font-size: 16px;
-    --el-menu-item-height: 48px;
-    margin-left: -10px;
-    border-right: 0;
-    padding: 8px 0;
-    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item,
-    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item-group__title,
-    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
-        white-space: nowrap;
-        padding-left: 0;
-    }
-    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
-        padding-right: 10px;
-    }
-    .el-sub-menu__title {
-        padding: 0;
-    }
-    .el-menu-item, .el-sub-menu {
-        padding: 15px 0 0 30px !important;
-        min-width: initial;
-        transition: 0.2s;
-        .hc-aside-menu-item {
-            flex: 1;
-            position: relative;
-            border-radius: 50px 0 0 50px;
-            padding: 0 16px;
-            display: flex;
-            align-items: center;
-            transition: 0.2s;
-            .menu---item {
-                display: contents;
-            }
-            .hc-menu-icon {
-                font-size: 22px;
-                margin-right: 10px;
-                line-height: initial;
-            }
-            .name {
-                flex: 1;
-                width: 0;
-            }
-            .el-badge, .el-badge .el-badge__content {
-                vertical-align: initial;
-            }
-        }
-    }
-    .el-sub-menu .el-icon {
-        display: none;
-    }
-    .el-sub-menu .el-icon.hc-icon-i {
-        position: relative;
-        display: inline-block;
-        font-size: 16px;
-        right: 15px;
-        top: initial;
-        height: initial;
-        width: initial;
-        margin-top: 0;
-        vertical-align: initial;
-    }
-    .el-sub-menu .el-sub-menu__title .hc-aside-menu-item:hover,
-    .el-menu-item:not(.is-active) .hc-aside-menu-item:hover {
-        color: var(--el-color-primary);
-    }
-    .el-sub-menu.is-active > .el-sub-menu__title > .hc-aside-menu-item {
-        color: var(--el-color-primary);
-    }
-    .el-menu-item.is-active {
-        .hc-aside-menu-item {
-            --radius-size: 20px;
-            background-color: var(--el-color-primary);
-            box-shadow: 0 2px 8px 0 var(--hc-shadow-color-5);
-            &::before, &::after {
-                content: '';
-                display: block;
-                height: var(--radius-size);
-                width: var(--radius-size);
-                position: absolute;
-                background: radial-gradient(
-                        var(--radius-size) at var(--radius-size) 0px,
-                        transparent var(--radius-size),
-                        var(--el-color-primary) var(--radius-size)
-                );
-            }
-            &::before {
-                right: 0;
-                transform: scaleX(-1);
-                top: calc(-1 * var(--radius-size));
-                z-index: 999;
-            }
-            &::after {
-                right: 0;
-                bottom: calc(-1 * var(--radius-size));
-                transform: scale(-1);
-                z-index: 999;
-            }
-        }
-    }
-}
-.hc-aside-menu.el-menu--collapse {
-    margin-left: 0;
-    width: 90px;
-    .el-sub-menu__title {
-        height: inherit;
-        line-height: initial;
-        width: 90px;
-        justify-content: center;
-        transition: 0.2s;
-    }
-    .el-menu-item, .el-sub-menu {
-        padding: 0 !important;
-        height: 60px;
-        line-height: initial;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        width: 90px;
-        transition: 0.2s;
-        .hc-aside-menu-item {
-            display: inline-flex;
-            align-items: center;
-            justify-content: center;
-            width: 60px;
-            height: 60px;
-            text-align: center;
-            border-radius: 10px;
-            padding: 5px;
-            flex: initial;
-            transition: 0.2s;
-            .menu---item {
-                position: relative;
-                display: block;
-            }
-            .hc-menu-icon {
-                margin-right: 0;
-            }
-            .name {
-                flex: initial;
-                width: 100%;
-            }
-            .el-badge, .el-badge .el-badge__content {
-                vertical-align: initial;
-            }
-            .el-badge {
-                position: absolute;
-                top: -20px;
-                right: -24px;
-            }
-        }
-    }
-    .el-sub-menu .el-icon.hc-icon-i {
-        display: none;
-    }
-    .el-menu-item + .el-menu-item,
-    .el-menu-item + .el-sub-menu,
-    .el-sub-menu + .el-menu-item,
-    .el-sub-menu + .el-sub-menu {
-        margin-top: 24px;
-    }
-    .el-sub-menu:not(.is-active):hover,
-    .el-menu-item:not(.is-active):hover {
-        .hc-aside-menu-item {
-            background-color: var(--el-color-primary-light-9);
-            color: var(--el-color-primary);
-        }
-    }
-    .el-menu-item.is-active, .el-sub-menu.is-active {
-        .hc-aside-menu-item {
-            color: #ffffff !important;
-            background: linear-gradient(90deg, var(--el-color-primary-light-5), var(--el-color-primary) 100%);
-            box-shadow: 0 2px 8px 0 var(--hc-shadow-color-5);
-            &::before, &::after {
-                content: '';
-                display: none;
-            }
-        }
-    }
+//菜单被点击
+const MenuClick = (item) => {
+    setMenuItem(item)
 }
 }
-.aside-menu-popper.el-popper.is-light {
-    background: initial !important;
-    border: 0 !important;
-    outline: none;
-}
-.aside-menu-popper.el-popper .el-menu--vertical .el-menu {
-    --el-menu-bg-color: #f1f5f8;
-    --el-menu-text-color: #838791;
-    --el-menu-active-color: #ffffff;
-    --el-menu-hover-bg-color: initial;
-    --el-menu-item-font-size: 16px;
-    background-color: #f1f5f8;
-    color: #838791;
-    .el-sub-menu__title {
-        padding: 0;
-        justify-content: center;
-        transition: 0.2s;
-    }
-    .el-menu-item, .el-sub-menu {
-        color: inherit;
-        padding: 0;
-        transition: 0.2s;
-        .hc-aside-menu-item {
-            flex: 1;
-            position: relative;
-            padding: 0 16px;
-            display: flex;
-            align-items: center;
-            transition: 0.2s;
-            .menu---item {
-                display: contents;
-            }
-            .hc-menu-icon {
-                font-size: 22px;
-                margin-right: 10px;
-                line-height: initial;
-            }
-            .name {
-                flex: 1;
-                width: 0;
-            }
-            .el-badge, .el-badge .el-badge__content {
-                vertical-align: initial;
-            }
-        }
-        &.is-active {
-            color: white;
-        }
-    }
-    .el-sub-menu .el-icon {
-        display: none;
-    }
-    .el-sub-menu .el-icon.hc-icon-i {
-        position: relative;
-        display: inline-block;
-        font-size: 16px;
-        right: 10px;
-        top: initial;
-        height: initial;
-        width: initial;
-        margin-top: 0;
-        vertical-align: initial;
-    }
-    .el-sub-menu:not(.is-active) .el-sub-menu__title:hover {
-        background-color: var(--el-color-primary-light-9);
-        color: var(--el-color-primary);
-    }
-    .el-menu-item:not(.is-active):hover {
-        .hc-aside-menu-item {
-            background-color: var(--el-color-primary-light-9);
-            color: var(--el-color-primary);
-        }
-    }
-    .el-menu-item.is-active {
-        .hc-aside-menu-item {
-            background-color: var(--el-color-primary);
-        }
-    }
-    .el-sub-menu.is-active .el-sub-menu__title {
-        background-color: var(--el-color-primary-light-9);
-        color: var(--el-color-primary);
-    }
-}
-
-.aside-menu-popper.el-popper .el-menu--vertical.home-index .el-menu {
-    --el-menu-bg-color: initial;
-    --el-menu-text-color: initial;
-    color: white;
-    background-color: rgba(255, 255, 255, 0.25);
-    backdrop-filter: blur(4px);
-}
-</style>
+</script>

+ 10 - 32
src/layout/modules/MenuItem.vue

@@ -1,22 +1,12 @@
 <template>
 <template>
     <template v-for="item in datas" :key="item?.code">
     <template v-for="item in datas" :key="item?.code">
-        <el-sub-menu
-            v-if="item?.children && item?.children.length > 0" :index="item?.code" :popper-offset="0"
-            :popper-class="`aside-menu-popper ${curKey}`"
-        >
+        <el-sub-menu v-if="item?.children && item?.children.length > 0" :index="item?.code" :popper-offset="0" :popper-class="`aside-menu-popper ${curKey}`">
             <template #title>
             <template #title>
                 <div class="hc-aside-menu-item">
                 <div class="hc-aside-menu-item">
                     <div class="menu---item">
                     <div class="menu---item">
-                        <HcIcon
-                            v-if="item?.source" :name="item?.source" :fill="curKey === item?.code"
-                            class="hc-menu-icon"
-                        />
-                        <div v-if="isCollapse" class="name truncate">
-                            {{ item?.name.substring(0, 2) }}
-                        </div>
-                        <div v-else class="name truncate">
-                            {{ item?.name }}
-                        </div>
+                        <HcIcon v-if="item?.source" :name="item?.source" :fill="curKey === item?.code" class="hc-menu-icon" />
+                        <div v-if="isCollapse" class="name truncate">{{ item?.name.substring(0, 2) }}</div>
+                        <div v-else class="name truncate">{{ item?.name }}</div>
                         <el-badge v-if="item?.code === 'tasks' && msgCount?.allCount > 0" :value="msgCount.allCount" />
                         <el-badge v-if="item?.code === 'tasks' && msgCount?.allCount > 0" :value="msgCount.allCount" />
                     </div>
                     </div>
                 </div>
                 </div>
@@ -27,24 +17,11 @@
         <el-menu-item v-else :index="item?.code" @click="MenuClick(item)">
         <el-menu-item v-else :index="item?.code" @click="MenuClick(item)">
             <div class="hc-aside-menu-item">
             <div class="hc-aside-menu-item">
                 <div class="menu---item">
                 <div class="menu---item">
-                    <HcIcon
-                        v-if="item?.source" :name="item?.source" :fill="curKey === item?.code"
-                        class="hc-menu-icon"
-                    />
-                    <div v-if="isCollapse" class="name truncate">
-                        {{ item?.name.substring(0, 2) }}
-                    </div>
-                    <div v-else class="name truncate">
-                        {{ item?.name }}
-                    </div>
-                    <el-badge
-                        v-if="item?.code === 'tasks-data' && msgCount?.taskCount > 0"
-                        :value="msgCount.taskCount"
-                    />
-                    <el-badge
-                        v-if="item?.code === 'message-data' && msgCount?.messageCount > 0"
-                        :value="msgCount.messageCount"
-                    />
+                    <HcIcon v-if="item?.source" :name="item?.source" :fill="curKey === item?.code" class="hc-menu-icon" />
+                    <div v-if="isCollapse" class="name truncate">{{ item?.name.substring(0, 2) }}</div>
+                    <div v-else class="name truncate">{{ item?.name }}</div>
+                    <el-badge v-if="item?.code === 'tasks-data' && msgCount?.taskCount > 0" :value="msgCount.taskCount" />
+                    <el-badge v-if="item?.code === 'message-data' && msgCount?.messageCount > 0" :value="msgCount.messageCount" />
                 </div>
                 </div>
             </div>
             </div>
         </el-menu-item>
         </el-menu-item>
@@ -84,6 +61,7 @@ const props = defineProps({
 })
 })
 //事件
 //事件
 const emit = defineEmits(['change'])
 const emit = defineEmits(['change'])
+
 //初始变量
 //初始变量
 const curKey = ref(props.cur)
 const curKey = ref(props.cur)
 const isCollapse = ref(props.collapse)
 const isCollapse = ref(props.collapse)

+ 20 - 90
src/layout/modules/TopMenuBar.vue → src/layout/modules/RouterMenu.vue

@@ -1,35 +1,31 @@
 <template>
 <template>
-    <div class="hc-top-menu-bar">
-        <el-scrollbar always>
-            <div class="bar-menu-content">
-                <div
-                    v-for="(item, index) in barMenuData" :key="item.key"
-                    :class="item.key === barRoutes.key ? 'cur' : ''"
-                    class="bar-menu-btn"
-                    @click="barMenuClick(item)" @contextmenu.prevent="barMenuContextMenu($event, item, index)"
-                >
-                    <span>{{ item.title }}</span>
-                    <div class="bar-close-icon" @click.stop="barMenuCloseClick(item, index)">
-                        <HcIcon name="close" />
-                    </div>
+    <el-scrollbar>
+        <div class="hc-router-tab-item" :class="(barRoutes.key === 'home' || barRoutes.key === 'home-index') ? 'cur' : ''" @click="toHomeClick">首页</div>
+        <template v-for="(item, index) in barMenuData" :key="item.key">
+            <div
+                :class="item.key === barRoutes.key ? 'cur' : ''" class="hc-router-tab-item"
+                @click="barMenuClick(item)" @contextmenu.prevent="barMenuContextMenu($event, item, index)"
+            >
+                <span>{{ item.title }}</span>
+                <div class="close-icon" @click.stop="barMenuCloseClick(item, index)">
+                    <HcIcon name="close" />
                 </div>
                 </div>
             </div>
             </div>
-        </el-scrollbar>
-        <!-- 右键菜单 -->
-        <HcContextMenu ref="contextMenuRef" :datas="menusData" @item-click="handleMenuSelect" />
-    </div>
+        </template>
+    </el-scrollbar>
+    <!-- 右键菜单 -->
+    <HcContextMenu ref="contextMenuRef" :datas="menusData" @item-click="handleMenuSelect" />
 </template>
 </template>
 
 
 <script setup>
 <script setup>
 import { onMounted, ref, watch } from 'vue'
 import { onMounted, ref, watch } from 'vue'
-import { useAppStore } from '~src/store'
 import { useRoute, useRouter } from 'vue-router'
 import { useRoute, useRouter } from 'vue-router'
 import { getStoreValue, setStoreValue } from '~src/utils/storage'
 import { getStoreValue, setStoreValue } from '~src/utils/storage'
 
 
+const emit = defineEmits(['load'])
 //初始组合式
 //初始组合式
 const router = useRouter()
 const router = useRouter()
 const useRoutes = useRoute()
 const useRoutes = useRoute()
-const useAppState = useAppStore()
 
 
 //初始变量
 //初始变量
 const barMenuData = ref(getStoreValue('bar-menu-datas') || [])
 const barMenuData = ref(getStoreValue('bar-menu-datas') || [])
@@ -63,6 +59,7 @@ const setBarMenuData = () => {
         }
         }
         setStoreValue('bar-menu-datas', barMenuData.value)
         setStoreValue('bar-menu-datas', barMenuData.value)
     }
     }
+    emit('load', barRoutes.value)
 }
 }
 
 
 //菜单被点击
 //菜单被点击
@@ -129,76 +126,9 @@ const barMenuCloseClick = (item, index) => {
         setStoreValue('bar-menu-datas', barMenuData.value)
         setStoreValue('bar-menu-datas', barMenuData.value)
     }
     }
 }
 }
-</script>
 
 
-<style lang="scss">
-.hc-top-menu-bar {
-    position: relative;
-    width: 100%;
-    padding-bottom: 10px;
-    margin-top: 10px;
-    .bar-menu-content {
-        display: flex;
-        position: relative;
-        .bar-menu-btn {
-            position: relative;
-            color: #b3b3b3;
-            padding-left: 10px;
-            padding-right: 6px;
-            height: 32px;
-            font-size: 14px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            background: #ffffff;
-            border: 1px solid #ffffff;
-            border-radius: 4px;
-            user-select: none;
-            cursor: pointer;
-            white-space: nowrap;
-            transition: background 0.3s, color 0.3s;
-            &:hover:not([class*='cur']) {
-                background: var(--el-color-primary-light-9);
-                color: #838791;
-            }
-            &:active:not([class*='cur']) {
-                background: var(--el-color-primary-light-8);
-                color: #838791;
-            }
-            &.cur {
-                color: #ffffff;
-                cursor: default;
-                background: linear-gradient(to right, var(--el-color-primary-light-5), var(--el-color-primary), var(--el-color-primary-dark-2));
-                background-size: 200%;
-                transition: background-position 0.5s;
-            }
-            .bar-close-icon {
-                height: 30px;
-                width: 18px;
-                display: flex;
-                align-items: center;
-                justify-content: center;
-                margin-left: 6px;
-                font-size: 16px;
-                cursor: pointer;
-                transition: color 0.3s;
-                &:hover {
-                    color: var(--el-color-primary);
-                }
-            }
-        }
-        .bar-menu-btn.cur .bar-close-icon:hover {
-            color: #000000;
-        }
-        .bar-menu-btn + .bar-menu-btn {
-            margin-left: 10px;
-        }
-    }
-    .el-scrollbar__bar.is-horizontal {
-        bottom: -10px;
-    }
-    .el-scrollbar__bar.is-vertical {
-        display: none;
-    }
+//点击了首页
+const toHomeClick = () => {
+    router.push({ name: 'home' })
 }
 }
-</style>
+</script>

+ 15 - 13
src/layout/modules/UserInfoBar.vue

@@ -29,22 +29,23 @@ import { getStoreValue } from '~src/utils/storage'
 import { calcDate, isNullES } from 'js-fast-way'
 import { calcDate, isNullES } from 'js-fast-way'
 
 
 //事件
 //事件
-const emit = defineEmits(['change'])
+const emit = defineEmits(['load'])
+
 //变量
 //变量
 const router = useRouter()
 const router = useRouter()
-const userStore = useAppStore()
-const userInfo = ref(userStore.getUserInfo)
+const store = useAppStore()
+const userInfo = ref(store.getUserInfo)
 const refreshLock = ref(false)
 const refreshLock = ref(false)
 
 
 //监听
 //监听
-watch(() => [
-    userStore.getUserInfo,
-], ([info]) => {
+watch(() => store.getUserInfo, (info) => {
     userInfo.value = info
     userInfo.value = info
+    emit('load', info)
 })
 })
 
 
 onMounted(() => {
 onMounted(() => {
     getRefreshToken()
     getRefreshToken()
+    emit('load', userInfo.value)
 })
 })
 
 
 //刷新token
 //刷新token
@@ -97,11 +98,12 @@ const handleSelect = (key) => {
     align-items: center;
     align-items: center;
     height: 100%;
     height: 100%;
     cursor: pointer;
     cursor: pointer;
-    padding-left: 24px;
+    padding-left: 16px;
+    margin-left: 4px;
     outline: none;
     outline: none;
     .user-avatar {
     .user-avatar {
-        width: 40px;
-        height: 40px;
+        width: 26px;
+        height: 26px;
         border-radius: 50%;
         border-radius: 50%;
         background: white;
         background: white;
         object-fit: cover;
         object-fit: cover;
@@ -109,20 +111,20 @@ const handleSelect = (key) => {
     .user-name {
     .user-name {
         font-size: 16px;
         font-size: 16px;
         margin-left: 10px;
         margin-left: 10px;
-        color: #202532;
+        color: white;
     }
     }
     .arrow-icon {
     .arrow-icon {
         margin-left: 5px;
         margin-left: 5px;
         font-size: 20px;
         font-size: 20px;
-        color: #202532;
+        color: white;
     }
     }
     &::before {
     &::before {
         position: absolute;
         position: absolute;
         content: '';
         content: '';
         left: 0;
         left: 0;
         width: 0;
         width: 0;
-        height: 24px;
-        border-left: 1px solid #ccd0de;
+        height: 20px;
+        border-left: 1px solid #7291ff;
     }
     }
 }
 }
 .hc-layout-box .hc-container-view.home .hc-header-view .hc-header-content .user-info-bar {
 .hc-layout-box .hc-container-view.home .hc-header-view .hc-header-content .user-info-bar {

+ 56 - 0
src/plugins/HcSocket.js

@@ -0,0 +1,56 @@
+import website from '~src/config/index'
+import { isNullES } from 'js-fast-way'
+
+// 长链接推送插件
+export default class HcSocket {
+
+    static socket = null
+
+    static create(data, change) {
+        const socket = new WebSocket(website.socket + data)
+        socket.onopen = function () {
+            console.log('websocket 链接成功')
+        }
+        socket.onclose = function () {
+            console.log('websocket 链接已断开')
+        }
+        socket.onmessage = function ({ data }) {
+            if (typeof change !== 'function') {
+                return false
+            } else {
+                change(JSON.parse(data))
+            }
+        }
+        socket.onerror = function ({ data }) {
+            console.log('websocket 发生错误:', data)
+        }
+        this.socket = socket
+    }
+
+    //发送消息
+    static async send(data) {
+        const is_socket = await this.isSocket()
+        if (!is_socket) return false
+        this.socket.send(data)
+    }
+
+    //链接是否存在
+    static async isSocket(i = 0) {
+        let _this = this
+        return new Promise((resolve) => {
+            if (isNullES(_this.socket)) {
+                if (i <= 30) {
+                    setTimeout(async () => {
+                        i++
+                        resolve(await _this.isSocket(i))
+                    }, 1000)
+                } else {
+                    resolve(false)
+                }
+            } else {
+                resolve(true)
+            }
+        })
+    }
+
+}

+ 47 - 0
src/plugins/HcTopMenu.js

@@ -0,0 +1,47 @@
+import { isPathUrl } from '~uti/tools'
+import { getToken } from '~src/api/util/auth'
+import { getStoreValue } from '~uti/storage'
+import { getTenantDetail } from '~api/other'
+import { getArrValue, getObjValue } from 'js-fast-way'
+
+export default class HcTopMenu {
+
+    // 基础菜单
+    static baseMenu = [
+        'home', 'home-index', 'home-index-static', 'home-config', 'order-service', 'user-index', '403', '404', '500',
+    ]
+
+    static initMenu({ routes, menu, load, change }) {
+        const topName = routes.matched[0]?.name
+        if (this.baseMenu.includes(topName)) {
+            load(topName)
+            return false
+        }
+        for (let i = 0; i < menu.length; i++) {
+            if (menu[i].code === topName) {
+                change(topName, menu[i])
+            }
+        }
+    }
+
+    static async setMenuItem(item) {
+        if (isPathUrl(item?.path)) {
+            let token = getToken(), domain = item?.path
+            if (item?.code === 'to-archives-url') {
+                const tenantId = getStoreValue('tenantId')
+                if (tenantId === '000000' || !tenantId) {
+                    domain = item?.path
+                } else {
+                    const { error, code, data } = await getTenantDetail(tenantId)
+                    if (!error && code === 200) {
+                        const url = getObjValue(data).domainUrl
+                        domain = url ? url : item?.path
+                    }
+                }
+            }
+            window.open(domain + '/#/auth?token=' + token, '_blank')
+        } else {
+            return getArrValue(item?.children)
+        }
+    }
+}

+ 290 - 289
src/router/modules/base.js

@@ -52,150 +52,307 @@ export default [
         ],
         ],
     },
     },
     {
     {
-        path: '/data-fill',
-        name: 'data-fill',
+        path: '/quality-control',
+        name: 'qualityControl',
         redirect: '/data-fill/wbs',
         redirect: '/data-fill/wbs',
-        meta: { title: '资料管理' },
+        meta: { title: '质量管理' },
         component: Layout,
         component: Layout,
         children: [
         children: [
             {
             {
-                path: '/data-fill/wbs',
-                name: 'data-fill-wbs',
-                meta: { title: '资料填报' },
-                component: () => import('~src/views/data-fill/wbs.vue'),
-            },
-            {
-                path: '/data-fill/query',
-                name: 'data-query',
-                meta: { title: '资料查询' },
-                component: () => import('~src/views/data-fill/query.vue'),
-            },
-            {
-                path: '/data-fill/division',
-                name: 'data-division',
-                meta: { title: '系统分部分项划分' },
-                component: () => import('~src/views/data-fill/division.vue'),
-            },
-        ],
-    },
-    {
-        path: '/ledger',
-        name: 'ledger',
-        redirect: '/ledger/query',
-        meta: { title: '台账日志' },
-        component: Layout,
-        children: [
-            {
-                path: '/ledger/query',
-                name: 'ledger-write',
-                meta: { title: '日志填报' },
-                component: () => import('~src/views/ledger/query.vue'),
-            },
-            {
-                path: '/ledger/write',
-                name: 'ledger-query',
-                meta: { title: '台账管理' },
-                component: () => import('~src/views/ledger/write.vue'),
-            },
-        ],
-    },
-    {
-        path: '/schedule',
-        name: 'schedule',
-        redirect: '/schedule/write',
-        meta: { title: '进度查询' },
-        component: Layout,
-        children: [
-            {
-                path: '/schedule/write',
-                name: 'schedule-internal',
-                meta: { title: '内外业进度' },
-                component: () => import('~src/views/schedule/write.vue'),
-            },
-            {
-                path: '/schedule/data',
-                name: 'schedule-data',
-                meta: { title: '资料进度' },
-                component: () => import('~src/views/schedule/hc-data.vue'),
-            },
-            {
-                path: '/schedule/table',
-                name: 'schedule-table',
-                meta: { title: 'WBS节点进度' },
-                component: () => import('~src/views/schedule/hc-table.vue'),
+                path: '/data-fill',
+                name: 'data-fill',
+                redirect: '/data-fill/wbs',
+                meta: { title: '资料管理' },
+                children: [
+                    {
+                        path: '/data-fill/wbs',
+                        name: 'data-fill-wbs',
+                        meta: { title: '资料填报' },
+                        component: () => import('~src/views/data-fill/wbs.vue'),
+                    },
+                    {
+                        path: '/data-fill/query',
+                        name: 'data-query',
+                        meta: { title: '资料查询' },
+                        component: () => import('~src/views/data-fill/query.vue'),
+                    },
+                    {
+                        path: '/data-fill/division',
+                        name: 'data-division',
+                        meta: { title: '系统分部分项划分' },
+                        component: () => import('~src/views/data-fill/division.vue'),
+                    },
+                ],
+            },
+            {
+                path: '/ledger',
+                name: 'ledger',
+                redirect: '/ledger/query',
+                meta: { title: '台账日志' },
+                children: [
+                    {
+                        path: '/ledger/query',
+                        name: 'ledger-write',
+                        meta: { title: '日志填报' },
+                        component: () => import('~src/views/ledger/query.vue'),
+                    },
+                    {
+                        path: '/ledger/write',
+                        name: 'ledger-query',
+                        meta: { title: '台账管理' },
+                        component: () => import('~src/views/ledger/write.vue'),
+                    },
+                ],
+            },
+            {
+                path: '/schedule',
+                name: 'schedule',
+                redirect: '/schedule/write',
+                meta: { title: '进度查询' },
+                children: [
+                    {
+                        path: '/schedule/write',
+                        name: 'schedule-internal',
+                        meta: { title: '内外业进度' },
+                        component: () => import('~src/views/schedule/write.vue'),
+                    },
+                    {
+                        path: '/schedule/data',
+                        name: 'schedule-data',
+                        meta: { title: '资料进度' },
+                        component: () => import('~src/views/schedule/hc-data.vue'),
+                    },
+                    {
+                        path: '/schedule/table',
+                        name: 'schedule-table',
+                        meta: { title: 'WBS节点进度' },
+                        component: () => import('~src/views/schedule/hc-table.vue'),
+                    },
+                ],
+            },
+            {
+                path: '/other-file',
+                name: 'other-file',
+                redirect: '/other-file/image-data',
+                meta: { title: '其他文件' },
+                children: [
+                    {
+                        path: '/other-file/image-data',
+                        name: 'image-data',
+                        meta: { title: '影像资料' },
+                        component: () => import('~src/views/other-file/image-data.vue'),
+                    },
+                    {
+                        path: '/other-file/image-view',
+                        name: 'other-file-view',
+                        meta: { title: '查看影像资料' },
+                        component: () => import('~src/views/other-file/image-view.vue'),
+                    },
+                    {
+                        path: '/other-file/image-form',
+                        name: 'other-file-form',
+                        meta: { title: '影像资料上传' },
+                        component: () => import('~src/views/other-file/image-form.vue'),
+                    },
+                    {
+                        path: '/other-file/project-scanning',
+                        name: 'project-scanning',
+                        meta: { title: '工程文件扫描、上传' },
+                        component: () => import('~src/views/other-file/project-scanning.vue'),
+                    },
+                ],
+            },
+            {
+                path: '/gauge',
+                name: 'gauge-base',
+                redirect: '/gauge/station',
+                meta: { title: '综合管理' },
+                children: [
+                    {
+                        path: '/gauge/testdata',
+                        name: 'gauge-testdata',
+                        meta: { title: '试验数据' },
+                        component: () => import('~src/views/gauge/testdata.vue'),
+                    },
+                    {
+                        path: '/gauge/station',
+                        name: 'gauge-station',
+                        meta: { title: '测站点' },
+                        component: () => import('~src/views/gauge/station.vue'),
+                    },
+                    {
+                        path: '/gauge/bezier',
+                        name: 'gauge-bezier',
+                        meta: { title: '平曲线' },
+                        component: () => import('~src/views/gauge/bezier.vue'),
+                    },
+                    {
+                        path: '/other/first-item',
+                        name: 'other-first-item',
+                        meta: { title: '首件工程' },
+                        component: () => import('~src/views/other/first-item.vue'),
+                    },
+                ],
             },
             },
         ],
         ],
     },
     },
     {
     {
-        path: '/other-file',
-        name: 'other-file',
-        redirect: '/other-file/image-data',
-        meta: { title: '其他文件' },
+        path: '/tentative',
+        name: 'tentative-menu',
+        redirect: '/tentative/material',
+        meta: { title: '试验管理' },
         component: Layout,
         component: Layout,
         children: [
         children: [
             {
             {
-                path: '/other-file/image-data',
-                name: 'image-data',
-                meta: { title: '影像资料' },
-                component: () => import('~src/views/other-file/image-data.vue'),
-            },
-            {
-                path: '/other-file/image-view',
-                name: 'other-file-view',
-                meta: { title: '查看影像资料' },
-                component: () => import('~src/views/other-file/image-view.vue'),
-            },
-            {
-                path: '/other-file/image-form',
-                name: 'other-file-form',
-                meta: { title: '影像资料上传' },
-                component: () => import('~src/views/other-file/image-form.vue'),
-            },
-            {
-                path: '/other-file/project-scanning',
-                name: 'project-scanning',
-                meta: { title: '工程文件扫描、上传' },
-                component: () => import('~src/views/other-file/project-scanning.vue'),
-            },
-        ],
-    },
-    {
-        path: '/gauge',
-        name: 'gauge-base',
-        redirect: '/gauge/station',
-        meta: { title: '综合管理' },
-        component: Layout,
-        children: [
-            {
-                path: '/gauge/testdata',
-                name: 'gauge-testdata',
-                meta: { title: '试验数据' },
-                component: () => import('~src/views/gauge/testdata.vue'),
-            },
-            {
-                path: '/gauge/station',
-                name: 'gauge-station',
-                meta: { title: '测站点' },
-                component: () => import('~src/views/gauge/station.vue'),
-            },
-            {
-                path: '/gauge/bezier',
-                name: 'gauge-bezier',
-                meta: { title: '平曲线' },
-                component: () => import('~src/views/gauge/bezier.vue'),
-            },
-            {
-                path: '/other/first-item',
-                name: 'other-first-item',
-                meta: { title: '首件工程' },
-                component: () => import('~src/views/other/first-item.vue'),
+                path: '/tentative/material',
+                name: 'tentative-material',
+                redirect: '/tentative/material/approach',
+                meta: { title: '材料管理' },
+                children: [
+                    {
+                        path: '/tentative/material/approach',
+                        name: 'tentative-material-approach',
+                        meta: { title: '材料进场' },
+                        component: () => import('~src/views/tentative/material/approach.vue'),
+                    },
+                    {
+                        path: '/tentative/material/sampling',
+                        name: 'tentative-material-sampling',
+                        meta: { title: '材料取样' },
+                        component: () => import('~src/views/tentative/material/sampling.vue'),
+                    },
+                ],
+            },
+            {
+                path: '/tentative/detect',
+                name: 'tentative-detect',
+                redirect: '/tentative/detect/approach',
+                meta: { title: '试验检测' },
+                children: [
+                    {
+                        path: '/tentative/detect/third',
+                        name: 'tentative-detect-third',
+                        meta: { title: '外委检测' },
+                        component: () => import('~src/views/tentative/detect/third.vue'),
+                    },
+                    {
+                        path: '/tentative/detect/outside',
+                        name: 'tentative-detect-outside',
+                        meta: { title: '第三方检测' },
+                        component: () => import('~src/views/tentative/detect/outside.vue'),
+                    },
+                    {
+                        path: '/tentative/detect/test',
+                        name: 'tentative-detect-test',
+                        meta: { title: '试验检测' },
+                        component: () => import('~src/views/tentative/detect/test.vue'),
+                    },
+                    {
+                        path: '/tentative/detect/test-form',
+                        name: 'tentative-detect-test-form',
+                        meta: { title: '试验检测表单' },
+                        component: () => import('~src/views/tentative/detect/test-form.vue'),
+                    },
+                ],
+            },
+            {
+                path: '/tentative/collect',
+                name: 'tentative-collect',
+                redirect: '/tentative/collect/approach',
+                meta: { title: '汇总管理' },
+                children: [
+                    {
+                        path: '/tentative/collect/test',
+                        name: 'tentative-collect-test',
+                        meta: { title: '试验汇总' },
+                        component: () => import('~src/views/tentative/collect/test.vue'),
+                    },
+                    {
+                        path: '/tentative/collect/monthly',
+                        name: 'tentative-collect-monthly',
+                        meta: { title: '月报汇总' },
+                        component: () => import('~src/views/tentative/collect/monthly.vue'),
+                    },
+                ],
+            },
+            {
+                path: '/tentative/device',
+                name: 'tentative-device',
+                redirect: '/tentative/device/approach',
+                meta: { title: '设备管理' },
+                children: [
+                    {
+                        path: '/tentative/device/approach',
+                        name: 'tentative-device-approach',
+                        meta: { title: '设备进场管理' },
+                        component: () => import('~src/views/tentative/device/approach.vue'),
+                    },
+                    {
+                        path: '/tentative/device/employ',
+                        name: 'tentative-device-employ',
+                        meta: { title: '设备使用管理' },
+                        component: () => import('~src/views/tentative/device/employ.vue'),
+                    },
+                    {
+                        path: '/tentative/device/overhaul',
+                        name: 'tentative-device-overhaul',
+                        meta: { title: '设备检修管理' },
+                        component: () => import('~src/views/tentative/device/overhaul.vue'),
+                    },
+                ],
+            },
+            {
+                path: '/tentative/parameter',
+                name: 'tentative-parameter',
+                redirect: '/tentative/parameter/container',
+                meta: { title: '参数设置' },
+                children: [
+                    {
+                        path: '/tentative/parameter/container',
+                        name: 'tentative-parameter-container',
+                        meta: { title: '试验容器' },
+                        component: () => import('~src/views/tentative/parameter/container.vue'),
+                    },
+                    {
+                        path: '/tentative/parameter/sieve',
+                        name: 'tentative-parameter-sieve',
+                        meta: { title: '自定义筛孔类型' },
+                        component: () => import('~src/views/tentative/parameter/sieve.vue'),
+                    },
+                    {
+                        path: '/tentative/parameter/density',
+                        name: 'tentative-parameter-density',
+                        meta: { title: '温度及密度参数' },
+                        component: () => import('~src/views/tentative/parameter/density.vue'),
+                    },
+                    {
+                        path: '/tentative/parameter/compactness',
+                        name: 'tentative-parameter-compactness',
+                        meta: { title: '压实度评标参数' },
+                        component: () => import('~src/views/tentative/parameter/compactness.vue'),
+                    },
+                ],
+            },
+            {
+                path: '/tentative/laboratory',
+                name: 'tentative-laboratory',
+                redirect: '/tentative/laboratory/container',
+                meta: { title: '实验室管理' },
+                children: [
+                    {
+                        path: '/tentative/laboratory/user',
+                        name: 'tentative-laboratory-user',
+                        meta: { title: '人员档案' },
+                        component: () => import('~src/views/tentative/laboratory/user.vue'),
+                    },
+                    {
+                        path: '/tentative/laboratory/print',
+                        name: 'tentative-laboratory-print',
+                        meta: { title: '打印空表' },
+                        component: () => import('~src/views/tentative/laboratory/print.vue'),
+                    },
+                ],
             },
             },
-            // {
-            //     path: '/other/first-item',
-            //     name: 'other-first-item',
-            //     meta: {title: '首件工程'},
-            //     component: () => import('~src/views/other/first-item copy.vue')
-            // }
         ],
         ],
     },
     },
     {
     {
@@ -208,7 +365,7 @@ export default [
             {
             {
                 path: '/tasks/hc-data',
                 path: '/tasks/hc-data',
                 name: 'tasks-data',
                 name: 'tasks-data',
-                meta: { title: '待办任务、已办任务、任务查看' },
+                meta: { title: '任务查看' },
                 component: () => import('~src/views/tasks/hc-data.vue'),
                 component: () => import('~src/views/tasks/hc-data.vue'),
             },
             },
             {
             {
@@ -231,162 +388,6 @@ export default [
             },
             },
         ],
         ],
     },
     },
-    {
-        path: '/tentative/material',
-        name: 'tentative-material',
-        redirect: '/tentative/material/approach',
-        meta: { title: '材料管理' },
-        component: Layout,
-        children: [
-            {
-                path: '/tentative/material/approach',
-                name: 'tentative-material-approach',
-                meta: { title: '材料进场' },
-                component: () => import('~src/views/tentative/material/approach.vue'),
-            },
-            {
-                path: '/tentative/material/sampling',
-                name: 'tentative-material-sampling',
-                meta: { title: '材料取样' },
-                component: () => import('~src/views/tentative/material/sampling.vue'),
-            },
-        ],
-    },
-    {
-        path: '/tentative/detect',
-        name: 'tentative-detect',
-        redirect: '/tentative/detect/approach',
-        meta: { title: '试验检测' },
-        component: Layout,
-        children: [
-            {
-                path: '/tentative/detect/third',
-                name: 'tentative-detect-third',
-                meta: { title: '外委检测' },
-                component: () => import('~src/views/tentative/detect/third.vue'),
-            },
-            {
-                path: '/tentative/detect/outside',
-                name: 'tentative-detect-outside',
-                meta: { title: '第三方检测' },
-                component: () => import('~src/views/tentative/detect/outside.vue'),
-            },
-            {
-                path: '/tentative/detect/test',
-                name: 'tentative-detect-test',
-                meta: { title: '试验检测' },
-                component: () => import('~src/views/tentative/detect/test.vue'),
-            },
-            {
-                path: '/tentative/detect/test-form',
-                name: 'tentative-detect-test-form',
-                meta: { title: '试验检测表单' },
-                component: () => import('~src/views/tentative/detect/test-form.vue'),
-            },
-        ],
-    },
-    {
-        path: '/tentative/collect',
-        name: 'tentative-collect',
-        redirect: '/tentative/collect/approach',
-        meta: { title: '汇总管理' },
-        component: Layout,
-        children: [
-            {
-                path: '/tentative/collect/test',
-                name: 'tentative-collect-test',
-                meta: { title: '试验汇总' },
-                component: () => import('~src/views/tentative/collect/test.vue'),
-            },
-            {
-                path: '/tentative/collect/monthly',
-                name: 'tentative-collect-monthly',
-                meta: { title: '月报汇总' },
-                component: () => import('~src/views/tentative/collect/monthly.vue'),
-            },
-        ],
-    },
-    {
-        path: '/tentative/device',
-        name: 'tentative-device',
-        redirect: '/tentative/device/approach',
-        meta: { title: '设备管理' },
-        component: Layout,
-        children: [
-            {
-                path: '/tentative/device/approach',
-                name: 'tentative-device-approach',
-                meta: { title: '设备进场管理' },
-                component: () => import('~src/views/tentative/device/approach.vue'),
-            },
-            {
-                path: '/tentative/device/employ',
-                name: 'tentative-device-employ',
-                meta: { title: '设备使用管理' },
-                component: () => import('~src/views/tentative/device/employ.vue'),
-            },
-            {
-                path: '/tentative/device/overhaul',
-                name: 'tentative-device-overhaul',
-                meta: { title: '设备检修管理' },
-                component: () => import('~src/views/tentative/device/overhaul.vue'),
-            },
-        ],
-    },
-    {
-        path: '/tentative/parameter',
-        name: 'tentative-parameter',
-        redirect: '/tentative/parameter/container',
-        meta: { title: '参数设置' },
-        component: Layout,
-        children: [
-            {
-                path: '/tentative/parameter/container',
-                name: 'tentative-parameter-container',
-                meta: { title: '试验容器' },
-                component: () => import('~src/views/tentative/parameter/container.vue'),
-            },
-            {
-                path: '/tentative/parameter/sieve',
-                name: 'tentative-parameter-sieve',
-                meta: { title: '自定义筛孔类型' },
-                component: () => import('~src/views/tentative/parameter/sieve.vue'),
-            },
-            {
-                path: '/tentative/parameter/density',
-                name: 'tentative-parameter-density',
-                meta: { title: '温度及密度参数' },
-                component: () => import('~src/views/tentative/parameter/density.vue'),
-            },
-            {
-                path: '/tentative/parameter/compactness',
-                name: 'tentative-parameter-compactness',
-                meta: { title: '压实度评标参数' },
-                component: () => import('~src/views/tentative/parameter/compactness.vue'),
-            },
-        ],
-    },
-    {
-        path: '/tentative/laboratory',
-        name: 'tentative-laboratory',
-        redirect: '/tentative/laboratory/container',
-        meta: { title: '实验室管理' },
-        component: Layout,
-        children: [
-            {
-                path: '/tentative/laboratory/user',
-                name: 'tentative-laboratory-user',
-                meta: { title: '人员档案' },
-                component: () => import('~src/views/tentative/laboratory/user.vue'),
-            },
-            {
-                path: '/tentative/laboratory/print',
-                name: 'tentative-laboratory-print',
-                meta: { title: '打印空表' },
-                component: () => import('~src/views/tentative/laboratory/print.vue'),
-            },
-        ],
-    },
     {
     {
         path: '/other',
         path: '/other',
         name: 'other',
         name: 'other',

+ 23 - 0
src/styles/app/element.scss

@@ -15,3 +15,26 @@
         text-align: left;
         text-align: left;
     }
     }
 }
 }
+
+.el-dialog__footer .el-button {
+    border-radius: 0;
+    padding: 0 10px;
+    font-weight: initial;
+    height: 28px;
+    font-size: 14px;
+}
+
+//新改变版按钮
+.el-button[hc-btn] {
+    border-radius: 0;
+    padding: 0 10px;
+    font-weight: initial;
+    height: 28px;
+    font-size: 14px;
+    border: 0;
+    box-shadow: none;
+}
+
+.el-button + .el-button {
+    margin-left: 10px;
+}

+ 3 - 1
src/styles/app/main.scss

@@ -1,6 +1,8 @@
 html, body, #app {
 html, body, #app {
     height: 100%;
     height: 100%;
-    background-color: #F1F5F8;
+    font-size: 14px;
+    background-color: #F0F2F5;
+    overflow: hidden;
 }
 }
 
 
 embed {
 embed {

+ 8 - 4
src/styles/data-fill/wbs.scss

@@ -5,10 +5,10 @@
     .hc-layout-left-box {
     .hc-layout-left-box {
         width: 382px;
         width: 382px;
         position: relative;
         position: relative;
-        background: #f1f5f8;
+        background: white;
         border-radius: 10px;
         border-radius: 10px;
         transition: 0.2s;
         transition: 0.2s;
-        margin-right: 24px;
+        margin-right: 16px;
         margin-left: -24px;
         margin-left: -24px;
         visibility: hidden;
         visibility: hidden;
         box-shadow: -2px 0 10px 0 rgba(32, 37, 50, 0.03), 0 10px 21px 20px rgba(32, 37, 50, 0.03);
         box-shadow: -2px 0 10px 0 rgba(32, 37, 50, 0.03), 0 10px 21px 20px rgba(32, 37, 50, 0.03);
@@ -49,13 +49,17 @@
             position: relative;
             position: relative;
             padding: 15px 20px;
             padding: 15px 20px;
             height: calc(100% - 187px);
             height: calc(100% - 187px);
+            .hc-tree-back-to {
+                font-size: 12px;
+                margin-bottom: 10px;
+            }
             .hc-search-tree-val {
             .hc-search-tree-val {
                 position: relative;
                 position: relative;
-                margin-bottom: 24px;
+                margin-bottom: 10px;
             }
             }
             .hc-tree-scrollbar {
             .hc-tree-scrollbar {
                 position: relative;
                 position: relative;
-                height: calc(100% - 68px);
+                height: calc(100% - 44px);
             }
             }
         }
         }
         .hc-tree-foot-tip-box {
         .hc-tree-foot-tip-box {

+ 17 - 2
src/styles/view/home.scss

@@ -1,7 +1,22 @@
 .home-styles-box {
 .home-styles-box {
-    position: relative;
-    height: 100%;
+    position: absolute;
+    inset: 0;
     overflow: hidden;
     overflow: hidden;
+    margin: -12px;
+    .hc-home-bg-box {
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        right: 0;
+        top: 0;
+        z-index: 0;
+        display: flex;
+        img {
+            width: 100%;
+            height: 100%;
+            object-fit: cover;
+        }
+    }
     .hc-home-input-box {
     .hc-home-input-box {
         position: relative;
         position: relative;
         height: 100%;
         height: 100%;

+ 78 - 61
src/views/data-fill/collapse-form/index.scss

@@ -6,33 +6,63 @@ table {
     .hc-collapse-item-header {
     .hc-collapse-item-header {
         flex: 1;
         flex: 1;
         position: relative;
         position: relative;
-        margin-left: 46px;
+        margin-left: 10px;
         display: flex;
         display: flex;
         align-items: center;
         align-items: center;
+        .real-fill-rate {
+            position: relative;
+            height: 100%;
+            line-height: initial;
+            margin-right: 18px;
+            padding-right: 18px;
+            &::after {
+                content: "";
+                background: #bfc8cf;
+                position: absolute;
+                right: 0;
+                height: 100%;
+                width: 1px;
+                top: 0;
+            }
+            .tag {
+                position: relative;
+                background: white;
+                font-size: 12px;
+                color: #BD3124;
+                padding: 1px 6px;
+                border-radius: 3px;
+                border: 1px solid #BD3124;
+                margin-bottom: 2px;
+                margin-top: 2px;
+            }
+            .tag.yes {
+                color: #88CF65;
+                border-color: #88CF65;
+            }
+        }
         .item-title {
         .item-title {
             flex: 1;
             flex: 1;
             position: relative;
             position: relative;
             user-select: none;
             user-select: none;
-            color: #50545E;
+            color: #591BB7;
             font-size: 16px;
             font-size: 16px;
-            font-weight: 400;
+            font-weight: bold;
             cursor: pointer;
             cursor: pointer;
         }
         }
         .hc-extra-text-box {
         .hc-extra-text-box {
             position: relative;
             position: relative;
             padding-right: 24px;
             padding-right: 24px;
+            line-height: initial;
         }
         }
     }
     }
     .data-fill-list-item-content {
     .data-fill-list-item-content {
         position: relative;
         position: relative;
-        display: flex;
-        height: calc(100vh - 386px);
+        height: calc(100vh - 222px);
         .data-fill-table-form-box {
         .data-fill-table-form-box {
-            flex: 1;
             position: relative;
             position: relative;
-            height: 100%;
+            height: calc(100% - 36px);
             overflow: hidden;
             overflow: hidden;
-            border: 8px solid #c4c4c4;
+            border: 4px solid #c4c4c4;
             &.is-window {
             &.is-window {
                 border: 0;
                 border: 0;
                 .hc-window-tip {
                 .hc-window-tip {
@@ -55,64 +85,21 @@ table {
                 }
                 }
             }
             }
         }
         }
-        .hc-window-switch-box {
+        .data-fill-table-action {
+            position: relative;
             display: flex;
             display: flex;
             align-items: center;
             align-items: center;
-            position: absolute;
-            top: 14px;
-            right: 260px;
-            .icon-btn-view {
-                padding: 0 18px;
-                height: 34px;
-                display: flex;
-                align-items: center;
-                justify-content: center;
-                color: #ffffff;
+            padding: 4px 10px;
+            .tip-action {
                 cursor: pointer;
                 cursor: pointer;
-                user-select: none;
-                border-radius: 80px;
-                box-shadow: 4px 4px 8px 0 rgba(54, 92, 167, 0.15), -3px -2px 8px 0 #ffffff;
-                background: linear-gradient(to right, var(--el-color-primary-light-5), var(--el-color-primary), var(--el-color-primary-dark-2));
-                background-size: 200%;
-                transition: background-position .5s;
-                .icon {
-                    font-size: 16px;
-                }
-                &:hover {
-                    background-position: 100% 0;
-                }
-            }
-        }
-        .data-fill-table-tip-box {
-            width: 240px;
-            position: relative;
-            border-left: 1px solid #E9E9E9;
-            padding: 20px 15px 80px;
-            .tip-title {
-                font-size: 16px;
-                margin-bottom: 10px;
-                display: flex;
-                align-items: center;
+                margin-right: 24px;
             }
             }
-            .tip-item {
-                margin-bottom: 20px;
+            .link-action {
+                position: relative;
+                flex: 1;
             }
             }
-            .table-tip-foot {
-                position: absolute;
-                bottom: 15px;
-                right: 0;
-                left: 0;
-                display: flex;
-                align-items: center;
-                padding: 0 15px;
-                .tip-left-btn {
-                    flex: 1;
-                    .dow-text {
-                        cursor: pointer;
-                        display: flex;
-                        align-items: center;
-                    }
-                }
+            .btn-action {
+                position: relative;
             }
             }
         }
         }
     }
     }
@@ -120,3 +107,33 @@ table {
 .radio-group-box {
 .radio-group-box {
     text-align: center;
     text-align: center;
 }
 }
+
+.data-fill-table-tip-box {
+    position: relative;
+    .tip-title {
+        font-size: 16px;
+        margin-bottom: 10px;
+        display: flex;
+        align-items: center;
+    }
+    .tip-item {
+        margin-bottom: 20px;
+    }
+    .table-tip-foot {
+        position: absolute;
+        bottom: 15px;
+        right: 0;
+        left: 0;
+        display: flex;
+        align-items: center;
+        padding: 0 15px;
+        .tip-left-btn {
+            flex: 1;
+            .dow-text {
+                cursor: pointer;
+                display: flex;
+                align-items: center;
+            }
+        }
+    }
+}

+ 88 - 147
src/views/data-fill/collapse-form/index.vue

@@ -8,92 +8,43 @@
             >
             >
                 <template #title>
                 <template #title>
                     <div class="hc-collapse-item-header">
                     <div class="hc-collapse-item-header">
-                        <div class="text-lg truncate item-title">
-                            <span v-if="item.realFillRate > 0" class="text-blue mr-3"> 【已填报:{{ item.realFillRate }}%】</span> {{ item.nodeName }}
+                        <div class="real-fill-rate">
+                            <div class="tag" :class="item.realFillRate >= 80 ? 'yes' : ''">已填{{ item.realFillRate ?? 0 }}%</div>
+                            <HcTooltip v-if="isStatus !== 3" keys="wbs_preview_table">
+                                <el-link v-if="item.isBussShow === 2 || item.isTabPdf === 1 || item.pdfUrl === '' || item.pdfUrl === null" type="primary" disabled>本 表 预 览</el-link>
+                                <el-link v-else type="primary" :disabled="tableFormPreviewLoading" @click.stop="previewClick(item)">本 表 预 览</el-link>
+                            </HcTooltip>
                         </div>
                         </div>
+                        <div class="text-lg truncate item-title">{{ item.nodeName }}</div>
                         <div class="hc-extra-text-box">
                         <div class="hc-extra-text-box">
                             <HcTooltip v-if="item.isCopeTab === 2 || item.isCopeTab === 3" keys="wbs_del_table">
                             <HcTooltip v-if="item.isCopeTab === 2 || item.isCopeTab === 3" keys="wbs_del_table">
-                                <el-button
-                                    :disabled="item.isBussShow === 2"
-                                    :loading="tableFormDelLoading"
-                                    plain
-                                    type="danger"
-                                    @click.stop="delClick(item, index)"
-                                >
-                                    删除本表
-                                </el-button>
+                                <el-link type="danger" :disabled="item.isBussShow === 2 || tableFormDelLoading" @click.stop="delClick(item, index)">删除本表</el-link>
                             </HcTooltip>
                             </HcTooltip>
                             <HcTooltip keys="wbs_copy_table">
                             <HcTooltip keys="wbs_copy_table">
-                                <el-button
-                                    v-if="item.isLinkTable === 1 || item.isBussShow === 2"
-                                    disabled plain
-                                    type="info"
-                                >
-                                    复制本表
-                                </el-button>
-                                <el-button
-                                    v-else :loading="copyClickLoading" plain type="primary"
-                                    @click.stop="copyClick(item, index)"
-                                >
-                                    复制本表
-                                </el-button>
-                            </HcTooltip>
-                            <HcTooltip keys="wbs_hide_table">
-                                <el-button
-                                    :loading="tableFormHideLoading" plain type="primary"
-                                    @click.stop="hideClick(item, index)"
-                                >
-                                    <template v-if="item.isBussShow === 1 || item.isBussShow === null">
-                                        隐藏本表
-                                    </template>
-                                    <template v-else>
-                                        显示本表
-                                    </template>
-                                </el-button>
-                            </HcTooltip>
-                            <HcTooltip v-if="isStatus !== 3" keys="wbs_preview_table">
-                                <el-button
-                                    v-if="item.isBussShow === 2 || item.isTabPdf === 1 || item.pdfUrl === '' || item.pdfUrl === null"
-                                    disabled plain
-                                    type="info"
-                                >
-                                    预览
-                                </el-button>
-                                <el-button
-                                    v-else :loading="tableFormPreviewLoading" plain type="primary"
-                                    @click.stop="previewClick(item)"
-                                >
-                                    预览
-                                </el-button>
+                                <el-link v-if="item.isLinkTable === 1 || item.isBussShow === 2" type="primary" disabled>复制本表</el-link>
+                                <el-link v-else type="primary" :disabled="copyClickLoading" @click.stop="copyClick(item, index)">复制本表</el-link>
                             </HcTooltip>
                             </HcTooltip>
                             <HcTooltip keys="wbs_upload_table">
                             <HcTooltip keys="wbs_upload_table">
-                                <el-button
-
-                                    :type="item.tabFileType === 2 ? 'success' : 'primary'" plain
-                                    @click.stop="uploadClick(item, index)"
-                                >
-                                    <template v-if="item.tabFileType === 2">
-                                        已上传
-                                    </template>
-                                    <template v-else>
-                                        上传
-                                    </template>
-                                </el-button>
+                                <el-link :type="item.tabFileType === 2 ? 'success' : 'primary'" @click.stop="uploadClick(item, index)">
+                                    <template v-if="item.tabFileType === 2">已上传</template>
+                                    <template v-else>附件上传</template>
+                                </el-link>
+                            </HcTooltip>
+                            <HcTooltip keys="wbs_hide_table">
+                                <el-link type="primary" :disabled="tableFormHideLoading" @click.stop="hideClick(item, index)">
+                                    <template v-if="item.isBussShow === 1 || item.isBussShow === null">隐藏本表</template>
+                                    <template v-else>显示本表</template>
+                                </el-link>
                             </HcTooltip>
                             </HcTooltip>
                         </div>
                         </div>
                     </div>
                     </div>
                 </template>
                 </template>
-                <div
-                    :style="`height: calc(100vh - ${draw_type ? '555px' : '360px'});`"
-                    class="data-fill-list-item-content"
-                >
+                <div :style="`height: calc(100vh - ${draw_type ? '555px' : '222px'});`" class="data-fill-list-item-content">
                     <div v-if="item?.isWindow" class="data-fill-table-form-box is-window">
                     <div v-if="item?.isWindow" class="data-fill-table-form-box is-window">
                         <div class="hc-window-tip">
                         <div class="hc-window-tip">
                             <div class="table-form-no">
                             <div class="table-form-no">
                                 <img :src="NoDataSvg" alt="">
                                 <img :src="NoDataSvg" alt="">
-                                <div class="desc">
-                                    当前表单处于窗口模式,关闭相关窗口后恢复
-                                </div>
+                                <div class="desc">当前表单处于窗口模式,关闭相关窗口后恢复</div>
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>
@@ -112,82 +63,41 @@
                             @rightTap="tableFormRightTap($event, index)"
                             @rightTap="tableFormRightTap($event, index)"
                         />
                         />
                     </div>
                     </div>
-                    <div class="hc-window-switch-box">
-                        <el-tooltip
-                            :content="item.isWindow ? '关闭窗口并恢复' : '当前表单窗口化'" :hide-after="0"
-                            placement="top"
-                        >
-                            <div class="icon-btn-view" @click.stop="windowClick(item, index)">
-                                <template v-if="item.isWindow">
-                                    <HcIcon class="icon" name="picture-in-picture-2" />
-                                    <span class="ml-1">关闭窗口化</span>
-                                </template>
-                                <template v-else>
-                                    <HcIcon class="icon" name="picture-in-picture-exit" />
-                                    <span class="ml-1">表单窗口化</span>
-                                </template>
-                            </div>
-                        </el-tooltip>
-                    </div>
-                    <div class="data-fill-table-tip-box">
-                        <el-scrollbar>
-                            <div class="text-orange tip-title">
-                                <HcIcon fill name="information" ui="text-2xl" />
-                                <span class="ml-1">提示</span>
-                            </div>
-                            <div class="text-gray-400 tip-item">
-                                1、灰色框代表可通过系统识别计算,公式自动引用,可通过公式计算少量数据,(表头数据及简单),也可只填写白色框数据
-                            </div>
-                            <div class="text-gray-400 tip-item">
-                                2、系统支持键盘中,shift +
-                                tab键向上一个填报框切换,tab向下一个填报框切换。Shift + 上 ( ↑ )、下 ( ↓ )、左 ( ← )、右 ( →
-                                )键,切换填报输入框焦点。
-                            </div>
-                            <div class="text-gray-400 tip-item">
-                                3、先点击一下表单任一区域,再键盘按住 ⌘/ctrl +
-                                点击,选择输入框,变为绿色边框,选中成功。选择完毕后,键盘按 ⌘/ctrl + c 复制所选中的数据,
-                                再其它表内,或同一张表内,再次按住 ⌘/ctrl + 点击,选择输入框。键盘按 ⌘/ctrl + v
-                                依次粘贴所选的数据。(目前仅支持输入框和文本框的操作)
-                            </div>
-                            <div class="text-orange-500 tip-item">
-                                4、完善资料填写后记得一定要保存哦
-                            </div>
-                        </el-scrollbar>
-                        <div class="table-tip-foot">
-                            <div class="tip-left-btn">
-                                <HcTooltip keys="wbs_import_table">
-                                    <div class="text-main dow-text" @click="uploadFileClick(item)">
-                                        <HcIcon name="publish" ui="text-lg" />
-                                        <span class="ml-1">导入表格数据</span>
-                                    </div>
-                                </HcTooltip>
-                                <HcUploadFile
-                                    ref="dataHcUploadFileRef"
-                                    :params="{ pKeyId: checkItem.pkeyId }"
-                                    :options="UploadFileOptions"
-                                    multiple="false"
-                                    @success="HcUploadFileSuccess"
-                                />
-                                <HcTooltip keys="wbs_download_table">
-                                    <div v-loading="downloadLoading" class="text-main dow-text" @click="downModal(item)">
-                                        <HcIcon name="file_download" ui="text-lg" />
-                                        <span class="ml-1">下载导入模板</span>
-                                    </div>
-                                </HcTooltip>
-                            </div>
-                            <div class="tip-right-btn">
-                                <HcTooltip keys="wbs_save_table">
-                                    <el-button
-                                        :disabled="!item?.isTableForm"
-                                        :loading="tableFormSaveLoading" hc-btn
-                                        type="primary"
-                                        @click="tableFormSaveClick(item)"
-                                    >
-                                        <HcIcon name="save" />
-                                        <span>保存</span>
-                                    </el-button>
-                                </HcTooltip>
-                            </div>
+                    <div class="data-fill-table-action">
+                        <div class="text-orange tip-action" @click="actionTipModal = true">
+                            <HcIcon fill name="information" ui="text-2xl" />
+                        </div>
+                        <div v-loading="downloadLoading" class="link-action">
+                            <HcTooltip keys="wbs_download_table">
+                                <el-link type="primary" :disabled="downloadLoading" @click="downModal(item)">下载导入模板</el-link>
+                            </HcTooltip>
+                            <HcTooltip keys="wbs_import_table">
+                                <el-link type="primary" @click="uploadFileClick(item)">导入表格数据</el-link>
+                            </HcTooltip>
+                            <HcUploadFile
+                                ref="dataHcUploadFileRef"
+                                :params="{ pKeyId: checkItem.pkeyId }"
+                                :options="UploadFileOptions"
+                                multiple="false"
+                                @success="HcUploadFileSuccess"
+                            />
+                        </div>
+                        <div class="btn-action">
+                            <el-tooltip :content="item.isWindow ? '关闭窗口并恢复' : '当前表单窗口化'" :hide-after="0" placement="top">
+                                <el-button type="primary" size="small" @click.stop="windowClick(item, index)">
+                                    <template v-if="item.isWindow">关闭窗口化</template>
+                                    <template v-else>表单窗口化</template>
+                                </el-button>
+                            </el-tooltip>
+                            <HcTooltip keys="wbs_save_table">
+                                <el-button
+                                    :disabled="!item?.isTableForm" :loading="tableFormSaveLoading"
+                                    color="#3794FF" size="small" style="color: white"
+                                    @click="tableFormSaveClick(item)"
+                                >
+                                    仅保存本表数据
+                                </el-button>
+                            </HcTooltip>
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
@@ -203,6 +113,29 @@
         <HcUpload :datas="uploadData" :file-list="fileListData" :is-canupload="isStatus == 3" @change="uploadChange" />
         <HcUpload :datas="uploadData" :file-list="fileListData" :is-canupload="isStatus == 3" @change="uploadChange" />
     </HcDialog>
     </HcDialog>
 
 
+    <!-- 操作提示 -->
+    <HcDialog :footer="false" :show="actionTipModal" title="操作提示" widths="38rem" @close="actionTipModalClose">
+        <div class="data-fill-table-tip-box">
+            <div class="text-gray-400 tip-item">
+                1、灰色框代表可通过系统识别计算,公式自动引用,可通过公式计算少量数据,(表头数据及简单),也可只填写白色框数据
+            </div>
+            <div class="text-gray-400 tip-item">
+                2、系统支持键盘中,shift +
+                tab键向上一个填报框切换,tab向下一个填报框切换。Shift + 上 ( ↑ )、下 ( ↓ )、左 ( ← )、右 ( →
+                )键,切换填报输入框焦点。
+            </div>
+            <div class="text-gray-400 tip-item">
+                3、先点击一下表单任一区域,再键盘按住 ⌘/ctrl +
+                点击,选择输入框,变为绿色边框,选中成功。选择完毕后,键盘按 ⌘/ctrl + c 复制所选中的数据,
+                再其它表内,或同一张表内,再次按住 ⌘/ctrl + 点击,选择输入框。键盘按 ⌘/ctrl + v
+                依次粘贴所选的数据。(目前仅支持输入框和文本框的操作)
+            </div>
+            <div class="text-orange-500 tip-item">
+                4、完善资料填写后记得一定要保存哦
+            </div>
+        </div>
+    </HcDialog>
+
     <!-- 插入设计值/频率 -->
     <!-- 插入设计值/频率 -->
     <HcDialog
     <HcDialog
         :loading="designModalLoading" :show="designModal" is-to-body save-text="确认插入"
         :loading="designModalLoading" :show="designModal" is-to-body save-text="确认插入"
@@ -1666,6 +1599,14 @@ const waterSaveClick = async ()=>{
     waterModal.value = false
     waterModal.value = false
 }
 }
 
 
+
+//操作提示
+const actionTipModal = ref(false)
+const actionTipModalClose = () => {
+    actionTipModal.value = false
+}
+
+
 // 暴露出去
 // 暴露出去
 defineExpose({
 defineExpose({
     getFormData,
     getFormData,

+ 16 - 8
src/views/data-fill/collapse-form/style.scss

@@ -7,11 +7,11 @@
 
 
 .data-fill-list-box {
 .data-fill-list-box {
     .el-collapse {
     .el-collapse {
-        --el-collapse-header-height: 60px;
+        --el-collapse-header-height: 50px;
         border: 0;
         border: 0;
         .el-collapse-item {
         .el-collapse-item {
-            margin: 0 0 16px;
-            background-color: #f1f5f8;
+            margin: 0 0 6px;
+            background-color: #E6EEF4;
             border: 1px solid #E9E9E9;
             border: 1px solid #E9E9E9;
             border-radius: 4px;
             border-radius: 4px;
         }
         }
@@ -22,11 +22,7 @@
             cursor: default;
             cursor: default;
             font-size: 14px;
             font-size: 14px;
             .el-collapse-item__arrow {
             .el-collapse-item__arrow {
-                position: absolute;
-                color: #50545E;
-                cursor: pointer;
-                left: 20px;
-                margin: 0;
+               display: none;
             }
             }
         }
         }
         .el-collapse-item.is-active .el-collapse-item__header.is-active {
         .el-collapse-item.is-active .el-collapse-item__header.is-active {
@@ -44,6 +40,18 @@
             }
             }
         }
         }
     }
     }
+    .hc-collapse-item-header .real-fill-rate .el-link {
+        font-size: 12px;
+    }
+    .el-link {
+        text-decoration: underline;
+        &:hover {
+            text-decoration: auto;
+        }
+    }
+    .el-link + .el-link {
+        margin-left: 20px;
+    }
 }
 }
 .data-fill-list-box .data-fill-table-form-box .hc-table-form-data-item {
 .data-fill-list-box .data-fill-table-form-box .hc-table-form-data-item {
     padding: 0;
     padding: 0;

+ 5 - 8
src/views/data-fill/division.vue

@@ -6,10 +6,7 @@
                     <HcIcon name="stack" />
                     <HcIcon name="stack" />
                 </div>
                 </div>
                 <div class="ml-2 project-name-box">
                 <div class="ml-2 project-name-box">
-                    <span class="text-xl text-cut project-alias">{{ projectInfo.projectAlias }}</span>
-                    <div class="text-xs text-cut project-name">
-                        {{ projectInfo.name }}
-                    </div>
+                    <div class="project-name">{{ projectInfo.name }}</div>
                 </div>
                 </div>
             </div>
             </div>
             <div v-loading="treeLoading" class="hc-tree-box" element-loading-text="加载中...">
             <div v-loading="treeLoading" class="hc-tree-box" element-loading-text="加载中...">
@@ -70,7 +67,7 @@
                 </HcCard>
                 </HcCard>
             </div>
             </div>
             <div class="footer-box">
             <div class="footer-box">
-                <el-button hc-btn @click="downloadXlsx">
+                <el-button hc-btn color="#A16222" @click="downloadXlsx">
                     <HcIcon name="download-2" />
                     <HcIcon name="download-2" />
                     <span>下载导入划分模板</span>
                     <span>下载导入划分模板</span>
                 </el-button>
                 </el-button>
@@ -78,7 +75,7 @@
                     <HcIcon name="folder-upload" />
                     <HcIcon name="folder-upload" />
                     <span>导入划分模板</span>
                     <span>导入划分模板</span>
                 </el-button>
                 </el-button>
-                <el-button hc-btn @click="toBackClick">
+                <el-button hc-btn color="#e03997" @click="toBackClick">
                     <HcIcon name="arrow-go-back" />
                     <HcIcon name="arrow-go-back" />
                     <span>进入资料填报</span>
                     <span>进入资料填报</span>
                 </el-button>
                 </el-button>
@@ -252,7 +249,7 @@
         <!-- 新增子节点 -->
         <!-- 新增子节点 -->
         <HcDialog
         <HcDialog
             :loading="addNodeLoading" :show="addNodeModal" loading-text="新增节点中,请耐心等待..."
             :loading="addNodeLoading" :show="addNodeModal" loading-text="新增节点中,请耐心等待..."
-            title="新增子节点" widths="720px" @close="addNodeModal = false" 
+            title="新增子节点" widths="720px" @close="addNodeModal = false"
         >
         >
             <el-alert
             <el-alert
                 :closable="false" title="双击节点,可编辑节点名称,编辑完成后,请按回车或输入框消失后,再点提交"
                 :closable="false" title="双击节点,可编辑节点名称,编辑完成后,请按回车或输入框消失后,再点提交"
@@ -722,7 +719,7 @@ const ElTreeMenuClick = async ({ key, node, data, keys }) => {
         addTreeNodeOldId.value = data?.oldId
         addTreeNodeOldId.value = data?.oldId
         addNodeLoading.value = false
         addNodeLoading.value = false
         addNodeModal.value = true
         addNodeModal.value = true
-   
+
     } else if (key === 'copy') {
     } else if (key === 'copy') {
         const parent = deepClone(node?.parent?.data || {})
         const parent = deepClone(node?.parent?.data || {})
         formCopyNodeModel.value = { ...deepClone(data), parent: parent }
         formCopyNodeModel.value = { ...deepClone(data), parent: parent }

+ 19 - 58
src/views/data-fill/query.vue

@@ -6,37 +6,18 @@
                     <HcIcon name="stack" />
                     <HcIcon name="stack" />
                 </div>
                 </div>
                 <div class="ml-2 project-name-box">
                 <div class="ml-2 project-name-box">
-                    <span class="text-xl text-cut project-alias">{{ projectInfo.projectAlias }}</span>
-                    <div class="text-xs text-cut project-name">
-                        {{ projectInfo.name }}
-                    </div>
+                    <div class="project-alias">{{ projectInfo.name }}</div>
                 </div>
                 </div>
             </div>
             </div>
             <div class="hc-tree-box">
             <div class="hc-tree-box">
                 <div class="hc-search-tree-val">
                 <div class="hc-search-tree-val">
-                    <el-input
-                        v-model="searchTreeVal" block clearable placeholder="请输入名称关键词检索" size="large"
-                        @keyup="searchTreeKeyUp"
-                    >
+                    <el-input v-model="searchTreeVal" block clearable placeholder="请输入名称关键词检索" @keyup="searchTreeKeyUp">
                         <template #suffix>
                         <template #suffix>
                             <HcIcon name="search-2" ui="text-xl iscusor" @click="searchTreeClick" />
                             <HcIcon name="search-2" ui="text-xl iscusor" @click="searchTreeClick" />
                         </template>
                         </template>
                     </el-input>
                     </el-input>
                 </div>
                 </div>
-                <div
-                    v-if="isShowLeft" id="hc-tree-scrollbar" v-loading="treeLoading"
-                    class="hc-tree-scrollbar"
-                    element-loading-text="获取数据中..."
-                >
-                    <!-- <HcTreeV2
-                        :isShow="isSearchTree"
-                        :datas="searchTreeData"
-                        :height="searchTreeHeight"
-                        :searchVal="searchTreeVal"
-                        isCounts
-                        isType
-                        @nodeTap="wbsElTreeClick"
-                    /> -->
+                <div v-if="isShowLeft" id="hc-tree-scrollbar" v-loading="treeLoading" class="hc-tree-scrollbar" element-loading-text="获取数据中...">
                     <el-scrollbar v-show="isSearchTree" class="scroll-bar-right-16">
                     <el-scrollbar v-show="isSearchTree" class="scroll-bar-right-16">
                         <HcDataTree
                         <HcDataTree
                             :datas="searchTreeData"
                             :datas="searchTreeData"
@@ -47,7 +28,6 @@
                             @nodeTap="wbsElTreeClick"
                             @nodeTap="wbsElTreeClick"
                         />
                         />
                     </el-scrollbar>
                     </el-scrollbar>
-
                     <el-scrollbar v-show="!isSearchTree" class="scroll-bar-right-16">
                     <el-scrollbar v-show="!isSearchTree" class="scroll-bar-right-16">
                         <HcLazyTree
                         <HcLazyTree
                             ref="wbstree"
                             ref="wbstree"
@@ -61,30 +41,19 @@
                 </div>
                 </div>
             </div>
             </div>
             <div class="hc-tree-foot-tip-box">
             <div class="hc-tree-foot-tip-box">
-                <div class="dot-view green">
-                    已审批
-                </div>
-                <div class="dot-view black">
-                    未填报
-                </div>
-                <div class="dot-view orange">
-                    已填报-待审批
-                </div>
-                <div class="dot-view blue">
-                    已填报-未上报
-                </div>
+                <div class="dot-view green">已审批</div>
+                <div class="dot-view black">未填报</div>
+                <div class="dot-view orange">已填报-待审批</div>
+                <div class="dot-view blue">已填报-未上报</div>
             </div>
             </div>
             <!-- 左右拖动 -->
             <!-- 左右拖动 -->
             <div class="horizontal-drag-line" @mousedown="onmousedown" />
             <div class="horizontal-drag-line" @mousedown="onmousedown" />
         </div>
         </div>
         <div class="hc-layout-content-box">
         <div class="hc-layout-content-box">
-            <HcCard :scrollbar="false" action-size="lg">
+            <HcNewCard :scrollbar="false" padding>
                 <template #header>
                 <template #header>
                     <HcTooltip keys="query_report">
                     <HcTooltip keys="query_report">
-                        <el-button
-                            :disabled="tableCheckedKeys.length <= 0" :loading="reportLoading" hc-btn
-                            type="primary" @click="reportModalClick"
-                        >
+                        <el-button :disabled="tableCheckedKeys.length <= 0" :loading="reportLoading" hc-btn color="#FF976A" style="color: white;" @click="reportModalClick">
                             <HcIcon name="send-plane-2" />
                             <HcIcon name="send-plane-2" />
                             <span>上报</span>
                             <span>上报</span>
                         </el-button>
                         </el-button>
@@ -92,7 +61,7 @@
                     <HcTooltip keys="query_download">
                     <HcTooltip keys="query_download">
                         <el-button
                         <el-button
                             :disabled="tableCheckedKeys.length <= 0" :loading="downloadLoading" hc-btn
                             :disabled="tableCheckedKeys.length <= 0" :loading="downloadLoading" hc-btn
-                            @click="batchDownload"
+                            color="#A16222" @click="batchDownload"
                         >
                         >
                             <HcIcon name="download" />
                             <HcIcon name="download" />
                             <span>下载</span>
                             <span>下载</span>
@@ -101,14 +70,14 @@
                     <HcTooltip keys="query_print">
                     <HcTooltip keys="query_print">
                         <el-button
                         <el-button
                             :disabled="tableCheckedKeys.length <= 0" :loading="printLoading" hc-btn
                             :disabled="tableCheckedKeys.length <= 0" :loading="printLoading" hc-btn
-                            @click="batchPrint"
+                            color="#A16222" @click="batchPrint"
                         >
                         >
                             <HcIcon name="printer" />
                             <HcIcon name="printer" />
                             <span>打印</span>
                             <span>打印</span>
                         </el-button>
                         </el-button>
                     </HcTooltip>
                     </HcTooltip>
                     <HcTooltip keys="query_abolish">
                     <HcTooltip keys="query_abolish">
-                        <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn @click="batchAbolishClick">
+                        <el-button :disabled="tableCheckedKeys.length <= 0" hc-btn color="#567722" @click="batchAbolishClick">
                             <HcIcon name="delete-bin-3" />
                             <HcIcon name="delete-bin-3" />
                             <span>废除</span>
                             <span>废除</span>
                         </el-button>
                         </el-button>
@@ -116,7 +85,7 @@
                     <HcTooltip keys="query_local_attestation">
                     <HcTooltip keys="query_local_attestation">
                         <el-button
                         <el-button
                             :disabled="tableCheckedKeys.length <= 0" :loading="localLoading" hc-btn
                             :disabled="tableCheckedKeys.length <= 0" :loading="localLoading" hc-btn
-                            @click="batchLocal"
+                            color="#e03997" @click="batchLocal"
                         >
                         >
                             <HcIcon name="folder-download" />
                             <HcIcon name="folder-download" />
                             <span>本地验签</span>
                             <span>本地验签</span>
@@ -125,7 +94,7 @@
                     <HcTooltip keys="query_online_attestation">
                     <HcTooltip keys="query_online_attestation">
                         <el-button
                         <el-button
                             :disabled="tableCheckedKeys.length <= 0" :loading="onlineLoading" hc-btn
                             :disabled="tableCheckedKeys.length <= 0" :loading="onlineLoading" hc-btn
-                            @click="batchOnline"
+                            color="#e03997" @click="batchOnline"
                         >
                         >
                             <HcIcon name="cloud" />
                             <HcIcon name="cloud" />
                             <span>在线验签</span>
                             <span>在线验签</span>
@@ -211,25 +180,17 @@
                     <div class="lr-dialog-footer">
                     <div class="lr-dialog-footer">
                         <div class="left">
                         <div class="left">
                             <span class="text-success">任务人员中:</span>
                             <span class="text-success">任务人员中:</span>
-                            <el-tag class="mx-1" effect="dark" type="info">
-                                未签字
-                            </el-tag>
-                            <el-tag class="mx-1" effect="dark" type="success">
-                                已签字
-                            </el-tag>
-                            <el-tag class="mx-1" effect="dark" type="warning">
-                                已废除
-                            </el-tag>
-                            <el-tag class="mx-1" effect="dark" type="danger">
-                                签字异常
-                            </el-tag>
+                            <el-tag class="mx-1" effect="dark" type="info">未签字</el-tag>
+                            <el-tag class="mx-1" effect="dark" type="success">已签字</el-tag>
+                            <el-tag class="mx-1" effect="dark" type="warning">已废除</el-tag>
+                            <el-tag class="mx-1" effect="dark" type="danger">签字异常</el-tag>
                         </div>
                         </div>
                         <div class="right">
                         <div class="right">
                             <HcPages :pages="searchForm" @change="pageChange" />
                             <HcPages :pages="searchForm" @change="pageChange" />
                         </div>
                         </div>
                     </div>
                     </div>
                 </template>
                 </template>
-            </HcCard>
+            </HcNewCard>
         </div>
         </div>
 
 
         <!-- 批量上报审批 -->
         <!-- 批量上报审批 -->

+ 59 - 120
src/views/data-fill/wbs.vue

@@ -3,7 +3,7 @@
         <div v-if="wbsTypeTabKey === 'tree'" v-loading="nodeSaveLoading" class="hc-layout-box" element-loading-text="批量保存数据中...">
         <div v-if="wbsTypeTabKey === 'tree'" v-loading="nodeSaveLoading" class="hc-layout-box" element-loading-text="批量保存数据中...">
             <div
             <div
                 id="wbs-left-tree" :class="[isWbsTreeShow ? 'show' : '', isMouseTree ? 'on-transition' : '']"
                 id="wbs-left-tree" :class="[isWbsTreeShow ? 'show' : '', isMouseTree ? 'on-transition' : '']"
-                :style="`width:${isWbsTreeShow ? leftWidth : 0}px;`"
+                :style="`width:${isWbsTreeShow ? leftWidth : 0}px; ${isWbsTreeShow ? '' : 'display: none'}`"
                 class="hc-layout-left-box"
                 class="hc-layout-left-box"
             >
             >
                 <div class="hc-project-box">
                 <div class="hc-project-box">
@@ -11,36 +11,22 @@
                         <HcIcon name="stack" />
                         <HcIcon name="stack" />
                     </div>
                     </div>
                     <div class="ml-2 project-name-box">
                     <div class="ml-2 project-name-box">
-                        <span class="text-xl text-cut project-alias">{{ projectInfo.projectAlias }}</span>
-                        <div class="text-xs text-cut project-name">
-                            {{ projectInfo.name }}
-                        </div>
+                        <div class="project-alias">{{ projectInfo.name }}</div>
                     </div>
                     </div>
                 </div>
                 </div>
                 <div class="hc-tree-box">
                 <div class="hc-tree-box">
+                    <div class="hc-tree-back-to">
+                        <el-link type="primary">回到上一次填报部位</el-link>
+                        <el-link type="warning" class="ml-4" @click="wbsMapTypeTab">导图结构填报</el-link>
+                    </div>
                     <div class="hc-search-tree-val">
                     <div class="hc-search-tree-val">
-                        <el-input
-                            v-model="searchTreeVal" block clearable placeholder="请输入名称关键词检索"
-                            size="large" @keyup="searchTreeKeyUp"
-                        >
+                        <el-input v-model="searchTreeVal" block clearable placeholder="请输入名称关键词检索" @keyup="searchTreeKeyUp">
                             <template #suffix>
                             <template #suffix>
                                 <HcIcon name="search-2" ui="text-xl iscusor" @click="searchTreeClick" />
                                 <HcIcon name="search-2" ui="text-xl iscusor" @click="searchTreeClick" />
                             </template>
                             </template>
                         </el-input>
                         </el-input>
                     </div>
                     </div>
                     <div v-if="isShowLeft" id="hc-tree-scrollbar" v-loading="treeLoading" class="hc-tree-scrollbar" element-loading-text="获取数据中...">
                     <div v-if="isShowLeft" id="hc-tree-scrollbar" v-loading="treeLoading" class="hc-tree-scrollbar" element-loading-text="获取数据中...">
-                        <!-- <HcTreeV2
-                            :isShow="isSearchTree"
-                            :datas="searchTreeData"
-                            :height="searchTreeHeight"
-                            :isMark="TreeMark"
-                            :menus="ElTreeMenu"
-                            :searchVal="searchTreeVal"
-                            isCounts
-                            isType
-                            @menuTap="ElTreeMenuClick"
-                            @nodeTap="wbsElTreeClick"
-                        /> -->
                         <el-scrollbar v-show="isSearchTree" class="scroll-bar-right-16">
                         <el-scrollbar v-show="isSearchTree" class="scroll-bar-right-16">
                             <HcDataTree
                             <HcDataTree
                                 :datas="searchTreeData"
                                 :datas="searchTreeData"
@@ -74,18 +60,10 @@
                     </div>
                     </div>
                 </div>
                 </div>
                 <div class="hc-tree-foot-tip-box">
                 <div class="hc-tree-foot-tip-box">
-                    <div class="dot-view green">
-                        已审批
-                    </div>
-                    <div class="dot-view black">
-                        未填报
-                    </div>
-                    <div class="dot-view orange">
-                        已填报-待审批
-                    </div>
-                    <div class="dot-view blue">
-                        已填报-未上报
-                    </div>
+                    <div class="dot-view green">已审批</div>
+                    <div class="dot-view black">未填报</div>
+                    <div class="dot-view orange">已填报-待审批</div>
+                    <div class="dot-view blue">已填报-未上报</div>
                 </div>
                 </div>
                 <!-- 左右拖动 -->
                 <!-- 左右拖动 -->
                 <div class="horizontal-drag-line" @mousedown="onmousedown" />
                 <div class="horizontal-drag-line" @mousedown="onmousedown" />
@@ -96,19 +74,48 @@
                     <HcIcon v-show="isWbsTreeShow" name="arrow-left-s" />
                     <HcIcon v-show="isWbsTreeShow" name="arrow-left-s" />
                     <HcIcon v-show="!isWbsTreeShow" name="arrow-right-s" />
                     <HcIcon v-show="!isWbsTreeShow" name="arrow-right-s" />
                 </div>
                 </div>
-
-                <HcCard action-ui="text-center">
-                    <template #header>
-                        <HcNewSwitch
-                            :datas="authBtnTabdata" :keys="authBtnTabKey" :round="false"
-                            size="default" @change="authBtnTabClick"
-                        />
-                    </template>
-                    <!-- 切换导图或树形模式 -->
+                <HcTabCard :tabs="authBtnTabdata" :tab-key="authBtnTabKey" @change="authBtnTabClick">
                     <template #extra>
                     <template #extra>
-                        <HcNewSwitch :datas="wbsTypeTab" :keys="wbsTypeTabKey" @change="wbsTypeTabChange" />
+                        <el-button :loading="nodeSaveLoading" hc-btn type="primary" @click="NodeSaveClick">辅助保存</el-button>
+                        <HcTooltip keys="wbs_views_drawings">
+                            <el-button :disabled="!nodeDataInfo?.fileUrl" hc-btn color="#e03997" @click="viewsDrawings">图纸</el-button>
+                        </HcTooltip>
+                        <HcTooltip keys="wbs_preview">
+                            <el-button
+                                :disabled="NodeStatus === '1'"
+                                :loading="bussPdfsLoading"
+                                hc-btn
+                                color="#A16222"
+                                @click="bussPdfsClick"
+                            >
+                                预览
+                            </el-button>
+                        </HcTooltip>
+                        <el-button hc-btn color="#A16222" @click="attachmentModalShow">查看附件</el-button>
+                        <el-button hc-btn :disabled="isCanadd" color="#567722" @click="addFilelist">上传附件</el-button>
+                        <HcTooltip v-if="NodeStatus !== '3'" keys="wbs_report">
+                            <el-button
+                                :disabled="NodeStatus === '3' || NodeStatus === '1'" :loading="reportLoading"
+                                hc-btn color="#FF976A" style="color: white;" @click="reportModalClick"
+                            >
+                                上报
+                            </el-button>
+                        </HcTooltip>
+                        <HcTooltip v-if="NodeStatus === '3'" keys="wbs_abolish">
+                            <el-button hc-btn :laoding="abolishLoaing" color="#FF976A" style="color: white;" @click="abolishOneClick">撤回上报流程</el-button>
+                        </HcTooltip>
+                        <el-button v-if="authBtnTabKey === '2'" hc-btn color="#37c0fe" style="color: white;" :loading="syncdataloading" @click="syncdata">同步质检资料</el-button>
+                        <HcTooltip v-if="NodeStatus !== '3'" keys="wbs_save">
+                            <el-button
+                                :disabled="NodeStatus === '3' || ListItemDatas.length <= 0"
+                                :loading="tableFormSaveLoading" hc-btn color="#12C060"
+                                style="color: white; font-weight: bold"
+                                @click="tableFormSaveClick"
+                            >
+                                保存数据
+                            </el-button>
+                        </HcTooltip>
                     </template>
                     </template>
-                    <!-- 清表列表 -->
                     <el-scrollbar v-if="ListItemDatas.length > 0" ref="ListItemScrollRef" v-loading="ListItemLoading">
                     <el-scrollbar v-if="ListItemDatas.length > 0" ref="ListItemScrollRef" v-loading="ListItemLoading">
                         <CollapseForm
                         <CollapseForm
                             ref="ListItemRef"
                             ref="ListItemRef"
@@ -129,81 +136,8 @@
                             @getList="searchNodeAllTable1"
                             @getList="searchNodeAllTable1"
                         />
                         />
                     </el-scrollbar>
                     </el-scrollbar>
-
                     <HcStatus v-else text="暂无表单" />
                     <HcStatus v-else text="暂无表单" />
-
-                    <!-- 底部按钮区域 -->
-                    <template #action>
-                        <div class="hc-table-form-action-tip">
-                            <el-alert
-                                :closable="false"
-                                class="hc-alert"
-                                show-icon
-                                style=""
-                                title="完善资料填写后记得一定要保存哦"
-                                type="warning"
-                            />
-                        </div>
-
-                        <el-button :loading="nodeSaveLoading" hc-btn type="primary" style="position: absolute;left: 10px;" @click="NodeSaveClick">辅助保存</el-button>
-
-                        <HcTooltip v-if="NodeStatus !== '3'" keys="wbs_save">
-                            <el-button
-                                :disabled="NodeStatus === '3' || ListItemDatas.length <= 0"
-                                :loading="tableFormSaveLoading"
-                                hc-btn
-                                style="width:150px;font-weight: bold;font-size:large"
-                                type="primary"
-                                @click="tableFormSaveClick"
-                            >
-                                <HcIcon name="save" />
-                                <span>保存</span>
-                            </el-button>
-                        </HcTooltip>
-                        <HcTooltip v-if="NodeStatus !== '3'" keys="wbs_report">
-                            <el-button
-                                :disabled="NodeStatus === '3' || NodeStatus === '1'" :loading="reportLoading"
-                                hc-btn @click="reportModalClick"
-                            >
-                                <HcIcon name="send-plane-2" />
-                                <span>上报</span>
-                            </el-button>
-                        </HcTooltip>
-                        <HcTooltip keys="wbs_preview">
-                            <el-button
-                                :disabled="NodeStatus === '1'" :loading="bussPdfsLoading" hc-btn
-                                @click="bussPdfsClick"
-                            >
-                                <HcIcon name="eye" />
-                                <span>预览</span>
-                            </el-button>
-                        </HcTooltip>
-                        <HcTooltip v-if="NodeStatus === '3'" keys="wbs_abolish">
-                            <el-button hc-btn :laoding="abolishLoaing" @click="abolishOneClick">
-                                <HcIcon name="arrow-go-back" />
-                                <span>撤回上报流程</span>
-                            </el-button>
-                        </HcTooltip>
-                        <HcTooltip keys="wbs_views_drawings">
-                            <el-button :disabled="!nodeDataInfo?.fileUrl" hc-btn @click="viewsDrawings">
-                                <HcIcon name="image" />
-                                <span>图纸</span>
-                            </el-button>
-                        </HcTooltip>
-                        <el-button hc-btn @click="attachmentModalShow">
-                            <HcIcon name="file" />
-                            <span>附件</span>
-                        </el-button>
-                        <el-button hc-btn :disabled="isCanadd" @click="addFilelist">
-                            <HcIcon name="add" />
-                            <span>附件添加</span>
-                        </el-button>
-                        <el-button v-if="authBtnTabKey === '2'" hc-btn :loading="syncdataloading" @click="syncdata">
-                            <HcIcon name="refresh" />
-                            <span>同步质检资料</span>
-                        </el-button>
-                    </template>
-                </HcCard>
+                </HcTabCard>
             </div>
             </div>
         </div>
         </div>
         <HcCard v-if="wbsTypeTabKey === 'map'" id-ref="wbs-node-tree-card-target">
         <HcCard v-if="wbsTypeTabKey === 'map'" id-ref="wbs-node-tree-card-target">
@@ -906,6 +840,11 @@ const wbsTypeTabChange = (item) => {
     })
     })
     getSearchTreeData()
     getSearchTreeData()
 }
 }
+//切换导图结构
+const wbsMapTypeTab = () => {
+    wbsTypeTabChange({ key: 'map', name: '导图结构填报' })
+}
+
 
 
 //上传文件的
 //上传文件的
 const HcUploadFileRef = ref(null)
 const HcUploadFileRef = ref(null)
@@ -2144,9 +2083,9 @@ const NodeSaveClick = async () => {
 }
 }
 .hc-expansion-contraction-tree {
 .hc-expansion-contraction-tree {
     position: absolute;
     position: absolute;
-    left: -21px;
+    left: -13px;
     top: 0;
     top: 0;
-    width: 18px;
+    width: 10px;
     height: 100%;
     height: 100%;
     user-select: none;
     user-select: none;
     cursor: pointer;
     cursor: pointer;

+ 3 - 0
src/views/home/index.vue

@@ -1,5 +1,8 @@
 <template>
 <template>
     <div class="home-styles-box">
     <div class="home-styles-box">
+        <div class="hc-home-bg-box">
+            <img v-if="HomeTheme.bg" id="imagebox" :src="HomeTheme.bg" alt="" crossOrigin="anonymous">
+        </div>
         <div class="hc-home-input-box">
         <div class="hc-home-input-box">
             <div class="hc-home-content">
             <div class="hc-home-content">
                 <div class="hc-slogan-icon">
                 <div class="hc-slogan-icon">

+ 9 - 9
src/views/ledger/components/table-form.vue

@@ -56,8 +56,8 @@
             <HcTooltip keys="ledger_query_save_form">
             <HcTooltip keys="ledger_query_save_form">
                 <el-button
                 <el-button
                     :disabled="!isTableForm || taskStatus === 3 || taskStatus === 4"
                     :disabled="!isTableForm || taskStatus === 3 || taskStatus === 4"
-                    :loading="tableFormSaveLoading" hc-btn
-                    type="primary" @click="tableFormSaveClick"
+                    :loading="tableFormSaveLoading" hc-btn color="#12C060" style="color: white;"
+                    @click="tableFormSaveClick"
                 >
                 >
                     <HcIcon name="save" />
                     <HcIcon name="save" />
                     <span>保存</span>
                     <span>保存</span>
@@ -66,7 +66,7 @@
             <HcTooltip keys="ledger_query_report_form">
             <HcTooltip keys="ledger_query_report_form">
                 <el-button
                 <el-button
                     :disabled="!isTableForm || taskStatus === 1 || taskStatus === 3 || taskStatus === 4" hc-btn
                     :disabled="!isTableForm || taskStatus === 1 || taskStatus === 3 || taskStatus === 4" hc-btn
-                    @click="reportModalClick"
+                    color="#FF976A" style="color: white;" @click="reportModalClick"
                 >
                 >
                     <HcIcon name="send-plane-2" />
                     <HcIcon name="send-plane-2" />
                     <span>上报</span>
                     <span>上报</span>
@@ -75,7 +75,7 @@
             <HcTooltip keys="ledger_query_preview_form">
             <HcTooltip keys="ledger_query_preview_form">
                 <el-button
                 <el-button
                     :disabled="!isTableForm || taskStatus === 1 " :loading="previewLoading" hc-btn
                     :disabled="!isTableForm || taskStatus === 1 " :loading="previewLoading" hc-btn
-                    @click="previewBussPdf"
+                    color="#A16222" @click="previewBussPdf"
                 >
                 >
                     <HcIcon name="eye" />
                     <HcIcon name="eye" />
                     <span>预览</span>
                     <span>预览</span>
@@ -84,7 +84,7 @@
             <HcTooltip keys="ledger_query_copy_form">
             <HcTooltip keys="ledger_query_copy_form">
                 <el-button
                 <el-button
                     :disabled="!isTableForm || taskStatus === 3 || taskStatus === 4" hc-btn
                     :disabled="!isTableForm || taskStatus === 3 || taskStatus === 4" hc-btn
-                    @click="copyTableFormClick"
+                    color="#567722" @click="copyTableFormClick"
                 >
                 >
                     <HcIcon name="file-copy-2" />
                     <HcIcon name="file-copy-2" />
                     <span>复制当前表格及内容</span>
                     <span>复制当前表格及内容</span>
@@ -93,7 +93,7 @@
             <HcTooltip keys="ledger_query_time_form">
             <HcTooltip keys="ledger_query_time_form">
                 <el-button
                 <el-button
                     :disabled="!isTableForm || taskStatus === 3 || taskStatus === 4" hc-btn
                     :disabled="!isTableForm || taskStatus === 3 || taskStatus === 4" hc-btn
-                    @click="copyTimeLogModal"
+                    color="#567722" @click="copyTimeLogModal"
                 >
                 >
                     <HcIcon name="file-copy-2" />
                     <HcIcon name="file-copy-2" />
                     <span>复制任意时间</span>
                     <span>复制任意时间</span>
@@ -102,7 +102,7 @@
             <HcTooltip keys="ledger_query_add_form">
             <HcTooltip keys="ledger_query_add_form">
                 <el-button
                 <el-button
                     :disabled="!isTableForm || taskStatus === 3 || taskStatus === 4" hc-btn
                     :disabled="!isTableForm || taskStatus === 3 || taskStatus === 4" hc-btn
-                    @click="addTableFormClick"
+                    color="#37c0fe" style="color: white;" @click="addTableFormClick"
                 >
                 >
                     <HcIcon name="add-circle" />
                     <HcIcon name="add-circle" />
                     <span>新增表格</span>
                     <span>新增表格</span>
@@ -111,7 +111,7 @@
             <HcTooltip keys="ledger_query_abolish_form">
             <HcTooltip keys="ledger_query_abolish_form">
                 <el-button
                 <el-button
                     :disabled="!isTableForm || taskStatus === 1 || taskStatus === 2" hc-btn
                     :disabled="!isTableForm || taskStatus === 1 || taskStatus === 2" hc-btn
-                    @click="abolishTableFormClick"
+                    color="#FF976A" style="color: white;" @click="abolishTableFormClick"
                 >
                 >
                     <HcIcon name="delete-bin-3" />
                     <HcIcon name="delete-bin-3" />
                     <span>废除</span>
                     <span>废除</span>
@@ -772,7 +772,7 @@ const closeBussDataInfo = async (item, index) => {
         //处理数据
         //处理数据
         if (!error && code === 200) {
         if (!error && code === 200) {
            window.$message.success('删除成功')
            window.$message.success('删除成功')
-           
+
         } else {
         } else {
             window.$message.error('操作失败')
             window.$message.error('操作失败')
         }
         }

+ 95 - 82
src/views/ledger/components/table-list.vue

@@ -3,113 +3,127 @@
         <HcCard>
         <HcCard>
             <template #header>
             <template #header>
                 <div class="w-64">
                 <div class="w-64">
-                    <HcDatePicker :dates="betweenTime" clearable size="large" @change="betweenTimeUpdate"/>
+                    <HcDatePicker :dates="betweenTime" clearable size="large" @change="betweenTimeUpdate" />
                 </div>
                 </div>
                 <div class="w-40 ml-3">
                 <div class="w-40 ml-3">
                     <el-select v-model="searchForm.createUser" block clearable placeholder="请选择记录人" size="large">
                     <el-select v-model="searchForm.createUser" block clearable placeholder="请选择记录人" size="large">
-                        <el-option v-for="item in recordData" :label="item['userName']" :value="item['userId']"/>
+                        <el-option v-for="item in recordData" :label="item.userName" :value="item.userId" />
                     </el-select>
                     </el-select>
                 </div>
                 </div>
                 <div class="ml-2">
                 <div class="ml-2">
                     <el-button size="large" type="primary" @click="searchClick">
                     <el-button size="large" type="primary" @click="searchClick">
-                        <HcIcon name="search-2"/>
+                        <HcIcon name="search-2" />
                         <span>搜索</span>
                         <span>搜索</span>
                     </el-button>
                     </el-button>
                 </div>
                 </div>
             </template>
             </template>
             <template #extra>
             <template #extra>
                 <HcTooltip keys="ledger_query_report">
                 <HcTooltip keys="ledger_query_report">
-                    <el-button :disabled="tableCheckedKeys.length <= 0" :loading="reportLoading" hc-btn type="primary"
-                               @click="reportModalClick">
-                        <HcIcon name="send-plane-2"/>
+                    <el-button
+                        :disabled="tableCheckedKeys.length <= 0" :loading="reportLoading" hc-btn
+                        color="#FF976A" style="color: white;" @click="reportModalClick"
+                    >
+                        <HcIcon name="send-plane-2" />
                         <span>批量上报</span>
                         <span>批量上报</span>
                     </el-button>
                     </el-button>
                 </HcTooltip>
                 </HcTooltip>
                 <HcTooltip keys="ledger_query_abolish">
                 <HcTooltip keys="ledger_query_abolish">
-                    <el-button :disabled="tableCheckedKeys.length <= 0" :loading="abolishLoading" hc-btn
-                               @click="batchAbolishClick">
-                        <HcIcon name="delete-bin-3"/>
+                    <el-button
+                        :disabled="tableCheckedKeys.length <= 0" :loading="abolishLoading" hc-btn
+                        color="#A16222" @click="batchAbolishClick"
+                    >
+                        <HcIcon name="delete-bin-3" />
                         <span>批量废除</span>
                         <span>批量废除</span>
                     </el-button>
                     </el-button>
                 </HcTooltip>
                 </HcTooltip>
                 <HcTooltip keys="ledger_query_delete">
                 <HcTooltip keys="ledger_query_delete">
-                    <el-button :disabled="tableCheckedKeys.length <= 0" :loading="deleteLoading" hc-btn
-                               @click="batchDeleteClick">
-                        <HcIcon name="delete-bin"/>
+                    <el-button
+                        :disabled="tableCheckedKeys.length <= 0" :loading="deleteLoading" hc-btn
+                        color="#e03997" @click="batchDeleteClick"
+                    >
+                        <HcIcon name="delete-bin" />
                         <span>批量删除</span>
                         <span>批量删除</span>
                     </el-button>
                     </el-button>
                 </HcTooltip>
                 </HcTooltip>
                 <HcTooltip keys="ledger_query_print">
                 <HcTooltip keys="ledger_query_print">
-                    <el-button :disabled="tableCheckedKeys.length <= 0" :loading="previewPrintLoading" hc-btn
-                               @click="previewAndPrintClick">
-                        <HcIcon name="printer"/>
+                    <el-button
+                        :disabled="tableCheckedKeys.length <= 0" :loading="previewPrintLoading" hc-btn
+                        color="#567722" @click="previewAndPrintClick"
+                    >
+                        <HcIcon name="printer" />
                         <span>批量预览/打印</span>
                         <span>批量预览/打印</span>
                     </el-button>
                     </el-button>
                 </HcTooltip>
                 </HcTooltip>
             </template>
             </template>
-            <HcTable ref="tableListRef" :column="tableListColumn" :datas="tableListData" :loading="tableLoading" isCheck
-                     @selection-change="tableSelectionChange">
-                <template #action="{row}">
+            <HcTable
+                ref="tableListRef" :column="tableListColumn" :datas="tableListData" :loading="tableLoading" is-check
+                @selection-change="tableSelectionChange"
+            >
+                <template #action="{ row }">
                     <HcTooltip keys="ledger_query_table_query">
                     <HcTooltip keys="ledger_query_table_query">
                         <el-button plain size="small" type="primary" @click="handleTableQuery(row)">查询</el-button>
                         <el-button plain size="small" type="primary" @click="handleTableQuery(row)">查询</el-button>
                     </HcTooltip>
                     </HcTooltip>
                     <HcTooltip keys="ledger_query_table_del">
                     <HcTooltip keys="ledger_query_table_del">
-                        <el-button :disabled="!row.operation || row.status !== 0" plain size="small" type="danger"
-                                   @click="handleTableDel(row)">删除
+                        <el-button
+                            :disabled="!row.operation || row.status !== 0" plain size="small" type="danger"
+                            @click="handleTableDel(row)"
+                        >
+                            删除
                         </el-button>
                         </el-button>
                     </HcTooltip>
                     </HcTooltip>
                 </template>
                 </template>
             </HcTable>
             </HcTable>
             <template #action>
             <template #action>
-                <HcPages :pages="searchForm" @change="pageChange"/>
+                <HcPages :pages="searchForm" @change="pageChange" />
             </template>
             </template>
         </HcCard>
         </HcCard>
 
 
-        <!--批量上报审批-->
-        <HcReportModal :contractId="contractId"
-                       :datas="reportDatas"
-                       :ids="reportIds"
-                       :projectId="projectId"
-                       :show="showReportModal"
-                       :taskName="reportTaskName"
-                       :typeData="menuItem.primaryKeyId"
-                       isDatas
-                       title="批量上报审批"
-                       type="log"
-                       url="contractLog/batchTask"
-                       @finish="showReportFinish"
-                       @hide="showReportModal = false"
-                       @tagClose="reportTaskTagClose"
+        <!-- 批量上报审批 -->
+        <HcReportModal
+            :contract-id="contractId"
+            :datas="reportDatas"
+            :ids="reportIds"
+            :project-id="projectId"
+            :show="showReportModal"
+            :task-name="reportTaskName"
+            :type-data="menuItem.primaryKeyId"
+            is-datas
+            title="批量上报审批"
+            type="log"
+            url="contractLog/batchTask"
+            @finish="showReportFinish"
+            @hide="showReportModal = false"
+            @tagClose="reportTaskTagClose"
         />
         />
     </div>
     </div>
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import {ref, watch, nextTick} from "vue";
-import queryApi from '~api/ledger/query';
-import {eVisaTaskCheckApi} from "~api/other"
-import {arrToId, getArrValue, getObjValue, isString} from "js-fast-way"
+import { nextTick, ref, watch } from 'vue'
+import queryApi from '~api/ledger/query'
+import { eVisaTaskCheckApi } from '~api/other'
+import { arrToId, getArrValue, getObjValue, isString } from 'js-fast-way'
 
 
 //参数
 //参数
 const props = defineProps({
 const props = defineProps({
     projectId: {
     projectId: {
         type: [String, Number],
         type: [String, Number],
-        default: ''
+        default: '',
     },
     },
     contractId: {
     contractId: {
         type: [String, Number],
         type: [String, Number],
-        default: ''
+        default: '',
     },
     },
     items: {
     items: {
         type: Object,
         type: Object,
-        default: () => ({})
-    }
+        default: () => ({}),
+    },
 })
 })
 
 
 //变量
 //变量
-const projectId = ref(props.projectId);
-const contractId = ref(props.contractId);
-const menuItem = ref(props.items);
+const projectId = ref(props.projectId)
+const contractId = ref(props.contractId)
+const menuItem = ref(props.items)
 
 
 //监听
 //监听
 watch(() => [
 watch(() => [
@@ -137,32 +151,32 @@ const getQueryData = () => {
 //获取记录人数据
 //获取记录人数据
 const recordData = ref([])
 const recordData = ref([])
 const queryFillUser = async () => {
 const queryFillUser = async () => {
-    const {primaryKeyId} = menuItem.value
-    const {data} = await queryApi.queryFillUser({
+    const { primaryKeyId } = menuItem.value
+    const { data } = await queryApi.queryFillUser({
         contractId: contractId.value,
         contractId: contractId.value,
-        primaryKeyId: primaryKeyId
+        primaryKeyId: primaryKeyId,
     })
     })
     recordData.value = getArrValue(data)
     recordData.value = getArrValue(data)
 }
 }
 
 
 //搜索表单
 //搜索表单
-const searchForm = ref({queryTime: '', createUser: null, current: 1, size: 20, total: 0})
+const searchForm = ref({ queryTime: '', createUser: null, current: 1, size: 20, total: 0 })
 
 
 //日期时间被选择
 //日期时间被选择
 const betweenTime = ref(null)
 const betweenTime = ref(null)
-const betweenTimeUpdate = ({arr, query}) => {
+const betweenTimeUpdate = ({ arr, query }) => {
     betweenTime.value = arr
     betweenTime.value = arr
     searchForm.value.queryTime = query
     searchForm.value.queryTime = query
 }
 }
 
 
 //搜索
 //搜索
 const searchClick = () => {
 const searchClick = () => {
-    searchForm.value.current = 1;
+    searchForm.value.current = 1
     getTableData()
     getTableData()
 }
 }
 
 
 //分页被点击
 //分页被点击
-const pageChange = ({current, size}) => {
+const pageChange = ({ current, size }) => {
     searchForm.value.current = current
     searchForm.value.current = current
     searchForm.value.size = size
     searchForm.value.size = size
     getTableData()
     getTableData()
@@ -171,20 +185,20 @@ const pageChange = ({current, size}) => {
 //获取数据
 //获取数据
 const tableLoading = ref(false)
 const tableLoading = ref(false)
 const tableListColumn = ref([
 const tableListColumn = ref([
-    {key: 'recordTime', name: '记录日期'},
-    {key: 'statusValue', name: '流程状态'},
-    {key: 'createUserName', name: '记录人员'},
-    {key: 'action', name: '操作', width: 200}
+    { key: 'recordTime', name: '记录日期' },
+    { key: 'statusValue', name: '流程状态' },
+    { key: 'createUserName', name: '记录人员' },
+    { key: 'action', name: '操作', width: 200 },
 ])
 ])
 const tableListData = ref([])
 const tableListData = ref([])
 const getTableData = async () => {
 const getTableData = async () => {
     //初始数据处理
     //初始数据处理
     tableLoading.value = true
     tableLoading.value = true
-    const {primaryKeyId} = menuItem.value
+    const { primaryKeyId } = menuItem.value
     tableListRef.value?.clearSelection()
     tableListRef.value?.clearSelection()
     tableCheckedKeys.value = []
     tableCheckedKeys.value = []
     //请求数据
     //请求数据
-    const {error, code, data} = await queryApi.constructionLogPage({
+    const { error, code, data } = await queryApi.constructionLogPage({
         ...searchForm.value,
         ...searchForm.value,
         wbsNodeId: primaryKeyId,
         wbsNodeId: primaryKeyId,
         projectId: projectId.value,
         projectId: projectId.value,
@@ -207,7 +221,7 @@ const tableListRef = ref(null)
 const tableCheckedKeys = ref([])
 const tableCheckedKeys = ref([])
 const tableSelectionChange = (rows) => {
 const tableSelectionChange = (rows) => {
     tableCheckedKeys.value = rows.filter((item) => {
     tableCheckedKeys.value = rows.filter((item) => {
-        return (item ?? '') !== '';
+        return (item ?? '') !== ''
     })
     })
 }
 }
 
 
@@ -218,9 +232,9 @@ const reportDatas = ref([])
 const reportLoading = ref(false)
 const reportLoading = ref(false)
 const showReportModal = ref(false)
 const showReportModal = ref(false)
 const reportModalClick = async () => {
 const reportModalClick = async () => {
-    const rows = tableCheckedKeys.value;
+    const rows = tableCheckedKeys.value
     //判断是否满足条件
     //判断是否满足条件
-    const result = rows.every(({status}) => {
+    const result = rows.every(({ status }) => {
         return status !== 1 && status !== 2
         return status !== 1 && status !== 2
     })
     })
     //判断状态
     //判断状态
@@ -228,7 +242,7 @@ const reportModalClick = async () => {
         reportLoading.value = true
         reportLoading.value = true
         const taskCheck = await eVisaTaskCheckApi({
         const taskCheck = await eVisaTaskCheckApi({
             projectId: projectId.value,
             projectId: projectId.value,
-            contractId: contractId.value
+            contractId: contractId.value,
         })
         })
         if (taskCheck) {
         if (taskCheck) {
             //初始ID
             //初始ID
@@ -239,7 +253,7 @@ const reportModalClick = async () => {
             rows.forEach(item => {
             rows.forEach(item => {
                 reportDataArr.push({
                 reportDataArr.push({
                     id: item?.id,
                     id: item?.id,
-                    name: item?.fileName
+                    name: item?.fileName,
                 })
                 })
             })
             })
             reportDatas.value = reportDataArr
             reportDatas.value = reportDataArr
@@ -257,7 +271,7 @@ const reportModalClick = async () => {
 
 
 //上报的审批内容移除
 //上报的审批内容移除
 const reportTaskTagClose = (index) => {
 const reportTaskTagClose = (index) => {
-    const row = tableCheckedKeys.value[index];
+    const row = tableCheckedKeys.value[index]
     tableListRef.value?.toggleRowSelection(row, false)
     tableListRef.value?.toggleRowSelection(row, false)
 }
 }
 
 
@@ -270,9 +284,9 @@ const showReportFinish = () => {
 //批量废除
 //批量废除
 const abolishLoading = ref(false)
 const abolishLoading = ref(false)
 const batchAbolishClick = () => {
 const batchAbolishClick = () => {
-    const rows = tableCheckedKeys.value;
+    const rows = tableCheckedKeys.value
     //判断是否满足条件
     //判断是否满足条件
-    const result = rows.every(({status, operation}) => {
+    const result = rows.every(({ status, operation }) => {
         return status !== 0 && status !== 3 && operation
         return status !== 0 && status !== 3 && operation
     })
     })
     //判断状态
     //判断状态
@@ -287,7 +301,7 @@ const batchAbolishClick = () => {
                 if (action === 'confirm') {
                 if (action === 'confirm') {
                     batchAbolishSave(ids)
                     batchAbolishSave(ids)
                 }
                 }
-            }
+            },
         })
         })
     } else {
     } else {
         window.$message?.warning('未上报的文件,和不是自己的文件,不能废除')
         window.$message?.warning('未上报的文件,和不是自己的文件,不能废除')
@@ -297,7 +311,7 @@ const batchAbolishClick = () => {
 //废除勾选的已上报文件
 //废除勾选的已上报文件
 const batchAbolishSave = async (ids) => {
 const batchAbolishSave = async (ids) => {
     abolishLoading.value = true
     abolishLoading.value = true
-    const {error, code} = await queryApi.batchAbolish({ids: ids})
+    const { error, code } = await queryApi.batchAbolish({ ids: ids })
     //处理数据
     //处理数据
     abolishLoading.value = false
     abolishLoading.value = false
     if (!error && code === 200) {
     if (!error && code === 200) {
@@ -309,9 +323,9 @@ const batchAbolishSave = async (ids) => {
 
 
 //批量删除
 //批量删除
 const batchDeleteClick = () => {
 const batchDeleteClick = () => {
-    const rows = tableCheckedKeys.value;
+    const rows = tableCheckedKeys.value
     //判断是否满足条件
     //判断是否满足条件
-    const result = rows.every(({status, operation}) => {
+    const result = rows.every(({ status, operation }) => {
         return status === 0 && operation
         return status === 0 && operation
     })
     })
     //判断状态
     //判断状态
@@ -325,7 +339,7 @@ const batchDeleteClick = () => {
                 if (action === 'confirm') {
                 if (action === 'confirm') {
                     theLogRemoveByIds(ids)
                     theLogRemoveByIds(ids)
                 }
                 }
-            }
+            },
         })
         })
     } else {
     } else {
         window.$message?.warning('只能删除自己的未上报日志文件')
         window.$message?.warning('只能删除自己的未上报日志文件')
@@ -336,11 +350,11 @@ const batchDeleteClick = () => {
 const previewPrintLoading = ref(false)
 const previewPrintLoading = ref(false)
 const previewAndPrintClick = async () => {
 const previewAndPrintClick = async () => {
     previewPrintLoading.value = true
     previewPrintLoading.value = true
-    const rows = tableCheckedKeys.value;
+    const rows = tableCheckedKeys.value
     const rowsIds = arrToId(rows)
     const rowsIds = arrToId(rows)
     const ids = rowsIds.split(',')
     const ids = rowsIds.split(',')
-    const {error, code, data} = await queryApi.theLogPreviewAndPrint({
-        ids: ids
+    const { error, code, data } = await queryApi.theLogPreviewAndPrint({
+        ids: ids,
     })
     })
     //处理数据
     //处理数据
     previewPrintLoading.value = false
     previewPrintLoading.value = false
@@ -351,7 +365,7 @@ const previewAndPrintClick = async () => {
 }
 }
 
 
 //查询
 //查询
-const handleTableQuery = ({evisaPdfUrl, pdfUrl}) => {
+const handleTableQuery = ({ evisaPdfUrl, pdfUrl }) => {
     if (evisaPdfUrl) {
     if (evisaPdfUrl) {
         window.open(evisaPdfUrl, '_blank')
         window.open(evisaPdfUrl, '_blank')
     } else if (pdfUrl) {
     } else if (pdfUrl) {
@@ -362,7 +376,7 @@ const handleTableQuery = ({evisaPdfUrl, pdfUrl}) => {
 }
 }
 
 
 //删除
 //删除
-const handleTableDel = ({id, status, operation}) => {
+const handleTableDel = ({ id, status, operation }) => {
     //判断是否满足条件
     //判断是否满足条件
     if (status === 0 && operation) {
     if (status === 0 && operation) {
         window?.$messageBox?.alert('是否删除勾选的日志文件?', '删除文件', {
         window?.$messageBox?.alert('是否删除勾选的日志文件?', '删除文件', {
@@ -373,7 +387,7 @@ const handleTableDel = ({id, status, operation}) => {
                 if (action === 'confirm') {
                 if (action === 'confirm') {
                     theLogRemoveByIds([id])
                     theLogRemoveByIds([id])
                 }
                 }
-            }
+            },
         })
         })
     } else {
     } else {
         window.$message?.warning('只能删除自己的未上报日志文件')
         window.$message?.warning('只能删除自己的未上报日志文件')
@@ -384,8 +398,8 @@ const handleTableDel = ({id, status, operation}) => {
 const deleteLoading = ref(false)
 const deleteLoading = ref(false)
 const theLogRemoveByIds = async (ids) => {
 const theLogRemoveByIds = async (ids) => {
     deleteLoading.value = true
     deleteLoading.value = true
-    const {error, code} = await queryApi.theLogRemoveByIds({
-        ids: ids
+    const { error, code } = await queryApi.theLogRemoveByIds({
+        ids: ids,
     })
     })
     deleteLoading.value = false
     deleteLoading.value = false
     if (!error && code === 200) {
     if (!error && code === 200) {
@@ -394,7 +408,6 @@ const theLogRemoveByIds = async (ids) => {
         getTableData()
         getTableData()
     }
     }
 }
 }
-
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>