Browse Source

修改看板的bug

695593266@qq.com 2 months ago
parent
commit
57116c4198

+ 215 - 6
src/views/bpm/vis-page/factoryProductionDashboard.vue

@@ -333,7 +333,47 @@
                 >
                   仓管
                 </span>
-                <i class="el-icon-setting fp-filter-icon"></i>
+                <i
+                  class="el-icon-setting fp-filter-icon"
+                  @click.stop="showInventoryDropdown = !showInventoryDropdown"
+                ></i>
+                <div
+                  v-if="showInventoryDropdown"
+                  class="fp-inventory-dropdown"
+                  @click.stop
+                >
+                  <div class="fp-dropdown-header">
+                    <el-checkbox
+                      :value="isAllInventoryChecked"
+                      :indeterminate="
+                        checkedInventoryCount > 0 &&
+                        checkedInventoryCount < inventoryXAxisOptions.length
+                      "
+                      @change="toggleAllInventoryXAxis"
+                    >
+                      展示设置
+                    </el-checkbox>
+                    <span class="fp-dropdown-count"
+                      >({{ checkedInventoryCount }}/{{
+                        inventoryXAxisOptions.length
+                      }})</span
+                    >
+                  </div>
+                  <div class="fp-dropdown-content">
+                    <div
+                      v-for="item in inventoryXAxisOptions"
+                      :key="item.name"
+                      class="fp-dropdown-item"
+                    >
+                      <el-checkbox
+                        v-model="item.checked"
+                        @change="handleInventoryXAxisChange"
+                      >
+                        {{ item.name }}
+                      </el-checkbox>
+                    </div>
+                  </div>
+                </div>
               </div>
             </div>
             <div class="fp-chart-box card-content">
@@ -460,13 +500,28 @@
         return this.$store.state.theme.contentWidth || '100%';
       },
       inventoryLedgerDisplayData() {
-        return this.activeInventoryFilter === 'keeper'
-          ? this.inventoryLedgerKeeperData
-          : this.inventoryLedgerData;
+        const sourceData =
+          this.activeInventoryFilter === 'keeper'
+            ? this.inventoryLedgerKeeperData
+            : this.inventoryLedgerData;
+        const checkedNames = this.inventoryXAxisOptions
+          .filter((opt) => opt.checked)
+          .map((opt) => opt.name);
+        if (checkedNames.length === 0) return [];
+        return sourceData.filter((item) => checkedNames.includes(item.name));
       },
       inventoryBarColors() {
         return (this.inventoryLedgerDisplayData || []).map(() => '#1163fb');
       },
+      checkedInventoryCount() {
+        return this.inventoryXAxisOptions.filter((opt) => opt.checked).length;
+      },
+      isAllInventoryChecked() {
+        return (
+          this.inventoryXAxisOptions.length > 0 &&
+          this.checkedInventoryCount === this.inventoryXAxisOptions.length
+        );
+      },
       filteredPlanRows() {
         if (this.activePlanTab === 'all') return this.planRows;
         return this.planRows.filter((r) => r.type === this.activePlanTab);
@@ -571,6 +626,8 @@
         inventoryLedgerData: [],
         inventoryLedgerKeeperData: [],
         activeInventoryFilter: 'category',
+        showInventoryDropdown: false,
+        inventoryXAxisOptions: [],
         deviceLedger: {
           categories: [],
           barData: [],
@@ -601,6 +658,7 @@
       const today = this.formatDate(now);
       this.dateRange = [today, today];
       this.getFactoryListByData();
+      document.addEventListener('click', this.handleDocumentClick);
     },
     mounted() {
       this.applyScreenSize();
@@ -631,8 +689,32 @@
         'webkitfullscreenchange',
         this.handleFullscreenChange
       );
+      document.removeEventListener('click', this.handleDocumentClick);
     },
     methods: {
+      handleDocumentClick() {
+        this.showInventoryDropdown = false;
+      },
+      toggleAllInventoryXAxis(val) {
+        this.inventoryXAxisOptions.forEach((item) => {
+          item.checked = val;
+        });
+        this.handleInventoryXAxisChange();
+      },
+      handleInventoryXAxisChange() {
+        // Force reactivity update by replacing array
+        this.inventoryXAxisOptions = [...this.inventoryXAxisOptions];
+      },
+      updateInventoryXAxisOptions(data) {
+        const newNames = data.map((item) => item.name);
+        const updatedOptions = newNames.map((name) => {
+          const existing = this.inventoryXAxisOptions.find(
+            (opt) => opt.name === name
+          );
+          return { name, checked: existing ? existing.checked : true };
+        });
+        this.inventoryXAxisOptions = updatedOptions;
+      },
       handleWindowResize() {
         clearTimeout(this.resizeTimer);
         this.resizeTimer = setTimeout(() => {
@@ -703,7 +785,11 @@
             });
           }
         });
