4 Ревизии f61539df2e ... 2bce104c2a

Автор SHA1 Съобщение Дата
  wjc 2bce104c2a Merge branch 'dev' of http://git.wisdomcity.com.cn/WisdomCity-Web/SaaS-DataScreen into feat-b2 преди 2 седмици
  wjc 85b9804bd7 wip: b1/b2 屏幕视频 преди 2 седмици
  wjc 01a543dc21 wip: b2 布局 преди 2 седмици
  wjc b4baaf6e99 wip: b2 布局 преди 2 седмици

+ 5 - 3
src/assets/css/theme.scss

@@ -2,6 +2,7 @@
 // 主题1:原始主题蓝色系
 // @import 'theme_1.scss';
 // 主题2:暗蓝色系
+@import '@/assets/css/function';
 @import 'theme_2.scss';
 
 // 菜单颜色
@@ -19,9 +20,10 @@ $left-width: 220px;
   --title-secondary: #a1a1a1;
   --content-bg: #0C1425;
   --primary: #007bd3;
+  --page-bg: #070D19;
 }
 .title-icon {
-  width: 28px;
-  height: 28px;
-  margin-right: 8px;
+  width: halfW(28);
+  height: halfW(28);
+  margin-right: halfW(8);
 }

BIN
src/assets/images/dblxzhb.png


BIN
src/assets/images/ewm.png


BIN
src/assets/images/glgd.png


BIN
src/assets/images/gwxx.png


BIN
src/assets/images/hjkj1.png


BIN
src/assets/images/hjkj2.png


BIN
src/assets/images/jgxx.png


BIN
src/assets/images/jytj.png


BIN
src/assets/images/qst.png


BIN
src/assets/images/ryzb.png


BIN
src/assets/images/xtxq.png


BIN
src/assets/images/zhhb.png


BIN
src/assets/images/zhnmj.png


BIN
src/assets/images/zhxggd.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"),
+  },
 ]

+ 106 - 25
src/views/hui-jia/b1-screen/index.vue

@@ -1,42 +1,123 @@
 <template>
   <div class="b1-screen">
-    <div>1</div>
-    <div>2</div>
-    <implementationTotal />
-    <Market />
-    <implementationIng />
-    <implementationNowYear />
+    <div class="logo">
+      <img src="@/assets/images/hjkj1.png" class="logo-img" />
+    </div>
+    <div class="b1-screen-content">
+      <div style="color: #fff" class="item-1">1</div>
+      <div class="middle-wrap">
+        <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>
+      <div class="right-wrap">
+        <Market />
+        <implementationTotal />
+      </div>
+      <div class="bottom-wrap">
+        <implementationIng />
+        <implementationNowYear />
+      </div>
+    </div>
   </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 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"
 
-export default {
-  name: 'B1Screen',
-  components: {
-    implementationTotal,
-    implementationIng,
-    implementationNowYear,
-    Market
+  export default {
+    name: "B1Screen",
+    components: {
+      implementationTotal,
+      implementationIng,
+      implementationNowYear,
+      Market,
+    },
   }
-}
 </script>
 
 <style lang="scss" scoped>
+  @import "@/assets/css/theme.scss";
+
+  $gap-padding: halfW(8);
   .b1-screen {
     height: 100vh;
     width: 100vw;
-    display: grid;
-    grid-template-columns: repeat(4, 1fr);
-    grid-template-rows: repeat(3, 1fr);
-    gap: 20px;
-    .now-year-container {
-      grid-column: 1 / span 2;
-      grid-row: 1 / span 2;
+    background: var(--page-bg);
+    .logo {
+      text-align: right;
+      padding: halfH(10) 0;
+      .logo-img {
+        height: halfH(64);
+      }
+    }
+  }
+  .b1-screen-content {
+    height: calc(100% - halfH(64) - halfH(28));
+    width: 100%;
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: flex-start;
+    gap: halfW(16);
+    .item-1 {
+      width: calc(25% - $gap-padding);
+      height: calc(64% - $gap-padding);
+      background: #f5f5f5;
+    }
+    .middle-wrap {
+      width: calc(50% - $gap-padding - $gap-padding);
+      height: calc(64% - $gap-padding);
+      display: flex;
+      flex-wrap: wrap;
+      gap: halfW(16);
+      justify-content: flex-start;
+      .item-2 {
+        flex: 0 0 100%;
+        width: 100%;
+        height: calc(50% - $gap-padding);
+        background: #f5f5f5;
+      }
+      .item-3 {
+        background: green;
+        flex: 0 0 calc(50% - $gap-padding);
+        width: calc(50% - $gap-padding);
+        height: calc(50% - $gap-padding);
+      }
+      .item-4 {
+        flex: 0 0 calc(50% - $gap-padding);
+        width: calc(50% - $gap-padding);
+        height: calc(50% - $gap-padding);
+        background: green;
+      }
+    }
+    .right-wrap {
+      display: flex;
+      flex-direction: column;
+      width: calc(25% - $gap-padding);
+      height: calc(64% - $gap-padding);
+      gap: calc($gap-padding * 2);
+      .total-container {
+        height: calc(50% - $gap-padding);
+      }
+      .market-container {
+        height: calc(50% - $gap-padding);
+      }
+    }
+    .bottom-wrap {
+      display: flex;
+      justify-content: space-around;
+      gap: halfW(16);
+      width: 100%;
+      height: calc(36% - $gap-padding);
+      .now-year-container {
+        width: 50%;
+      }
+      .implementing-container {
+        width: 50%;
+      }
     }
   }
 </style>

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

@@ -0,0 +1,132 @@
+<!--
+ * @Author: wjc
+ * @Date: 2025-11-19 16:09:12
+ * @LastEditors: wjc
+ * @LastEditTime: 2025-11-20 10:58:02
+ * @Description: 
+-->
+<template>
+  <div class="b2-screen">
+    <div class="logo">
+      <img src="@/assets/images/hjkj2.png" class="logo-img" />
+    </div>
+    <div class="b2-screen-content">
+      <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>
+  </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>
+  @import "@/assets/css/theme.scss";
+
+  $gap-padding: halfW(8);
+  .b2-screen {
+    height: 100vh;
+    width: 100vw;
+    background: var(--page-bg);
+    .logo {
+      text-align: left;
+      padding: halfH(10) 0;
+      .logo-img {
+        height: halfH(64);
+      }
+    }
+  }
+  .b2-screen-content {
+    height: calc(100% - halfH(64) - halfH(28));
+    width: 100%;
+    display: flex;
+    flex-wrap: wrap;
+    justify-content: flex-start;
+    gap: halfW(16);
+    .left-wrap {
+      display: flex;
+      flex-direction: column;
+      gap: halfW(16);
+      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: halfW(16);
+      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%;
+          gap: halfW(16);
+          .item-2 {
+            flex: 1 1 0%;
+            width: 100%;
+            background: #f5f5f5;
+          }
+          .item-3 {
+            flex: 1 1 0%;
+            background: green;
+            width: 100%;
+          }
+          .item-4 {
+            flex: 1 1 0%;
+            width: 100%;
+            background: green;
+          }
+        }
+        .hardware-data {
+          width: 50%;
+          height: 100%;
+        }
+      }
+      .work-card-container {
+        width: 100%;
+        height: calc(25% - $gap-padding);
+      }
+    }
+  }
+</style>

+ 271 - 66
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,37 +55,39 @@
     <!-- 智能水表部分 -->
     <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="water-device-name">智能水表</div>
+        </div>
       </div>
       <div class="data-cards">
         <div class="data-card">
           <div class="data-label">年度用水</div>
           <div>
             <div class="data-value">89321</div>
-            <div class="data-unit">m³</div>
+            <div class="water-data-unit">m³</div>
           </div>
         </div>
         <div class="data-card">
           <div class="data-label">月均用水</div>
           <div>
             <div class="data-value">9212</div>
-            <div class="data-unit">m³</div>
+            <div class="water-data-unit">m³</div>
           </div>
         </div>
         <div class="data-card">
           <div class="data-label">日均用水</div>
           <div>
             <div class="data-value">921</div>
-            <div class="data-unit">m³</div>
+            <div class="water-data-unit">m³</div>
           </div>
         </div>
         <div class="data-card">
           <div class="data-label">开关次数</div>
           <div>
             <div class="data-value">887</div>
-            <div class="data-unit">近12个月</div>
+            <div class="water-data-unit">近12个月</div>
           </div>
         </div>
       </div>
