|
|
@@ -15,7 +15,7 @@
|
|
|
<!-- 菜单项列表 -->
|
|
|
<div class="sidebar-menu-list">
|
|
|
<!-- 首页 (无子菜单) -->
|
|
|
- <div class="sidebar-item active">
|
|
|
+ <div class="sidebar-item active" @click="onPath('/indexDataDiy')">
|
|
|
<div class="item-icon-wrapper">
|
|
|
<svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
@@ -26,7 +26,7 @@
|
|
|
</div>
|
|
|
|
|
|
<!-- 工作台 (无子菜单) -->
|
|
|
- <div class="sidebar-item">
|
|
|
+ <div class="sidebar-item" @click="onPath('/enterprise/companyInfo')">
|
|
|
<div class="item-icon-wrapper">
|
|
|
<svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
<rect x="2" y="3" width="20" height="14" rx="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
@@ -37,252 +37,30 @@
|
|
|
<span class="item-text">{{ isSidebarCollapsed ? '工作台' : '采购工作台' }}</span>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 采购单管理 -->
|
|
|
- <div class="sidebar-item has-sub" :class="{ 'sub-open': openMenus.purchase }" @click="toggleMenu('purchase')">
|
|
|
- <div class="item-icon-wrapper">
|
|
|
- <svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <path d="M9 11l3 3L22 4" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- <path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- </svg>
|
|
|
- </div>
|
|
|
- <span class="item-text">{{ isSidebarCollapsed ? '采购单' : '采购单管理' }}</span>
|
|
|
- <svg class="arrow-icon" v-if="!isSidebarCollapsed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <polyline points="6 9 12 15 18 9" />
|
|
|
- </svg>
|
|
|
-
|
|
|
- <!-- 窄栏折叠悬停二级菜单 (通用 absolute 气泡弹出,完美卡合在对应项右侧) -->
|
|
|
- <div class="sidebar-hover-pop" v-if="isSidebarCollapsed">
|
|
|
- <div class="sub-item">
|
|
|
- 我的购物车
|
|
|
- <span class="cart-badge">1</span>
|
|
|
+ <template v-for="(item1, index1) in menuList" :key="index1">
|
|
|
+ <div v-if="item1.show" class="sidebar-item has-sub" :class="{ 'sub-open': openMenus[item1.title] }" @click="toggleMenu(item1.title)">
|
|
|
+ <div class="item-icon-wrapper">
|
|
|
+ <img :src="item1.icon" alt="" class="s-icon" />
|
|
|
</div>
|
|
|
- <div class="sub-item">我的采购单</div>
|
|
|
- <div class="sub-item">清单选品</div>
|
|
|
- <div class="sub-item">我的收藏</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 二级子菜单 -->
|
|
|
- <div class="sidebar-sub-menu" v-if="!isSidebarCollapsed" :class="{ 'show': openMenus.purchase }">
|
|
|
- <div class="sub-item">
|
|
|
- 我的购物车
|
|
|
- <span class="cart-badge">1</span>
|
|
|
- </div>
|
|
|
- <div class="sub-item">我的采购单</div>
|
|
|
- <div class="sub-item">清单选品</div>
|
|
|
- <div class="sub-item">我的收藏</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 非招标采购 -->
|
|
|
- <div class="sidebar-item has-sub" :class="{ 'sub-open': openMenus.nonTender }" @click="toggleMenu('nonTender')">
|
|
|
- <div class="item-icon-wrapper">
|
|
|
- <svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <rect x="3" y="7" width="18" height="13" rx="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- <path d="M20 7h-9M14 3L7 21" stroke-linecap="round" />
|
|
|
- </svg>
|
|
|
- </div>
|
|
|
- <span class="item-text">非招标采购</span>
|
|
|
- <svg class="arrow-icon" v-if="!isSidebarCollapsed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <polyline points="6 9 12 15 18 9" />
|
|
|
- </svg>
|
|
|
-
|
|
|
- <!-- 折叠悬停二级菜单 -->
|
|
|
- <div class="sidebar-hover-pop" v-if="isSidebarCollapsed">
|
|
|
- <div class="sub-item">竞价采购</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 二级子菜单 -->
|
|
|
- <div class="sidebar-sub-menu" v-if="!isSidebarCollapsed" :class="{ 'show': openMenus.nonTender }">
|
|
|
- <div class="sub-item">竞价采购</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 订单管理 -->
|
|
|
- <div class="sidebar-item has-sub" :class="{ 'sub-open': openMenus.order }" @click="toggleMenu('order')">
|
|
|
- <div class="item-icon-wrapper">
|
|
|
- <svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- <polyline points="14 2 14 8 20 8" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- <line x1="16" y1="13" x2="8" y2="13" stroke-linecap="round" />
|
|
|
- <line x1="16" y1="17" x2="8" y2="17" stroke-linecap="round" />
|
|
|
- </svg>
|
|
|
- </div>
|
|
|
- <span class="item-text">{{ isSidebarCollapsed ? '订单' : '订单管理' }}</span>
|
|
|
- <svg class="arrow-icon" v-if="!isSidebarCollapsed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <polyline points="6 9 12 15 18 9" />
|
|
|
- </svg>
|
|
|
-
|
|
|
- <!-- 折叠悬停二级菜单 -->
|
|
|
- <div class="sidebar-hover-pop" v-if="isSidebarCollapsed">
|
|
|
- <div class="sub-item">我的订单</div>
|
|
|
- <div class="sub-item">订单打印</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 二级子菜单 -->
|
|
|
- <div class="sidebar-sub-menu" v-if="!isSidebarCollapsed" :class="{ 'show': openMenus.order }">
|
|
|
- <div class="sub-item">我的订单</div>
|
|
|
- <div class="sub-item">订单打印</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 发票管理 -->
|
|
|
- <div class="sidebar-item has-sub" :class="{ 'sub-open': openMenus.invoice }" @click="toggleMenu('invoice')">
|
|
|
- <div class="item-icon-wrapper">
|
|
|
- <svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <rect x="2" y="4" width="20" height="16" rx="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- <line x1="12" y1="4" x2="12" y2="20" stroke-linecap="round" />
|
|
|
- <line x1="2" y1="12" x2="22" y2="12" stroke-linecap="round" />
|
|
|
- </svg>
|
|
|
- </div>
|
|
|
- <span class="item-text">{{ isSidebarCollapsed ? '发票' : '发票管理' }}</span>
|
|
|
- <svg class="arrow-icon" v-if="!isSidebarCollapsed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <polyline points="6 9 12 15 18 9" />
|
|
|
- </svg>
|
|
|
-
|
|
|
- <!-- 折叠悬停二级菜单 -->
|
|
|
- <div class="sidebar-hover-pop" v-if="isSidebarCollapsed">
|
|
|
- <div class="sub-item">普票抬头管理</div>
|
|
|
- <div class="sub-item">开具发票</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 二级子菜单 -->
|
|
|
- <div class="sidebar-sub-menu" v-if="!isSidebarCollapsed" :class="{ 'show': openMenus.invoice }">
|
|
|
- <div class="sub-item">普票抬头管理</div>
|
|
|
- <div class="sub-item">开具发票</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 售后管理 -->
|
|
|
- <div class="sidebar-item has-sub" :class="{ 'sub-open': openMenus.afterSale }" @click="toggleMenu('afterSale')">
|
|
|
- <div class="item-icon-wrapper">
|
|
|
- <svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <path d="M21.5 2v6h-6M21.34 15.57a10 10 0 1 1-.57-8.38l5.67-5.67" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- </svg>
|
|
|
- </div>
|
|
|
- <span class="item-text">{{ isSidebarCollapsed ? '售后' : '售后管理' }}</span>
|
|
|
- <svg class="arrow-icon" v-if="!isSidebarCollapsed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <polyline points="6 9 12 15 18 9" />
|
|
|
- </svg>
|
|
|
-
|
|
|
- <!-- 折叠悬停二级菜单 -->
|
|
|
- <div class="sidebar-hover-pop" v-if="isSidebarCollapsed">
|
|
|
- <div class="sub-item">退换货</div>
|
|
|
- <div class="sub-item">售后记录</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 二级子菜单 -->
|
|
|
- <div class="sidebar-sub-menu" v-if="!isSidebarCollapsed" :class="{ 'show': openMenus.afterSale }">
|
|
|
- <div class="sub-item">退换货</div>
|
|
|
- <div class="sub-item">售后记录</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 财务管理 -->
|
|
|
- <div class="sidebar-item has-sub" :class="{ 'sub-open': openMenus.finance }" @click="toggleMenu('finance')">
|
|
|
- <div class="item-icon-wrapper">
|
|
|
- <svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <circle cx="12" cy="12" r="10" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- <path d="M12 8V16M8 12h8" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
+ <span class="item-text">{{ isSidebarCollapsed ? item1.title.slice(0, 2) : item1.title }}</span>
|
|
|
+ <svg class="arrow-icon" v-if="!isSidebarCollapsed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
+ <polyline points="6 9 12 15 18 9" />
|
|
|
</svg>
|
|
|
- </div>
|
|
|
- <span class="item-text">{{ isSidebarCollapsed ? '财务' : '财务管理' }}</span>
|
|
|
- <svg class="arrow-icon" v-if="!isSidebarCollapsed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <polyline points="6 9 12 15 18 9" />
|
|
|
- </svg>
|
|
|
|
|
|
- <!-- 折叠悬停二级菜单 -->
|
|
|
- <div class="sidebar-hover-pop" v-if="isSidebarCollapsed">
|
|
|
- <div class="sub-item">结算中心</div>
|
|
|
- <div class="sub-item">自助认款</div>
|
|
|
- <div class="sub-item">合并支付</div>
|
|
|
- <div class="sub-item">企业结算</div>
|
|
|
- <div class="sub-item">企业金采</div>
|
|
|
- <div class="sub-item">金采报销</div>
|
|
|
- <div class="sub-item">商家结算</div>
|
|
|
- <div class="sub-item">我的余额</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 二级子菜单 -->
|
|
|
- <div class="sidebar-sub-menu" v-if="!isSidebarCollapsed" :class="{ 'show': openMenus.finance }">
|
|
|
- <div class="sub-item">结算中心</div>
|
|
|
- <div class="sub-item">自助认款</div>
|
|
|
- <div class="sub-item">合并支付</div>
|
|
|
- <div class="sub-item">企业结算</div>
|
|
|
- <div class="sub-item">企业金采</div>
|
|
|
- <div class="sub-item">金采报销</div>
|
|
|
- <div class="sub-item">商家结算</div>
|
|
|
- <div class="sub-item">我的余额</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 数据中心 -->
|
|
|
- <div class="sidebar-item has-sub" :class="{ 'sub-open': openMenus.dataCenter }" @click="toggleMenu('dataCenter')">
|
|
|
- <div class="item-icon-wrapper">
|
|
|
- <svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <line x1="18" y1="20" x2="18" y2="10" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- <line x1="12" y1="20" x2="12" y2="4" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- <line x1="6" y1="20" x2="6" y2="14" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- </svg>
|
|
|
- </div>
|
|
|
- <span class="item-text">{{ isSidebarCollapsed ? '数据' : '数据中心' }}</span>
|
|
|
- <svg class="arrow-icon" v-if="!isSidebarCollapsed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <polyline points="6 9 12 15 18 9" />
|
|
|
- </svg>
|
|
|
-
|
|
|
- <!-- 折叠悬停二级菜单 -->
|
|
|
- <div class="sidebar-hover-pop" v-if="isSidebarCollapsed">
|
|
|
- <div class="sub-item">下载中心</div>
|
|
|
- <div class="sub-item">数据报表</div>
|
|
|
- <div class="sub-item">明细数据报表</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 二级子菜单 -->
|
|
|
- <div class="sidebar-sub-menu" v-if="!isSidebarCollapsed" :class="{ 'show': openMenus.dataCenter }">
|
|
|
- <div class="sub-item">下载中心</div>
|
|
|
- <div class="sub-item">数据报表</div>
|
|
|
- <div class="sub-item">明细数据报表</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 地址管理 -->
|
|
|
- <div class="sidebar-item has-sub" :class="{ 'sub-open': openMenus.address }" @click="toggleMenu('address')">
|
|
|
- <div class="item-icon-wrapper">
|
|
|
- <svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- <circle cx="12" cy="10" r="3" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- </svg>
|
|
|
- </div>
|
|
|
- <span class="item-text">{{ isSidebarCollapsed ? '地址' : '地址管理' }}</span>
|
|
|
- <svg class="arrow-icon" v-if="!isSidebarCollapsed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <polyline points="6 9 12 15 18 9" />
|
|
|
- </svg>
|
|
|
-
|
|
|
- <!-- 折叠悬停二级菜单 -->
|
|
|
- <div class="sidebar-hover-pop" v-if="isSidebarCollapsed">
|
|
|
- <div class="sub-item">我的地址</div>
|
|
|
+ <!-- 折叠悬停二级菜单 -->
|
|
|
+ <div class="sidebar-hover-pop" v-if="isSidebarCollapsed">
|
|
|
+ <template v-for="(item2, index2) in item1.children" :key="index2">
|
|
|
+ <div @click.stop="onPath(item2.path)" class="sub-item">{{ item2.title }}</div>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- <!-- 二级子菜单 -->
|
|
|
- <div class="sidebar-sub-menu" v-if="!isSidebarCollapsed" :class="{ 'show': openMenus.address }">
|
|
|
- <div class="sub-item">我的地址</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 账号安全 -->
|
|
|
- <div class="sidebar-item has-sub" :class="{ 'sub-open': openMenus.security }" @click="toggleMenu('security')">
|
|
|
- <div class="item-icon-wrapper">
|
|
|
- <svg class="s-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- </svg>
|
|
|
+ <!-- 二级子菜单 -->
|
|
|
+ <div class="sidebar-sub-menu" v-if="!isSidebarCollapsed" :class="{ 'show': openMenus[item1.title] }">
|
|
|
+ <template v-for="(item2, index2) in item1.children" :key="index2">
|
|
|
+ <div @click.stop="onPath(item2.path)" class="sub-item">{{ item2.title }}</div>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
- <span class="item-text">{{ isSidebarCollapsed ? '安全' : '账号安全' }}</span>
|
|
|
- <svg class="arrow-icon" v-if="!isSidebarCollapsed" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <polyline points="6 9 12 15 18 9" />
|
|
|
- </svg>
|
|
|
-
|
|
|
- <!-- 折叠悬停二级菜单 -->
|
|
|
- <div class="sidebar-hover-pop" v-if="isSidebarCollapsed">
|
|
|
- <div class="sub-item">账号设置</div>
|
|
|
- <div class="sub-item">绑定员工</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 二级子菜单 -->
|
|
|
- <div class="sidebar-sub-menu" v-if="!isSidebarCollapsed" :class="{ 'show': openMenus.security }">
|
|
|
- <div class="sub-item">账号设置</div>
|
|
|
- <div class="sub-item">绑定员工</div>
|
|
|
- </div>
|
|
|
+ </template>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
@@ -291,7 +69,7 @@
|
|
|
<!-- 采购单 (悬停时呈现为纯大红背景 58x58,图2完美复刻) -->
|
|
|
<div class="toolbar-item selection-item">
|
|
|
<!-- 购物车微型数字红圈角标 -->
|
|
|
- <div class="cart-badge">5</div>
|
|
|
+ <div class="cart-badge">{{ cartCount }}</div>
|
|
|
<div class="toolbar-icon-wrapper">
|
|
|
<svg class="t-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
<circle cx="9" cy="21" r="1" />
|
|
|
@@ -302,16 +80,6 @@
|
|
|
<span class="toolbar-text">采购单</span>
|
|
|
</div>
|
|
|
|
|
|
- <!-- 企业消息 (悬停时呈现为纯大红背景 58x58,图3完美复刻) -->
|
|
|
- <div class="toolbar-item msg-item">
|
|
|
- <div class="toolbar-icon-wrapper">
|
|
|
- <svg class="t-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
- <path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9M13.73 21a2 2 0 0 1-3.46 0" stroke-linecap="round" stroke-linejoin="round" />
|
|
|
- </svg>
|
|
|
- </div>
|
|
|
- <span class="toolbar-text">消息</span>
|
|
|
- </div>
|
|
|
-
|
|
|
<!-- 我的客服 (悬停时呈现为纯大红背景 58x58,并向左滑出精致气泡面板,图4完美复刻) -->
|
|
|
<div class="toolbar-item service-item">
|
|
|
<div class="toolbar-icon-wrapper">
|
|
|
@@ -399,18 +167,18 @@
|
|
|
<div class="purchase-classroom">
|
|
|
<div class="classroom-header">
|
|
|
<span class="classroom-title">采购课堂</span>
|
|
|
- <span class="classroom-more">查看全部</span>
|
|
|
+ <span class="classroom-more"></span>
|
|
|
</div>
|
|
|
- <div class="classroom-content">
|
|
|
+ <div class="classroom-content" @click="onPath('/solve/real?id=' + announcement.id)">
|
|
|
<div class="classroom-time">
|
|
|
- <span class="c-year">2026年</span>
|
|
|
- <span class="c-week">第 21 周</span>
|
|
|
+ <span class="c-year">{{ announcement.yearAndWeek?.yearField }}</span>
|
|
|
+ <span class="c-week">{{ announcement.yearAndWeek?.weekField }}</span>
|
|
|
</div>
|
|
|
<div class="classroom-info">
|
|
|
- <p class="c-desc">防洪防汛特辑 | 工厂园区篇</p>
|
|
|
+ <p class="c-desc">{{ announcement.announcementTitle }}</p>
|
|
|
</div>
|
|
|
<div class="classroom-cover">
|
|
|
- <img src="@/assets/data/classroom_cover.png" alt="课程封面" />
|
|
|
+ <img :src="announcement.coverImage" alt="课程封面" />
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -436,6 +204,154 @@ import { headerCategoryList } from '@/api/home/index-data';
|
|
|
import { getInfo } from '@/api/login';
|
|
|
import { computed } from 'vue';
|
|
|
import { onPath } from '@/utils/siteConfig';
|
|
|
+import workbench1 from '@/assets/images/layout/workbench1.png';
|
|
|
+import workbench2 from '@/assets/images/layout/workbench2.png';
|
|
|
+import workbench3 from '@/assets/images/layout/workbench3.png';
|
|
|
+import workbench4 from '@/assets/images/layout/workbench4.png';
|
|
|
+import workbench5 from '@/assets/images/layout/workbench5.png';
|
|
|
+import workbench6 from '@/assets/images/layout/workbench6.png';
|
|
|
+import workbench7 from '@/assets/images/layout/workbench7.png';
|
|
|
+import { cartStore } from '@/store/modules/cart';
|
|
|
+import { getWorkbenchMenuList } from '@/api/pc/system/index';
|
|
|
+import { getAnnouncementList } from '@/api/pc/system/announcement';
|
|
|
+const announcement = ref<any>({});
|
|
|
+const cartStoreData = cartStore();
|
|
|
+const cartCount = computed(() => cartStoreData.cartCount);
|
|
|
+const menuList = ref<any>([
|
|
|
+ {
|
|
|
+ path: '/enterprise',
|
|
|
+ title: '企业账户',
|
|
|
+ icon: workbench1,
|
|
|
+ show: false,
|
|
|
+ children: [
|
|
|
+ { path: '/enterprise/companyInfo', title: '企业信息' },
|
|
|
+ { path: '/enterprise/messageNotice', title: '消息通知' }, // 接口没返这个,应该被过滤
|
|
|
+ { path: '/easybuv', title: '地址管理' },
|
|
|
+ { path: '/enterprise/invoiceManage', title: '发票抬头管理' },
|
|
|
+ { path: '/enterprise/purchasePlan', title: '专属采购方案' },
|
|
|
+ { path: '/enterprise/agreementSupply', title: '协议供货' },
|
|
|
+ { path: '/enterprise/myCollection', title: '我的收藏' },
|
|
|
+ { path: '/enterprise/purchaseHistory', title: '历史购买' },
|
|
|
+ { path: '/enterprise/myFootprint', title: '我的足迹' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: '/order',
|
|
|
+ title: '交易管理',
|
|
|
+ icon: workbench2,
|
|
|
+ show: false,
|
|
|
+ children: [
|
|
|
+ { path: '/order/orderManage', title: '订单管理' },
|
|
|
+ { path: '/order/orderAudit', title: '审核订单' },
|
|
|
+ { path: '/order/afterSale', title: '售后服务' },
|
|
|
+ { path: '/order/batchOrder', title: '批量下单' },
|
|
|
+ { path: '/order/orderEvaluation', title: '订单评价' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: '/organization',
|
|
|
+ title: '组织管理',
|
|
|
+ icon: workbench3,
|
|
|
+ show: false,
|
|
|
+ children: [
|
|
|
+ { path: '/i', title: '个人信息' },
|
|
|
+ { path: '/organization/deptManage', title: '部门管理' },
|
|
|
+ { path: '/organization/staffManage', title: '人员管理' },
|
|
|
+ { path: '/organization/roleManage', title: '角色管理' },
|
|
|
+ { path: '/organization/approvalFlow', title: '审批流程' },
|
|
|
+ { path: '/organization/groupEnterprise', title: '集团关联企业' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: '/cost',
|
|
|
+ title: '成本管理',
|
|
|
+ icon: workbench4,
|
|
|
+ show: false,
|
|
|
+ children: [
|
|
|
+ { path: '/cost/itemExpense', title: '分项费用' },
|
|
|
+ { path: '/cost/quotaControl', title: '额度控制' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: '/reconciliation',
|
|
|
+ title: '对账管理',
|
|
|
+ icon: workbench5,
|
|
|
+ show: false,
|
|
|
+ children: [
|
|
|
+ { path: '/reconciliation/billManage', title: '对账单管理' },
|
|
|
+ { path: '/reconciliation/invoiceManage', title: '开票管理' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: '/valueAdded',
|
|
|
+ title: '增值服务',
|
|
|
+ icon: workbench6,
|
|
|
+ show: false,
|
|
|
+ children: [
|
|
|
+ { path: '/valueAdded/maintenance', title: '维保服务' },
|
|
|
+ { path: '/valueAdded/complaint', title: '投诉与建议' }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+ {
|
|
|
+ path: '/analysis',
|
|
|
+ title: '采购分析',
|
|
|
+ icon: workbench7,
|
|
|
+ show: false,
|
|
|
+ children: [
|
|
|
+ { path: '/analysis/orderAnalysis', title: '订单交易分析' },
|
|
|
+ { path: '/analysis/purchaseDetail', title: '商品采购明细' },
|
|
|
+ { path: '/analysis/orderStatus', title: '订单执行状态' },
|
|
|
+ { path: '/analysis/settlementStatus', title: '对账结算状况' },
|
|
|
+ { path: '/analysis/deptPurchase', title: '部门采购金额' }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+]);
|
|
|
+
|
|
|
+getWorkbenchMenuList().then((res: any) => {
|
|
|
+ const apiData = res.data || res;
|
|
|
+ if (Array.isArray(apiData)) {
|
|
|
+ processMenuPermissions(apiData);
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+const allowedPaths = ref<Set<string>>(new Set());
|
|
|
+const processMenuPermissions = (apiMenuList: any[]) => {
|
|
|
+ // 1. 收集接口返回的所有合法 path
|
|
|
+ const paths = new Set<string>();
|
|
|
+ const traverse = (items: any[]) => {
|
|
|
+ items.forEach((item) => {
|
|
|
+ // 统一格式:确保以 / 开头
|
|
|
+ const p = item.path.startsWith('/') ? item.path : `/${item.path}`;
|
|
|
+ paths.add(p);
|
|
|
+ if (item.children && item.children.length > 0) {
|
|
|
+ traverse(item.children);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ traverse(apiMenuList);
|
|
|
+ allowedPaths.value = paths;
|
|
|
+
|
|
|
+ // 2. 更新本地 menuList:过滤子菜单并设置父级显示状态
|
|
|
+ menuList.value.forEach((menu) => {
|
|
|
+ if (!menu.children) {
|
|
|
+ menu.show = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 【核心修改】过滤出有权限的子菜单
|
|
|
+ const permittedChildren = menu.children.filter((child) => {
|
|
|
+ const childPath = child.path.startsWith('/') ? child.path : `/${child.path}`;
|
|
|
+ return paths.has(childPath);
|
|
|
+ });
|
|
|
+
|
|
|
+ // 将过滤后的子菜单重新赋值给 menu.children
|
|
|
+ // 这样模板里 v-for 循环时就只有有权限的子项了
|
|
|
+ menu.children = permittedChildren;
|
|
|
+
|
|
|
+ // 如果过滤后还有子菜单,则显示父级;否则隐藏父级
|
|
|
+ menu.show = permittedChildren.length > 0;
|
|
|
+ });
|
|
|
+};
|
|
|
|
|
|
const userInfo = ref<any>({});
|
|
|
getInfo().then((res) => {
|
|
|
@@ -444,6 +360,35 @@ getInfo().then((res) => {
|
|
|
}
|
|
|
});
|
|
|
|
|
|
+getAnnouncementList({ pageNum: 1, pageSize: 1, isShow: 1 }).then((res) => {
|
|
|
+ if (res.code == 200) {
|
|
|
+ if (res.rows.length > 0) {
|
|
|
+ announcement.value = res.rows[0];
|
|
|
+ announcement.value.yearAndWeek = getYearAndWeek(announcement.value.createTime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+});
|
|
|
+
|
|
|
+function getYearAndWeek(dateStr) {
|
|
|
+ const date = new Date(dateStr.replace(/-/g, '/')); // 兼容 Safari 等浏览器
|
|
|
+ const year = date.getFullYear();
|
|
|
+
|
|
|
+ // 获取当年的 1月1日
|
|
|
+ const firstDayOfYear = new Date(year, 0, 1);
|
|
|
+
|
|
|
+ // 计算两个日期相差的毫秒数,转换为天数
|
|
|
+ const diffTime = date.getTime() - firstDayOfYear.getTime();
|
|
|
+ const diffDays = Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
|
|
+
|
|
|
+ // 1月1日为第一周,所以天数差除以7向上取整
|
|
|
+ const weekNumber = Math.ceil((diffDays + 1) / 7);
|
|
|
+
|
|
|
+ return {
|
|
|
+ yearField: `${year}年`,
|
|
|
+ weekField: `第${weekNumber}周`
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
const navItems = ref<any>([]);
|
|
|
headerCategoryList({}).then((res) => {
|
|
|
if (res.code == 200) {
|
|
|
@@ -455,17 +400,7 @@ headerCategoryList({}).then((res) => {
|
|
|
const isSidebarCollapsed = ref(true);
|
|
|
|
|
|
// 一二级子菜单的高保真展开折叠状态管理 (默认展开图2、图3中所有可展开的项,且地址、账号默认关闭符合图2初始态)
|
|
|
-const openMenus = ref({
|
|
|
- purchase: true, // 采购单管理,默认展开
|
|
|
- nonTender: false, // 非招标采购,默认闭合 (图2为闭合,小箭头向下)
|
|
|
- order: true, // 订单管理,默认展开
|
|
|
- invoice: true, // 发票管理,默认展开
|
|
|
- afterSale: true, // 售后管理,默认展开
|
|
|
- finance: true, // 财务管理,默认展开
|
|
|
- dataCenter: true, // 数据中心,默认展开
|
|
|
- address: false, // 地址管理,图2为闭合,图3为展开
|
|
|
- security: false // 账号安全,图2为闭合,图3为展开
|
|
|
-});
|
|
|
+const openMenus = ref<any>({});
|
|
|
|
|
|
// 通用子菜单展开/闭合切换处理器,带窄栏时自动展宽逻辑
|
|
|
const toggleMenu = (key) => {
|
|
|
@@ -477,10 +412,6 @@ const toggleMenu = (key) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-// 完美向后兼容原先对采购单管理展开状态的引用
|
|
|
-const isPurchaseMenuOpen = computed(() => openMenus.value.purchase);
|
|
|
-const handlePurchaseClick = () => toggleMenu('purchase');
|
|
|
-
|
|
|
const scrollToTop = () => {
|
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
|
};
|