-        this.factoryId = this.factoryList.length ? this.factoryList[0].id : '';
+        this.factoryId = this.$store.state.user.info.factoryId
+          ? this.$store.state.user.info.factoryId
+          : this.factoryList.length
+          ? this.factoryList[0].id
+          : '';
       },
 
       triggerChartResize() {
@@ -988,6 +1074,7 @@
           } else {
             this.inventoryLedgerData = normalized;
           }
+          this.updateInventoryXAxisOptions(normalized);
         } catch (error) {
           console.error('获取库存台账数据失败:', error);
           if (filterType === 'keeper') {
@@ -1195,7 +1282,7 @@
     flex: 0.8 !important;
     background-color: rgba(8, 29, 65, 0.8);
     border: 1px solid #124c77;
-    overflow: hidden;
+    overflow: visible;
     display: flex;
     flex-direction: column;
     min-height: 0;
@@ -1256,6 +1343,128 @@
     cursor: pointer;
   }
 
+  .fp-inventory-card .card-content {
+    overflow: hidden;
+    flex: 1;
+    min-height: 0;
+  }
+
+  .fp-inventory-header {
+    position: relative;
+    z-index: 10;
+  }
+
+  .fp-inventory-dropdown {
+    position: absolute;
+    top: calc(100% + 6px);
+    right: 0;
+    min-width: 160px;
+    background: rgba(1, 25, 68, 0.96);
+    border: 1px solid rgba(11, 111, 213, 0.8);
+    border-radius: 2px;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.6), 0 0 6px rgba(11, 111, 213, 0.3);
+    z-index: 1000;
+    overflow: hidden;
+  }
+
+  .fp-dropdown-header {
+    padding: 8px 12px;
+    background: rgba(11, 111, 213, 0.25);
+    border-bottom: 1px solid rgba(11, 111, 213, 0.4);
+    color: #e9f3ff;
+    font-size: 0.8rem;
+    display: flex;
+    align-items: center;
+    gap: 4px;
+  }
+
+  .fp-dropdown-count {
+    color: #9fc5ff;
+    font-size: 0.75rem;
+    margin-left: auto;
+  }
+
+  .fp-dropdown-content {
+    max-height: 280px;
+    overflow-y: auto;
+    padding: 2px 0;
+  }
+
+  .fp-dropdown-content::-webkit-scrollbar {
+    width: 6px;
+  }
+
+  .fp-dropdown-content::-webkit-scrollbar-track {
+    background: rgba(3, 29, 66, 0.5);
+  }
+
+  .fp-dropdown-content::-webkit-scrollbar-thumb {
+    background: rgba(11, 111, 213, 0.6);
+    border-radius: 3px;
+  }
+
+  .fp-dropdown-item {
+    padding: 6px 12px;
+    cursor: pointer;
+    transition: background-color 0.15s;
+    border-bottom: 1px solid rgba(11, 111, 213, 0.1);
+  }
+
+  .fp-dropdown-item:last-child {
+    border-bottom: none;
+  }
+
+  .fp-dropdown-item:hover {
+    background-color: rgba(11, 111, 213, 0.15);
+  }
+
+  ::v-deep .fp-dropdown-item .el-checkbox,
+  ::v-deep .fp-dropdown-header .el-checkbox {
+    display: flex;
+    align-items: center;
+    width: 100%;
+  }
+
+  ::v-deep .fp-dropdown-item .el-checkbox__label,
+  ::v-deep .fp-dropdown-header .el-checkbox__label {
+    color: #d4e4ff;
+    font-size: 0.78rem;
+    padding-left: 6px;
+  }
+
+  ::v-deep .fp-dropdown-item .el-checkbox__input.is-checked .el-checkbox__inner,
+  ::v-deep
+    .fp-dropdown-header
+    .el-checkbox__input.is-checked
+    .el-checkbox__inner {
+    background-color: #0b6fd5;
+    border-color: #0b6fd5;
+  }
+
+  ::v-deep
+    .fp-dropdown-item
+    .el-checkbox__input.is-checked
+    + .el-checkbox__label,
+  ::v-deep
+    .fp-dropdown-header
+    .el-checkbox__input.is-checked
+    + .el-checkbox__label {
+    color: #fff;
+  }
+
+  ::v-deep .fp-dropdown-item .el-checkbox__inner,
+  ::v-deep .fp-dropdown-header .el-checkbox__inner {
+    width: 14px;
+    height: 14px;
+    background-color: rgba(1, 25, 68, 0.6);
+    border-color: rgba(11, 111, 213, 0.6);
+  }
+
+  ::v-deep .fp-dropdown-item .el-checkbox__inner:hover,
+  ::v-deep .fp-dropdown-header .el-checkbox__inner:hover {
+    border-color: #3bfff2;
+  }
+
   /* left number card */
   .fp-number-card {
     height: 100%;

+ 194 - 33
src/views/bpm/vis-page/renewableResourcesDashboard.vue

@@ -278,28 +278,34 @@
 
           <section class="rr-panel rr-panel-equipment">
             <div class="rr-panel-title">设备总览</div>
-            <div class="rr-equipment-body">
-              <div class="rr-equipment-gauge">
-                <div class="rr-gauge-wrap">
-                  <div ref="utilDonutRef" class="rr-native-chart"></div>
+            <div class="rr-equipment-body-new">
+              <!-- 左侧环形图+数据 -->
+              <div class="rr-equip-left">
+                <div class="rr-equip-donut-area">
+                  <div ref="equipmentDonutRef" class="rr-equip-donut-chart"></div>
+                  <div class="rr-equip-donut-center">
+                    <span class="rr-equip-donut-val">{{ equipmentOverview.online }}</span>
+                    <span class="rr-equip-donut-lbl">设备总量</span>
+                  </div>
+                </div>
+                <div class="rr-equip-stats">
+                  <div class="rr-equip-stat-item" v-for="item in equipmentStatsList" :key="item.label">
+                    <span class="rr-equip-stat-val">{{ item.value }}</span>
+                    <span class="rr-equip-stat-lbl">{{ item.label }}</span>
+                  </div>
                 </div>
-                <ul class="rr-equipment-list">
-                  <li v-for="item in leftEquipmentList" :key="item.label">
-                    <span>{{ item.label }}</span>
-                    <strong>{{ item.value }}</strong>
-                  </li>
-                </ul>
               </div>
-              <div class="rr-equipment-gauge">
-                <div class="rr-gauge-wrap">
-                  <div ref="faultDonutRef" class="rr-native-chart"></div>
+              <!-- 中间利用率仪表盘 -->
+              <div class="rr-equip-gauge-col">
+                <div class="rr-equip-gauge-box">
+                  <div ref="utilDonutRef" class="rr-equip-gauge-chart"></div>
+                </div>
+              </div>
+              <!-- 右侧故障率仪表盘 -->
+              <div class="rr-equip-gauge-col">
+                <div class="rr-equip-gauge-box">
+                  <div ref="faultDonutRef" class="rr-equip-gauge-chart"></div>
                 </div>
-                <ul class="rr-equipment-list">
-                  <li v-for="item in rightEquipmentList" :key="item.label">
-                    <span>{{ item.label }}</span>
-                    <strong>{{ item.value }}</strong>
-                  </li>
-                </ul>
               </div>
             </div>
           </section>
@@ -472,7 +478,8 @@
           inventoryDonut: null,
           inventoryTrend: null,
           utilDonut: null,
-          faultDonut: null
+          faultDonut: null,
+          equipmentDonut: null
         }
       };
     },
