Bläddra i källkod

wip: b2 布局

wjc 2 veckor sedan
förälder
incheckning
01a543dc21

+ 1 - 0
src/assets/css/theme.scss

@@ -2,6 +2,7 @@
 // 主题1:原始主题蓝色系
 // @import 'theme_1.scss';
 // 主题2:暗蓝色系
+@import '@/assets/css/function';
 @import 'theme_2.scss';
 
 // 菜单颜色

BIN
src/assets/images/dblxzhb.png


BIN
src/assets/images/zhhb.png


BIN
src/assets/images/zhnmj.png


+ 51 - 34
src/route/white-list.js

@@ -2,10 +2,10 @@
  * @Author: WangQiBiao
  * @Date: 2019-09-18 09:40:26
  * @LastEditors: wjc
- * @LastEditTime: 2025-11-18 17:37:59
+ * @LastEditTime: 2025-11-19 16:16:33
  * @Description: 白名单菜单
  */
-import _import from './_import'
+import _import from "./_import"
 /**
  * title 菜单名称
  * hideInMenu 是否隐藏菜单,默认显示
@@ -14,60 +14,77 @@ import _import from './_import'
 
 export default [
   {
-    path: '',
-    redirect: 'login'
+    path: "",
+    redirect: "login",
   },
   {
-    path: '/',
-    redirect: 'login'
+    path: "/",
+    redirect: "login",
   },
   {
-    path: '/index',
-    component: _import('index'),
+    path: "/index",
+    component: _import("index"),
     meta: {
-      title: '首页',
+      title: "首页",
       hideInMenu: false,
-      icon: ''
-    }
+      icon: "",
+    },
   },
   {
-    path: '/total-sum',
-    component: _import('total-sum'),
+    path: "/total-sum",
+    component: _import("total-sum"),
     meta: {
-      title: '总金额统计',
+      title: "总金额统计",
       hideInMenu: false,
-      icon: ''
-    }
+      icon: "",
+    },
   },
   {
-    path: '/hui-jia',
-    component: () => import('@/views/hui-jia/b1-screen/index.vue'),
+    path: "/hui-jia",
+    component: () => import('@/components/main/index.vue'),
     meta: {
-      title: '绘家科技',
+      title: "绘家科技",
       hideInMenu: false,
-      icon: ''
-    }
+    },
+    children: [
+      {
+        path: "b1",
+        component: () => import("@/views/hui-jia/b1-screen/index.vue"),
+        meta: {
+          title: "绘家科技",
+          hideInMenu: false,
+        },
+      },
+      {
+        path: "b2",
+        component: () => import("@/views/hui-jia/b2-screen/index.vue"),
+        meta: {
+          title: "绘家科技",
+          hideInMenu: false,
+        },
+      },
+    ],
   },
   {
-    path: '/login',
-    component: _import('login'),
+    path: "/login",
+    component: _import("login"),
     meta: {
-      title: '登录',
+      title: "登录",
       hideInMenu: false,
-      icon: ''
-    }
+      icon: "",
+    },
   },
   {
-    path: '/no-login',
-    component: _import('no-login'),
+    path: "/no-login",
+    component: _import("no-login"),
     meta: {
-      title: '没有登录权限',
+      title: "没有登录权限",
       hideInMenu: false,
-      icon: ''
-    }
+      icon: "",
+    },
   },
   {
-    path: '*',
-    component: _import('not-found')
-  }
+    path: "*",
+    component: _import("not-found"),
+  },
 ]

+ 0 - 2
src/views/hui-jia/b1-screen/index.vue

@@ -96,11 +96,9 @@
       height: calc(36% - $gap-padding);
       .now-year-container {
         width: 50%;
-        // height: 100%;
       }
       .implementing-container {
         width: 50%;
-        // height: 100%;
       }
     }
   }

+ 117 - 0
src/views/hui-jia/b2-screen/index.vue

@@ -0,0 +1,117 @@
+<!--
+ * @Author: wjc
+ * @Date: 2025-11-19 16:09:12
+ * @LastEditors: wjc
+ * @LastEditTime: 2025-11-19 17:01:02
+ * @Description: 
+-->
+<template>
+  <div class="b2-screen">
+    <div class="left-wrap">
+      <div style="color: #fff" class="item-1">1</div>
+      <Smart />
+    </div>
+    <div class="middle-wrap">
+      <div class="top">
+        <div class="top-left">
+          <div style="color: #fff" class="item-2">2</div>
+          <div style="color: #fff" class="item-3">3</div>
+          <div style="color: #fff" class="item-4">4</div>
+        </div>
+        <Hardware />
+      </div>
+      <WorkCard />
+    </div>
+  </div>
+</template>
+
+<script>
+  import Smart from "../components/smart.vue"
+  import Hardware from "../components/hardware.vue"
+  import WorkCard from "../components/work-card.vue"
+
+  export default {
+    name: "B1Screen",
+    components: {
+      Smart,
+      Hardware,
+      WorkCard,
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+  $gap-padding: 8px;
+
+  .b2-screen {
+    height: 100vh;
+    width: 100vw;
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: flex-start;
+    gap: 16px;
+    .left-wrap {
+      display: flex;
+      flex-direction: column;
+      gap: 16px;
+      width: calc(25% - $gap-padding);
+      .item-1 {
+        width: 100%;
+        height: calc(50% - $gap-padding);
+        background: #f5f5f5;
+      }
+      .smart-door {
+        width: 100%;
+        height: calc(50% - $gap-padding);
+      }
+    }
+    .middle-wrap {
+      width: calc(75% - $gap-padding);
+      height: 100%;
+      display: flex;
+      flex-wrap: wrap;
+      gap: 16px;
+      justify-content: flex-start;
+      .top {
+        flex: 1 1 0%;
+        display: flex;
+        gap: calc($gap-padding * 2);
+        width: 100%;
+        height: calc(75% - $gap-padding);
+        .top-left {
+          display: flex;
+          flex-direction: column;
+          width: 50%;
+          height: 100%;
+          .item-2 {
+            flex: 1 1 0%;
+            width: 100%;
+            // height: calc(25% - $gap-padding);
+            background: #f5f5f5;
+          }
+          .item-3 {
+            flex: 1 1 0%;
+            background: green;
+            width: 100%;
+            // height: calc(25% - $gap-padding);
+          }
+          .item-4 {
+            flex: 1 1 0%;
+            width: 100%;
+            // height: calc(25% - $gap-padding);
+            background: green;
+          }
+        }
+        .hardware-data {
+          width: 50%;
+          height: 100%;
+        //   height: calc(75% - $gap-padding);
+        }
+      }
+      .work-card-container {
+        width: 100%;
+        height: calc(25% - $gap-padding);
+      }
+    }
+  }
+</style>

+ 33 - 61
src/views/hui-jia/components/hardware.vue

@@ -1,12 +1,15 @@
 <template>
   <div class="hardware-data">
     <!-- 标题 -->
-    <div class="module-title">硬件数据</div>
+    <div class="module-title">
+      <img src="@/assets/images/shb.png" class="title-icon" />
+      硬件数据
+    </div>
 
     <!-- 智能电表部分 -->
     <div class="data-section">
       <div class="device-info">
-        <div class="device-icon electric"></div>
+        <img src="@/assets/images/dblxzhb.png" class="title-icon" />
         <div>
           <div class="device-count">8921</div>
           <div class="device-name">智能电表</div>
@@ -52,9 +55,11 @@
     <!-- 智能水表部分 -->
     <div class="data-section">
       <div class="device-info">
-        <div class="device-icon water"></div>
-        <div class="device-name">智能水表</div>
-        <div class="device-count">8921</div>
+        <img src="@/assets/images/zhnmj.png" class="title-icon" />
+        <div>
+          <div class="device-count">8921</div>
+          <div class="device-name">智能水表</div>
+        </div>
       </div>
       <div class="data-cards">
         <div class="data-card">
@@ -233,6 +238,7 @@
         }
 
         this.powerChartInstance.setOption(option)
+        this.powerChartInstance.resize()
       },
 
       // 初始化用水量柱状图
@@ -342,6 +348,7 @@
         }
 
         this.waterChartInstance.setOption(option)
+        this.waterChartInstance.resize()
       },
 
       handleResize() {
@@ -362,24 +369,28 @@
   .hardware-data {
     background: var(--content-bg);
     border-radius: 4px;
-    padding: 20px;
     height: 100%;
     display: flex;
     flex-direction: column;
-    gap: 20px;
+    gap: halfW(20);
   }
 
   .module-title {
+    display: flex;
+    align-items: center;
     color: var(--title-primary);
-    font-size: 18px;
+    font-size: halfW(18);
     font-weight: 500;
-    margin-bottom: 10px;
+    border-radius: 4px;
+    padding: halfH(4) halfW(10);
+    background: var(--title-bg);
   }
 
   .data-section {
     display: flex;
     justify-content: space-between;
-    gap: 20px;
+    gap: halfW(16);
+    padding: halfH(10) halfW(10);
   }
 
   .device-info {
@@ -387,60 +398,24 @@
     background: var(--title-bg);
     display: flex;
     align-items: center;
-    gap: 20px;
+    gap: halfW(20);
     justify-content: space-between;
     border: 1px solid rgba(64, 158, 255, 0.1);
-    border-radius: 6px;
-    padding: 16px;
-  }
-
-  .device-icon {
-    width: 48px;
-    height: 48px;
-    border-radius: 50%;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    position: relative;
-  }
-
-  .device-icon.electric {
-    background: linear-gradient(135deg, #ff8c00 0%, #ffd700 100%);
-  }
-
-  .device-icon.water {
-    background: linear-gradient(135deg, #00bfff 0%, #87ceeb 100%);
-  }
-
-  .device-icon::after {
-    content: "";
-    position: absolute;
-    width: 24px;
-    height: 24px;
-    background-size: contain;
-    background-repeat: no-repeat;
-    background-position: center;
-  }
-
-  .device-icon.electric::after {
-    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white"><path d="M12 2C13.1 2 14 .9 14 0H10C10 .9 10.9 2 12 2M15.78 9H14.22L14 12H10L9.78 9H8.22L7.79 14H9.2L9.5 17H14.5L14.8 14H16.21L15.78 9M12 4C10.9 4 10 4.9 10 6S10.9 8 12 8 14 7.1 14 6 13.1 4 12 4Z"/></svg>');
-  }
-
-  .device-icon.water::after {
-    background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white"><path d="M12 2C13.1 2 14 .9 14 0H10C10 .9 10.9 2 12 2M12 18.5C11.45 18.5 11 18.05 11 17.5C11 16.95 11.45 16.5 12 16.5C12.55 16.5 13 16.95 13 17.5C13 18.05 12.55 18.5 12 18.5M12 12C9.79 12 8 13.79 8 16H16C16 13.79 14.21 12 12 12M12 4C9.79 4 8 5.79 8 8H16C16 5.79 14.21 4 12 4M3 20V22H13V20H3M16.5 18.21L17.79 16.93L19.5 18.65L23.07 15.07L24.5 16.45L19.5 21.45L16.5 18.21Z"/></svg>');
+    border-radius: halfW(6);
+    padding: halfH(16) halfW(16);
   }
 
   .device-name {
     color: #fea373;
-    font-size: 16px;
+    font-size: halfW(14);
     font-weight: 500;
   }
 
   .device-count {
     color: #fff;
-    font-size: 18px;
+    font-size: halfW(18);
     font-weight: 500;
-    margin-bottom: 10px;
+    margin-bottom: halfH(10);
   }
 
   .data-cards {
@@ -448,11 +423,10 @@
     display: flex;
     align-items: center;
     justify-content: space-between;
-    // gap: 20px;
     flex-wrap: wrap;
     background: var(--title-bg);
     border: 1px solid rgba(64, 158, 255, 0.1);
-    border-radius: 6px;
+    border-radius: halfW(4);
   }
 
   .data-card {
@@ -462,7 +436,7 @@
     align-items: center;
     border-right: 1px solid rgba(64, 158, 255, 0.3);
     text-align: right;
-    padding: 10px 20px;
+    padding: halfH(10) halfW(20);
     &:last-child {
       border-right: none;
     }
@@ -470,20 +444,20 @@
 
   .data-label {
     color: var(--primary);
-    font-size: 18px;
+    font-size: halfW(14);
     font-weight: 500;
   }
 
   .data-value {
     color: #fff;
-    font-size: 18px;
+    font-size: halfW(18);
     font-weight: 600;
-    margin-bottom: 2px;
+    margin-bottom: halfH(2);
   }
 
   .data-unit {
     color: #fea373;
-    font-size: 16px;
+    font-size: halfW(14);
   }
 
   /* 修改为两个图表容器 */