@@ -351,7 +356,233 @@ export default {
       if (this.waterChartInstance) {
         this.waterChartInstance.resize()
       }
-    }
+    },
+    methods: {
+      // 初始化用电量柱状图
+      initPowerChart() {
+        this.powerChartInstance = echarts.init(this.$refs.powerChart)
+
+        const option = {
+          tooltip: {
+            trigger: "axis",
+            backgroundColor: "rgba(0, 0, 0, 0.8)",
+            borderColor: "rgba(64, 158, 255, 0.3)",
+            textStyle: {
+              color: "#fff",
+            },
+            formatter: (params) => {
+              let result = ``
+              params.forEach((param) => {
+                result += `${param.name}<br/>${
+                  param.seriesName
+                }: ${param.value.toLocaleString()}<br/>`
+              })
+              return result
+            },
+          },
+          grid: {
+            left: "1%",
+            right: "1%",
+            top: "5%",
+            bottom: "2%",
+            containLabel: true,
+          },
+          xAxis: {
+            type: "category",
+            data: this.monthlyData.map((item) => item.month),
+            axisLine: {
+              lineStyle: {
+                color: "rgba(160, 179, 214, 0.3)",
+                type: "dashed",
+              },
+            },
+            axisLabel: {
+              color: "rgba(160, 179, 214, 0.7)",
+              fontSize: 11,
+              interval: 0,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: true,
+              // 将坐标轴内的线设置为虚线
+              lineStyle: {
+                color: "rgba(160, 179, 214, 0.3)",
+                type: "dashed",
+              },
+            },
+          },
+          yAxis: {
+            type: "value",
+            axisLine: {
+              show: false,
+            },
+            axisLabel: {
+              color: "rgba(160, 179, 214, 0.7)",
+              fontSize: 11,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              lineStyle: {
+                color: "rgba(160, 179, 214, 0.1)",
+                type: "dashed",
+                width: 1,
+              },
+            },
+          },
+          series: [
+            {
+              name: "用电量",
+              type: "bar",
+              data: this.monthlyData.map((item) => item.power),
+              barWidth: "30%",
+              itemStyle: {
+                color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [
+                  { offset: 0, color: "#FCE2B4" },
+                  { offset: 1, color: "#F66757" },
+                ]),
+                borderRadius: [20, 20, 0, 0],
+              },
+              label: {
+                show: true,
+                position: "top",
+                color: "#fff",
+                fontSize: 10,
+                formatter: (params) =>
+                  params.value >= 10000
+                    ? (params.value / 10000).toFixed(1) + "万"
+                    : params.value,
+              },
+            },
+          ],
+        }
+
+        this.powerChartInstance.setOption(option)
+        this.powerChartInstance.resize()
+      },
+
+      // 初始化用水量柱状图
+      initWaterChart() {
+        this.waterChartInstance = echarts.init(this.$refs.waterChart)
+
+        const option = {
+          tooltip: {
+            trigger: "axis",
+            backgroundColor: "rgba(0, 0, 0, 0.8)",
+            borderColor: "rgba(64, 158, 255, 0.3)",
+            textStyle: {
+              color: "#fff",
+            },
+            formatter: (params) => {
+              let result = ``
+              params.forEach((param) => {
+                result += `${param.name}<br/>${
+                  param.seriesName
+                }: ${param.value.toLocaleString()}<br/>`
+              })
+              return result
+            },
+          },
+          grid: {
+            left: "1%",
+            right: "1%",
+            top: "2%",
+            bottom: "5%",
+            containLabel: true,
+          },
+          xAxis: {
+            type: "category",
+            data: this.monthlyData.map((item) => item.month),
+            axisLine: {
+              lineStyle: {
+                color: "rgba(160, 179, 214, 0.3)",
+                type: "dashed",
+              },
+            },
+            axisLabel: {
+              color: "rgba(160, 179, 214, 0.7)",
+              fontSize: 11,
+              interval: 0,
+              show: false,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              show: true,
+              // 将坐标轴内的线设置为虚线
+              lineStyle: {
+                color: "rgba(160, 179, 214, 0.3)",
+                type: "dashed",
+              },
+            },
+          },
+          yAxis: {
+            type: "value",
+            // 反转 y 轴的 min 和 max,实现“倒立”
+            min: 400000,
+            max: 0,
+            axisLine: {
+              show: false,
+            },
+            axisLabel: {
+              color: "rgba(160, 179, 214, 0.7)",
+              fontSize: 11,
+            },
+            axisTick: {
+              show: false,
+            },
+            splitLine: {
+              lineStyle: {
+                color: "rgba(160, 179, 214, 0.1)",
+                type: "dashed",
+                width: 1,
+              },
+            },
+          },
+          series: [
+            {
+              name: "用水量",
+              type: "bar",
+              data: this.monthlyData.map((item) => item.water),
+              barWidth: "30%",
+              itemStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: "#3AB3E3" },
+                  { offset: 1, color: "#1620D4" },
+                ]),
+                borderRadius: [0, 0, 20, 20],
+              },
+              label: {
+                show: true,
+                position: "bottom",
+                color: "#fff",
+                fontSize: 10,
+                formatter: (params) =>
+                  params.value >= 10000
+                    ? (params.value / 10000).toFixed(1) + "万"
+                    : params.value,
+              },
+            },
+          ],
+        }
+
+        this.waterChartInstance.setOption(option)
+        this.waterChartInstance.resize()
+      },
+
+      handleResize() {
+        if (this.powerChartInstance) {
+          this.powerChartInstance.resize()
+        }
+        if (this.waterChartInstance) {
+          this.waterChartInstance.resize()
+        }
+      },
+    },
   }
 }
 </script>