@@ -500,6 +507,15 @@
           { label: '产品设备', value: this.equipmentOverview.productCount },
           { label: '备件库存', value: this.equipmentOverview.spareCount }
         ];
+      },
+      equipmentStatsList() {
+        return [
+          { label: '生产设备', value: this.equipmentOverview.deviceCount },
+          { label: '关键设备', value: 50 },
+          { label: '仪表计量', value: this.equipmentOverview.spareCount },
+          { label: '备品备件', value: 58 },
+          { label: '工夹刀模具', value: 83 }
+        ];
       }
     },
     created() {
@@ -622,7 +638,7 @@
         const designWidth = 1920;
         const designHeight = 1080;
         const scale = Math.min(w / designWidth, h / designHeight);
-        const baseFontSize = isFs ? 16 * scale : 16;
+        const baseFontSize = 16 * scale;
         document.documentElement.style.fontSize = `${baseFontSize}px`;
       },
       initNativeCharts() {
@@ -640,6 +656,7 @@
         );
         this.initInventoryDonutChart();
         this.initInventoryTrendChart();
+        this.initEquipmentDonutChart();
         this.initGaugeChart(
           'utilDonut',
           this.$refs.utilDonutRef,
@@ -1070,6 +1087,47 @@
           ]
         });
         this.chartInstances[key] = chart;
