5 Revīzijas 6ab7e65a9f ... f2d7a58ab4

Autors SHA1 Ziņojums Datums
  wjc f2d7a58ab4 Merge branch 'dev' of http://git.wisdomcity.com.cn/WisdomCity-Web/SaaS-DataScreen into feat-b2 1 nedēļu atpakaļ
  wjc 41f2789b4f feat: 接口字段对接 1 nedēļu atpakaļ
  wjc ab5d229aa1 fix: b1 栅格处理 1 nedēļu atpakaļ
  wjc 2dd5315d21 fix: b2 市场 优化 1 nedēļu atpakaļ
  wjc 3caf635af4 wip: b1 部分接口调试 1 nedēļu atpakaļ

+ 7 - 1
.eslintrc.js

@@ -1,10 +1,16 @@
+/*
+ * @Author: wjc
+ * @Date: 2021-05-31 09:36:11
+ * @LastEditors: wjc
+ * @LastEditTime: 2025-11-25 10:07:44
+ * @Description: 
+ */
 module.exports = {
   root: true,
   env: {
     node: true
   },
   'extends': [
-    'plugin:vue/essential',
     '@vue/standard'
   ],
   rules: {

+ 67 - 0
src/api/hui-jia.js

@@ -0,0 +1,67 @@
+/*
+ * @Author: wjc
+ * @Date: 2025-11-21 10:08:08
+ * @LastEditors: wjc
+ * @LastEditTime: 2025-11-24 15:43:45
+ * @Description:
+ */
+import axios from "../assets/js/api.request"
+export default {
+  getImplementaryData(data) {
+    return axios.request({
+      url: "/platform/bigData/screen/statistics",
+      params: data,
+      method: "get",
+    })
+  },
+  /**
+   * 部分业务 http://yapi.wisdomcity.com.cn/project/25/interface/api/26531
+   */
+  getBusinessData(data) {
+    return axios.request({
+      url: "/platform/bigData/business/statistics",
+      params: data,
+      method: "get",
+    })
+  },
+  /**
+   * 智能门禁 http://yapi.wisdomcity.com.cn/project/25/interface/api/26522
+   */
+  getFaceDeviceData(data) {
+    return axios.request({
+      url: "/platform/bigData/faceDeviceManage/statistics",
+      params: data,
+      method: "get",
+    })
+  },
+  /**
+   * 智能电表 http://yapi.wisdomcity.com.cn/project/25/interface/api/26504
+   */
+  getElectricData(data) {
+    return axios.request({
+      url: "/platform/bigData/meterHouse/electricMeter/monthStats",
+      params: data,
+      method: "get",
+    })
+  },
+  /**
+   * 智能水表 http://yapi.wisdomcity.com.cn/project/25/interface/api/26513
+   */
+  getWaterData(data) {
+    return axios.request({
+      url: "/platform/bigData/meterHouse/waterMeter/monthStats",
+      params: data,
+      method: "get",
+    })
+  },
+  /**
+   * 实施相关数据 http://yapi.wisdomcity.com.cn/project/25/interface/api/26576
+   */
+  getScreenData(data) {
+    return axios.request({
+      url: "/platform/bigData/screen/statistics",
+      params: data,
+      method: "get",
+    })
+  },
+}

+ 5 - 3
src/api/index.js

@@ -1,16 +1,18 @@
 /*
  * @Author: mozhuangru
- * @LastEditors: wangjiacheng
+ * @LastEditors: wjc
  * @Description: api
  * @Date: 2019-10-09 09:21:46
- * @LastEditTime: 2021-10-14 12:04:06
+ * @LastEditTime: 2025-11-21 10:10:57
  */
 import api from './api'
 import totalSum from './total-sum'
 import screen from './screen'
+import huiJiaApi from './hui-jia'
 
 export {
   api,
   totalSum,
-  screen
+  screen,
+  huiJiaApi
 }

+ 216 - 96
src/views/hui-jia/b1-screen/index.vue

@@ -8,9 +8,7 @@
         <CommunityMap />
       </div>
       <div class="middle-wrap">
-        <div class="item-2">
-          <User />>
-        </div>
+        <div class="item-2"><User />></div>
         <div class="item-3">
           <Resident :showOperate="false" class="b1-resident" />
         </div>
@@ -19,121 +17,243 @@
         </div>
       </div>
       <div class="right-wrap">
-        <Market />
-        <implementationTotal />
+        <Market :data="state.market_vs_month" />
+        <implementationTotal :data="state.summary" />
       </div>
       <div class="bottom-wrap">
-        <implementationIng />
-        <implementationNowYear />
+        <implementationIng :data="state.data" />
+        <implementationNowYear :data="serviceData" />
       </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 CommunityMap from '../components/community-map'
-import CommunityType from '../components/community-type'
-import Resident from '../components/resident'
-import User from '../components/user'
+  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 CommunityMap from "../components/community-map"
+  import CommunityType from "../components/community-type"
+  import Resident from "../components/resident"
+  import User from "../components/user"
+
+  import { huiJiaApi } from "@/api"
 
-export default {
-  name: 'B1Screen',
-  components: {
-    implementationTotal,
-    implementationIng,
-    implementationNowYear,
-    Market,
-    CommunityMap,
-    CommunityType,
-    Resident,
-    User
+  export default {
+    name: "B1Screen",
+    components: {
+      implementationTotal,
+      implementationIng,
+      implementationNowYear,
+      Market,
+      CommunityType,
+      Resident,
+      User,
+      CommunityMap,
+    },
+    data() {
+      return {
+        state: {
+          data: [], // 进行中的实施服务列表
+          market_vs_month: {
+            customer: {
+              // 新增企业
+              last_month: 3,
+              this_month: 2,
+            },
+            followup: {
+              // 新增企业
+              last_month: 0,
+              this_month: 0,
+            },
+            contact: {
+              // 新增联系人
+              last_month: 1,
+              this_month: 0,
+            },
+            residence: {
+              // 新增小区
+              last_month: 3,
+              this_month: 4,
+            },
+            contract: {
+              // 新增合同
+              last_month: 5,
+              this_month: 3,
+            },
+            household: {
+              // 新增户数
+              last_month: 0,
+              this_month: 1,
+            },
+          }, // 市场拓展数据
+          summary: {
+            cities: 35, // 城市总数
+            customers: 270, // 企业总数
+            contracts: 349, // 合同总数
+            perform_times: 815, // 履约次数
+            service_time: 163990350, // 服务时长
+            residences: 806, // 小区总数
+            contracted_households: 473652, // 签约户数
+            actual_households: 459667, // 实施户数
+          }, // 实施服务,汇总
+          year_summary: {
+            cities: 14, // 履约城市
+            customers: 35, // 服务企业
+            residences: 71, // 服务小区
+            contracts: 44, // 合同份数
+            contracted_households: "24107", // 签约户数
+            actual_households: "22808", // 实施户数
+          },
+          service_ing: {
+            // 实施服务,进行中
+            cities: 7,
+            customers: 11,
+            contracts: 11,
+            residences: 9,
+            contracted_households: "3040",
+            plan: 0,
+          },
+          service_last_month: {
+            // 实施服务,上月
+            cities: 0,
+            customers: 0,
+            contracts: 0,
+            residences: 0,
+            contracted_households: 0,
+            actual_households: 0,
+          },
+        },
+        implementationData: {
+          ing: {},
+          nowYear: {},
+          total: {},
+        },
+      }
+    },
+    computed: {
+      serviceData() {
+        // 图表字段顺序
+        const properties = [
+          "contracted_households",
+          "contracts",
+          "residences",
+          "customers",
+          "cities",
+        ]
+        const result = {
+          year_summary: properties.map((key) => this.state.year_summary[key]),
+          service_ing: properties.map((key) => this.state.service_ing[key]),
+          service_last_month: properties.map(
+            (key) => this.state.service_last_month[key]
+          ),
+        }
+
+        return result
+      },
+    },
+    mounted() {
+      huiJiaApi.getImplementaryData().then((res) => {
+        this.implementationData = res.data.data
+      })
+    },
+    methods: {
+      getData() {
+        huiJiaApi.getScreenData().then((res) => {
+          if (res && res.data) {
+            console.log("大屏数据----", res)
+          }
+        })
+      },
+    },
   }
-}
 </script>
 
 <style lang="scss" scoped>
-  @import "@/assets/css/theme.scss";
+    @import "@/assets/css/theme.scss";
 
-  $gap-padding: halfW(8);
-  .b1-screen {
-    height: 100vh;
-    width: 100vw;
-    background: var(--page-bg);
-    .logo {
-      text-align: right;
-      padding: halfH(10) 0;
-      .logo-img {
-        height: halfH(64);
+    $gap-padding: halfW(8);
+    .b1-screen {
+      height: 100vh;
+      width: 100vw;
+      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);
+    .b1-screen-content {
+      height: calc(100% - halfH(64) - halfH(28));
+      width: 100%;
       display: flex;
       flex-wrap: wrap;
+      justify-content: center;
+      align-items: center;
       gap: halfW(16);
-      justify-content: flex-start;
-      .item-2 {
-        flex: 0 0 100%;
-        width: 100%;
-        height: calc(35% - $gap-padding);
-        // background: #f5f5f5;
+      // padding: 0px halfW(16) halfW(16);
+      .item-1 {
+        width: calc(25% - $gap-padding - $gap-padding);
+        height: calc(64% - $gap-padding - $gap-padding);
+        background: #f5f5f5;
       }
-      .item-3 {
-        // background: green;
-        flex: 0 0 calc(50% - $gap-padding);
-        width: calc(50% - $gap-padding);
-        height: calc(65% - $gap-padding);
+      .middle-wrap {
+        width: calc(
+          50% - $gap-padding - $gap-padding - $gap-padding - $gap-padding
+        );
+        height: calc(64% - $gap-padding - $gap-padding);
+        display: flex;
+        flex-wrap: wrap;
+        gap: halfW(16);
+        justify-content: flex-start;
+        align-items: center;
+        .item-2 {
+          flex: 0 0 100%;
+          width: 100%;
+          height: calc(35% - $gap-padding);
+          // background: #f5f5f5;
+        }
+        .item-3 {
+          background: green;
+          width: calc(50% - $gap-padding);
+          height: calc(65% - $gap-padding);
+        }
+        .item-4 {
+          width: calc(50% - $gap-padding);
+          height: calc(65% - $gap-padding);
+          // background: green;
+        }
       }
-      .item-4 {
-        flex: 0 0 calc(50% - $gap-padding);
-        width: calc(50% - $gap-padding);
-        height: calc(65% - $gap-padding);
-        // background: green;
+      .right-wrap {
+        display: flex;
+        flex-direction: column;
+        width: calc(25% - $gap-padding - $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);
+        }
       }
-    }
-    .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%;
+      .bottom-wrap {
+        display: flex;
+        justify-content: space-around;
+        gap: halfW(16);
+        width: calc(
+          100% - $gap-padding - $gap-padding - $gap-padding - $gap-padding
+        );
+        height: calc(36% - $gap-padding);
+        .now-year-container {
+          width: 50%;
+        }
+        .implementing-container {
+          width: 50%;
+        }
       }
     }
-  }
 </style>

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

@@ -2,8 +2,8 @@
  * @Author: wjc
  * @Date: 2025-11-19 16:09:12
  * @LastEditors: wjc
- * @LastEditTime: 2025-11-20 10:58:02
- * @Description:
+ * @LastEditTime: 2025-11-25 10:25:53
+ * @Description: 
 -->
 <template>
   <div class="b2-screen">

+ 104 - 266
src/views/hui-jia/components/hardware.vue

@@ -11,7 +11,7 @@
       <div class="device-info">
         <img src="@/assets/images/dblxzhb.png" class="title-icon" />
         <div>
-          <div class="device-count">8921</div>
+          <div class="device-count">{{ electricState.deviceCount }}</div>
           <div class="device-name">智能电表</div>
         </div>
       </div>
@@ -19,28 +19,28 @@
         <div class="data-card">
           <div class="data-label">年度用电</div>
           <div>
-            <div class="data-value">428921</div>
+            <div class="data-value">{{ electricState.annualUsage }}</div>
             <div class="data-unit">kW·h</div>
           </div>
         </div>
         <div class="data-card">
           <div class="data-label">月均用电</div>
           <div>
-            <div class="data-value">18921</div>
+            <div class="data-value">{{ electricState.monthlyAvgUsage }}</div>
             <div class="data-unit">kW·h</div>
           </div>
         </div>
         <div class="data-card">
           <div class="data-label">日均用电</div>
           <div>
-            <div class="data-value">8921</div>
+            <div class="data-value">{{ electricState.dailyAvgUsage }}</div>
             <div class="data-unit">kW·h</div>
           </div>
         </div>
         <div class="data-card">
           <div class="data-label">开关次数</div>
           <div>
-            <div class="data-value">887</div>
+            <div class="data-value">{{ electricState.switchCount }}</div>
             <div class="data-unit">近12个月</div>
           </div>
         </div>
@@ -57,7 +57,7 @@
       <div class="device-info">
         <img src="@/assets/images/zhnmj.png" class="title-icon" />
         <div>
-          <div class="device-count">8921</div>
+          <div class="device-count">{{ waterState.deviceCount }}</div>
           <div class="water-device-name">智能水表</div>
         </div>
       </div>
@@ -65,28 +65,28 @@
         <div class="data-card">
           <div class="data-label">年度用水</div>
           <div>
-            <div class="data-value">89321</div>
+            <div class="data-value">{{ waterState.annualUsage }}</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-value">{{ waterState.monthlyAvgUsage }}</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-value">{{ waterState.dailyAvgUsage }}</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-value">{{ waterState.switchCount }}</div>
             <div class="water-data-unit">近12个月</div>
           </div>
         </div>
@@ -96,268 +96,105 @@
 </template>
 
 <script>
-import * as echarts from 'echarts'
-export default {
-  name: 'HardwareData',
-  data () {
-    return {
-      powerChartInstance: null,
-      waterChartInstance: null,
-      // 模拟月度数据
-      monthlyData: [
-        { month: '十二月', power: 220000, water: 180000 },
-        { month: '一月', power: 210000, water: 170000 },
-        { month: '二月', power: 230000, water: 190000 },
-        { month: '三月', power: 225000, water: 185000 },
-        { month: '四月', power: 215000, water: 175000 },
-        { month: '五月', power: 200000, water: 160000 },
-        { month: '六月', power: 205000, water: 165000 },
-        { month: '七月', power: 210000, water: 170000 },
-        { month: '八月', power: 215000, water: 175000 },
-        { month: '九月', power: 220000, water: 180000 },
-        { month: '十月', power: 225000, water: 185000 },
-        { month: '十一月', power: 230000, water: 190000 }
-      ]
-    }
-  },
-  mounted () {
-    this.initPowerChart()
-    this.initWaterChart()
-    window.addEventListener('resize', this.handleResize)
-  },
-  beforeDestroy () {
-    window.removeEventListener('resize', this.handleResize)
-    if (this.powerChartInstance) {
-      this.powerChartInstance.dispose()
-    }
-    if (this.waterChartInstance) {
-      this.waterChartInstance.dispose()
-    }
-  },
-  methods: {
-    // 初始化用电量柱状图
-    initPowerChart () {
-      this.powerChartInstance = echarts.init(this.$refs.powerChart)
+  import { huiJiaApi } from "@/api"
+  import * as echarts from "echarts"
 
-      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'
-            }
-          }
+  export default {
+    name: "HardwareData",
+    data() {
+      return {
+        electricState: {
+          deviceCount: 8921, // 设备数量
+          annualUsage: 428921, // 年度用量 近12月的用量之和
+          monthlyAvgUsage: 18921, // 月均用量 近12月用量月平均数
+          dailyAvgUsage: 8921, // 日均用量 近12月用量日平均数
+          switchCount: 887, // 开关次数 近12月成功开启、关闭次数
+          list: [
+            {
+              statData: "2024-01", // 时间段
+              count: 8921, // 总数
+            },
+            {
+              statData: "2024-02", // 时间段
+              count: 7891, // 总数
+            },
+            {
+              statData: "2024-03", // 时间段
+              count: 8931, // 总数
+            },
+            {
+              statData: "2024-04", // 时间段
+              count: 6131, // 总数
+            },
+            {
+              statData: "2024-05", // 时间段
+              count: 1891, // 总数
+            },
+          ],
         },
-        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
-            }
-          }
+        waterState: {
+          deviceCount: 8921, // 设备数量
+          annualUsage: 428921, // 年度用量 近12月的用量之和
+          monthlyAvgUsage: 18921, // 月均用量 近12月用量月平均数
+          dailyAvgUsage: 8921, // 日均用量 近12月用量日平均数
+          switchCount: 887, // 开关次数 近12月成功开启、关闭次数
+          list: [
+            {
+              statData: "2024-01", // 时间段
+              count: 8921, // 总数
+            },
+            {
+              statData: "2024-02", // 时间段
+              count: 7891, // 总数
+            },
+            {
+              statData: "2024-03", // 时间段
+              count: 8931, // 总数
+            },
+            {
+              statData: "2024-04", // 时间段
+              count: 6131, // 总数
+            },
+            {
+              statData: "2024-05", // 时间段
+              count: 1891, // 总数
+            },
+          ],
         },
-        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
-            }
-          }
-        ]
+        powerChartInstance: null,
+        waterChartInstance: null,
       }
-
-      this.powerChartInstance.setOption(option)
     },
-
-    // 初始化用水量柱状图
-    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)
+    mounted() {
+      this.initPowerChart()
+      this.initWaterChart()
+      window.addEventListener("resize", this.handleResize)
+      this.getData()
     },
-
-    handleResize () {
+    beforeDestroy() {
+      window.removeEventListener("resize", this.handleResize)
       if (this.powerChartInstance) {
-        this.powerChartInstance.resize()
+        this.powerChartInstance.dispose()
       }
       if (this.waterChartInstance) {
-        this.waterChartInstance.resize()
+        this.waterChartInstance.dispose()
       }
     },
     methods: {
+      getData() {
+        huiJiaApi.getElectricData().then((res) => {
+          if (res && res.data) {
+            this.state = res.data.data
+          }
+          console.log("业务数据----", res.data.data)
+        })
+        huiJiaApi.getWaterData().then((res) => {
+          if (res && res.data) {
+            this.state = res.data.data
+          }
+          console.log("业务数据----", res.data.data)
+        })
+      },
       // 初始化用电量柱状图
       initPowerChart() {
         this.powerChartInstance = echarts.init(this.$refs.powerChart)
@@ -389,7 +226,7 @@ export default {
           },
           xAxis: {
             type: "category",
-            data: this.monthlyData.map((item) => item.month),
+            data: this.electricState.list.map((item) => item.statData),
             axisLine: {
               lineStyle: {
                 color: "rgba(160, 179, 214, 0.3)",
@@ -415,6 +252,8 @@ export default {
           },
           yAxis: {
             type: "value",
+            min: 0,
+            max: 40000,
             axisLine: {
               show: false,
             },
@@ -437,7 +276,7 @@ export default {
             {
               name: "用电量",
               type: "bar",
-              data: this.monthlyData.map((item) => item.power),
+              data: this.electricState.list.map((item) => item.count),
               barWidth: "30%",
               itemStyle: {
                 color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [
@@ -495,7 +334,7 @@ export default {
           },
           xAxis: {
             type: "category",
-            data: this.monthlyData.map((item) => item.month),
+            data: this.waterState.list.map((item) => item.statData),
             axisLine: {
               lineStyle: {
                 color: "rgba(160, 179, 214, 0.3)",
@@ -523,7 +362,7 @@ export default {
           yAxis: {
             type: "value",
             // 反转 y 轴的 min 和 max,实现“倒立”
-            min: 400000,
+            min: 40000,
             max: 0,
             axisLine: {
               show: false,
@@ -547,7 +386,7 @@ export default {
             {
               name: "用水量",
               type: "bar",
-              data: this.monthlyData.map((item) => item.water),
+              data: this.waterState.list.map((item) => item.count),
               barWidth: "30%",
               itemStyle: {
                 color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
@@ -584,7 +423,6 @@ export default {
       },
     },
   }
-}
 </script>
 
 <style lang="scss" scoped>

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

@@ -5,23 +5,22 @@
       进行中的实施服务
     </div>
     <vueSeamless
-      :data="implementingList"
+      :data="data"
       :class-option="optionScroll"
       class="implementing-list"
     >
-      <!-- <div class="implementing-list"> -->
       <div
-        v-for="(item, index) in implementingList"
+        v-for="(item, index) in data"
         :key="index"
         class="implementing-item"
         :class="{ 'even-item': index % 2 === 1 }"
       >
         <div class="item-content">
-          <div class="item-date">{{ item.date }}</div>
-          <div class="item-city">{{ item.city }}</div>
+          <div class="item-date">{{ dayjs(item.created_at).format("YYYY-MM-DD") }}</div>
+          <div class="item-city">{{ item.residence.location.region_name }}</div>
           <div class="project-info">
-            <div class="project-name">{{ item.projectName }}</div>
-            <div class="company-name">{{ item.companyName }}</div>
+            <div class="project-name">{{ item.residence.residence_name }}</div>
+            <div class="company-name">{{ item.service.customer.customer_name }}</div>
           </div>
           <div class="project-stats">
             <div class="stat-item">
@@ -29,41 +28,44 @@
               <span class="stat-label">户</span>
             </div>
             <div class="stat-item">
-              <span class="stat-value">{{ item.area }}</span>
+              <span class="stat-value">{{ item.service.liable_person.real_name }}</span>
             </div>
             <div class="stat-item">
               <div class="progress-wrapper">
-                <span class="progress-text">{{ item.progress }}%</span>
+                <span class="progress-text">{{ item.service.perform_ratio }}%</span>
               </div>
             </div>
             <div class="stat-item service-item">
-              <span class="service-content">{{ item.serviceContent }}</span>
+              <span class="service-content">{{ item.service.work_template.display_name }}</span>
             </div>
             <div class="stat-item">
-              <span class="period">{{ item.period }}</span>
+              <span class="period">{{ item.updated_at }}</span>
             </div>
           </div>
         </div>
       </div>
-      <!-- </div> -->
     </vueSeamless>
   </div>
 </template>
 
 <script>
+  import dayjs from "dayjs"
   import { mapState } from "vuex"
   import vueSeamless from "vue-seamless-scroll"
-  import { api } from "@/api"
 
   export default {
     name: "ImplementingServices",
     components: {
       vueSeamless,
     },
+    props: {
+      data: {
+        type: Object,
+        default: () => ([]),
+      },
+    },
     data() {
       return {
-        implementingList: [],
-        timer: null,
       }
     },
     computed: {
@@ -74,107 +76,7 @@
         }
       },
     },
-    mounted() {
-      this.init()
-      // 设置定时刷新
-      this.timer = setInterval(() => {
-        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)
-        }
-      },
-      // 加载模拟数据
-      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>

+ 18 - 47
src/views/hui-jia/components/implementary/now-year.vue

@@ -15,21 +15,26 @@
 
   export default {
     name: "NowYearServices",
+    props: {
+      data: {
+        type: Object,
+        default: () => ({}),
+      },
+    },
     data() {
       return {
         chartInstance: null,
         chartData: {
           categories: [
-            "履约城市",
-            "服务企业",
-            "服务项目",
-            "合同数",
             "签约户数",
+            "合同份数",
+            "服务小区",
+            "服务企业",
+            "履约城市",
           ],
-          ongoing: [88888, 88888, 88888, 88888, 88888], // 进行中
+          ongoing: [999, 88888, 88888, 88888, 88888], // 进行中
           lastMonthCompleted: [88888, 88888, 88888, 88888, 88888], // 上月完成
           yearTotal: [88888, 88888, 888888, 88888, 88888], // 今年累计
-          totalNumbers: [8888, 8888, 8888, 8888, 8888], // 左侧显示的总数
         },
       }
     },
@@ -50,7 +55,6 @@
       // 初始化组件
       init() {
         this.initChart()
-        this.loadData()
       },
 
       // 初始化图表
@@ -88,7 +92,7 @@
             containLabel: true,
           },
           xAxis: {
-            type: "value",
+            type: "log",
             show: false, // 隐藏x轴
             axisLine: {
               show: false,
@@ -124,9 +128,7 @@
               name: "进行中",
               type: "bar",
               stack: "total",
-              emphasis: {
-                focus: "series",
-              },
+              barMinHeight: 10,
               itemStyle: {
                 color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                   { offset: 0, color: "#1620D4" },
@@ -141,15 +143,13 @@
               barWidth: 30,
               barGap: "0%",
               barCategoryGap: "20%",
-              data: this.chartData.ongoing,
+              data: this.data.service_ing,
             },
             {
               name: "上月完成",
               type: "bar",
               stack: "total",
-              emphasis: {
-                focus: "series",
-              },
+              barMinHeight: 10,
               itemStyle: {
                 color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                   { offset: 0, color: "#192FC9" },
@@ -163,15 +163,13 @@
               },
               barWidth: 30,
               barGap: "0%",
-              data: this.chartData.lastMonthCompleted,
+              data: this.data.service_last_month,
             },
             {
               name: "今年累计",
               type: "bar",
               stack: "total",
-              emphasis: {
-                focus: "series",
-              },
+              barMinHeight: 10,
               label: {
                 show: true,
                 color: "#fff",
@@ -185,7 +183,7 @@
               },
               barWidth: 30,
               barGap: "0%",
-              data: this.chartData.yearTotal,
+              data: this.data.year_summary,
             },
           ],
         }
@@ -194,33 +192,6 @@
         this.chartInstance.resize()
       },
 
-      // 加载数据
-      async loadData() {
-        this.updateChart()
-      },
-
-      // 更新图表
-      updateChart() {
-        if (this.chartInstance) {
-          this.chartInstance.setOption({
-            yAxis: {
-              data: this.chartData.categories,
-            },
-            series: [
-              {
-                data: this.chartData.ongoing,
-              },
-              {
-                data: this.chartData.lastMonthCompleted,
-              },
-              {
-                data: this.chartData.yearTotal,
-              },
-            ],
-          })
-        }
-      },
-
       // 处理窗口大小变化
       handleResize() {
         if (this.chartInstance) {

+ 20 - 66
src/views/hui-jia/components/implementary/total.vue

@@ -7,35 +7,35 @@
     <div class="total-grid">
       <div class="total-item">
         <div class="total-label">城市总数</div>
-        <div class="total-value">{{ cityCount }}</div>
+        <div class="total-value">{{ formatNumber(data.cities) }}</div>
       </div>
       <div class="total-item">
         <div class="total-label">企业总数</div>
-        <div class="total-value">{{ enterpriseCount }}</div>
+        <div class="total-value">{{ data.customers }}</div>
       </div>
       <div class="total-item">
         <div class="total-label">合同总数</div>
-        <div class="total-value">{{ contractCount }}</div>
+        <div class="total-value">{{ formatNumber(data.contracts) }}</div>
       </div>
       <div class="total-item">
         <div class="total-label">履约次数</div>
-        <div class="total-value">{{ performanceCount }}</div>
+        <div class="total-value">{{ formatNumber(data.perform_times) }}</div>
       </div>
       <div class="total-item">
         <div class="total-label">服务时长</div>
-        <div class="total-value">{{ serviceHours }}</div>
+        <div class="total-value">{{ formatNumber(data.service_time) }}</div>
       </div>
       <div class="total-item">
         <div class="total-label">项目总数</div>
-        <div class="total-value">{{ projectCount }}</div>
+        <div class="total-value">{{ formatNumber(data.residences) }}</div>
       </div>
       <div class="total-item">
         <div class="total-label">签约户数</div>
-        <div class="total-value">{{ signedUserCount }}</div>
+        <div class="total-value">{{ formatNumber(data.contracted_households) }}</div>
       </div>
       <div class="total-item">
         <div class="total-label">实施户数</div>
-        <div class="total-value">{{ implementationUserCount }}</div>
+        <div class="total-value">{{ formatNumber(data.actual_households) }}</div>
       </div>
     </div>
   </div>
@@ -43,73 +43,27 @@
 
 <script>
   import { mapState } from "vuex"
-  import { api } from "@/api"
 
   export default {
     name: "ImplementationTotal",
+    props: {
+      data: {
+        type: Object,
+        default: () => ({}),
+      },
+    },
     data() {
-      return {
-        cityCount: 99,
-        enterpriseCount: 99,
-        contractCount: 99,
-        performanceCount: 99,
-        serviceHours: 99,
-        projectCount: 99,
-        signedUserCount: 99,
-        implementationUserCount: 99,
-        timer: null,
-      }
+      return {}
     },
     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)
-        }
-      },
-      // 更新数据
-      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()
+        return num.toLocaleString("zh", {
+          maximumFractionDigits: 2,
+        })
       },
     },
   }
@@ -125,7 +79,7 @@
     overflow: hidden;
 
     .total-title {
-      padding:  halfH(4) halfW(10);
+      padding: halfH(4) halfW(10);
       display: flex;
       align-items: center;
       font-size: halfW(18);
@@ -157,7 +111,7 @@
       }
 
       .total-value {
-        font-size: halfW(28);
+        font-size: halfW(24);
         font-weight: bold;
         color: #ffffff;
       }

+ 130 - 95
src/views/hui-jia/components/market.vue

@@ -8,7 +8,10 @@
       <div class="legend-item">上月</div>
       <div class="legend-item">本月</div>
     </div>
-    <div id="marketChart" class="chart"></div>
+    <div class="chart-wrap">
+      <div id="marketChart" class="chart"></div>
+      <div id="marketChart2" class="chart2"></div>
+    </div>
   </div>
 </template>
 
@@ -19,33 +22,50 @@
 
   export default {
     name: "MarketExpansion",
+    props: {
+      data: {
+        type: Object,
+        default: () => ({}),
+      },
+    },
     data() {
       return {
-        chartInstance: null,
+        chartInstanceA: null,
+        chartInstanceB: null,
         chartData: {
           categories: [
-            "新增企业",
-            "跟进项目",
-            "新增联系人",
-            "新增合同",
-            "新增项目",
             "新增户数",
+            "新增项目",
+            "新增合同",
+            "新增联系人",
+            "跟进企业",
+            "新增企业",
           ],
-          lastMonthData: [-9, -9, -9, -9, -3, -12], // 上月数据
-          thisMonthData: [9, 9, 1, 1, 9, 10], // 本月数据
         },
       }
     },
     computed: {
       ...mapState(["entCode", "communityId"]),
+      lastMonthData() {
+        const data = this.data || {}
+        return Object.keys(data).map((key, index) => {
+          return -data[key].last_month
+        }).reverse()
+      },
+      thisMonthData() {
+        const data = this.data || {}
+        return Object.keys(data).map((key, index) => {
+          return data[key].this_month
+        }).reverse()
+      }
     },
     mounted() {
       this.init()
       window.addEventListener("resize", this.handleResize)
     },
     beforeDestroy() {
-      if (this.chartInstance) {
-        this.chartInstance.dispose()
+      if (this.chartInstanceA) {
+        this.chartInstanceA.dispose()
       }
       window.removeEventListener("resize", this.handleResize)
     },
@@ -53,16 +73,18 @@
       // 初始化组件
       init() {
         this.initChart()
-        this.loadData()
       },
 
       // 初始化图表
       initChart() {
-        this.chartInstance = echarts.init(
+        this.chartInstanceA = echarts.init(
           document.getElementById("marketChart")
         )
+        this.chartInstanceB = echarts.init(
+          document.getElementById("marketChart2")
+        )
 
-        const option = {
+        const optionA = {
           tooltip: {
             trigger: "axis",
             axisPointer: {
@@ -88,10 +110,10 @@
             },
           },
           grid: {
-            left: "25%",
-            right: "25%",
-            bottom: "3%",
-            top: 50,
+            left: "10%",
+            right: "1%",
+            bottom: "5%",
+            top: "5%",
             containLabel: true,
           },
           xAxis: {
@@ -118,33 +140,13 @@
                 show: false,
               },
             },
-            {
-              type: "category",
-              data: this.chartData.categories,
-              axisLine: {
-                show: false,
-              },
-              axisTick: {
-                show: false,
-              },
-              axisLabel: {
-                show: false,
-                color: "#a0b3d6",
-                fontSize: 14,
-              },
-            },
           ],
           series: [
             {
               name: "上月",
               type: "bar",
-              //   stack: "sameStack",
-              stack: "Total",
-              emphasis: {
-                focus: "series",
-              },
-              barMinHeight: 4,
-              data: this.chartData.lastMonthData,
+              barMinHeight: 20,
+              data: this.lastMonthData,
               barWidth: 16,
               itemStyle: {
                 // 左侧渐变色:从#F66757到#FCE2B4
@@ -165,16 +167,75 @@
                 },
               },
             },
+          ],
+        }
+
+        const optionB = {
+          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 +
+                  ": " +
+                  Math.abs(item.value) +
+                  "<br/>"
+              })
+              return result
+            },
+          },
+          grid: {
+            left: "1%",
+            right: "10%",
+            bottom: "5%",
+            top: "5%",
+            containLabel: true,
+          },
+          xAxis: {
+            type: "value",
+            axisLabel: {
+              formatter: (value) => {
+                if (value < 0) return -value //这里是针对取负值
+                else return value
+              },
+            },
+            show: false, // 隐藏x轴
+          },
+          yAxis: [
+            {
+              type: "category",
+              data: this.chartData.categories,
+              axisLine: {
+                show: false,
+              },
+              axisTick: {
+                show: false,
+              },
+              axisLabel: {
+                show: true,
+                color: "#a0b3d6",
+                fontSize: 14,
+                align: "right",
+              },
+            },
+          ],
+          series: [
             {
               name: "本月",
               type: "bar",
-              //   stack: "sameStack",
-              stack: "Total",
-              emphasis: {
-                focus: "series",
-              },
-              barMinHeight: 4,
-              data: this.chartData.thisMonthData,
+              barMinHeight: 2,
+              data: this.thisMonthData,
               barWidth: 16,
               itemStyle: {
                 // 右侧渐变色:从#1620D4到#3AB3E3
@@ -195,56 +256,19 @@
           ],
         }
 
-        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,
-              },
-            ],
-          })
-        }
+        this.chartInstanceA.setOption(optionA)
+        this.chartInstanceA.resize()
+        this.chartInstanceB.setOption(optionB)
+        this.chartInstanceB.resize()
       },
 
       // 处理窗口大小变化
       handleResize() {
-        if (this.chartInstance) {
-          this.chartInstance.resize()
+        if (this.chartInstanceA) {
+          this.chartInstanceA.resize()
+        }
+        if (this.chartInstanceB) {
+          this.chartInstanceB.resize()
         }
       },
     },
@@ -284,9 +308,20 @@
     border-bottom: 1px solid rgba(64, 158, 255, 0.2);
   }
 
-  .chart {
+  .chart-wrap {
+    display: flex;
+    align-items: center;
     width: 100%;
     height: 100%;
-    background: var(--content-bg);
+    .chart {
+      width: 40%;
+      height: 100%;
+      background: var(--content-bg);
+    }
+    .chart2 {
+      width: 60%;
+      height: 100%;
+      background: var(--content-bg);
+    }
   }
 </style>

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

@@ -9,17 +9,17 @@
     <!-- 数据卡片 -->
     <div class="data-cards">
       <div class="data-card">
-        <div class="data-value">{{ doorDevices }}</div>
+        <div class="data-value">{{ state.count }}</div>
         <div class="data-label">门禁设备</div>
       </div>
 
       <div class="data-card">
-        <div class="data-value">{{ activeProjects }}</div>
+        <div class="data-value">{{ state.accessControlProjectCount }}</div>
         <div class="data-label">开通项目</div>
       </div>
 
       <div class="data-card">
-        <div class="data-value">{{ accessTimes }}</div>
+        <div class="data-value">{{ state.openCount }}</div>
         <div class="data-label">出入次数</div>
       </div>
     </div>
@@ -33,30 +33,35 @@
 </template>
 
 <script>
+import { huiJiaApi } from "@/api"
+
 export default {
   name: 'SmartDoor',
   data () {
     return {
-      doorDevices: '921',
-      activeProjects: '92',
-      accessTimes: '900000',
-      chartInstance: null,
-      // 模拟的通行流量数据
-      trafficData: [
-        { time: '01:00', count: 150 },
-        { time: '04:00', count: 250 },
-        { time: '07:00', count: 420 },
-        { time: '10:00', count: 380 },
-        { time: '13:00', count: 320 },
-        { time: '16:00', count: 230 },
-        { time: '19:00', count: 220 },
-        { time: '22:00', count: 300 }
-      ]
+      state: {
+        count: '921',
+        accessControlProjectCount: '92',
+        openCount: '900000',
+        chartInstance: null,
+        // 模拟的通行流量数据
+        list: [
+          { statData: '01:00', count: 150 },
+          { statData: '04:00', count: 250 },
+          { statData: '07:00', count: 420 },
+          { statData: '10:00', count: 380 },
+          { statData: '13:00', count: 320 },
+          { statData: '16:00', count: 230 },
+          { statData: '19:00', count: 220 },
+          { statData: '22:00', count: 300 }
+        ]
+      }
     }
   },
   mounted () {
     this.initChart()
     window.addEventListener('resize', this.handleResize)
+    this.getData()
   },
   beforeDestroy () {
     window.removeEventListener('resize', this.handleResize)
@@ -65,6 +70,14 @@ export default {
     }
   },
   methods: {
+    getData () {
+      huiJiaApi.getFaceDeviceData().then((res) => {
+        if (res && res.data) {
+          this.state = res.data.data
+        }
+        console.log("业务数据----", res.data.data)
+      })
+    },
     initChart () {
       const echarts = require('echarts')
       this.chartInstance = echarts.init(this.$refs.trafficChart)
@@ -98,7 +111,7 @@ export default {
         },
         xAxis: {
           type: 'category',
-          data: this.trafficData.map((item) => item.time),
+          data: this.state.list.map((item) => item.statData),
           axisLine: {
             lineStyle: {
               color: 'rgba(160, 179, 214, 0.6)'
@@ -144,7 +157,7 @@ export default {
           {
             name: '开门次数',
             type: 'bar',
-            data: this.trafficData.map((item) => item.count),
+            data: this.state.list.map((item) => item.count),
             barWidth: '30%',
             // 添加标签配置,设置颜色为白色
             label: {
@@ -190,6 +203,7 @@ export default {
   .module-title {
     display: flex;
     border-radius: halfW(4);
+    font-size: halfW(18);
     align-items: center;
     color: var(--title-primary);
     background: var(--title-bg);

+ 162 - 139
src/views/hui-jia/components/work-card.vue

@@ -5,14 +5,72 @@
       部分业务统计
     </div>
     <div class="work-card">
-      <div class="work-card-item" v-for="item in dataList" :key="item.title">
+      <div class="work-card-item">
         <div class="card-header">
-          <img :src="item.icon" class="title-icon" />
-          <span class="card-title">{{ item.title }}</span>
+          <img src="@/assets/images/jgxx.png" class="title-icon" />
+          <span class="card-title">数电票业务</span>
         </div>
         <div class="card-content">
-          <div class="card-subtitle">{{ item.subtitle }}</div>
-          <div class="card-value">{{ formatNumber(item.value) }}</div>
+          <div class="card-subtitle">已开发票数</div>
+          <div class="card-value">
+            {{ formatNumber(state.issuedInvoiceCount) }}
+          </div>
+        </div>
+      </div>
+      <div class="work-card-item">
+        <div class="card-header">
+          <img src="@/assets/images/glgd.png" class="title-icon" />
+          <span class="card-title">道闸系统</span>
+        </div>
+        <div class="card-content">
+          <div class="card-subtitle">设备数量</div>
+          <div class="card-value">
+            {{ formatNumber(state.gateDeviceCount) }}
+          </div>
+        </div>
+      </div>
+      <div class="work-card-item">
+        <div class="card-header">
+          <img src="@/assets/images/ewm.png" class="title-icon" />
+          <span class="card-title">智慧二维码</span>
+        </div>
+        <div class="card-content">
+          <div class="card-subtitle">配置数量</div>
+          <div class="card-value">{{ formatNumber(state.qrCount) }}</div>
+        </div>
+      </div>
+      <div class="work-card-item">
+        <div class="card-header">
+          <img src="@/assets/images/zhxggd.png" class="title-icon" />
+          <span class="card-title">短信业务</span>
+        </div>
+        <div class="card-content">
+          <div class="card-subtitle">销售数量</div>
+          <div class="card-value">{{ formatNumber(state.smsSalesQty) }}</div>
+        </div>
+      </div>
+      <div class="work-card-item">
+        <div class="card-header">
+          <img src="@/assets/images/gwxx.png" class="title-icon" />
+          <span class="card-title">房屋租售</span>
+        </div>
+        <div class="card-content">
+          <div class="card-subtitle">发布资产数</div>
+          <div class="card-value">
+            {{ formatNumber(state.rentalPublishCount) }}
+          </div>
+        </div>
+      </div>
+      <div class="work-card-item">
+        <div class="card-header">
+          <img src="@/assets/images/ryzb.png" class="title-icon" />
+          <span class="card-title">业委会</span>
+        </div>
+        <div class="card-content">
+          <div class="card-subtitle">开通数量</div>
+          <div class="card-value">
+            {{ formatNumber(state.ownerCommitteeOpenCount) }}
+          </div>
         </div>
       </div>
     </div>
@@ -20,156 +78,121 @@
 </template>
 
 <script>
-  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"
+import { huiJiaApi } from "@/api"
 
-  export default {
-    name: "WorkCard",
-    props: {
-      title: {
-        type: String,
-        required: true,
-      },
-      subtitle: {
-        type: String,
-        required: true,
-      },
-      value: {
-        type: [Number, String],
-        required: true,
-        default: 0,
+export default {
+  name: "WorkCard",
+  props: {},
+  data() {
+    return {
+      state: {
+        issuedInvoiceCount: "", // 数电票业务
+        gateDeviceCount: "", // 闸道设备数量
+        qrCount: "", // 二维码数量
+        smsSalesQty: "", // 短信销售数量
+        rentalPublishCount: "", // 房屋租赁发布数量
+        ownerCommitteeOpenCount: "", // 业委会开通数量
       },
-    },
-    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,
-          },
-        ],
-      }
-    },
-    methods: {
-      // 格式化数字显示
-      formatNumber(num) {
-        if (typeof num === "string") {
-          return num
+    }
+  },
+  mounted() {
+    this.getData()
+  },
+  methods: {
+    getData() {
+      huiJiaApi.getBusinessData().then((res) => {
+        if (res && res.data) {
+          this.state = res.data.data
         }
-        // 如果数字是整数,直接返回字符串形式
-        return num.toString()
-      },
+        console.log("业务数据----", res.data.data)
+      })
     },
-  }
+    // 格式化数字显示
+    formatNumber(num) {
+      return num.toLocaleString("zh", {
+        maximumFractionDigits: 2,
+      })
+    },
+  },
+}
 </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 {
-    flex: 1 1 0%;
-    padding: 0px halfW(20);
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    gap: halfW(10);
-  }
+@import "@/assets/css/theme.scss";
 
-  .work-card-item {
-    background: var(--title-bg);
-    border-radius: halfW(4);
-    display: flex;
-    flex-direction: column;
-    justify-content: space-between;
-  }
+.work-card-container {
+  background: var(--content-bg);
+  border-radius: halfW(4);
+  height: 100%;
+  width: 100%;
+  display: flex;
+  flex-direction: column;
 
-  .card-header {
+  .title {
+    font-size: halfW(18);
     display: flex;
+    border-radius: halfW(4);
     align-items: center;
-    margin-bottom: halfH(10);
-    padding: halfH(4) halfW(10);
+    color: var(--title-primary);
     background: var(--title-bg);
+    padding: halfH(4) halfW(10);
+  }
+}
 
-    .iconfont {
-      font-size: halfH(24);
-      margin-right: halfW(10);
-      // 根据不同图标使用不同颜色
-      color: var(--primary-color, #409eff);
-    }
+.work-card {
+  flex: 1 1 0%;
+  padding: 0px halfW(20);
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: halfW(10);
+}
 
-    .card-title {
-      font-size: halfW(16);
-      font-weight: 500;
-      color: var(--title-primary);
-    }
+.work-card-item {
+  background: var(--title-bg);
+  border-radius: halfW(4);
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+}
+
+.card-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: halfH(10);
+  padding: halfH(4) halfW(10);
+  background: var(--title-bg);
+
+  .iconfont {
+    font-size: halfH(24);
+    margin-right: halfW(10);
+    // 根据不同图标使用不同颜色
+    color: var(--primary-color, #409eff);
   }
 
-  .card-content {
-    display: flex;
-    align-items: center;
-    padding: halfH(20) halfW(20);
-    .card-subtitle {
-      font-size: halfW(14);
-      color: #82d1f6;
-    }
+  .card-title {
+    font-size: halfW(16);
+    font-weight: 500;
+    color: var(--title-primary);
+  }
+}
 
-    .card-value {
-      margin-left: halfW(12);
-      font-size: halfW(18);
-      font-weight: 600;
-      color: #fff;
-      letter-spacing: 1px;
-    }
+.card-content {
+  display: flex;
+  align-items: center;
+  padding: halfH(20) halfW(20);
+
+  .card-subtitle {
+    font-size: halfW(14);
+    color: #82d1f6;
+  }
+
+  .card-value {
+    margin-left: halfW(12);
+    font-size: halfW(18);
+    font-weight: 600;
+    color: #fff;
+    letter-spacing: 1px;
   }
+}
 </style>