@@ -362,24 +593,28 @@ export default {
   .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 +622,29 @@ export default {
     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(10);
   }
 
   .device-name {
     color: #fea373;
-    font-size: 16px;
+    font-size: halfW(14);
+    font-weight: 500;
+  }
+  .water-device-name {
+    color: #3ab3e3;
+    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 +652,10 @@ export default {
     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 +665,7 @@ export default {
     align-items: center;
     border-right: 1px solid rgba(64, 158, 255, 0.3);
     text-align: right;
-    padding: 10px 20px;
+    padding: halfH(10) halfW(10);
     &:last-child {
       border-right: none;
     }
@@ -470,20 +673,24 @@ export default {
 
   .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);
+  }
+  .water-data-unit {
+    color: #3ab3e3;
+    font-size: halfW(14);
   }
 
   /* 修改为两个图表容器 */
@@ -492,13 +699,11 @@ export default {
     flex-direction: column;
     width: 100%;
     height: 100%;
-    // min-height: 600px;
   }
 
   .chart-item {
     flex: 1;
     width: 100%;
     height: 100%;
-    min-height: 300px;
   }
 </style>

+ 157 - 206
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,185 +45,171 @@
           </div>
         </div>
       </div>
-    </div>
+      <!-- </div> -->
+    </vueSeamless>
   </div>
 </template>
 
 <script>
-import { mapState } from 'vuex'
-// import { api } from '@/api'
-
-export default {
-  name: 'ImplementingServices',
-  data () {
-    return {
-      implementingList: [],
-      timer: null
-    }
-  },
-  computed: {
-    ...mapState(['entCode', 'communityId'])
-  },
-  mounted () {
-    this.init()
-    // 设置定时刷新
-    this.timer = setInterval(() => {
+  import { mapState } from "vuex"
+  import vueSeamless from "vue-seamless-scroll"
+  import { api } from "@/api"
+
+  export default {
+    name: "ImplementingServices",
+    components: {
+      vueSeamless,
+    },
+    data() {
+      return {
+        implementingList: [],
+        timer: null,
+      }
+    },
+    computed: {
+      ...mapState(["entCode", "communityId"]),
+      optionScroll() {
+        return {
+          step: 0.5,
+        }
+      },
+    },
+    mounted() {
       this.init()
-    }, 30000) // 每30秒刷新一次
-  },
-  beforeDestroy () {
-    if (this.timer) {
-      clearInterval(this.timer)
-    }
-  },
-  methods: {
-    // 初始化数据
-    async init () {
-      try {
-        // const params = {
-        //   entCode: this.entCode,
-        //   communityId: this.communityId
-        // }
-        // 这里应该调用实际的API获取数据
-        // const res = await api.getImplementingServices(params)
-        // this.implementingList = res.data || []
-
-        // 暂时使用模拟数据
-        this.loadMockData()
-      } catch (error) {
-        console.error('获取进行中实施服务数据失败:', error)
+      // 设置定时刷新
+      this.timer = setInterval(() => {
+        this.init()
+      }, 30000) // 每30秒刷新一次
+    },
+    beforeDestroy() {
+      if (this.timer) {
+        clearInterval(this.timer)
       }
     },
-    // 加载模拟数据
-    loadMockData () {
-      this.implementingList = [
-        {
-          date: '2025-11-19',
-          city: '五指山市',
-          projectName: '项目名称',
-          companyName: '物业公司名称',
-          householdCount: '999',
-          area: '北滨端',
-          progress: 90,
-          serviceContent: '数据清单模板填写培训',
-          period: '3周前'
-        },
-        {
-          date: '2025-11-19',
-          city: '五指山市',
-          projectName: '项目名称',
-          companyName: '物业公司名称',
-          householdCount: '999',
-          area: '北滨端',
-          progress: 90,
-          serviceContent: '数据清单模板填写培训',
-          period: '3周前'
-        },
-        {
-          date: '2025-11-19',
-          city: '五指山市',
-          projectName: '项目名称',
-          companyName: '物业公司名称',
-          householdCount: '999',
-          area: '北滨端',
-          progress: 90,
-          serviceContent: '数据清单模板填写培训',
-          period: '3周前'
-        },
-        {
-          date: '2025-11-19',
-          city: '五指山市',
-          projectName: '项目名称',
-          companyName: '物业公司名称',
-          householdCount: '999',
-          area: '北滨端',
-          progress: 90,
-          serviceContent: '数据清单模板填写培训',
-          period: '3周前'
-        },
-        {
-          date: '2025-11-19',
-          city: '五指山市',
-          projectName: '项目名称',
-          companyName: '物业公司名称',
-          householdCount: '999',
-          area: '北滨端',
-          progress: 90,
-          serviceContent: '数据清单模板填写培训',
-          period: '3周前'
-        },
-        {
-          date: '2025-11-19',
-          city: '五指山市',
-          projectName: '项目名称',
-          companyName: '物业公司名称',
-          householdCount: '999',
-          area: '北滨端',
-          progress: 90,
-          serviceContent: '数据清单模板填写培训',
-          period: '3周前'
+    methods: {
+      // 初始化数据
+      async init() {
+        try {
+          const params = {
+            entCode: this.entCode,
+            communityId: this.communityId,
+          }
+          // 这里应该调用实际的API获取数据
+          // const res = await api.getImplementingServices(params)
+          // this.implementingList = res.data || []
+
+          // 暂时使用模拟数据
+          this.loadMockData()
+        } catch (error) {
+          console.error("获取进行中实施服务数据失败:", error)
         }
-      ]
-    }
+      },
+      // 加载模拟数据
+      loadMockData() {
+        this.implementingList = [
+          {
+            date: "2025-11-19",
+            city: "五指山市",
+            projectName: "项目名称",
+            companyName: "物业公司名称",
+            householdCount: "999",
+            area: "北滨端",
+            progress: 90,
+            serviceContent: "数据清单模板填写培训",
+            period: "3周前",
+          },
+          {
+            date: "2025-11-19",
+            city: "五指山市",
+            projectName: "项目名称",
+            companyName: "物业公司名称",
+            householdCount: "999",
+            area: "北滨端",
+            progress: 90,
+            serviceContent: "数据清单模板填写培训",
+            period: "3周前",
+          },
+          {
+            date: "2025-11-19",
+            city: "五指山市",
+            projectName: "项目名称",
+            companyName: "物业公司名称",
+            householdCount: "999",
+            area: "北滨端",
+            progress: 90,
+            serviceContent: "数据清单模板填写培训",
+            period: "3周前",
+          },
+          {
+            date: "2025-11-19",
+            city: "五指山市",
+            projectName: "项目名称",
+            companyName: "物业公司名称",
+            householdCount: "999",
+            area: "北滨端",
+            progress: 90,
+            serviceContent: "数据清单模板填写培训",
+            period: "3周前",
+          },
+          {
+            date: "2025-11-19",
+            city: "五指山市",
+            projectName: "项目名称",
+            companyName: "物业公司名称",
+            householdCount: "999",
+            area: "北滨端",
+            progress: 90,
+            serviceContent: "数据清单模板填写培训",
+            period: "3周前",
+          },
+          {
+            date: "2025-11-19",
+            city: "五指山市",
+            projectName: "项目名称",
+            companyName: "物业公司名称",
+            householdCount: "999",
+            area: "北滨端",
+            progress: 90,
+            serviceContent: "数据清单模板填写培训",
+            period: "3周前",
+          },
+        ]
+      },
+    },
   }
-}
 </script>
 
 <style lang="scss" scoped>
   @import "@/assets/css/theme.scss";
 
   .implementing-container {
-    background: var(--title-bg);
-    border-radius: 4px;
-    padding: 20px;
-    height: 100%;
+    background: var(--content-bg);
+    border-radius: halfW(4);
     display: flex;
     flex-direction: column;
   }
 
   .implementing-title {
-    font-size: 18px;
+    background: var(--title-bg);
+    font-size: halfW(18);
     font-weight: 500;
     color: var(--title-primary);
-    margin-bottom: 20px;
+    padding: halfH(4) halfW(10);
+    border-radius: halfW(4);
     display: flex;
     align-items: center;
-
-    .iconfont {
-      margin-right: 8px;
-      font-size: 20px;
-    }
   }
 
   .implementing-list {
     flex: 1;
     overflow-y: auto;
-
-    // 自定义滚动条样式
-    &::-webkit-scrollbar {
-      width: 6px;
-    }
-
-    &::-webkit-scrollbar-track {
-      background: rgba(64, 158, 255, 0.1);
-      border-radius: 3px;
-    }
-
-    &::-webkit-scrollbar-thumb {
-      background: rgba(64, 158, 255, 0.3);
-      border-radius: 3px;
-    }
-
-    &::-webkit-scrollbar-thumb:hover {
-      background: rgba(64, 158, 255, 0.5);
-    }
+    padding: 0px halfW(10);
+    height: calc(100% - halfH(36));
   }
 
   .implementing-item {
     background: var(--content-bg); // 第一个项目使用--content-bg
     padding: 16px;
-    margin-bottom: 12px;
-
     &:last-child {
       margin-bottom: 0;
     }
@@ -232,37 +223,37 @@ export default {
     display: flex;
     justify-content: space-between;
     align-items: center;
-    gap: 20px;
+    gap: halfW(16);
     .item-date {
       color: var(--title-secondary);
-      font-size: 14px;
-      margin-right: 16px;
+      font-size: halfW(14);
+      margin-right: halfW(16);
     }
 
     .item-city {
       color: var(--title-primary);
-      font-size: 14px;
+      font-size: halfW(14);
       font-weight: 500;
-      padding: 2px 8px;
-      border-radius: 4px;
+      padding: halfH(2) halfW(8);
+      border-radius: halfW(4);
     }
 
     .project-info {
       flex: 1;
-      min-width: 200px;
-      margin-right: 20px;
+      min-width: halfW(200);
+      margin-right: halfW(20);
 
       .project-name {
         flex: 0 0 1;
         color: var(--title-primary);
-        font-size: 14px;
-        margin-bottom: 4px;
+        font-size: halfW(14);
+        margin-bottom: halfH(4);
         font-weight: 400;
       }
 
       .company-name {
         color: var(--title-secondary);
-        font-size: 14px;
+        font-size: halfW(14);
       }
     }
 
@@ -270,7 +261,7 @@ export default {
       display: flex;
       align-items: center;
       flex-wrap: wrap;
-      gap: 20px;
+      gap: halfW(20);
     }
 
     .stat-item {
@@ -283,80 +274,40 @@ export default {
       }
       .stat-value {
         color: #fff;
-        font-size: 16px;
+        font-size: halfW(16);
         font-weight: 500;
-        margin-right: 4px;
+        margin-right: halfW(4);
       }
 
       .stat-label {
         color: #fff;
-        font-size: 14px;
+        font-size: halfW(14);
       }
 
       .progress-wrapper {
         display: flex;
         align-items: center;
-        gap: 8px;
+        gap: halfW(8);
         .progress-text {
           color: #40d9ac;
-          font-size: 14px;
+          font-size: halfW(14);
           font-weight: 500;
-          min-width: 35px;
+          min-width: halfW(35);
         }
       }
 
       .service-content {
         color: #ffffff;
-        font-size: 14px;
+        font-size: halfW(14);
       }
 
       .period {
         color: #a0b3d6;
-        font-size: 14px;
+        font-size: halfW(14);
       }
     }
     .service-item {
       flex: 1;
     }
   }
-
-  // 响应式设计
-  @media (max-width: 1200px) {
-    .item-content {
-      .content-main {
-        flex-direction: column;
-        gap: 12px;
-      }
-
-      .project-info {
-        margin-right: 0;
-        margin-bottom: 8px;
-      }
-
-      .project-stats {
-        width: 100%;
-        justify-content: space-between;
-      }
-    }
-  }
-
-  @media (max-width: 768px) {
-    .implementing-container {
-      padding: 16px;
-    }
-
-    .implementing-title {
-      font-size: 16px;
-    }
-
-    .item-content {
-      .project-stats {
-        gap: 12px;
-      }
-
-      .stat-item {
-        font-size: 12px;
-      }
-    }
-  }
 </style>

+ 202 - 285
src/views/hui-jia/components/implementary/now-year.vue

@@ -1,342 +1,259 @@
 <template>
   <div class="now-year-container">
     <div class="now-year-title">
-      <img src="@/assets/images/shb.png" class="title-icon" />
+      <img src="@/assets/images/qst.png" class="title-icon" />
       实施服务(今年数据)
     </div>
-    <div class="chart-container">
-      <div id="nowYearChart" class="chart"></div>
-    </div>
+    <div id="nowYearChart" class="chart"></div>
   </div>
 </template>
 
 <script>
-import { mapState } from 'vuex'
-// import { api } from '@/api'
-import * as echarts from 'echarts'
-
-export default {
-  name: 'NowYearServices',
-  data () {
-    return {
-      chartInstance: null,
-      chartData: {
-        categories: [
-          '履约城市',
-          '服务企业',
-          '服务项目',
-          '合同数',
-          '签约户数'
-        ],
-        ongoing: [88888, 88888, 88888, 88888, 88888], // 进行中
-        lastMonthCompleted: [88888, 88888, 88888, 88888, 88888], // 上月完成
-        yearTotal: [88888, 88888, 888888, 88888, 88888], // 今年累计
-        totalNumbers: [8888, 8888, 8888, 8888, 8888] // 左侧显示的总数
-      },
-      timer: null
-    }
-  },
-  computed: {
-    ...mapState(['entCode', 'communityId'])
-  },
-  mounted () {
-    this.init()
-    window.addEventListener('resize', this.handleResize)
+  import { mapState } from "vuex"
+  import { api } from "@/api"
+  import * as echarts from "echarts"
 
-    // 设置定时刷新
-    this.timer = setInterval(() => {
-      this.loadData()
-    }, 30000) // 每30秒刷新一次
-  },
-  beforeDestroy () {
-    if (this.chartInstance) {
-      this.chartInstance.dispose()
-    }
-    window.removeEventListener('resize', this.handleResize)
-    if (this.timer) {
-      clearInterval(this.timer)
-    }
-  },
-  methods: {
-    // 初始化组件
-    init () {
-      this.initChart()
-      this.loadData()
+  export default {
+    name: "NowYearServices",
+    data() {
+      return {
+        chartInstance: null,
+        chartData: {
+          categories: [
+            "履约城市",
+            "服务企业",
+            "服务项目",
+            "合同数",
+            "签约户数",
+          ],
+          ongoing: [88888, 88888, 88888, 88888, 88888], // 进行中
+          lastMonthCompleted: [88888, 88888, 88888, 88888, 88888], // 上月完成
+          yearTotal: [88888, 88888, 888888, 88888, 88888], // 今年累计
+          totalNumbers: [8888, 8888, 8888, 8888, 8888], // 左侧显示的总数
+        },
+      }
+    },
+    computed: {
+      ...mapState(["entCode", "communityId"]),
+    },
+    mounted() {
+      this.init()
+      window.addEventListener("resize", this.handleResize)
+    },
+    beforeDestroy() {
+      if (this.chartInstance) {
+        this.chartInstance.dispose()
+      }
+      window.removeEventListener("resize", this.handleResize)
     },
+    methods: {
+      // 初始化组件
+      init() {
+        this.initChart()
+        this.loadData()
+      },
 
-    // 初始化图表
-    initChart () {
-      this.chartInstance = echarts.init(
-        document.getElementById('nowYearChart')
-      )
+      // 初始化图表
+      initChart() {
+        this.chartInstance = echarts.init(
+          document.getElementById("nowYearChart")
+        )
 
-      const option = {
-        tooltip: {
-          trigger: 'axis',
-          axisPointer: {
-            type: 'shadow'
-          },
-          backgroundColor: 'rgba(17, 28, 49, 0.9)',
-          borderColor: 'rgba(64, 158, 255, 0.2)',
-          textStyle: {
-            color: '#ffffff'
-          }
-        },
-        legend: {
-          data: ['进行中', '上月完成', '今年累计'],
-          textStyle: {
-            color: '#a0b3d6'
-          },
-          itemWidth: 16,
-          itemHeight: 8,
-          top: 10
-        },
-        grid: {
-          left: '3%',
-          right: '4%',
-          bottom: '3%',
-          top: 50,
-          containLabel: true
-        },
-        xAxis: {
-          type: 'value',
-          show: false, // 隐藏x轴
-          axisLine: {
-            show: false
-          },
-          axisTick: {
-            show: false
-          },
-          axisLabel: {
-            show: false
+        const option = {
+          tooltip: {
+            trigger: "axis",
+            axisPointer: {
+              type: "shadow",
+            },
+            backgroundColor: "rgba(17, 28, 49, 0.9)",
+            borderColor: "rgba(64, 158, 255, 0.2)",
+            textStyle: {
+              color: "#ffffff",
+            },
           },
-          splitLine: {
-            show: false
-          }
-        },
-        yAxis: {
-          type: 'category',
-          data: this.chartData.categories,
-          show: true, // 隐藏y轴
-          axisLine: {
-            show: false
+          legend: {
+            data: ["进行中", "上月完成", "今年累计"],
+            textStyle: {
+              color: "#a0b3d6",
+            },
+            itemWidth: 16,
+            itemHeight: 8,
+            top: 10,
           },
-          axisTick: {
-            show: false
+          grid: {
+            left: "3%",
+            right: "4%",
+            bottom: "3%",
+            top: 50,
+            containLabel: true,
           },
-          axisLabel: {
-            show: true,
-            color: '#a1a1a1',
-            fontSize: 14
-          }
-        },
-        series: [
-          {
-            name: '进行中',
-            type: 'bar',
-            stack: 'total',
-            emphasis: {
-              focus: 'series'
+          xAxis: {
+            type: "value",
+            show: false, // 隐藏x轴
+            axisLine: {
+              show: false,
             },
-            itemStyle: {
-              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
-                { offset: 0, color: '#1620D4' },
-                { offset: 0.8, color: '#3AB3E3' }
-              ]),
-              borderRadius: [20, 0, 0, 20]
+            axisTick: {
+              show: false,
             },
-            label: {
-              show: true,
-              color: '#fff'
+            axisLabel: {
+              show: false,
+            },
+            splitLine: {
+              show: false,
             },
-            barWidth: 30,
-            barGap: '0%',
-            barCategoryGap: '20%',
-            data: this.chartData.ongoing
           },
-          {
-            name: '上月完成',
-            type: 'bar',
-            stack: 'total',
-            emphasis: {
-              focus: 'series'
+          yAxis: {
+            type: "category",
+            data: this.chartData.categories,
+            show: true, // 隐藏y轴
+            axisLine: {
+              show: false,
             },
-            itemStyle: {
-              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
-                { offset: 0, color: '#192FC9' },
-                { offset: 0.8, color: '#6D44BC' }
-              ]),
-              borderRadius: [0, 0, 0, 0]
+            axisTick: {
+              show: false,
             },
-            label: {
+            axisLabel: {
               show: true,
-              color: '#fff'
+              color: "#a1a1a1",
+              fontSize: 14,
             },
-            barWidth: 30,
-            barGap: '0%',
-            data: this.chartData.lastMonthCompleted
           },
-          {
-            name: '今年累计',
-            type: 'bar',
-            stack: 'total',
-            emphasis: {
-              focus: 'series'
+          series: [
+            {
+              name: "进行中",
+              type: "bar",
+              stack: "total",
+              emphasis: {
+                focus: "series",
+              },
+              itemStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+                  { offset: 0, color: "#1620D4" },
+                  { offset: 0.8, color: "#3AB3E3" },
+                ]),
+                borderRadius: [20, 0, 0, 20],
+              },
+              label: {
+                show: true,
+                color: "#fff",
+              },
+              barWidth: 30,
+              barGap: "0%",
+              barCategoryGap: "20%",
+              data: this.chartData.ongoing,
             },
-            label: {
-              show: true,
-              color: '#fff'
+            {
+              name: "上月完成",
+              type: "bar",
+              stack: "total",
+              emphasis: {
+                focus: "series",
+              },
+              itemStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+                  { offset: 0, color: "#192FC9" },
+                  { offset: 0.8, color: "#6D44BC" },
+                ]),
+                borderRadius: [0, 0, 0, 0],
+              },
+              label: {
+                show: true,
+                color: "#fff",
+              },
+              barWidth: 30,
+              barGap: "0%",
+              data: this.chartData.lastMonthCompleted,
             },
-            itemStyle: {
-              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
-                { offset: 0, color: '#F7897D' },
-                { offset: 0.8, color: '#F66C89' }
-              ]),
-              borderRadius: [0, 20, 20, 0]
+            {
+              name: "今年累计",
+              type: "bar",
+              stack: "total",
+              emphasis: {
+                focus: "series",
+              },
+              label: {
+                show: true,
+                color: "#fff",
+              },
+              itemStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+                  { offset: 0, color: "#F7897D" },
+                  { offset: 0.8, color: "#F66C89" },
+                ]),
+                borderRadius: [0, 20, 20, 0],
+              },
+              barWidth: 30,
+              barGap: "0%",
+              data: this.chartData.yearTotal,
             },
-            barWidth: 30,
-            barGap: '0%',
-            data: this.chartData.yearTotal
-          }
-        ]
-      }
+          ],
+        }
 
-      this.chartInstance.setOption(option)
-    },
-
-    // 加载数据
-    async loadData () {
-      try {
-        // const params = {
-        //   entCode: this.entCode,
-        //   communityId: this.communityId
-        // }
-        // 这里应该调用实际的API获取数据
-        // const res = await api.getNowYearServices(params)
-        // this.chartData = res.data || this.chartData
+        this.chartInstance.setOption(option)
+        this.chartInstance.resize()
+      },
 
-        // 暂时使用模拟数据
+      // 加载数据
+      async loadData() {
         this.updateChart()
-      } catch (error) {
-        console.error('获取今年实施服务数据失败:', error)
-      }
-    },
+      },
 
-    // 更新图表
-    updateChart () {
-      if (this.chartInstance) {
-        this.chartInstance.setOption({
-          yAxis: {
-            data: this.chartData.categories
-          },
-          series: [
-            {
-              data: this.chartData.ongoing
-            },
-            {
-              data: this.chartData.lastMonthCompleted
+      // 更新图表
+      updateChart() {
+        if (this.chartInstance) {
+          this.chartInstance.setOption({
+            yAxis: {
+              data: this.chartData.categories,
             },
-            {
-              data: this.chartData.yearTotal
-            }
-          ]
-        })
-      }
-    },
+            series: [
+              {
+                data: this.chartData.ongoing,
+              },
+              {
+                data: this.chartData.lastMonthCompleted,
+              },
+              {
+                data: this.chartData.yearTotal,
+              },
+            ],
+          })
+        }
+      },
 
-    // 处理窗口大小变化
-    handleResize () {
-      if (this.chartInstance) {
-        this.chartInstance.resize()
-      }
-    }
+      // 处理窗口大小变化
+      handleResize() {
+        if (this.chartInstance) {
+          this.chartInstance.resize()
+        }
+      },
+    },
   }
-}
 </script>
 
 <style lang="scss" scoped>
   @import "@/assets/css/theme.scss";
 
   .now-year-container {
-    background: var(--title-bg);
-    border-radius: 4px;
-    padding: 20px;
-    height: 100%;
+    background: var(--content-bg);
+    border-radius: halfW(4);
     display: flex;
     flex-direction: column;
   }
 
   .now-year-title {
-    font-size: 18px;
+    font-size: halfW(18);
     font-weight: 500;
+    border-radius: halfW(4);
     color: var(--title-primary);
-    margin-bottom: 20px;
+    background: var(--title-bg);
+    padding: halfH(4) halfW(10);
     display: flex;
     align-items: center;
-
-    .iconfont {
-      margin-right: 8px;
-      font-size: 20px;
-    }
-  }
-
-  .chart-container {
-    flex: 1;
-    min-height: 0;
-    position: relative;
-    // 添加自定义内容显示
-    &::before {
-      content: "";
-      display: flex;
-      flex-direction: column;
-      justify-content: space-around;
-      position: absolute;
-      left: 20px;
-      top: 20px;
-      bottom: 20px;
-      width: 120px;
-      z-index: 1;
-    }
   }
 
   .chart {
     width: 100%;
     height: 100%;
-    min-height: 400px;
-  }
-
-  // 添加自定义标签显示
-  .chart-container::before {
-    content: "";
-  }
-
-  // 响应式设计
-  @media (max-width: 1200px) {
-    .now-year-container {
-      padding: 16px;
-    }
-
-    .now-year-title {
-      font-size: 16px;
-      margin-bottom: 16px;
-    }
-
-    .chart {
-      min-height: 350px;
-    }
-  }
-
-  @media (max-width: 768px) {
-    .now-year-container {
-      padding: 12px;
-    }
-
-    .now-year-title {
-      font-size: 14px;
-    }
-
-    .chart {
-      min-height: 300px;
-    }
   }
 </style>

+ 82 - 138
src/views/hui-jia/components/implementary/total.vue

@@ -42,181 +42,125 @@
 </template>
 
 <script>
-import { mapState } from 'vuex'
-// import { api } from '@/api'
-
-export default {
-  name: 'ImplementationTotal',
-  data () {
-    return {
-      cityCount: 99,
-      enterpriseCount: 99,
-      contractCount: 99,
-      performanceCount: 99,
-      serviceHours: 99,
-      projectCount: 99,
-      signedUserCount: 99,
-      implementationUserCount: 99,
-      timer: null
-    }
-  },
-  computed: {
-    ...mapState(['entCode', 'communityId'])
-  },
-  mounted () {
-    this.init()
-    // 设置定时刷新
-    this.timer = setInterval(() => {
-      this.init()
-    }, 60000) // 每分钟刷新一次
-  },
-  beforeDestroy () {
-    if (this.timer) {
-      clearInterval(this.timer)
-    }
-  },
-  methods: {
-    // 初始化数据
-    async init () {
-      try {
-        // const params = {
-        //   entCode: this.entCode,
-        //   communityId: this.communityId
-        // }
-        // 这里应该调用实际的API获取数据
-        // const res = await api.getImplementationTotal(params)
-        // 暂时使用模拟数据
-        this.updateData()
-      } catch (error) {
-        console.error('获取实施服务汇总数据失败:', error)
+  import { mapState } from "vuex"
+  import { api } from "@/api"
+
+  export default {
+    name: "ImplementationTotal",
+    data() {
+      return {
+        cityCount: 99,
+        enterpriseCount: 99,
+        contractCount: 99,
+        performanceCount: 99,
+        serviceHours: 99,
+        projectCount: 99,
+        signedUserCount: 99,
+        implementationUserCount: 99,
+        timer: null,
       }
     },
-    // 更新数据
-    updateData () {
-      // 这里可以根据实际API返回的数据进行更新
-      // 目前使用固定值展示
-      this.cityCount = 99
-      this.enterpriseCount = 99
-      this.contractCount = 99
-      this.performanceCount = 99
-      this.serviceHours = 99
-      this.projectCount = 99
-      this.signedUserCount = 99
-      this.implementationUserCount = 99
+    computed: {
+      ...mapState(["entCode", "communityId"]),
     },
-    // 格式化数字显示
-    formatNumber (num) {
-      if (num >= 10000) {
-        return (num / 10000).toFixed(1) + '万'
+    mounted() {
+      this.init()
+      // 设置定时刷新
+      this.timer = setInterval(() => {
+        this.init()
+      }, 60000) // 每分钟刷新一次
+    },
+    beforeDestroy() {
+      if (this.timer) {
+        clearInterval(this.timer)
       }
-      return num.toString()
-    }
+    },
+    methods: {
+      // 初始化数据
+      async init() {
+        try {
+          const params = {
+            entCode: this.entCode,
+            communityId: this.communityId,
+          }
+          // 这里应该调用实际的API获取数据
+          // const res = await api.getImplementationTotal(params)
+          // 暂时使用模拟数据
+          this.updateData()
+        } catch (error) {
+          console.error("获取实施服务汇总数据失败:", error)
+        }
+      },
+      // 更新数据
+      updateData() {
+        // 这里可以根据实际API返回的数据进行更新
+        // 目前使用固定值展示
+        this.cityCount = 99
+        this.enterpriseCount = 99
+        this.contractCount = 99
+        this.performanceCount = 99
+        this.serviceHours = 99
+        this.projectCount = 99
+        this.signedUserCount = 99
+        this.implementationUserCount = 99
+      },
+      // 格式化数字显示
+      formatNumber(num) {
+        if (num >= 10000) {
+          return (num / 10000).toFixed(1) + "万"
+        }
+        return num.toString()
+      },
+    },
   }
-}
 </script>
 
 <style lang="scss" scoped>
   @import "@/assets/css/theme.scss";
 
   .total-container {
-    background: var(--title-bg);
-    border-radius: 4px;
-    padding: 20px;
+    background: var(--content-bg);
+    border-radius: halfW(4);
     position: relative;
     overflow: hidden;
 
-    &::before {
-      content: "";
-      position: absolute;
-      top: 0;
-      left: 0;
-      right: 0;
-      height: 2px;
-      background: linear-gradient(90deg, transparent, #409eff, transparent);
-    }
-
     .total-title {
+      padding:  halfH(4) halfW(10);
       display: flex;
       align-items: center;
-      font-size: 18px;
+      font-size: halfW(18);
       font-weight: 500;
       color: var(--title-primary);
-      margin-bottom: 20px;
+      background: var(--title-bg);
+      margin-bottom: halfH(20);
     }
 
     .total-grid {
+      padding: 0 halfW(10);
       display: grid;
-      grid-template-columns: repeat(2, 1fr);
-      grid-template-rows: repeat(4, 1fr);
-      gap: 16px;
+      grid-template-columns: repeat(4, 1fr);
+      grid-template-rows: repeat(2, 1fr);
+      gap: halfH(16);
+      height: calc(100% - halfH(84));
+      align-items: center;
     }
 
     .total-item {
+      flex: 1 1 0%;
       background: var(--content-bg);
-      border-radius: 6px;
-      padding: 16px;
       text-align: center;
-      transition: all 0.3s ease;
-      border: 1px solid rgba(64, 158, 255, 0.1);
-
-      &:hover {
-        transform: translateY(-2px);
-        box-shadow: 0 4px 12px rgba(64, 158, 255, 0.2);
-        border-color: rgba(64, 158, 255, 0.3);
-      }
 
       .total-label {
-        font-size: 14px;
+        font-size: halfW(14);
         color: #a0b3d6;
-        margin-bottom: 8px;
+        margin-bottom: halfH(8);
       }
 
       .total-value {
-        font-size: 28px;
+        font-size: halfW(28);
         font-weight: bold;
         color: #ffffff;
-        line-height: 1.2;
-        // 添加数字闪烁动画
-        animation: pulse 2s infinite;
       }
     }
   }
-
-  @keyframes pulse {
-    0% {
-      opacity: 1;
-      transform: scale(1);
-    }
-    50% {
-      opacity: 0.9;
-      transform: scale(1.02);
-    }
-    100% {
-      opacity: 1;
-      transform: scale(1);
-    }
-  }
-
-  // 响应式设计
-  @media (max-width: 1200px) {
-    .total-grid {
-      grid-template-columns: repeat(3, 1fr);
-      grid-template-rows: repeat(3, 1fr);
-    }
-
-    .total-value {
-      font-size: 24px !important;
-    }
-  }
-
-  @media (max-width: 768px) {
-    .total-grid {
-      grid-template-columns: repeat(2, 1fr);
-      grid-template-rows: repeat(4, 1fr);
-    }
-
-    .total-value {
-      font-size: 20px !important;
-    }
-  }
 </style>

+ 234 - 271
src/views/hui-jia/components/market.vue

@@ -1,274 +1,254 @@
 <template>
   <div class="market-container">
     <div class="market-title">
-      <i class="iconfont icon-enterprise"></i>
+      <img src="@/assets/images/shb.png" class="title-icon" />
       市场拓展
     </div>
-    <div class="chart-content">
-      <div class="legend">
-        <div class="legend-item">上月</div>
-        <div class="legend-item">本月</div>
-      </div>
-      <div class="chart-container">
-        <div id="marketChart" class="chart"></div>
-      </div>
+    <div class="legend">
+      <div class="legend-item">上月</div>
+      <div class="legend-item">本月</div>
     </div>
+    <div id="marketChart" class="chart"></div>
   </div>
 </template>
 
 <script>
-import { mapState } from 'vuex'
-// import { api } from '@/api'
-import * as echarts from 'echarts'
+  import { mapState } from "vuex"
+  import { api } from "@/api"
+  import * as echarts from "echarts"
 
-export default {
-  name: 'MarketExpansion',
-  data () {
-    return {
-      chartInstance: null,
-      chartData: {
-        categories: [
-          '新增企业',
-          '跟进项目',
-          '新增联系人',
-          '新增合同',
-          '新增项目',
-          '新增户数'
-        ],
-        lastMonthData: [-9, -9, -9, -9, -3, -12], // 上月数据
-        thisMonthData: [9, 9, 1, 1, 9, 10] // 本月数据
-      },
-      timer: null
-    }
-  },
-  computed: {
-    ...mapState(['entCode', 'communityId'])
-  },
-  mounted () {
-    this.init()
-    window.addEventListener('resize', this.handleResize)
-
-    // 设置定时刷新
-    this.timer = setInterval(() => {
-      this.loadData()
-    }, 30000) // 每30秒刷新一次
-  },
-  beforeDestroy () {
-    if (this.chartInstance) {
-      this.chartInstance.dispose()
-    }
-    window.removeEventListener('resize', this.handleResize)
-    if (this.timer) {
-      clearInterval(this.timer)
-    }
-  },
-  methods: {
-    // 初始化组件
-    init () {
-      this.initChart()
-      this.loadData()
+  export default {
+    name: "MarketExpansion",
+    data() {
+      return {
+        chartInstance: null,
+        chartData: {
+          categories: [
+            "新增企业",
+            "跟进项目",
+            "新增联系人",
+            "新增合同",
+            "新增项目",
+            "新增户数",
+          ],
+          lastMonthData: [-9, -9, -9, -9, -3, -12], // 上月数据
+          thisMonthData: [9, 9, 1, 1, 9, 10], // 本月数据
+        },
+      }
+    },
+    computed: {
+      ...mapState(["entCode", "communityId"]),
+    },
+    mounted() {
+      this.init()
+      window.addEventListener("resize", this.handleResize)
+    },
+    beforeDestroy() {
+      if (this.chartInstance) {
+        this.chartInstance.dispose()
+      }
+      window.removeEventListener("resize", this.handleResize)
     },
+    methods: {
+      // 初始化组件
+      init() {
+        this.initChart()
+        this.loadData()
+      },
 
-    // 初始化图表
-    initChart () {
-      this.chartInstance = echarts.init(
-        document.getElementById('marketChart')
-      )
+      // 初始化图表
+      initChart() {
+        this.chartInstance = echarts.init(
+          document.getElementById("marketChart")
+        )
 
-      const option = {
-        tooltip: {
-          trigger: 'axis',
-          axisPointer: {
-            type: 'shadow'
-          },
-          backgroundColor: 'rgba(17, 28, 49, 0.9)',
-          borderColor: 'rgba(64, 158, 255, 0.2)',
-          textStyle: {
-            color: '#ffffff'
-          },
-          formatter: (params) => {
-            // 自定义tooltip格式
-            let result = params[0].name + '<br/>'
-            params.forEach((item) => {
-              result +=
-                  item.marker + item.seriesName + ': ' + item.value + '<br/>'
-            })
-            return result
-          }
-        },
-        grid: {
-          left: '25%',
-          right: '25%',
-          bottom: '3%',
-          top: 50,
-          containLabel: true
-        },
-        xAxis: {
-          type: 'value',
-          axisLabel: {
-            formatter: (value) => {
-              if (value < 0) return -value // 这里是针对取负值
-              else return value
-            }
-          },
-          show: false // 隐藏x轴
-          // axisLine: {
-          //   show: false,
-          // },
-          // axisTick: {
-          //   show: false,
-          // },
-          // axisLabel: {
-          //   show: false,
-          // },
-          // splitLine: {
-          //   show: false,
-          // },
-        },
-        yAxis: [
-          {
-            type: 'category',
-            data: this.chartData.categories,
-            axisLine: {
-              show: false
+        const option = {
+          tooltip: {
+            trigger: "axis",
+            axisPointer: {
+              type: "shadow",
             },
-            axisTick: {
-              show: false
-            },
-            axisLabel: {
-              show: false
-            }
-          },
-          {
-            type: 'category',
-            data: this.chartData.categories,
-            axisLine: {
-              show: false
+            backgroundColor: "rgba(17, 28, 49, 0.9)",
+            borderColor: "rgba(64, 158, 255, 0.2)",
+            textStyle: {
+              color: "#ffffff",
             },
-            axisTick: {
-              show: false
+            formatter: (params) => {
+              // 自定义tooltip格式
+              let result = params[0].name + "<br/>"
+              params.forEach((item) => {
+                result +=
+                  item.marker +
+                  item.seriesName +
+                  ": " +
+                  Math.abs(item.value) +
+                  "<br/>"
+              })
+              return result
             },
+          },
+          grid: {
+            left: "25%",
+            right: "25%",
+            bottom: "3%",
+            top: 50,
+            containLabel: true,
+          },
+          xAxis: {
+            type: "value",
             axisLabel: {
-              show: false,
-              color: '#a0b3d6',
-              fontSize: 14
-            }
-          }
-        ],
-        series: [
-          {
-            name: '上月',
-            type: 'bar',
-            //   stack: "sameStack",
-            stack: 'Total',
-            emphasis: {
-              focus: 'series'
-            },
-            barMinHeight: 4,
-            data: this.chartData.lastMonthData,
-            barWidth: 25,
-            itemStyle: {
-              // 左侧渐变色:从#F66757到#FCE2B4
-              color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
-                { offset: 0, color: '#FCE2B4' },
-                { offset: 1, color: '#F66757' }
-              ]),
-              borderRadius: [20, 0, 0, 20]
-            },
-            label: {
-              show: true,
-              position: 'left',
-              // formatter: '{c}',
-              color: '#ffffff',
-              fontSize: 12,
               formatter: (value) => {
-                return -value.data
-              }
-            }
-          },
-          {
-            name: '本月',
-            type: 'bar',
-            //   stack: "sameStack",
-            stack: 'Total',
-            emphasis: {
-              focus: 'series'
-            },
-            barMinHeight: 4,
-            data: this.chartData.thisMonthData,
-            barWidth: 25,
-            itemStyle: {
-              // 右侧渐变色:从#1620D4到#3AB3E3
-              color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
-                { offset: 0, color: '#3AB3E3' },
-                { offset: 1, color: '#1620D4' }
-              ]),
-              borderRadius: [0, 20, 20, 0]
+                if (value < 0) return -value //这里是针对取负值
+                else return value
+              },
             },
-            label: {
-              show: true,
-              position: 'right',
-              formatter: '{c}',
-              color: '#ffffff',
-              fontSize: 12
-            }
-          }
-        ]
-      }
-
-      this.chartInstance.setOption(option)
-    },
-
-    // 加载数据
-    async loadData () {
-      try {
-        // const params = {
-        //   entCode: this.entCode,
-        //   communityId: this.communityId
-        // }
-        // 这里应该调用实际的API获取数据
-        // const res = await api.getMarketExpansionData(params)
-        // this.chartData = res.data || this.chartData
-
-        // 暂时使用模拟数据
-        this.updateChart()
-      } catch (error) {
-        console.error('获取市场拓展数据失败:', error)
-      }
-    },
-
-    // 更新图表
-    updateChart () {
-      if (this.chartInstance) {
-        this.chartInstance.setOption({
+            show: false, // 隐藏x轴
+          },
           yAxis: [
             {
-              data: this.chartData.categories
+              type: "category",
+              data: this.chartData.categories,
+              axisLine: {
+                show: false,
+              },
+              axisTick: {
+                show: false,
+              },
+              axisLabel: {
+                show: false,
+              },
             },
             {
-              data: this.chartData.categories
-            }
+              type: "category",
+              data: this.chartData.categories,
+              axisLine: {
+                show: false,
+              },
+              axisTick: {
+                show: false,
+              },
+              axisLabel: {
+                show: false,
+                color: "#a0b3d6",
+                fontSize: 14,
+              },
+            },
           ],
           series: [
             {
-              data: this.chartData.lastMonthData
+              name: "上月",
+              type: "bar",
+              //   stack: "sameStack",
+              stack: "Total",
+              emphasis: {
+                focus: "series",
+              },
+              barMinHeight: 4,
+              data: this.chartData.lastMonthData,
+              barWidth: 16,
+              itemStyle: {
+                // 左侧渐变色:从#F66757到#FCE2B4
+                color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
+                  { offset: 0, color: "#FCE2B4" },
+                  { offset: 1, color: "#F66757" },
+                ]),
+                borderRadius: [20, 0, 0, 20],
+              },
+              label: {
+                show: true,
+                position: "left",
+                formatter: "{c}",
+                color: "#ffffff",
+                fontSize: 12,
+                formatter: (value) => {
+                  return -value.data
+                },
+              },
             },
             {
-              data: this.chartData.thisMonthData
-            }
-          ]
-        })
-      }
-    },
+              name: "本月",
+              type: "bar",
+              //   stack: "sameStack",
+              stack: "Total",
+              emphasis: {
+                focus: "series",
+              },
+              barMinHeight: 4,
+              data: this.chartData.thisMonthData,
+              barWidth: 16,
+              itemStyle: {
+                // 右侧渐变色:从#1620D4到#3AB3E3
+                color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+                  { offset: 0, color: "#3AB3E3" },
+                  { offset: 1, color: "#1620D4" },
+                ]),
+                borderRadius: [0, 20, 20, 0],
+              },
+              label: {
+                show: true,
+                position: "right",
+                formatter: "{c}",
+                color: "#ffffff",
+                fontSize: 12,
+              },
+            },
+          ],
+        }
 
-    // 处理窗口大小变化
-    handleResize () {
-      if (this.chartInstance) {
+        this.chartInstance.setOption(option)
         this.chartInstance.resize()
-      }
-    }
+      },
+
+      // 加载数据
+      async loadData() {
+        try {
+          const params = {
+            entCode: this.entCode,
+            communityId: this.communityId,
+          }
+          // 这里应该调用实际的API获取数据
+          // const res = await api.getMarketExpansionData(params)
+          // this.chartData = res.data || this.chartData
+
+          // 暂时使用模拟数据
+          this.updateChart()
+        } catch (error) {
+          console.error("获取市场拓展数据失败:", error)
+        }
+      },
+
+      // 更新图表
+      updateChart() {
+        if (this.chartInstance) {
+          this.chartInstance.setOption({
+            yAxis: [
+              {
+                data: this.chartData.categories,
+              },
+              {
+                data: this.chartData.categories,
+              },
+            ],
+            series: [
+              {
+                data: this.chartData.lastMonthData,
+              },
+              {
+                data: this.chartData.thisMonthData,
+              },
+            ],
+          })
+        }
+      },
+
+      // 处理窗口大小变化
+      handleResize() {
+        if (this.chartInstance) {
+          this.chartInstance.resize()
+        }
+      },
+    },
   }
-}
 </script>
 
 <style lang="scss" scoped>
@@ -276,54 +256,37 @@ export default {
 
   .market-container {
     background: #0d1629;
-    border-radius: 4px;
-    border: 1px solid rgba(64, 158, 255, 0.2);
+    border-radius: halfW(4);
     height: 100%;
     display: flex;
     flex-direction: column;
+    background: var(--content-bg);
   }
 
   .market-title {
-    border-radius: 4px;
+    border-radius: halfW(4);
     background: var(--title-bg);
-    padding: 20px;
-    font-size: 18px;
+    padding: halfH(4) halfW(10);
+    font-size: halfW(18);
     font-weight: 500;
     color: var(--title-primary);
     display: flex;
     align-items: center;
-
-    .iconfont {
-      margin-right: 8px;
-      font-size: 20px;
-    }
-  }
-
-  .chart-content {
-    margin: 20px;
-    background: var(--title-bg);
-    .legend {
-      display: flex;
-      justify-content: space-around;
-      align-items: center;
-      padding: 20px;
-      margin: 0px 10px;
-      font-size: 14px;
-      font-weight: 500;
-      color: #fff;
-      border-bottom: 1px solid rgba(64, 158, 255, 0.2);
-    }
   }
-
-  .chart-container {
-    flex: 1;
-    min-height: 0;
-    position: relative;
+  .legend {
+    display: flex;
+    justify-content: space-around;
+    align-items: center;
+    padding: halfH(10) halfW(20);
+    font-size: halfW(14);
+    font-weight: 500;
+    color: #fff;
+    border-bottom: 1px solid rgba(64, 158, 255, 0.2);
   }
 
   .chart {
     width: 100%;
     height: 100%;
-    min-height: 400px;
+    background: var(--content-bg);
   }
 </style>

+ 31 - 50
src/views/hui-jia/components/smart.vue

@@ -1,32 +1,26 @@
 <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">
       <div class="data-card">
-        <div class="data-info">
-          <i class="iconfont icon-door"></i>
-          <div class="data-label">门禁设备</div>
-        </div>
         <div class="data-value">{{ doorDevices }}</div>
+        <div class="data-label">门禁设备</div>
       </div>
 
       <div class="data-card">
-        <div class="data-info">
-          <i class="iconfont icon-project"></i>
-          <div class="data-label">开通项目</div>
-        </div>
         <div class="data-value">{{ activeProjects }}</div>
+        <div class="data-label">开通项目</div>
       </div>
 
       <div class="data-card">
-        <div class="data-info">
-          <i class="iconfont icon-access"></i>
-          <div class="data-label">出入次数</div>
-        </div>
         <div class="data-value">{{ accessTimes }}</div>
+        <div class="data-label">出入次数</div>
       </div>
     </div>
 
@@ -189,35 +183,37 @@ export default {
 
   .smart-door {
     background: var(--content-bg);
-    border-radius: 4px;
-    padding: 20px;
+    border-radius: halfW(4);
     height: 100%;
   }
 
   .module-title {
+    display: flex;
+    border-radius: halfW(4);
+    align-items: center;
     color: var(--title-primary);
-    margin-bottom: 20px;
+    background: var(--title-bg);
+    padding: halfH(4) halfW(10);
   }
 
   .data-cards {
     display: flex;
-    gap: 16px;
-    margin-bottom: 24px;
-    flex-wrap: wrap;
-    padding: 10px 20px;
-    margin: 36px auto;
+    gap: halfW(12);
+    flex-wrap: nowrap;
+    margin: halfH(20) halfW(10);
     background: var(--title-bg);
     border: 1px solid rgba(64, 158, 255, 0.1);
-    border-radius: 6px;
+    border-radius: halfW(4);
   }
 
   .data-card {
     flex: 1;
-    min-width: 200px;
-    padding: 16px;
+    padding: halfH(10) halfW(6);
     display: flex;
+    flex-direction: column;
     justify-content: space-between;
     align-items: center;
+    gap: halfW(10);
     &:nth-child(1) {
       border-right: 1px solid rgba(64, 158, 255, 0.1);
     }
@@ -225,34 +221,16 @@ export default {
       border-right: 1px solid rgba(64, 158, 255, 0.1);
     }
 
-    .iconfont {
-      width: 40px;
-      height: 40px;
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      background: linear-gradient(135deg, #2196f3 0%, #64b5f6 100%);
-      border-radius: 6px;
-      font-size: 20px;
-      color: #ffffff;
-    }
-
-    .data-info {
-      display: flex;
-      gap: 12px;
-      align-items: center;
-    }
-
     .data-label {
-      font-size: 14px;
+      font-weight: 500;
+      font-size: halfW(14);
       color: var(--primary);
-      margin-bottom: 4px;
     }
 
     .data-value {
-      font-size: 24px;
-      font-weight: 600;
-      color: var(--title-primary, #ffffff);
+      font-size: halfW(18);
+      font-weight: 500;
+      color: #fff;
     }
   }
 
@@ -260,18 +238,21 @@ export default {
     flex: 1;
     display: flex;
     flex-direction: column;
+    padding: halfH(10);
+    height: calc(100% - halfH(200));
   }
 
   .chart-title {
-    font-size: 14px;
+    position: absolute;
+    font-size: halfW(14);
     font-weight: 500;
     color: #fff;
-    margin-bottom: 16px;
+    margin-top: halfH(10);
   }
 
   .traffic-chart {
     flex: 1;
     width: 100%;
-    min-height: 250px;
+    // min-height: halfH(250);
   }
 </style>

+ 122 - 92
src/views/hui-jia/components/work-card.vue

@@ -1,104 +1,134 @@
 <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="item.icon" 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>
 </template>
 
 <script>
-export default {
-  name: 'WorkCard',
-  props: {
-    iconName: {
-      type: String,
-      required: true,
-      default: 'icon-enterprise'
-    },
-    title: {
-      type: String,
-      required: true
+  import ewm from "@/assets/images/ewm.png"
+  import ryzb from "@/assets/images/ryzb.png"
+  import gwxx from "@/assets/images/gwxx.png"
+  import jgxx from "@/assets/images/jgxx.png"
+  import glgd from "@/assets/images/glgd.png"
+  import zhxggd from "@/assets/images/zhxggd.png"
+
+  export default {
+    name: "WorkCard",
+    props: {
+      title: {
+        type: String,
+        required: true,
+      },
+      subtitle: {
+        type: String,
+        required: true,
+      },
+      value: {
+        type: [Number, String],
+        required: true,
+        default: 0,
+      },
     },
-    subtitle: {
-      type: String,
-      required: true
+    data() {
+      return {
+        dataList: [
+          {
+            title: "数电票业务",
+            subtitle: "已开发票数",
+            value: 345345,
+            icon: jgxx,
+          },
+          {
+            title: "道闸系统",
+            subtitle: "设备数量",
+            value: 453,
+            icon: glgd,
+          },
+          {
+            title: "智慧二维码",
+            subtitle: "配置数量",
+            value: 45,
+            icon: ewm,
+          },
+          {
+            title: "短信业务",
+            subtitle: "销售数量",
+            value: 3456,
+            icon: zhxggd,
+          },
+          {
+            title: "房屋租售",
+            subtitle: "发布资产数",
+            value: 887,
+            icon: gwxx,
+          },
+          {
+            title: "业委会",
+            subtitle: "开通数量",
+            value: 34,
+            icon: ryzb,
+          },
+        ],
+      }
     },
-    value: {
-      type: [Number, String],
-      required: true,
-      default: 0
-    }
-  },
-  data () {
-    return {
-      dataList: [
-        {
-          title: '数电票业务',
-          subtitle: '已开发票数',
-          value: 345345
-        },
-        {
-          title: '道闸系统',
-          subtitle: '设备数量',
-          value: 453
-        },
-        {
-          title: '智慧二维码',
-          subtitle: '配置数量',
-          value: 45
-        },
-        {
-          title: '短信业务',
-          subtitle: '销售数量',
-          value: 3456
-        },
-        {
-          title: '房屋租售',
-          subtitle: '发布资产数',
-          value: 887
-        },
-        {
-          title: '业委会',
-          subtitle: '开通数量',
-          value: 34
+    methods: {
+      // 格式化数字显示
+      formatNumber(num) {
+        if (typeof num === "string") {
+          return num
         }
-      ]
-    }
-  },
-  methods: {
-    // 格式化数字显示
-    formatNumber (num) {
-      if (typeof num === 'string') {
-        return num
-      }
-      // 如果数字是整数,直接返回字符串形式
-      return num.toString()
-    }
+        // 如果数字是整数,直接返回字符串形式
+        return num.toString()
+      },
+    },
   }
-}
 </script>
 
 <style lang="scss" scoped>
   @import "@/assets/css/theme.scss";
-
+  .work-card-container {
+    background: var(--content-bg);
+    border-radius: halfW(4);
+    height: 100%;
+    width: 100%;
+    display: flex;
+    flex-direction: column;
+    .title {
+      display: flex;
+      border-radius: halfW(4);
+      align-items: center;
+      color: var(--title-primary);
+      background: var(--title-bg);
+      padding: halfH(4) halfW(10);
+    }
+  }
   .work-card {
-    display: grid;
-    grid-template-columns: repeat(3, 1fr);
-    grid-template-rows: repeat(2, 1fr);
-    gap: 10px;
+    flex: 1 1 0%;
+    padding: 0px halfW(20);
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: halfW(10);
   }
 
   .work-card-item {
-    background: var(--content-bg);
-    border-radius: 4px;
-    height: 100%;
+    background: var(--title-bg);
+    border-radius: halfW(4);
     display: flex;
     flex-direction: column;
     justify-content: space-between;
@@ -107,19 +137,19 @@ export default {
   .card-header {
     display: flex;
     align-items: center;
-    margin-bottom: 16px;
-    padding: 20px;
+    margin-bottom: halfH(10);
+    padding: halfH(4) halfW(10);
     background: var(--title-bg);
 
     .iconfont {
-      font-size: 24px;
-      margin-right: 10px;
+      font-size: halfH(24);
+      margin-right: halfW(10);
       // 根据不同图标使用不同颜色
       color: var(--primary-color, #409eff);
     }
 
     .card-title {
-      font-size: 16px;
+      font-size: halfW(16);
       font-weight: 500;
       color: var(--title-primary);
     }
@@ -127,16 +157,16 @@ export default {
 
   .card-content {
     display: flex;
-    align-items: flex-end;
-    padding: 20px;
+    align-items: center;
+    padding: halfH(20) halfW(20);
     .card-subtitle {
-      font-size: 14px;
+      font-size: halfW(14);
       color: #82d1f6;
     }
 
     .card-value {
-      margin-left: 12px;
-      font-size: 18px;
+      margin-left: halfW(12);
+      font-size: halfW(18);
       font-weight: 600;
       color: #fff;
       letter-spacing: 1px;

+ 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>