+      },
+      initEquipmentDonutChart() {
+        if (!this.$refs.equipmentDonutRef) return;
+        this.chartInstances.equipmentDonut?.dispose();
+        const chart = echarts.init(this.$refs.equipmentDonutRef);
+        const pieColors = ['#5b9bd5', '#ffb648', '#3cd8c8', '#7b69ff'];
+        const pieData = [
+          { name: '生产设备', value: this.equipmentOverview.deviceCount },
+          { name: '关键设备', value: 50 },
+          { name: '仪表计量', value: this.equipmentOverview.spareCount },
+          { name: '备品备件', value: 58 },
+          { name: '工夹刀模具', value: 83 }
+        ];
+        chart.setOption({
+          backgroundColor: 'transparent',
+          color: pieColors,
+          tooltip: {
+            trigger: 'item',
+            backgroundColor: 'rgba(8,29,65,0.92)',
+            borderColor: '#124c77',
+            textStyle: { color: '#fff', fontSize: 13 },
+            formatter: '{b}: {c}'
+          },
+          series: [
+            {
+              type: 'pie',
+              radius: ['42%', '68%'],
+              center: ['50%', '50%'],
+              padAngle: 3,
+              itemStyle: {
+                borderRadius: 6,
+                borderColor: 'rgba(3, 18, 41, 0.8)',
+                borderWidth: 2
+              },
+              label: { show: false },
+              labelLine: { show: false },
+              data: pieData
+            }
+          ]
+        });
+        this.chartInstances.equipmentDonut = chart;
       }
     }
   };
@@ -1420,7 +1478,7 @@
   .rr-summary-item {
     position: relative;
     display: grid;
-    grid-template-columns: clamp(2rem, 2.6vw, 2.6rem) minmax(0, 1fr);
+    grid-template-columns: clamp(2.5rem, 4vw, 4rem) minmax(0, 1fr);
     align-items: center;
     flex: 1 1 0;
     max-width: none;
@@ -1444,16 +1502,16 @@
   }
 
   .rr-summary-icon-box {
-    width: clamp(2rem, 2.6vw, 2.6rem);
-    flex: 0 0 clamp(2rem, 2.6vw, 2.6rem);
+    width: clamp(2.5rem, 4vw, 4rem);
+    flex: 0 0 clamp(2.5rem, 4vw, 4rem);
     display: flex;
     justify-content: center;
   }
 
   .rr-summary-icon-wrap {
     position: relative;
-    width: clamp(2rem, 2.6vw, 2.6rem);
-    height: clamp(2rem, 2.6vw, 2.6rem);
+    width: clamp(2.5rem, 4vw, 4rem);
+    height: clamp(2.5rem, 4vw, 4rem);
     flex-shrink: 0;
   }
 
@@ -1470,8 +1528,8 @@
     position: absolute;
     left: 50%;
     top: 50%;
-    width: clamp(1.4rem, 1.8vw, 1.9rem);
-    height: clamp(1.4rem, 1.8vw, 1.9rem);
+    width: clamp(1.8rem, 2.8vw, 2.8rem);
+    height: clamp(1.8rem, 2.8vw, 2.8rem);
     border-radius: 50%;
     transform: translate(-50%, -50%);
     display: flex;