@@ -492,13 +466,11 @@
     flex-direction: column;
     width: 100%;
     height: 100%;
-    // min-height: 600px;
   }
 
   .chart-item {
     flex: 1;
     width: 100%;
     height: 100%;
-    min-height: 300px;
   }
 </style>

+ 17 - 2
src/views/hui-jia/components/implementary/ing.vue

@@ -4,7 +4,12 @@
       <img src="@/assets/images/nz.png" class="title-icon" />
       进行中的实施服务
     </div>
-    <div class="implementing-list">
+    <vueSeamless
+      :data="implementingList"
+      :class-option="optionScroll"
+      class="implementing-list"
+    >
+      <!-- <div class="implementing-list"> -->
       <div
         v-for="(item, index) in implementingList"
         :key="index"
@@ -40,16 +45,21 @@
           </div>
         </div>
       </div>
-    </div>
+      <!-- </div> -->
+    </vueSeamless>
   </div>
 </template>
 
 <script>
   import { mapState } from "vuex"
+  import vueSeamless from "vue-seamless-scroll"
   import { api } from "@/api"
 
   export default {
     name: "ImplementingServices",
+    components: {
+      vueSeamless,
+    },
     data() {
       return {
         implementingList: [],
@@ -58,6 +68,11 @@
     },
     computed: {
       ...mapState(["entCode", "communityId"]),
+      optionScroll() {
+        return {
+          step: 0.5,
+        }
+      },
     },
     mounted() {
       this.init()

+ 2 - 2
src/views/hui-jia/components/market.vue

@@ -145,7 +145,7 @@
               },
               barMinHeight: 4,
               data: this.chartData.lastMonthData,
-              barWidth: 25,
+              barWidth: 16,
               itemStyle: {
                 // 左侧渐变色:从#F66757到#FCE2B4
                 color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
@@ -175,7 +175,7 @@
               },
               barMinHeight: 4,
               data: this.chartData.thisMonthData,
-              barWidth: 25,
+              barWidth: 16,
               itemStyle: {
                 // 右侧渐变色:从#1620D4到#3AB3E3
                 color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [

+ 20 - 13
src/views/hui-jia/components/smart.vue

@@ -1,7 +1,10 @@
 <template>
   <div class="smart-door">
     <!-- 标题 -->
-    <div class="module-title">智能门禁</div>
+    <div class="module-title">
+      <img src="@/assets/images/xlzb.png" class="title-icon" />
+      智能门禁
+    </div>
 
     <!-- 数据卡片 -->
     <div class="data-cards">
@@ -190,31 +193,31 @@
   .smart-door {
     background: var(--content-bg);
     border-radius: 4px;
-    padding: 20px;
     height: 100%;
   }
 
   .module-title {
+    display: flex;
+    border-radius: 4px;
+    align-items: center;
     color: var(--title-primary);
-    margin-bottom: 20px;
+    background: var(--title-bg);
+    padding: 4px 10px;
   }
 
   .data-cards {
     display: flex;
     gap: 16px;
-    margin-bottom: 24px;
-    flex-wrap: wrap;
-    padding: 10px 20px;
-    margin: 36px auto;
+    flex-wrap: nowrap;
+    margin: 20px 10px;
     background: var(--title-bg);
     border: 1px solid rgba(64, 158, 255, 0.1);
-    border-radius: 6px;
+    border-radius: 4px;
   }
 
   .data-card {
     flex: 1;
-    min-width: 200px;
-    padding: 16px;
+    padding: 6px 10px;
     display: flex;
     justify-content: space-between;
     align-items: center;
@@ -226,8 +229,8 @@
     }
 
     .iconfont {
-      width: 40px;
-      height: 40px;
+      width: 24px;
+      height: 24px;
       display: flex;
       align-items: center;
       justify-content: center;
@@ -260,18 +263,22 @@
     flex: 1;
     display: flex;
     flex-direction: column;
+    padding: 10px;
+    height: calc(100% - 200px);
   }
 
   .chart-title {
+    position: absolute;
     font-size: 14px;
     font-weight: 500;
     color: #fff;
-    margin-bottom: 16px;
+    margin-top: 10px;
   }
 
   .traffic-chart {
     flex: 1;
     width: 100%;
+    // height: 100%;
     min-height: 250px;
   }
 </style>

+ 38 - 21
src/views/hui-jia/components/work-card.vue

@@ -1,13 +1,19 @@
 <template>
-  <div class="work-card">
-    <div class="work-card-item" v-for="item in dataList" :key="item.title">
-      <div class="card-header">
-        <!-- <i class="iconfont" :class="iconName"></i> -->
-        <span class="card-title">{{ item.title }}</span>
-      </div>
-      <div class="card-content">
-        <div class="card-subtitle">{{ item.subtitle }}</div>
-        <div class="card-value">{{ formatNumber(item.value) }}</div>
+  <div class="work-card-container">
+    <div class="title">
+      <img src="@/assets/images/fwzj.png" class="title-icon" />
+      部分业务统计
+    </div>
+    <div class="work-card">
+      <div class="work-card-item" v-for="item in dataList" :key="item.title">
+        <div class="card-header">
+          <img src="@/assets/images/fwzj.png" class="title-icon" />
+          <span class="card-title">{{ item.title }}</span>
+        </div>
+        <div class="card-content">
+          <div class="card-subtitle">{{ item.subtitle }}</div>
+          <div class="card-value">{{ formatNumber(item.value) }}</div>
+        </div>
       </div>
     </div>
   </div>
@@ -17,11 +23,6 @@
   export default {
     name: "WorkCard",
     props: {
-      iconName: {
-        type: String,
-        required: true,
-        default: "icon-enterprise",
-      },
       title: {
         type: String,
         required: true,
@@ -87,18 +88,34 @@
 
 <style lang="scss" scoped>
   @import "@/assets/css/theme.scss";
-
+  .work-card-container {
+    background: var(--content-bg);
+    border-radius: 4px;
+    height: 100%;
+    width: 100%;
+    display: flex;
+    flex-direction: column;
+    .title {
+      display: flex;
+      border-radius: 4px;
+      align-items: center;
+      color: var(--title-primary);
+      background: var(--title-bg);
+      padding: 4px 10px;
+    }
+  }
   .work-card {
-    display: grid;
-    grid-template-columns: repeat(3, 1fr);
-    grid-template-rows: repeat(2, 1fr);
+    flex: 1 1 0%;
+    padding: 0px 20px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
     gap: 10px;
   }
 
   .work-card-item {
-    background: var(--content-bg);
+    background: var(--title-bg);
     border-radius: 4px;
-    height: 100%;
     display: flex;
     flex-direction: column;
     justify-content: space-between;
@@ -108,7 +125,7 @@
     display: flex;
     align-items: center;
     margin-bottom: 16px;
-    padding: 20px;
+    padding: 4px 10px;
     background: var(--title-bg);
 
     .iconfont {

+ 0 - 44
src/views/hui-jia/index.vue

@@ -1,44 +0,0 @@
-<!--
- * @Author: wjc
- * @Date: 2025-11-17 16:26:35
- * @LastEditors: wjc
- * @LastEditTime: 2025-11-18 15:51:58
- * @Description:
--->
-<template>
-  <div>
-    <implementationTotal />
-    <implementationIng />
-    <implementationNowYear />
-    <Market />
-    <WorkCard />
-    <Smart />
-    <Hardware />
-  </div>
-</template>
-
-<script>
-
-import implementationTotal from './components/implementary/total.vue'
-import implementationIng from './components/implementary/ing.vue'
-import implementationNowYear from './components/implementary/now-year.vue'
-import Market from './components/market.vue'
-import WorkCard from './components/work-card.vue'
-import Smart from './components/smart.vue'
-import Hardware from './components/hardware.vue'
-
-export default {
-  components: {
-    implementationTotal,
-    implementationIng,
-    implementationNowYear,
-    Market,
-    WorkCard,
-    Smart,
-    Hardware
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-</style>