@@ -1509,7 +1567,7 @@
 
   .rr-summary-label {
     color: #d9ebff;
-    font-size: clamp(0.48rem, 0.58vw, 0.64rem);
+    font-size: clamp(0.7rem, 0.9vw, 1rem);
     letter-spacing: 0.02rem;
     line-height: 1.2;
     white-space: nowrap;
@@ -1532,7 +1590,7 @@
 
   .rr-summary-value {
     color: #fff;
-    font-size: clamp(0.8rem, 1vw, 1.1rem);
+    font-size: clamp(1.2rem, 1.6vw, 1.8rem);
     line-height: 1;
     font-weight: 700;
     letter-spacing: 0.01rem;
@@ -1542,7 +1600,7 @@
 
   .rr-summary-unit {
     color: rgba(255, 255, 255, 0.72);
-    font-size: clamp(0.36rem, 0.42vw, 0.48rem);
+    font-size: clamp(0.55rem, 0.7vw, 0.8rem);
     line-height: 1;
     margin-bottom: 0.02rem;
     white-space: nowrap;
@@ -1556,7 +1614,7 @@
     gap: 0.02rem;
     min-width: 0;
     margin-left: 0.1rem;
-    font-size: clamp(0.3rem, 0.36vw, 0.4rem);
+    font-size: clamp(0.5rem, 0.6vw, 0.7rem);
     white-space: nowrap;
     flex-shrink: 0;
     align-self: stretch;
@@ -1568,7 +1626,7 @@
   }
 
   .rr-summary-trend-value {
-    font-size: clamp(0.32rem, 0.38vw, 0.42rem);
+    font-size: clamp(0.5rem, 0.65vw, 0.75rem);
     font-weight: 600;
     line-height: 1.2;
   }
@@ -1956,6 +2014,109 @@
     color: #fff;
   }
 
+  /* 新的设备总览布局样式 */
+  .rr-equipment-body-new {
+    flex: 1;
+    min-height: 0;
+    display: grid;
+    grid-template-columns: 1.2fr 1fr 1fr;
+    gap: 0.5rem;
+    padding: 0.5rem 0.75rem;
+    align-items: stretch;
+  }
+
+  .rr-equip-left {
+    display: flex;
+    align-items: center;
+    gap: 0.4rem;
+    min-height: 0;
+    overflow: hidden;
+  }
+
+  .rr-equip-donut-area {
+    position: relative;
+    flex: 0 0 50%;
+    height: 100%;
+    min-height: 10rem;
+  }
+
+  .rr-equip-donut-chart {
+    width: 100%;
+    height: 100%;
+  }
+
+  .rr-equip-donut-center {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%, -50%);
+    text-align: center;
+    pointer-events: none;
+  }
+
+  .rr-equip-donut-val {
+    display: block;
+    color: #fff;
+    font-size: clamp(1.1rem, 1.5vw, 1.7rem);
+    font-weight: 700;
+    line-height: 1;
+    text-shadow: 0 0 0.6rem rgba(60, 135, 255, 0.3);
+  }
+
+  .rr-equip-donut-lbl {
+    display: block;
+    margin-top: 0.15rem;
+    color: #b4d4f2;
+    font-size: clamp(0.55rem, 0.65vw, 0.75rem);
+  }
+
+  .rr-equip-stats {
+    flex: 1;
+    display: grid;
+    grid-template-columns: 1fr 1fr;
+    gap: 0.3rem 0.5rem;
+    align-content: center;
+    min-width: 0;
+  }
+
+  .rr-equip-stat-item {
+    display: flex;
+    flex-direction: column;
+    align-items: flex-start;
+    gap: 0.08rem;
+  }
+
+  .rr-equip-stat-val {
+    color: #fff;
+    font-size: clamp(0.85rem, 1.1vw, 1.3rem);
+    font-weight: 700;
+    line-height: 1.2;
+  }
+
+  .rr-equip-stat-lbl {
+    color: #b4d4f2;
+    font-size: clamp(0.5rem, 0.6vw, 0.7rem);
+  }
+
+  .rr-equip-gauge-col {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    min-height: 0;
+  }
+
+  .rr-equip-gauge-box {
+    position: relative;
+    width: 100%;
+    height: 100%;
+    min-height: 10rem;
+  }
+
+  .rr-equip-gauge-chart {
+    width: 100%;
+    height: 100%;
+  }
+
   @media (max-width: 1600px) {
     .rr-side-column {
       grid-template-rows: 1fr 1fr 1fr;