Переглянути джерело

feat: 新增生产管控大屏页面

yusheng 2 місяців тому
батько
коміт
47ddf0f5c0

+ 1 - 0
package.json

@@ -16,6 +16,7 @@
     "@amap/amap-jsapi-loader": "^1.0.1",
     "@ant-design/colors": "^6.0.0",
     "@babel/core": "^7.18.13",
+    "@jiaminghi/data-view": "^2.10.0",
     "axios": "^0.27.2",
     "bpmn-js": "8.9.0",
     "bpmn-js-properties-panel": "0.46.0",

+ 195 - 0
src/api/material/list.js

@@ -0,0 +1,195 @@
+import request from '@/utils/request';
+import { download } from '@/utils/file';
+
+// 获取列表
+export async function getGroupPage(data) {
+  const res = await request.get('/main/categorylevelgroup/page', {
+    params: data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+//  ==========  物料管理   =============/
+
+// 根据分类组编码查询分类树信息
+export async function getTreeByPid(pid) {
+  const res = await request.get(`/main/categoryLevel/getTreeByPid/${pid}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 新增物料
+export async function addMaterial(data) {
+  const res = await request.post(`/main/category/add`, data);
+  if (res.data.code == 0) {
+    return res.data.message;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 编辑物料
+export async function editMaterial(data) {
+  const res = await request.post(`/main/category/edit`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 获取列表
+export async function getMaterialList(data) {
+  const res = await request.get(`/main/category/getList`, {
+    params: data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 获取详情
+export async function getDetailInfo(id) {
+  const res = await request.get(`/main/category/info/${id}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+//删除
+export async function removeMaterial(id) {
+  const res = await request.get(`/main/category/remove/${id}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+//根据产品ID bom获取工艺路线列表【产品管理】
+export async function getBomRoutingList(categoryId) {
+  const res = await request.get(
+    `/main/bomCategory/bomRoutingListByCategoryId/${categoryId}`
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 根据产品ID获取bom列表
+export async function getBomAssociationList(params) {
+  const res = await request.get(`/main/bomCategory/getList`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 产品工序与模具关联
+export async function categoryTaskPallet(data) {
+  const res = await request.post(`/main/category/categoryTaskPallet`, data);
+  if (res.data.code == 0) {
+    return res.data.message;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 获取产品工序与模具关联
+export async function getCategoryTaskPallet(categoryId) {
+  const res = await request.get(
+    `/main/category/getCategoryTaskPallet/${categoryId}`
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 导入备品备件
+export async function importCategorySparePart(data) {
+  const res = await request.post(
+    `/main/excelUpload/importCategorySparePart`,
+    data
+  );
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 删除包装规格
+export async function deletePackageDisposition(data) {
+  const res = await request.delete(`/main/categoryPackageDisposition/delete`, {
+    data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 查询质检方案列表
+export async function getQualityTemplate(data) {
+  const res = await request.get(`/qms/qualitytemplate/page`, {
+    params: data
+  });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+// 导出
+export async function exportFile(data) {
+  const res = await request.post('/main/category/export', data, {
+    responseType: 'blob'
+  });
+  download(res.data, '产品/物品数据.xlsx');
+}
+
+export async function getProduceTreeByPid(parentId) {
+  console.log(parentId, '55555');
+  const res = await request.get(
+    `/main/categoryLevel/getProduceTreeByPid?type=${parentId}`
+  );
+  if (res.data.code == 0) {
+    return res.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export async function changeOnOff(id) {
+  const res = await request.post(`/main/category/changeOnOff/${id}`);
+  console.log('changeOnOff', res);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 获取实体列表分页
+export async function queryBindSubstanceList(data) {
+  let par = new URLSearchParams(data);
+  const res = await request.get(
+    `/main/asset/queryBindSubstanceList?` + par,
+    {}
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 获取实体物联点位
+export async function getPhysicalModel(id) {
+  const res = await request.get(
+    `/main/asset/getPhysicalModel/` + id,
+    {}
+  );
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 59 - 0
src/api/pcsData/index.js

@@ -0,0 +1,59 @@
+import request from '@/utils/request';
+
+//告警数据概览 - 环形图
+export async function alarmOverview(params) {
+  const res = await request.get(`/pcs/homePage/alarmOverview`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+//告警列表
+export async function queryAlarmList(params) {
+  const res = await request.get(`/pcs/homePage/queryAlarmList`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+//设备告警趋势图
+export async function deviceAlarmTrend(params) {
+  const res = await request.get(`/pcs/homePage/deviceAlarmTrend`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+//综合数据;
+export async function comprehensiveData(params) {
+  const res = await request.get(`/pcs/homePage/comprehensiveData`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+//用水用煤趋势图(trendType: 1-用水, 2-用煤);
+export async function waterCoalTrend(params) {
+  const res = await request.get(`/pcs/homePage/waterCoalTrend`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+//固废趋势图;
+export async function wasteTrend(params) {
+  const res = await request.get(`/pcs/homePage/wasteTrend`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+// 获取车间下的所有产线
+export async function listFactoryLine(params) {
+  const res = await request.get(`/main/factoryarea/page`, { params });
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

BIN
src/assets/pcs/back.png


BIN
src/assets/pcs/header.png


BIN
src/assets/pcs/home.png


BIN
src/assets/pcs/icon.png


BIN
src/assets/pcs/leftItem.png


BIN
src/assets/pcs/select.png


BIN
src/assets/pcs/titleIcon.png


BIN
src/assets/pcs/titleb.png


+ 4 - 0
src/main.js

@@ -21,6 +21,8 @@ import noChinese from './utils/noChinese.js';
 import { VirtualScroller } from 'vue-virtual-scroller';
 import 'vue-virtual-scroller/dist/vue-virtual-scroller.css';
 Vue.component('virtual-scroller', VirtualScroller);
+import dataV from '@jiaminghi/data-view'
+
 import { all, create } from 'mathjs'; // 引入mathjs工具并初始化
 // 注册全局自定义指令
 Vue.directive('click-once', clickOnce);
@@ -38,6 +40,8 @@ Vue.prototype.$math = create(all, {
   precision: 64
 });
 Vue.use(Vue2OrgTree);
+Vue.use(dataV);
+
 Vue.use(EleAdmin, {
   response: {
     dataName: 'list'

+ 1265 - 992
src/views/home/index.vue

@@ -1,1144 +1,1417 @@
 <template>
   <vue-fullscreen
+    class="box-container"
+    v-cloak
     v-model="isFullscreen"
+    fullscreenClass="box-container"
     :exit-on-click-wrapper="false"
-    class="h-[100%]"
   >
-    <div class="page" :class="{ 'fullscreen-active': isFullscreen }">
-      <div class="top_box">
-        <div class="title">
-          <span class="title_text">生产管控</span>
-        </div>
-        <div class="top_row">
-          <el-row :span="24">
-            <el-col :span="9">
-              <div class="col_box col_left">
-                <div class="left_name"></div>
-                <div class="right_box lessee_select">
-                  <img
-                    class="img"
-                    src="../../assets/imgs/side/top-box_left.png"
-                    alt=""
+    <div class="box-container" v-cloak>
+      <!-- 中间内容区域 - 可左右滚动,头部跟随 -->
+      <div class="box-content">
+        <div class="scroll-wrapper">
+          <!-- 头部区域 - 跟随滚动 -->
+          <div class="header-section">
+            <div class="box-header-scroll">
+              <div class="logo">
+                <el-select
+                  v-model="stationId"
+                  placeholder="请选择"
+                  class="custom-select"
+                  popper-class="custom-select-dropdown"
+                  @change="init"
+                >
+                  <el-option
+                    v-for="item in selectOptions"
+                    :key="item.value"
+                    :label="item.label"
+                    :value="item.value"
                   />
-                  <div class="content">
-                    <el-select
-                      v-model="dateType"
-                      @change="dateTypeChange"
-                      clearable
-                      placeholder=" "
-                    >
-                      <el-option label="单日" :value="1" />
-                      <el-option label="本月" :value="2" />
-                      <el-option label="本年度" :value="3" />
-                    </el-select>
-                  </div>
-                </div>
+                </el-select>
               </div>
-            </el-col>
-            <el-col :span="6">
-              <div class="col_box"></div>
-            </el-col>
-            <el-col :span="9">
-              <div class="col_box col_right">
-                <div class="lessee_select right_box">
-                  <img
-                    class="img"
-                    src="../../assets/imgs/side/top-box_right.png"
-                    alt=""
-                  />
-                  <div class="content">
-                    <el-select
-                      v-model="stationId"
-                      @change="dateTypeChange"
-                      clearable
-                      placeholder=" "
-                    >
-                      <el-option
-                        :label="item.name"
-                        :value="item.id"
-                        v-for="item in productLineList"
-                        :key="item.id"
-                      />
-                    </el-select>
-                  </div>
+              <div class="header-center">
+                <div class="title">生产管控</div>
+              </div>
+              <div class="time">
+                <div class="time-display">
+                  <span class="date-text">{{ date }}</span>
+                  <span class="time-text">{{ time }}</span>
                 </div>
-
-                <div class="fullscreen-btn" @click="toggleFullscreen">
+                <span class="fullscreen-toggle" @click.passive="onFullscreen">
                   <i
-                    :class="
-                      isFullscreen ? 'el-icon-close' : 'el-icon-full-screen'
-                    "
-                  ></i>
-                </div>
+                    v-if="isFullscreen"
+                    title="取消全屏"
+                    class="el-icon-_screen-restore"
+                  />
+                  <i v-else title="全屏" class="el-icon-_screen-full" />
+                </span>
               </div>
-            </el-col>
-          </el-row>
-        </div>
-      </div>
-      <div class="page_content">
-        <div class="left_box">
-          <div class="comprehensive" style="margin-top: 0">
-            <div class="header">
-              <img src="../../assets/imgs/side/box_icon.png" alt="" />
-              <div class="header_text">综合统计</div>
             </div>
+          </div>
 
-            <div class="content_box stats_content">
-              <div class="stats_box">
-                <div class="stats_icon">
-                  <span class="num">{{ statistics.productLineCount }}</span>
+          <!-- 双栏布局区域 -->
+          <div class="two-column-layout">
+            <!-- 左侧区域 -->
+            <div class="left-section">
+              <!-- 综合数据 -->
+              <div class="panel data-panel">
+                <div class="panel-title">
+                  <div class="panel-icon"></div>
+                  综合数据
                 </div>
-                <div class="stats_text">场站总数</div>
-              </div>
-              <div class="stats_box">
-                <div class="stats_icon">
-                  <span class="num">{{
-                    statistics.totalGasInjection || 0
-                  }}</span>
-                  <!-- <span class="text">人</span> -->
-                </div>
-                <div class="stats_text">注气总量</div>
-              </div>
-              <div class="stats_box">
-                <div class="stats_icon">
-                  <span class="num">{{ statistics.totalWater || 0 }}</span>
-                  <!-- <span class="text">个</span> -->
+                <div
+                  style="
+                    display: flex;
+                    flex: 1;
+                    align-items: center;
+                    justify-content: center;
+                  "
+                >
+                  <div class="data-grid">
+                    <div
+                      class="data-item"
+                      v-for="(item, index) in comprehensiveList"
+                      :key="index"
+                    >
+                      <div class="img"></div>
+                      <div class="data-item_value">
+                        <span class="data-label">{{ item.label }}</span>
+                        <span class="data-value">{{ item.value }}</span></div
+                      >
+                    </div>
+                  </div>
                 </div>
-                <div class="stats_text">用水量</div>
               </div>
-              <div class="stats_box">
-                <div class="stats_icon">
-                  <span class="num">{{
-                    statistics.totalElectricity || 0
-                  }}</span>
+
+              <!-- 区域用能对比 -->
+              <div class="panel chart-panel" style="position: relative">
+                <div class="panel-title energy-title">
+                  <div class="title-left">
+                    <div class="panel-icon"></div>
+                    用水用煤趋势图
+                  </div>
                 </div>
-                <div class="stats_text">用电量</div>
-              </div>
-              <div class="stats_box">
-                <div class="stats_icon">
-                  <span class="num">{{ statistics.totalCoal || 0 }}</span>
-                  <!-- <span class="text">人</span> -->
+                <div class="energy-tabs">
+                  <span
+                    v-for="tab in energyTabs"
+                    :key="tab.value"
+                    :class="[
+                      'tab-item',
+                      { active: activeEnergyTab === tab.value }
+                    ]"
+                    @click="energyTabsCahnge(tab.value)"
+                  >
+                    {{ tab.label }}
+                  </span>
                 </div>
-                <div class="stats_text">用煤量</div>
+                <div class="chart-container" ref="waterChart"></div>
               </div>
-              <div class="stats_box">
-                <div class="stats_icon">
-                  <span class="num">{{ statistics.totalCoalGas || 0 }}</span>
-                  <!-- <span class="text">个</span> -->
+
+              <!-- 区域能耗对比 -->
+              <div class="panel chart-panel">
+                <div class="panel-title energy-title">
+                  <div class="title-left">
+                    <div class="panel-icon"></div>
+                    固废量趋势图
+                  </div>
                 </div>
-                <div class="stats_text">煤灰量</div>
+                <div class="chart-container" ref="returnChart"></div>
               </div>
             </div>
-          </div>
-          <div class="work_order">
-            <div
-              class="header"
-              @click="$refs.DrawerRef.open('/page-eam/ledgerAssets/equipment')"
-            >
-              <img src="../../assets/imgs/side/box_icon.png" alt="" />
-              <div class="header_text">设备列表</div>
-            </div>
-            <div class="content_box" ref="deviceTableRef">
-              <el-table
-                v-if="true"
-                :data="deviceList"
-                style="width: 100%"
-                :header-cell-style="rowClass"
-                :max-height="deviceMaxHeight"
-                :show-overflow-tooltip="true"
-              >
-                <el-table-column
-                  prop="index"
-                  type="index"
-                  label="序号"
-                  width="60"
-                  align="center"
-                />
-                <el-table-column
-                  prop="ownershipGroupName"
-                  label="权属部门"
-                  min-width="120"
-                  align="center"
-                />
-                <el-table-column
-                  prop="name"
-                  label="设备名称"
-                  min-width="120"
-                  align="center"
-                />
-
-                <el-table-column
-                  prop="status"
-                  label="状态"
-                  width="120"
-                  align="center"
-                >
-                  <template slot-scope="scope">
-                    {{
-                      businessStatus.find(
-                        (item) => item.code == scope.row.status
-                      )?.label
-                    }}
-                  </template>
-                </el-table-column>
-              </el-table>
-            </div>
-          </div>
-          <div class="running_state">
-            <div class="header">
-              <img src="../../assets/imgs/side/box_icon.png" alt="" />
-              <div class="header_text">在岗人数-按班组</div>
-            </div>
-            <div class="content_box">
-              <v-chart ref="barRef" style="height: 100%" :option="barOption"
-            /></div>
-          </div>
-        </div>
-        <div class="center_box">
-          <div class="map_box" ref="mapBoxRef">
-            <MapDemo :mapHeight="mapHeight"></MapDemo>
-          </div>
-          <div class="lessee_box">
-            <div class="header">
-              <img src="../../assets/imgs/side/box_icon.png" alt="" />
-              <div class="header_text">场站列表</div></div
-            >
-
-            <div class="content_box" ref="stationTableRef">
-              <el-table
-                v-if="true"
-                :data="stationList"
-                style="width: 100%"
-                :header-cell-style="rowClass"
-                :max-height="stationMaxHeight"
-                :show-overflow-tooltip="true"
-              >
-                <el-table-column
-                  prop="date"
-                  label="序号"
-                  type="index"
-                  width="60"
-                  align="center"
-                />
-                <el-table-column
-                  prop="name"
-                  label="场站名称"
-                  min-width="120"
-                  align="center"
-                />
-                <el-table-column
-                  prop="water"
-                  label="用水量"
-                  width="150"
-                  align="center"
-                />
-                <el-table-column
-                  prop="electricity"
-                  label="用电量"
-                  width="150"
-                  align="center"
-                />
-                <el-table-column
-                  prop="coal"
-                  label="用煤量"
-                  width="150"
-                  align="center"
-                />
-                <el-table-column
-                  prop="gasInjection"
-                  label="注气量"
-                  width="150"
-                  align="center"
-                />
-                <el-table-column
-                  prop="coalGas"
-                  label="煤灰量"
-                  width="150"
-                  align="center"
-                />
-              </el-table>
-            </div>
-          </div>
-        </div>
-        <div class="right_box">
-          <div class="work_order" style="margin-top: 0">
-            <div
-              class="header"
-              @click="$refs.DrawerRef.open('/page-eam/warning/warningMessage')"
-            >
-              <img src="../../assets/imgs/side/box_icon.png" alt="" />
-              <div class="header_text">告警列表</div>
-            </div>
-            <div class="content_box" ref="alarmListRef">
-              <el-table
-                v-if="true"
-                :data="alarmList"
-                style="width: 100%"
-                :header-cell-style="rowClass"
-                :max-height="alarmMaxHeight"
-                :show-overflow-tooltip="true"
-              >
-                <el-table-column
-                  prop="date"
-                  label="序号"
-                  type="index"
-                  width="60"
-                  align="center"
-                />
-                <el-table-column
-                  prop="name"
-                  label="设备名称"
-                  min-width="150"
-                  align="center"
-                />
-                <el-table-column
-                  prop="ruleName"
-                  label="告警内容"
-                  min-width="150"
-                />
-                <el-table-column
-                  prop="alertLevel"
-                  label="告警级别"
-                  width="100"
-                  align="center"
-                />
-              </el-table>
-            </div>
-          </div>
-          <div class="comprehensive">
-            <div class="header">
-              <img src="../../assets/imgs/side/box_icon.png" alt="" />
-              <div class="header_text">预警统计</div>
-            </div>
-            <div class="content_box warning_stats_box">
-              <div class="warning_stats_left">
-                <div class="title_top">
-                  <div class="text">预警处理</div>
-                  <img
-                    class="img"
-                    src="../../assets/imgs/side/arrows.png"
-                    alt=""
-                  />
+
+            <!-- 右侧区域 -->
+            <div class="right-section">
+              <!-- 告警数据统计 -->
+              <div class="panel alert-panel">
+                <div class="panel-title">
+                  <divi class="panel-icon"></divi>
+                  告警数据概览
                 </div>
-                <div class="warning_line">
-                  <div class="warning_box warning_bgc">
-                    <div class="num" style="color: #ffc938">{{
-                      statistics.toDoToday || 0
-                    }}</div>
-                    <div class="text">今日待处理</div>
-                  </div>
-                  <div class="warning_box">
-                    <div class="num">{{
-                      statistics.pendingCumulative || 0
-                    }}</div>
-                    <div class="text">累计待处理</div>
-                  </div>
-                  <div class="warning_box">
-                    <div class="num">{{
-                      statistics.cumulativelyProcessed || 0
-                    }}</div>
-                    <div class="text">累计已处理</div>
+                <div class="alert-stats">
+                  <!-- 左侧数据卡片 -->
+                  <div class="alert-cards">
+                    <div
+                      class="alert-card-item"
+                      v-for="(item, index) in alertStatsData"
+                      :key="index"
+                    >
+                      <div class="img"></div>
+                      <div class="data-item_value">
+                        <span class="data-label">{{ item.label }}</span>
+                        <span class="data-value">{{ item.value }}</span></div
+                      >
+                    </div>
                   </div>
-                  <div class="warning_box">
-                    <div class="num">{{
-                      statistics.warningHandlingTotal || 0
-                    }}</div>
-                    <div class="text">累计总数</div>
+                  <!-- 右侧环形图 -->
+                  <div class="alert-pie-chart">
+                    <div class="alert-pie" ref="alertPieChart"></div>
                   </div>
                 </div>
               </div>
-              <div class="warning_stats_right">
-                <div class="title_top">
-                  <div class="text">预警巡检</div>
-                  <img
-                    class="img"
-                    src="../../assets/imgs/side/arrows.png"
-                    alt=""
+
+              <!-- 告警列表 -->
+              <div class="panel alert-list-panel">
+                <div class="panel-title">
+                  <div class="panel-icon"></div>
+                  告警列表
+                </div>
+                <div class="alert-table">
+                  <dv-scroll-board
+                    :config="alertConfig"
+                    style="width: 100%; height: calc(100% - 40px)"
                   />
                 </div>
-                <div class="warning_line">
-                  <div class="warning_box warning_bgc">
-                    <div class="num" style="color: #ffc938">{{
-                      statistics.inspectionDueToday || 0
-                    }}</div>
-                    <div class="text">今日待巡检</div>
-                  </div>
-                  <div class="warning_box">
-                    <div class="num">{{
-                      statistics.accumulatedPending || 0
-                    }}</div>
-                    <div class="text">累计待完成</div>
-                  </div>
-                  <div class="warning_box">
-                    <div class="num">{{
-                      statistics.cumulativelyCompleted || 0
-                    }}</div>
-                    <div class="text">累计已完成</div>
-                  </div>
-                  <div class="warning_box">
-                    <div class="num">{{
-                      statistics.warningPatrolTotal || 0
-                    }}</div>
-                    <div class="text">累计总数</div>
-                  </div>
+              </div>
+
+              <!-- 设备告警趋势图 -->
+              <div class="panel chart-panel">
+                <div class="panel-title">
+                  <div class="panel-icon"></div>
+                  设备告警趋势图
                 </div>
+                <div class="chart-container" ref="alertTrendChart"></div>
               </div>
             </div>
           </div>
-          <div class="running_state">
-            <div class="header">
-              <img src="../../assets/imgs/side/box_icon.png" alt="" />
-              <div class="header_text">视屏监控</div>
-            </div>
-            <div class="content_box monitoring_box">
-              <div class="site_box"> </div>
-            </div>
-          </div>
         </div>
       </div>
-      <Drawer ref="DrawerRef"></Drawer>
     </div>
   </vue-fullscreen>
 </template>
+
 <script>
+  import { component } from 'vue-fullscreen';
+  import * as echarts from 'echarts';
   import {
-    queryComprehensiveStatisticsAndWarningStatistics,
-    queryDeviceList,
-    queryStationList,
+    alarmOverview,
     queryAlarmList,
-    queryOnDutyPersonnel
-  } from '@/api/home/index';
-  import { businessStatus } from '@/enum/dict.js';
-  import MapDemo from './map.vue';
-  import Drawer from './drawer.vue';
-  import VChart from 'vue-echarts';
-  import { echartsMixin } from '@/utils/echarts-mixin';
-  import { use } from 'echarts/core';
-  import { CanvasRenderer } from 'echarts/renderers';
-  import { BarChart } from 'echarts/charts';
-  import { getFactoryarea } from '@/api/factoryModel/index';
-  import { component } from 'vue-fullscreen';
+    deviceAlarmTrend,
+    comprehensiveData,
+    waterCoalTrend,
+    wasteTrend,
+    listFactoryLine
+  } from '@/api/pcsData/index.js';
 
-  import {
-    GridComponent,
-    TooltipComponent,
-    LegendComponent
-  } from 'echarts/components';
-  use([
-    CanvasRenderer,
-    BarChart,
-    GridComponent,
-    TooltipComponent,
-    LegendComponent
-  ]);
   export default {
-    // name: 'Home',
-    components: { MapDemo, VChart, Drawer, VueFullscreen: component },
-    mixins: [echartsMixin(['barRef'])],
+    name: 'PcsDataDashboard',
+    components: {
+      VueFullscreen: component
+    },
     data() {
       return {
-        timer: null,
-        deviceObserver: null,
-        stationObserver: null,
-        alarmObserver: null,
         isFullscreen: false,
-        dateType: 2,
-        stationId: 1,
-        businessStatus,
-        statistics: {
-          accumulatedPending: null,
-          createTime: null,
-          createUserId: null,
-          cumulativelyCompleted: null,
-          cumulativelyProcessed: null,
-          inspectionDueToday: null,
-          pendingCumulative: null,
-          productLineCount: null,
-          toDoToday: null,
-          totalCoal: null,
-          totalCoalGas: null,
-          totalElectricity: null,
-          totalGasInjection: null,
-          totalWater: null,
-          warningHandlingTotal: null,
-          warningPatrolTotal: null
-        },
-        deviceList: [],
-        deviceMaxHeight: 0,
-        stationList: [],
-        stationMaxHeight: 0,
-        alarmList: [],
-        alarmMaxHeight: 0,
-        mapHeight: 0,
-        barOption: {},
-        productLineList: []
+        isFlag: false,
+        date: '',
+        time: '',
+        week: '',
+        selectedValue: '',
+        selectOptions: [],
+        comprehensiveList: [],
+        boilerData: [
+          {
+            title: '锅炉运行参数',
+            params: []
+          },
+          {
+            title: '注气检查记录',
+            params: []
+          },
+          {
+            title: '蒸汽质量检查记录',
+            params: []
+          }
+        ],
+        alertStatsData: [],
+        alertLegend: [
+          { name: '一般告警', percent: 45.2, color: '#3b82f6' },
+          { name: '警告告警', percent: 35.3, color: '#f59e0b' },
+          { name: '严重告警', percent: 4.7, color: '#ef4444', value: 58 },
+          { name: '紧急告警', percent: 15.2, color: '#ef4444' }
+        ],
+        alertConfig: {},
+        unitValue: '',
+        unitOptions: [
+          { label: '1#机组', value: '1' },
+          { label: '2#机组', value: '2' },
+          { label: '3#机组', value: '3' },
+          { label: '4#机组', value: '4' }
+        ],
+        energyTabs: [
+          { label: '水', value: '1' },
+          { label: '煤', value: '2' }
+        ],
+        activeEnergyTab: '1',
+        charts: {},
+        stationId: ''
       };
     },
-    created() {},
     watch: {
-      isFullscreen() {
-        setTimeout(() => {
-          this.getMaxHeigth();
-          this.resizeAllCharts();
-        }, 300);
+      isFullscreen: {
+        handler() {
+          this.handleResize();
+        },
+        immediate: true
       }
     },
-    mounted() {
-      setTimeout(() => {
-        this.$refs.barRef.resize();
-        this.getMaxHeigth();
-      }, 300);
-      getFactoryarea({
+    created() {
+      this.init();
+      listFactoryLine({
         pageNum: 1,
         size: 999,
         type: 4
       }).then((res) => {
-        console.log(res, 'res');
-        this.productLineList = [{ id: 1, name: '全部' }, ...res.list];
+        this.selectOptions = res.list.map((item) => {
+          return {
+            label: item.name,
+            value: item.id
+          };
+        });
+        console.log(res);
       });
-      this.init();
-      this.timer = setInterval(() => {
-        this.init();
-      }, 3600000);
+    },
+    mounted() {
+      this.updateTimer = setInterval(this.updateTime, 1000);
 
-      window.addEventListener('resize', this.getMaxHeigth);
+      window.addEventListener('resize', this.handleResize);
+      // 初始化时同步头部宽度
+      this.$nextTick(() => {
+        this.syncHeaderWidth();
+      });
     },
     beforeDestroy() {
-      window.removeEventListener('resize', this.getMaxHeigth);
-      clearInterval(this.timer);
-      this.disconnectObservers();
+      clearInterval(this.updateTimer);
+      window.removeEventListener('resize', this.handleResize);
+      Object.values(this.charts).forEach((chart) => chart && chart.dispose());
     },
     methods: {
-      barOptionFn(data, dataY) {
-        return {
+      energyTabsCahnge(val) {
+        this.activeEnergyTab = val;
+        this.waterCoalTrend();
+      },
+
+      init() {
+        this.alarmOverview();
+        this.queryAlarmList();
+        this.deviceAlarmTrend();
+        this.waterCoalTrend();
+        this.wasteTrend();
+        this.comprehensiveData();
+      },
+      //告警数据概览
+      alarmOverview() {
+        alarmOverview({
+          stationId: this.stationId
+        }).then((res) => {
+          this.$nextTick(() => {
+            this.initAlertPieChart(res);
+          });
+        });
+      },
+      //设备告警趋势图
+      deviceAlarmTrend() {
+        deviceAlarmTrend({ stationId: this.stationId }).then((res) => {
+          this.$nextTick(() => {
+            this.initAlertTrendChart(res);
+          });
+        });
+      },
+      //综合数据
+      comprehensiveData() {
+        comprehensiveData({ stationId: this.stationId }).then((res) => {
+          this.comprehensiveList = [
+            { label: '年度总注气量(M³)', value: res.yearTotalGasInjection },
+            { label: '年度总水量(T)', value: res.yearTotalWater },
+            { label: '年度用煤总量(T)', value: res.yearTotalCoal },
+            { label: '年度固废量(T)', value: res.yearTotalWaste },
+            { label: '本月注气量(M³)', value: res.monthTotalGasInjection },
+            { label: '本月水量(T)', value: res.monthTotalWater },
+            { label: '本月用煤量(T)', value: res.monthTotalCoal },
+            { label: '本月固废量(T)', value: res.monthTotalWaste }
+          ];
+          this.$set(
+            this.boilerData[0],
+            'params',
+            this.getParams(res['dailyReportOnBoilerOperation'] || {})
+          );
+          this.$set(
+            this.boilerData[0],
+            'params',
+            this.getParams(res['gasInjectionInspectionRecord'] || {})
+          );
+          this.$set(
+            this.boilerData[0],
+            'params',
+            this.getParams(res['steamQualityInspectionRecord'] || {})
+          );
+        });
+      },
+      getParams(data = {}) {
+        let list = [
+          { name: '报工人:', value: data?.executeUsers?.userName },
+          { name: '报工时间:', value: data.checkFinishTime }
+        ];
+        data.detailList?.forEach((item) => {
+          list.push({
+            name: item.paramValue,
+            value: item.num,
+            unit: item.unitName
+          });
+        });
+        return list;
+      },
+      //用煤用水
+      waterCoalTrend() {
+        waterCoalTrend({
+          trendType: this.activeEnergyTab,
+          stationId: this.stationId
+        }).then((res) => {
+          this.$nextTick(() => {
+            this.initWaterChart(res);
+          });
+        });
+      },
+      //固废趋势图
+      wasteTrend() {
+        wasteTrend({ stationId: this.stationId }).then((res) => {
+          this.$nextTick(() => {
+            this.initReturnChart(res);
+          });
+        });
+      },
+      //告警列表
+      queryAlarmList() {
+        let dataKey = [
+          'name',
+          'deviceLocation',
+          'alertLevel',
+          'ruleName',
+          'alarmTime',
+          'handleStatus'
+        ];
+
+        queryAlarmList({ stationId: this.stationId }).then((res) => {
+          let dataArr = [];
+          res.forEach((item, index) => {
+            let data = [index + 1];
+            dataKey.forEach((key, index) => {
+              if (key == 'alertLevel') {
+                item[key] =
+                  item[key] == 1
+                    ? '紧急'
+                    : item[key] == 2
+                    ? '严重'
+                    : item[key] == 3
+                    ? '一般'
+                    : '告警';
+              }
+              if (key == 'handleStatus') {
+                item[key] =
+                  item[key] == 1
+                    ? '处理中'
+                    : item[key] == 2
+                    ? '已处理'
+                    : '未处理';
+              }
+              data.push(item[key]);
+            });
+            dataArr.push(data);
+          });
+          this.alertConfig = {
+            header: [
+              '序号',
+              '设备名称',
+              '设备位置',
+              '告警级别',
+              '告警内容描述',
+              '告警时间',
+              '处理状态'
+            ].map(
+              (item) =>
+                `<div style="color: #38fdf8;font-weight: bold">${item}</div>`
+            ),
+
+            data: dataArr.map((data) =>
+              data.map((item, index) => {
+                return `<div style="color: ${
+                  index == 3 ? this.getClolr(item) : '#fff'
+                };">${item}</div>`;
+              })
+            ),
+            rowNum: 4,
+            headerBGC: 'transparent',
+            oddRowBGC: 'rgba(13, 41, 96, 0.3)',
+            evenRowBGC: 'rgba(13, 41, 96, 0.1)',
+            headerHeight: 30,
+            waitTime: 3000,
+            align: [
+              'center',
+              'center',
+              'center',
+              'center',
+              'center',
+              'center',
+              'center'
+            ],
+            columnWidth: []
+          };
+        });
+      },
+
+      onFullscreen() {
+        this.isFullscreen = !this.isFullscreen;
+      },
+      getClolr(item) {
+        return item == '严重'
+          ? '#FF0000'
+          : item == '紧急'
+          ? '#FF7070'
+          : item == '警告'
+          ? '#FFD337'
+          : '#fff';
+      },
+      updateTime() {
+        const now = new Date();
+        const hours = now.getHours().toString().padStart(2, '0');
+        const minutes = now.getMinutes().toString().padStart(2, '0');
+        const seconds = now.getSeconds().toString().padStart(2, '0');
+        this.time = `${hours}:${minutes}:${seconds}`;
+
+        const year = now.getFullYear();
+        const month = (now.getMonth() + 1).toString().padStart(2, '0');
+        const day = now.getDate().toString().padStart(2, '0');
+        this.date = `${year}-${month}-${day}`;
+      },
+      syncHeaderWidth() {
+        this.$nextTick(() => {
+          const threeColumnLayout = document.querySelector(
+            '.two-column-layout'
+          );
+          const headerSection = document.querySelector('.header-section');
+          if (threeColumnLayout && headerSection) {
+            const layoutWidth = threeColumnLayout.scrollWidth;
+            headerSection.style.width = layoutWidth + 'px';
+          }
+        });
+      },
+      handleResize() {
+        this.$nextTick(() => {
+          // 同步头部宽度
+          this.syncHeaderWidth();
+
+          const { clientWidth, clientHeight } = document.documentElement;
+          const containers = document.getElementsByClassName('box-container');
+          Array.from(containers).forEach((item) => {
+            if (this.isFullscreen) {
+              item.style.height = clientHeight + 'px';
+              item.style.width = clientWidth + 'px';
+            } else {
+              item.style.height = clientHeight - 100 + 'px';
+              item.style.width = clientWidth - 240 + 'px';
+            }
+          });
+          Object.values(this.charts).forEach(
+            (chart) => chart && chart.resize()
+          );
+        });
+      },
+
+      initWaterChart(res) {
+        if (!this.$refs.waterChart) return;
+        console.log(res);
+
+        const chart = echarts.init(this.$refs.waterChart);
+        const option = {
           tooltip: {
-            // formatter: (item) => {
-            //   return item.name + ':' + item.seriesName + ' ' + item.value;
-            // },
-            trigger: 'item'
-          },
-          legend: { show: false },
-          grid: {
-            left: 100,
-            right: 55
-            // bottom: '13%' //也可设置left和right设置距离来控制图表的大小
+            trigger: 'axis',
+            backgroundColor: '#fff',
+            borderColor: '#e0e0e0',
+            borderWidth: 1,
+            textStyle: {
+              color: '#333'
+            },
+            axisPointer: {
+              type: 'line',
+              lineStyle: {
+                color: 'rgba(255, 255, 255, 0.5)'
+              }
+            }
           },
-          color: ['#1890ff'],
+          grid: { top: 30, right: 20, bottom: 30, left: 50 },
           xAxis: {
-            max: 'dataMax',
-            axisLine: {
-              show: false,
+            type: 'category',
+            data: res.map((item) => item.time),
+            axisLine: { lineStyle: { color: '#4a6fa5' } },
+            axisLabel: { color: '#8ba3c7' }
+          },
+          yAxis: {
+            type: 'value',
+            axisLine: { lineStyle: { color: '#4a6fa5' } },
+            axisLabel: { color: '#8ba3c7' },
+            splitLine: { lineStyle: { color: 'rgba(74, 111, 165, 0.2)' } }
+          },
+          series: [
+            {
+              data: res.map((item) => item.value),
+              type: 'line',
+              smooth: true,
+              areaStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: 'rgba(59, 130, 246, 0.5)' },
+                  { offset: 1, color: 'rgba(59, 130, 246, 0.05)' }
+                ])
+              },
+              lineStyle: { color: '#3b82f6', width: 2 },
+              itemStyle: { color: '#3b82f6' }
+            }
+          ]
+        };
+        chart.setOption(option);
+        this.charts.water = chart;
+      },
+      initReturnChart(res) {
+        if (!this.$refs.returnChart) return;
+        const chart = echarts.init(this.$refs.returnChart);
+        const option = {
+          tooltip: {
+            trigger: 'axis',
+            backgroundColor: '#fff',
+            borderColor: '#e0e0e0',
+            borderWidth: 1,
+            textStyle: {
+              color: '#333'
+            },
+            axisPointer: {
+              type: 'line',
               lineStyle: {
-                color: '#fff'
+                color: 'rgba(255, 255, 255, 0.5)'
               }
-            },
-            nameTextStyle: {
-              align: 'center',
-              color: '#fff',
-              fontSize: 50,
-              padding: [0, 20, -3, 0]
             }
           },
-          yAxis: [
+          grid: { top: 30, right: 20, bottom: 30, left: 50 },
+          xAxis: {
+            type: 'category',
+            data: res.map((item) => item.time),
+            axisLine: { lineStyle: { color: '#4a6fa5' } },
+            axisLabel: { color: '#8ba3c7' }
+          },
+          yAxis: {
+            type: 'value',
+            axisLine: { lineStyle: { color: '#4a6fa5' } },
+            axisLabel: { color: '#8ba3c7' },
+            splitLine: { lineStyle: { color: 'rgba(74, 111, 165, 0.2)' } }
+          },
+          series: [
+            {
+              data: res.map((item) => item.value),
+              type: 'line',
+              smooth: true,
+              areaStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: 'rgba(59, 130, 246, 0.5)' },
+                  { offset: 1, color: 'rgba(59, 130, 246, 0.05)' }
+                ])
+              },
+              lineStyle: { color: '#3b82f6', width: 2 },
+              itemStyle: { color: '#3b82f6' }
+            }
+          ]
+        };
+        chart.setOption(option);
+        this.charts.return = chart;
+      },
+      initAlertPieChart(res) {
+        this.alertStatsData = [
+          {
+            label: '系统告警总数',
+            value: res.yearTotalCount,
+            icon: 'el-icon-_alert'
+          },
+          {
+            label: '本月告警数',
+            value: res.monthTotalCount,
+            icon: 'el-icon-_month'
+          },
+          {
+            label: '本年已处理数',
+            value: res.yearHandledCount,
+            icon: 'el-icon-_check'
+          },
+          {
+            label: '本月已处理数',
+            value: res.monthHandledCount,
+            icon: 'el-icon-_check'
+          },
+          {
+            label: '年度未处理数',
+            value: res.yearUnhandledCount,
+            icon: 'el-icon-_warning'
+          },
+          {
+            label: '本月未处理数',
+            value: res.monthUnhandledCount,
+            icon: 'el-icon-_warning'
+          }
+        ];
+        if (!this.$refs.alertPieChart) return;
+        const chart = echarts.init(this.$refs.alertPieChart);
+
+        // 计算总数
+        const total =
+          res?.levelStats?.reduce((sum, item) => sum + item.count, 0) || 1247;
+
+        const option = {
+          tooltip: {
+            trigger: 'item',
+            formatter: '{b}: {c} ({d}%)'
+          },
+          series: [
             {
-              type: 'category',
-              data: dataY,
-              axisLine: {
+              type: 'pie',
+              radius: ['45%', '65%'],
+              center: ['50%', '50%'],
+              avoidLabelOverlap: true,
+              itemStyle: {
+                borderRadius: 4,
+                borderColor: '#0d1f4a',
+                borderWidth: 2
+              },
+              data: res?.levelStats?.map((item) => {
+                return {
+                  value: item.count,
+                  name: item.levelName,
+                  itemStyle: {
+                    color:
+                      item.level == 1
+                        ? '#ef4444'
+                        : item.level == 2
+                        ? '#dc2626'
+                        : item.level == 3
+                        ? '#3b82f6'
+                        : '#f59e0b'
+                  }
+                };
+              }) || [
+                {
+                  value: 564,
+                  name: '一般告警',
+                  itemStyle: { color: '#3b82f6' }
+                },
+                {
+                  value: 440,
+                  name: '警告告警',
+                  itemStyle: { color: '#f59e0b' }
+                },
+                {
+                  value: 58,
+                  name: '严重告警',
+                  itemStyle: { color: '#dc2626' }
+                },
+                {
+                  value: 185,
+                  name: '紧急告警',
+                  itemStyle: { color: '#ef4444' }
+                }
+              ],
+              label: {
+                show: true,
+                position: 'outside',
+                formatter: '{per|{d}%}\n{name|{b}}',
+                rich: {
+                  per: {
+                    fontSize: 14,
+                    fontWeight: 'bold',
+                    color: '#fff',
+                    padding: [0, 0, 4, 0]
+                  },
+                  name: {
+                    fontSize: 12,
+                    color: '#8ba3c7'
+                  }
+                }
+              },
+              labelLine: {
+                show: true,
+                length: 10,
+                length2: 10,
                 lineStyle: {
-                  color: '#fff'
+                  color: 'rgba(138, 163, 199, 0.5)'
                 }
               },
-              nameTextStyle: {
-                align: 'center',
-                color: '#fff',
-                fontSize: 50,
-                padding: [0, 20, -3, 0]
+              emphasis: {
+                scale: true,
+                scaleSize: 5,
+                label: {
+                  show: true,
+                  fontWeight: 'bold'
+                }
               }
             }
           ],
-          series: {
-            type: 'bar',
-            data
-          }
+          graphic: [
+            {
+              type: 'text',
+              left: 'center',
+              top: '45%',
+              style: {
+                text: String(total),
+                textAlign: 'center',
+                fill: '#fff',
+                fontSize: 24,
+                fontWeight: 'bold'
+              }
+            },
+            {
+              type: 'text',
+              left: 'center',
+              top: '60%',
+              style: {
+                text: '告警总数',
+                textAlign: 'center',
+                fill: '#8ba3c7',
+                fontSize: 11
+              }
+            }
+          ]
         };
+        chart.setOption(option);
+        this.charts.alertPie = chart;
       },
-      dateTypeChange() {
-        this.init();
-      },
-      disconnectObservers() {
-        if (this.deviceObserver) {
-          this.deviceObserver.disconnect();
-          this.deviceObserver = null;
-        }
-        if (this.stationObserver) {
-          this.stationObserver.disconnect();
-          this.stationObserver = null;
-        }
-        if (this.alarmObserver) {
-          this.alarmObserver.disconnect();
-          this.alarmObserver = null;
-        }
-      },
-      initResizeObservers() {
-        this.disconnectObservers();
-
-        const createObserver = (refName, callback) => {
-          const el = this.$refs[refName];
-          if (!el) return null;
-
-          const observer = new ResizeObserver((entries) => {
-            for (const entry of entries) {
-              callback(entry.contentRect.height);
+      initAlertTrendChart(res) {
+        if (!this.$refs.alertTrendChart) return;
+        const chart = echarts.init(this.$refs.alertTrendChart);
+        const option = {
+          tooltip: {
+            trigger: 'axis',
+            backgroundColor: '#fff',
+            borderColor: '#e0e0e0',
+            borderWidth: 1,
+            textStyle: {
+              color: '#333'
+            },
+            axisPointer: {
+              type: 'line',
+              lineStyle: {
+                color: 'rgba(255, 255, 255, 0.5)'
+              }
             }
-          });
-          observer.observe(el);
-          return observer;
+          },
+          grid: { top: 30, right: 20, bottom: 30, left: 50 },
+          xAxis: {
+            type: 'category',
+            data: res.map((item) => item.time),
+            axisLine: { lineStyle: { color: '#4a6fa5' } },
+            axisLabel: { color: '#8ba3c7' }
+          },
+          yAxis: {
+            type: 'value',
+            axisLine: { lineStyle: { color: '#4a6fa5' } },
+            axisLabel: { color: '#8ba3c7' },
+            splitLine: { lineStyle: { color: 'rgba(74, 111, 165, 0.2)' } }
+          },
+          series: [
+            {
+              data: res.map((item) => item.value),
+              type: 'line',
+              smooth: true,
+              areaStyle: {
+                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+                  { offset: 0, color: 'rgba(59, 130, 246, 0.5)' },
+                  { offset: 1, color: 'rgba(59, 130, 246, 0.05)' }
+                ])
+              },
+              lineStyle: { color: '#3b82f6', width: 2 },
+              itemStyle: { color: '#3b82f6' }
+            }
+          ]
         };
-
-        this.deviceObserver = createObserver('deviceTableRef', (height) => {
-          this.deviceMaxHeight = height - 10;
-        });
-
-        this.stationObserver = createObserver('stationTableRef', (height) => {
-          this.stationMaxHeight = height - 10;
-        });
-
-        this.alarmObserver = createObserver('alarmListRef', (height) => {
-          this.alarmMaxHeight = height - 10;
-        });
-      },
-      getMaxHeigth() {
-        this.$nextTick(() => {
-          this.initResizeObservers();
-
-          const mapEl = this.$refs.mapBoxRef;
-          if (mapEl) {
-            this.mapHeight = mapEl.clientHeight - 30;
-          }
-        });
-      },
-      toggleFullscreen() {
-        this.isFullscreen = !this.isFullscreen;
-      },
-      init() {
-        queryComprehensiveStatisticsAndWarningStatistics({
-          dateType: this.dateType,
-          stationId: this.stationId == 1 ? null : this.stationId
-        }).then((res) => {
-          this.statistics = res;
-        });
-        queryDeviceList({
-          dateType: this.dateType,
-          stationId: this.stationId == 1 ? null : this.stationId
-        }).then((res) => {
-          this.deviceList = res;
-        });
-        queryStationList({
-          dateType: this.dateType,
-          stationId: this.stationId == 1 ? null : this.stationId
-        }).then((res) => {
-          this.stationList = res;
-        });
-        queryAlarmList({
-          dateType: this.dateType,
-          stationId: this.stationId == 1 ? null : this.stationId
-        }).then((res) => {
-          this.alarmList = res;
-        });
-        queryOnDutyPersonnel({
-          dateType: this.dateType,
-          stationId: this.stationId == 1 ? null : this.stationId
-        }).then((res) => {
-          this.barOption = this.barOptionFn(
-            res.map((item) => item.value),
-            res.map((item) => item.name)
-          );
-        });
-      },
-      rowClass({ rowIndex, columnIndex }) {
-        console.log(rowIndex, 'rowIndex');
-        // table表头颜色设置
-        if (rowIndex === 0) {
-          return { background: 'transparent !important', color: '#38FFF9' };
-        }
+        chart.setOption(option);
+        this.charts.alertTrend = chart;
       }
     }
   };
 </script>
+
 <style lang="scss" scoped>
-  .page {
-    width: 100%;
-    height: calc(100vh - 96px);
-    background-image: url('../../assets/imgs/side/bgc.png');
-    background-size: 100% 100%;
-    overflow: auto;
-  }
-  .top_box {
-    position: relative;
-    width: 100%;
-    height: 75px;
-    background-image: url('../../assets/imgs/side/top.png');
-    background-size: 100% 100%;
-    .title {
-      position: absolute;
-      top: 0;
-      left: 0;
-      width: 100%;
-      height: 65px;
-      text-align: center;
-      line-height: 60px;
-      .title_text {
-        font-size: 32px;
-        font-weight: 900;
-        font-family: 'sideTitle';
-        background-image: linear-gradient(to top, #009dff, 15%, #fff);
-        background-clip: text;
-        -webkit-background-clip: text;
-        -webkit-text-fill-color: transparent;
-      }
-    }
-    .top_row {
-      position: absolute;
-      top: 0;
-      left: 0;
-      width: 100%;
-      height: 75px;
-      .col_box {
-        width: 100%;
-        height: 75px;
-      }
-    }
-    .col_left {
-      box-sizing: border-box;
-      padding: 0 6% 0 15px;
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-      .left_name {
-        height: 100%;
-        line-height: 60px;
-        font-size: 28px;
-        // font-weight: 400;
-        color: #fff;
-        font-family: 'BRLNSDB';
-      }
-    }
-    .col_right {
-      box-sizing: border-box;
-      padding: 0 15px 0 4%;
+  .box-container {
+    width: 100vw;
+    height: 100vh;
+
+    .box-header-scroll {
+      height: 80px;
+      background: url('~@/assets/pcs/header.png') no-repeat center top;
+      background-size: 100% 100%;
       display: flex;
       align-items: center;
-      .userName {
-        position: relative;
-        flex: 1;
-        margin-left: 20px;
-        // padding-bottom: 10px;
-        cursor: pointer;
-        .text {
-          text-align: right;
-          font-size: 18px;
-          color: #fff;
-          font-weight: 900;
-          font-family: 'AlibabaPuHuiTi-2-95-ExtraBold';
-          text-overflow: ellipsis;
-          overflow: hidden;
-          word-break: break-all;
-          white-space: nowrap;
-        }
-        .log_out {
-          position: absolute;
-          right: 0;
-          bottom: -55px;
-          width: 96px;
-          height: 46px;
-          line-height: 46px;
-          text-align: center;
-          font-size: 16px;
-          color: #fff;
-          font-weight: 900;
-          background: rgb(34, 156, 152);
-          border-radius: 6px;
-        }
-        .log_out::after {
-          content: '';
-          position: absolute;
-          top: -6px;
-          left: 70%;
-          transform: rotateZ(45deg);
-          width: 15px;
-          height: 15px;
-          background: rgb(34, 156, 152);
-        }
-      }
-      .fullscreen-btn {
+      justify-content: center;
+      padding: 0 20px;
+      position: relative;
+      z-index: 10;
+      min-width: 2200px;
+
+      .logo {
+        // width: 200px;
+        padding-top: 10px;
         position: absolute;
-        right: 15px;
-        width: 36px;
-        height: 36px;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        background: rgba(56, 255, 249, 0.15);
-        border: 1px solid #38fff9;
-        border-radius: 4px;
-        cursor: pointer;
-        transition: all 0.3s ease;
-
-        i {
-          font-size: 18px;
-          color: #38fff9;
-        }
+        left: 80px;
+
+        ::v-deep .custom-select {
+          .el-input__inner {
+            background: #0d2960;
+            border: 1px solid #1a4a8a;
+            color: #fff;
+            height: 36px;
+            line-height: 36px;
 
-        &:hover {
-          background: rgba(56, 255, 249, 0.3);
-          box-shadow: 0 0 10px rgba(56, 255, 249, 0.5);
+            &::placeholder {
+              color: #8ba3c7;
+            }
+          }
+
+          .el-input__suffix {
+            .el-input__icon {
+              color: #8ba3c7;
+            }
+          }
         }
       }
-    }
-    .right_box {
-      position: relative;
-      cursor: pointer;
-      .img {
-        padding-top: 5%;
-        height: 40px;
-        object-fit: cover;
+
+      .title {
+        flex: 1;
+        text-align: center;
+        font-size: 28px;
+        font-weight: bold;
+        color: #fff;
+        text-shadow: 0 0 10px rgba(59, 130, 246, 0.5);
+        letter-spacing: 4px;
       }
-      .content {
+
+      .time {
         position: absolute;
-        top: 0;
-        left: 0;
-        width: 100%;
-        height: 100%;
+        right: 30px;
+        width: 280px;
         display: flex;
         align-items: center;
-        justify-content: center;
-        .back_icon {
-          padding-top: 3px;
-          width: 18px;
-          object-fit: cover;
+        justify-content: flex-end;
+        gap: 15px;
+
+        .time-display {
+          display: flex;
+          flex-direction: column;
+          align-items: flex-end;
+
+          .date-text {
+            font-size: 14px;
+            color: #8ba3c7;
+          }
+
+          .time-text {
+            font-size: 20px;
+            font-weight: bold;
+            color: #fff;
+          }
         }
-        .back_text {
-          margin-left: 8px;
-          padding-top: 3px;
-          color: #fff;
-          font-size: 17px;
-          font-family: 'sideTitle';
+
+        .fullscreen-toggle {
+          cursor: pointer;
+          font-size: 20px;
+          color: #8ba3c7;
+          transition: color 0.3s;
+
+          &:hover {
+            color: #3b82f6;
+          }
         }
-        // background: #ccc;
       }
     }
-  }
-  .page_content {
-    box-sizing: border-box;
-    padding: 0px 10px 10px 10px;
-    flex: 1;
-    display: flex;
-    height: calc(100% - 75px);
-    .left_box,
-    .right_box {
-      display: flex;
-      flex-direction: column;
-      justify-content: space-between;
-      width: 25%;
-      height: 100%;
-      .comprehensive {
-        .header {
-          height: 14%;
-        }
-        width: 100%;
-        height: 27%;
-        min-height: 280px;
-        background-image: url('../../assets/imgs/side/box.png');
-        background-size: 100% 100%;
-        margin-top: 25px;
-      }
-      .work_order {
-        // margin: 3.5% 0;
-        width: 100%;
-        height: 33%;
-        min-height: 330px;
-        margin-top: 25px;
 
-        background-image: url('../../assets/imgs/side/box.png');
-        background-size: 100% 100%;
+    .box-content {
+      height: calc(100%);
+      background: radial-gradient(
+          ellipse at top,
+          rgba(13, 45, 110, 0.3) 0%,
+          transparent 50%
+        ),
+        radial-gradient(
+          ellipse at bottom,
+          rgba(8, 25, 65, 0.5) 0%,
+          transparent 50%
+        ),
+        linear-gradient(180deg, #0a1630 0%, #0d1f4a 50%, #08152e 100%);
+      overflow: auto;
+      font-family: 'Microsoft YaHei', sans-serif;
+      flex: 1;
+      // overflow-x: auto;
+      // overflow-y: hidden;
+
+      &::-webkit-scrollbar {
+        height: 6px;
       }
-      .running_state {
-        width: 100%;
-        height: 33%;
-        min-height: 330px;
-        margin-top: 25px;
 
-        background-image: url('../../assets/imgs/side/box.png');
-        background-size: 100% 100%;
+      &::-webkit-scrollbar-track {
+        background: rgba(12, 32, 70, 0.4);
       }
-      .comprehensive,
-      .work_order,
-      .running_state {
-        display: flex;
-        flex-direction: column;
+
+      &::-webkit-scrollbar-thumb {
+        background: linear-gradient(180deg, #1a4a8a, #0d2a5a);
+        border-radius: 3px;
       }
-      .header {
-        height: 13%;
-        display: flex;
-        align-items: center;
-        img {
-          margin: 0 10px;
-          height: 80%;
-          object-fit: cover;
+
+      .scroll-wrapper {
+        // display: flex;
+        display: inline-block;
+        height: 100%;
+        // flex-direction: column;
+        // gap: 20px;
+        // padding: 0 20px 20px 20px;
+        width: 100%;
+        .header-section {
+          width: auto;
+          flex-shrink: 0;
+          padding-top: 10px;
+          min-width: 100%;
         }
-        .header_text {
-          padding-top: 2px;
-          font-size: 16px;
-          font-family: 'sideTitle';
-          color: #fff;
+
+        .two-column-layout {
+          display: flex;
+          justify-content: space-between;
+          flex: 1;
+          min-height: 850px;
+          height: calc(100% - 130px);
+          min-width: 100%;
+          margin-top: 20px;
+          font-size: 0;
+          background: url('~@/assets/pcs/back.png') no-repeat center top;
+          background-size: 100% 100%;
         }
       }
-      .content_box {
+
+      .left-section,
+      .right-section {
+        display: inline-flex;
+        flex-direction: column;
+        gap: 15px;
         overflow: hidden;
+        height: 100%;
+        font-size: 14px;
+        white-space: normal;
+        min-width: 45%;
         flex: 1;
+        margin-right: 20px;
+
+        &:last-child {
+          margin-right: 0;
+        }
       }
-      .stats_content {
-        display: flex;
-        align-items: center;
-        justify-content: space-around;
-        flex-wrap: wrap;
-        .stats_box {
-          width: 26%;
+
+      .panel {
+        // background: linear-gradient(
+        //   135deg,
+        //   rgba(16, 42, 88, 0.9) 0%,
+        //   rgba(10, 28, 65, 0.85) 100%
+        // );
+        // border: 1px solid rgba(42, 90, 170, 0.4);
+        // border-radius: 8px;
+        padding: 15px;
+        min-height: 0;
+        // box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05),
+        //   0 4px 20px rgba(0, 0, 0, 0.3);
+
+        .panel-title {
+          font-size: 28px;
+          // font-weight: bold;
+          // font-style: italic;
+          font-family: 'YouSheBiaoTiHei', 'Microsoft YaHei', sans-serif;
+          color: #fff;
+          margin-bottom: 15px;
+          height: 42px;
+          padding-left: 40px;
+          position: relative;
           display: flex;
-          flex-direction: column;
           align-items: center;
-        }
-        .stats_icon {
-          box-sizing: border-box;
-          padding-top: 5px;
-          text-align: center;
-          width: 100%;
-          height: 60px;
-          background: url('../../assets/imgs/side/comprehensive_box.png');
-          background-size: cover;
-          .num {
-            font-size: 25px;
-            font-weight: 900;
-            font-family: 'DS-DIGI';
-            color: #38fff9;
+          background: url('~@/assets/pcs/titleb.png') no-repeat center top;
+          background-size: 100% 100%;
+
+          &.energy-title {
+            display: flex;
+            justify-content: space-between;
+            padding-right: 15px;
+
+            .title-left {
+              display: flex;
+              align-items: center;
+              gap: 8px;
+            }
           }
-          .text {
-            margin-left: 2px;
-            font-size: 8px;
-            color: #38fff9;
+          .panel-icon {
+            position: absolute;
+            left: 15px;
+            width: 20px;
+            height: 25px;
+            background: url('~@/assets/pcs/titleIcon.png') no-repeat center top;
+            background-size: 100% 100%;
           }
         }
-        .stats_text {
-          margin-top: 15px;
-          font-size: 14px;
-          color: #fff;
-          font-family: 'AlibabaPuHuiTi-2-95-ExtraBold';
+        .energy-tabs {
+          position: absolute;
+          top: 65px;
+          right: 40px;
+          z-index: 999;
+          display: flex;
+          gap: 0;
+          background: rgba(13, 41, 96, 0.5);
+          border-radius: 4px;
+          padding: 2px;
+
+          .tab-item {
+            padding: 4px 12px;
+            font-size: 12px;
+            color: #8ba3c7;
+            cursor: pointer;
+            border-radius: 3px;
+            transition: all 0.3s;
+
+            &:hover {
+              color: #fff;
+            }
+
+            &.active {
+              background: linear-gradient(135deg, #3b82f6, #1a6fd9);
+              color: #fff;
+            }
+          }
         }
       }
-      .warning_stats_box {
-        box-sizing: border-box;
-        padding: 22px 10px 18px 10px;
+
+      .data-panel {
+        min-height: 220px;
+        flex-shrink: 0;
         display: flex;
-        align-items: center;
-        .warning_stats_left,
-        .warning_stats_right {
-          flex: 1;
-        }
-        .warning_stats_right {
-          margin-left: 30px;
+        flex-direction: column;
+        flex: 0.7;
+
+        .panel-title {
+          flex-shrink: 0;
         }
-        .title_top {
-          margin-bottom: 18px;
+
+        .data-grid {
           display: flex;
+
+          gap: 12px;
+          // padding: 10px 0;
           align-items: center;
           justify-content: space-between;
-          .text {
-            font-size: 16px;
-            color: #dbfaff;
-            font-family: 'sideTitle';
-          }
-          .img {
-            width: 16px;
-            object-fit: cover;
-          }
-        }
-        .warning_line {
-          display: flex;
           flex-wrap: wrap;
-          justify-content: space-between;
-          .warning_box {
-            box-sizing: border-box;
-            padding: 10px 0;
-            width: 45%;
-            height: calc(5.9vh);
-            min-height: 63px;
-            margin-bottom: 18px;
+          overflow: hidden;
+          height: 100%;
+
+          .data-item {
+            // background: linear-gradient(
+            //   135deg,
+            //   rgba(20, 50, 105, 0.9) 0%,
+            //   rgba(14, 38, 82, 0.85) 100%
+            // );
+            // border: 1px solid rgba(45, 95, 180, 0.5);
+            .img {
+              width: 35px;
+              height: 35px;
+              background: url('~@/assets/pcs/icon.png') no-repeat center top;
+              background-size: 100% 100%;
+            }
+            border-radius: 6px;
             display: flex;
-            flex-direction: column;
-            justify-content: space-around;
+            .data-item_value {
+              display: flex;
+              flex-direction: column;
+              // align-items: center;
+            }
+            // flex-direction: column;
             align-items: center;
-            background: url('../../assets/imgs/side/warning2.png');
+            // justify-content: center;
+            padding-left: 15px;
+            gap: 8px;
+            position: relative;
+            overflow: hidden;
+            width: 21%;
+            height: 60px;
+            background: url('~@/assets/pcs/leftItem.png') no-repeat center top;
             background-size: 100% 100%;
-            .num {
-              font-size: 24px;
-              font-family: 'DS-DIGI';
-              color: #38fff9;
+
+            // &::before {
+            //   content: '';
+            //   position: absolute;
+            //   top: 0;
+            //   left: 0;
+            //   right: 0;
+            //   height: 2px;
+            //   background: linear-gradient(
+            //     90deg,
+            //     transparent,
+            //     #00d4ff,
+            //     transparent
+            //   );
+            //   box-shadow: 0 0 8px rgba(0, 212, 255, 0.6);
+            // }
+
+            .data-label {
+              font-size: 12px;
+              color: #8ba3c7;
+              text-align: center;
+              line-height: 1.3;
             }
-            .text {
-              font-size: 10px;
-              color: #fff;
+
+            .data-value {
+              font-size: 18px;
+              font-weight: bold;
+              color: #b6ceff;
+              text-shadow: 0 0 10px rgba(0, 212, 255, 0.5);
             }
           }
-          .warning_bgc {
-            background: url('../../assets/imgs/side/warning1.png');
-            background-size: 100% 100%;
-          }
         }
       }
-      .monitoring_box {
-        box-sizing: border-box;
-        padding: 10px;
+
+      .chart-panel {
+        flex: 1;
+        min-height: 250px;
         display: flex;
         flex-direction: column;
-        .site_box {
-          margin-top: 10px;
+
+        .chart-container {
           width: 100%;
           flex: 1;
-          background-image: url('../../assets/imgs/side/site.png');
-          background-size: 100% 100%;
+          min-height: 0;
         }
-        // .img {
-        // 	width: 100%;
-        // 	height: 100%;
-        // }
       }
-    }
-    .center_box {
-      box-sizing: border-box;
-      padding: 0 30px;
-      width: 50%;
-      display: flex;
-      flex-direction: column;
-      .map_box {
-        min-height: 650px;
-        position: relative;
-        flex: 1;
-        overflow: hidden;
-        // display: flex;
-        // align-items: center;
-        // justify-content: center;
-        // background: #ccc;
-        // .back_bottom {
-        //   position: absolute;
-        //   top: 30px;
-        //   left: 30px;
-        //   z-index: 999;
-        //   width: 90px;
-        //   height: 30px;
-        //   text-align: center;
-        //   line-height: 30px;
-        //   color: #fff;
-        //   font-size: 13px;
-        //   font-weight: 700;
-        //   border-radius: 10px;
-        //   background: #0db233;
-        //   cursor: pointer;
-        // }
+      .param-card3 {
+        right: 10px;
       }
-      .lessee_box {
+      .param-card2 {
+        left: 30%;
+      }
+      .param-card {
+        width: 23%;
+        top: 50px;
+
+        position: absolute;
+        background: rgba(39, 88, 233, 0.1);
+        border: 1px solid #3373d4;
+        border-radius: 8px;
+
+        &::before {
+          content: '';
+          position: absolute;
+          top: 0;
+          left: 0;
+          right: 0;
+          height: 2px;
+          background: linear-gradient(90deg, transparent, #00d4ff, transparent);
+          box-shadow: 0 0 8px rgba(0, 212, 255, 0.5);
+        }
+
+        .param-title {
+          font-size: 14px;
+          font-weight: bold;
+          color: #fff;
+          padding-bottom: 12px;
+          padding-top: 12px;
+          text-align: center;
+          text-shadow: 0 0 10px rgba(0, 212, 255, 0.3);
+          border-bottom: 1px solid rgba(0, 212, 255, 0.5);
+          background: rgba(39, 88, 233, 0.1);
+        }
+
+        .param-list {
+          padding: 15px;
+
+          display: flex;
+          flex-direction: column;
+          gap: 10px;
+
+          .param-item {
+            display: flex;
+            justify-content: space-between;
+            font-size: 12px;
+            padding: 4px 0;
+            // border-bottom: 1px dashed rgba(138, 163, 199, 0.2);
+
+            &:last-child {
+              border-bottom: none;
+            }
+
+            .param-name {
+              color: #8ba3c7;
+            }
+
+            .param-value {
+              color: #fff;
+              font-weight: 500;
+            }
+          }
+        }
+      }
+
+      .pipeline-container {
+        flex: 1;
+        min-height: 0;
+        position: absolute;
+        bottom: 15px;
+        left: 0;
+        height: 60%;
         width: 100%;
-        height: 30%;
+        // background: linear-gradient(
+        //   135deg,
+        //   rgba(14, 40, 85, 0.6) 0%,
+        //   rgba(10, 28, 60, 0.5) 100%
+        // );
+        // border: 1px solid rgba(45, 95, 180, 0.3);
+        // border-radius: 8px;
+        background: url('~@/assets/pcs/home.png') no-repeat center top;
+        background-size: 100% 100%;
+        // max-height: 680px;
+      }
+
+      .alert-panel {
+        min-height: 220px;
+        flex-shrink: 0;
         display: flex;
         flex-direction: column;
-        background-image: url('../../assets/imgs/side/box.png');
-        background-size: 100% 100%;
-        min-height: 300px;
-        .header {
-          height: 15%;
+        flex: 0.7;
+
+        .panel-title {
+          flex-shrink: 0;
+        }
+
+        .alert-stats {
+          flex: 1;
+          min-height: 0;
           display: flex;
           align-items: center;
-          img {
-            margin: 0 15px 0 20px;
-            height: 70%;
-            object-fit: cover;
+          height: calc(100% - 35px);
+          gap: 20px;
+
+          // 左侧数据卡片区域
+          .alert-cards {
+            width: 50%;
+            height: 100%;
+            display: grid;
+            grid-template-columns: repeat(2, 1fr);
+            grid-template-rows: repeat(3, 1fr);
+            gap: 12px;
+
+            .alert-card-item {
+              // background: linear-gradient(
+              //   135deg,
+              //   rgba(20, 50, 105, 0.9) 0%,
+              //   rgba(14, 38, 82, 0.85) 100%
+              // );
+              // border: 1px solid rgba(45, 95, 180, 0.5);
+              .img {
+                width: 35px;
+                height: 35px;
+                background: url('~@/assets/pcs/icon.png') no-repeat center top;
+                background-size: 100% 100%;
+              }
+              border-radius: 6px;
+              display: flex;
+              .data-item_value {
+                display: flex;
+                flex-direction: column;
+                // align-items: center;
+              }
+              // flex-direction: column;
+              align-items: center;
+              // justify-content: center;
+              padding-left: 15px;
+              gap: 8px;
+              position: relative;
+              overflow: hidden;
+              height: 60px;
+              background: url('~@/assets/pcs/leftItem.png') no-repeat center top;
+              background-size: 100% 100%;
+
+              // &::before {
+              //   content: '';
+              //   position: absolute;
+              //   top: 0;
+              //   left: 0;
+              //   right: 0;
+              //   height: 2px;
+              //   background: linear-gradient(
+              //     90deg,
+              //     transparent,
+              //     #00d4ff,
+              //     transparent
+              //   );
+              //   box-shadow: 0 0 8px rgba(0, 212, 255, 0.6);
+              // }
+
+              .data-label {
+                font-size: 12px;
+                color: #8ba3c7;
+                text-align: center;
+                line-height: 1.3;
+              }
+
+              .data-value {
+                font-size: 18px;
+                font-weight: bold;
+                color: #b6ceff;
+                text-shadow: 0 0 10px rgba(0, 212, 255, 0.5);
+              }
+            }
           }
-          .header_text {
-            padding-top: 2px;
-            font-size: 15px;
-            font-family: 'sideTitle';
-            color: #fff;
+
+          // 右侧环形图区域
+          .alert-pie-chart {
+            width: 50%;
+            height: 100%;
+            position: relative;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+
+            .alert-pie {
+              width: 100%;
+              height: 100%;
+              min-height: 180px;
+            }
           }
         }
-        .content_box {
+      }
+
+      .alert-list-panel {
+        flex: 1;
+        min-height: 0;
+        display: flex;
+        flex-direction: column;
+        min-height: 250px;
+
+        .alert-table {
           flex: 1;
-          // background: rgba(255, 255, 255, 0.2);
+          min-height: 0;
+          overflow: hidden;
+
+          .table-header {
+            display: grid;
+            grid-template-columns: 50px 90px 100px 70px 1fr 130px 70px;
+            gap: 6px;
+            padding: 10px 6px;
+            background: linear-gradient(
+              90deg,
+              rgba(16, 45, 95, 0.9) 0%,
+              rgba(12, 35, 75, 0.85) 100%
+            );
+            font-size: 12px;
+            color: #00d4ff;
+            text-align: center;
+            font-weight: 500;
+            border-bottom: 1px solid rgba(45, 95, 180, 0.4);
+          }
         }
       }
     }
-    .right_box {
-      width: 25%;
-    }
-  }
-
-  /************* */
-  /*** */
-  /***修改select选择框样式 */
-  /************* */
-
-  :deep(.el-input__inner) {
-    color: #fff;
-    font-size: 15px;
-    padding-top: 5px;
-    width: 125px;
-    background: transparent;
-    border: none;
-    box-shadow: none;
-    color: #fff;
-  }
-
-  /************* */
-  /*** */
-  /***修改table列表样式 */
-  /************* */
-  :deep(.el-table__row > td) {
-    /* 去除表格线 */
-    border: none;
-  }
-  :deep(.el-table th.is-leaf) {
-    /* 去除上边框 */
-    border: none;
-  }
-  :deep(.el-table),
-  :deep(.el-table__expanded-cell) {
-    background-color: transparent;
-  }
-  :deep(.el-table::before) {
-    background-color: transparent !important;
-  }
-  :deep(.el-table__inner-wrapper) {
-    background-color: transparent !important;
-  }
-  :deep(.el-table tr) {
-    background-color: transparent !important;
-    color: #fff !important;
-  }
-  :deep(.el-table__body tr:hover > td) {
-    background-color: rgba(255, 123, 48, 0.6) !important;
-  }
-  :deep(.el-table) {
-    height: 100% !important;
-  }
-  :deep(.el-table__body-wrapper) {
-    overflow-y: auto !important;
-    height: 100% !important;
   }
 
-  /* 全屏时 header 内容自适应居中 */
-  .fullscreen-active {
-    height: 100vh !important;
-    .header {
-      display: flex !important;
-      align-items: center !important;
-    }
+  [v-cloak] {
+    display: none;
   }
 </style>

+ 263 - 0
src/views/recordComponents/bindSubstanceList.vue

@@ -0,0 +1,263 @@
+<template>
+  <ele-modal
+    :title="title"
+    :visible.sync="visible"
+    :before-close="handleClose"
+    :close-on-click-modal="false"
+    :close-on-press-escape="false"
+    append-to-body
+    width="70%"
+    :maxable="true"
+  >
+    <el-card shadow="never">
+      <ele-split-layout
+        width="266px"
+        allow-collapse
+        :right-style="{ overflow: 'hidden' }"
+      >
+        <div>
+          <div class="ele-border-lighter sys-organization-list">
+            <el-tree
+              :data="treeList"
+              :props="{
+                children: 'children',
+                value: 'id',
+                label: 'name'
+              }"
+              node-key="id"
+              ref="tree"
+              :highlight-current="true"
+              :expand-on-click-node="false"
+              @node-click="handleNodeClick"
+              v-bind="$attrs"
+              :default-expand-all="true"
+            >
+            </el-tree>
+          </div>
+        </div>
+        <template v-slot:content>
+          <ele-pro-table
+            max-height="500px"
+            ref="table"
+            :columns="columns"
+            :datasource="physicalList"
+            @selection-change="handleSelectionChange"
+            row-key="id"
+            :initLoad="false"
+            :needPage="false"
+          >
+          </ele-pro-table>
+        </template>
+      </ele-split-layout>
+    </el-card>
+
+    <div class="rx-sc">
+      <el-button type="primary" size="small" @click="selected">选择</el-button>
+      <el-button size="small" @click="handleClose">关闭</el-button>
+    </div>
+  </ele-modal>
+</template>
+
+<script>
+  import {
+    queryBindSubstanceList,
+    getPhysicalModel
+  } from '@/api/material/list';
+  export default {
+    components: {},
+    props: {
+      // 是否多选
+      multiple: {
+        type: Boolean,
+        default: false
+      }
+    },
+    computed: {
+      seekList() {
+        return [
+          {
+            label: '名称',
+            value: 'name',
+            type: 'input',
+            placeholder: '请输入'
+          }
+        ];
+      },
+      // 表格列配置
+      columns() {
+        const list = [
+          {
+            columnKey: 'selection',
+            type: 'selection',
+            width: 45,
+            align: 'center',
+
+            reserveSelection: true,
+            fixed: 'left'
+          },
+          {
+            columnKey: 'index',
+            type: 'index',
+            label: '序号',
+            width: 55,
+            align: 'center',
+            showOverflowTooltip: true,
+            fixed: 'left'
+          },
+
+          {
+            prop: 'name',
+            label: '名称',
+            showOverflowTooltip: true
+          },
+          {
+            prop: 'identifier',
+            label: '点位',
+            showOverflowTooltip: true,
+            minWidth: 180
+          },
+          {
+            prop: 'dataType.specs.max',
+            label: '最大值',
+            showOverflowTooltip: true,
+            minWidth: 180
+          },
+          {
+            prop: 'dataType.specs.min',
+            label: '最小值',
+            showOverflowTooltip: true,
+            minWidth: 180
+          },
+          {
+            prop: 'dataType.specs.unitName',
+            label: '单位',
+            showOverflowTooltip: true,
+            minWidth: 180
+          }
+        ];
+
+        return list;
+      }
+    },
+    data() {
+      return {
+        visible: false,
+        title: '选择',
+
+        type: null,
+        // 表格选中数据
+        selection: [],
+        physicalList: [],
+        cachingData: {},
+        treeList: [],
+        current: null
+      };
+    },
+
+    watch: {},
+    methods: {
+      /* 表格数据源 */
+      async queryBindSubstanceList(id) {
+        let data = await queryBindSubstanceList({
+          id,
+          pageNum: 1,
+          size: 1000
+        });
+        this.treeList[0].children = data.list;
+      },
+      getPhysicalModel(id) {
+        getPhysicalModel(id).then((res) => {
+          this.physicalList = res.properties;
+          if (this.cachingData[id]) {
+            this.$refs.table.setSelectedRows(this.cachingData[id].list);
+          }
+        });
+      },
+
+      handleNodeClick(data) {
+        // if (data.id == this.treeList[0].id) {
+        //   this.physicalList = [];
+        //   return;
+        // }
+        this.current = data;
+        this.$refs.table.clearSelection();
+        this.getPhysicalModel(data.id);
+      },
+      open(id, name, code) {
+        this.visible = true;
+        if (id) {
+          this.treeList.push({
+            id,
+            name,
+            code,
+            children: []
+          });
+          this.$nextTick(() => {
+            this.queryBindSubstanceList(id);
+          });
+        }
+      },
+
+      handleSelectionChange(data) {
+        this.cachingData[this.current.id] = {
+          substanceCode: this.current.code,
+          substanceId: this.current.id,
+          substanceName: this.current.name,
+          list: data
+        };
+      },
+      handleClose() {
+        this.physicalList = [];
+        this.cachingData = [];
+        this.treeList = [];
+        this.visible = false;
+      },
+      selected() {
+        let cachingData = [];
+        let list = [];
+        for (let key in this.cachingData) {
+          cachingData.push(this.cachingData[key]);
+        }
+
+        if (!cachingData.length) {
+          this.$message.warning('请选择设备点位!');
+          return;
+        }
+        cachingData.forEach((item) => {
+          item.list.forEach((listItem) => {
+            list.push({
+              substanceCode: item.substanceCode,
+              substanceId: item.substanceId,
+              substanceName: item.substanceName,
+              paramCode: listItem.identifier,
+              paramValue: listItem.name,
+              maxValue: listItem.dataType?.specs.max,
+              minValue: listItem.dataType?.specs.min,
+              unitName: listItem.dataType?.specs.unitName
+            });
+          });
+        });
+        this.$emit('bindSubstanceSuccess', list);
+        this.handleClose();
+      }
+    }
+  };
+</script>
+
+<style lang="scss" scoped>
+  .rx-sc {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .ml60 {
+    margin-left: 60px;
+  }
+
+  :deep(.radio) {
+    .el-radio__label {
+      padding: 0;
+    }
+  }
+</style>

+ 143 - 20
src/views/recordComponents/programRulesDialog.vue

@@ -203,6 +203,7 @@
               v-model="addForm.associatedObject"
               size="small"
               style="width: 100%"
+              @change="associatedObjectChange"
             >
               <el-option :value="1" label="车间"></el-option>
               <el-option :value="2" label="设备"></el-option>
@@ -295,6 +296,14 @@
             >
               新建
             </el-button>
+            <el-button
+              type="primary"
+              icon="el-icon-plus"
+              class="ele-btn-icon"
+              @click="bindSubstanceListOpen"
+            >
+              添加物联参数
+            </el-button>
           </div>
         </template>
 
@@ -316,6 +325,7 @@
             placeholder="请选择参数类型"
             size="mini"
             @change="paramTypeChange(row)"
+            :disabled="!!row.paramCode"
           >
             <el-option label="数值" :value="1" />
             <el-option label="选择" :value="2" />
@@ -354,6 +364,7 @@
             placeholder="请输入参数内容"
             size="mini"
             type="textarea"
+            :readonly="!!row.paramCode"
             rows="1"
             autosize
           ></el-input>
@@ -486,6 +497,9 @@
             placeholder="请输入参数上限"
             size="mini"
           ></el-input>
+          <span v-else-if="row.paramType == 7 && row.paramCode">{{
+            row.maxValue
+          }}</span>
         </template>
         <template v-slot:minValue="{ row }">
           <el-input
@@ -494,6 +508,9 @@
             placeholder="请输入参数下限"
             size="mini"
           ></el-input>
+          <span v-else-if="row.paramType == 7 && row.paramCode">{{
+            row.minValue
+          }}</span>
         </template>
         <template v-slot:unitName="{ row }">
           <!-- <el-input
@@ -510,34 +527,33 @@
             size="mini"
           >
           </DictSelection>
+          <span v-else-if="row.paramType == 7 && row.paramCode">{{
+            row.unitName
+          }}</span>
         </template>
-        <template v-slot:toolName="{ row }">
+        <template v-slot:toolName="{ row, $index }">
           <el-link :underline="false" style="cursor: pointer">
             <div class="ele-cell">
-              <div @click="handleAdd(row)">
-                {{
-                  row.tools && row.tools.length > 0
-                    ? row.tools.map((i) => i.toolName).join(',')
-                    : '请选择'
-                }}
+              <div @click="handleAdd(row, $index)">
+                {{ row.substanceName || '请选择' }}
               </div>
               <i
-                v-if="row.tools.length == 0"
+                v-if="!row.substanceName"
                 class="el-icon-arrow-down"
-                @click="handleAdd(row)"
+                @click="handleAdd(row, $index)"
+              ></i>
+              <i
+                v-else
+                class="el-icon-close"
+                @click="clearTool(row, $index)"
               ></i>
-              <i v-else class="el-icon-close" @click="clearTool(row)"></i>
             </div>
           </el-link>
         </template>
         <template v-slot:toolCodes="{ row }">
           <el-input
-            :value="
-              row.tools && row.tools.length > 0
-                ? row.tools.map((i) => i.toolCode).join(',')
-                : ''
-            "
-            placeholder="工具自动带出"
+            :value="row.substanceCode"
+            placeholder="自动带出"
             disabled
             size="mini"
           ></el-input>
@@ -589,6 +605,10 @@
     <toolModal ref="toolModalTowRef" @chooseModal="chooseModalProduct" />
     <MaterialAdd ref="MaterialAddRef" @chooseEquipment="confirmWorkshops" />
     <toolModal ref="toolModalRef" @chooseModal="chooseModal" />
+    <bindSubstanceList
+      ref="bindSubstanceRef"
+      @bindSubstanceSuccess="bindSubstanceSuccess"
+    ></bindSubstanceList>
   </ele-modal>
 </template>
 
@@ -610,7 +630,18 @@
   import toolModal from '@/BIZComponents/toolModal.vue';
   import MaterialAdd from '@/components/common/MaterialAdd.vue';
   import { getteampage } from '@/api/main/index.js';
-
+  import bindSubstanceList from './bindSubstanceList.vue';
+  //设备初始化字段
+  const substanceKey = [
+    'substanceCode',
+    'substanceId',
+    'substanceName',
+    'paramCode',
+    'paramValue',
+    'maxValue',
+    'minValue',
+    'unitName'
+  ];
   const formBaseData = {
     address: '',
     areaId: 0,
@@ -645,7 +676,7 @@
     recordTemplateStyle: null,
     reportWorkType: null,
     executeIdList: [],
-    associatedObject: 1,
+    associatedObject: 2,
     deviceName: '',
     deviceId: '',
     deviceCode: '',
@@ -667,6 +698,7 @@
     components: {
       deptSelect,
       selectReleaseRules,
+      bindSubstanceList,
       selectWorkshop,
       toolModal,
       MaterialAdd
@@ -860,14 +892,14 @@
           },
           {
             prop: 'toolName',
-            label: '工具名称',
+            label: '设备名称',
             align: 'center',
             slot: 'toolName',
             minWidth: 110
           },
           {
             prop: 'toolCodes',
-            label: '工具编码',
+            label: '设备编码',
             align: 'center',
             slot: 'toolCodes',
             minWidth: 110
@@ -965,6 +997,21 @@
 
         console.log('this.addForm', this.addForm);
       },
+      associatedObjectChange() {
+        this.addForm.detailList = [];
+        this.addForm.deviceCode = '';
+        this.addForm.deviceId = '';
+        this.addForm.deviceName = '';
+        this.addForm.workshopId = '';
+        this.addForm.workshopName = '';
+        this.addForm.workshopPlanId = '';
+        this.addForm.workshopPlanName = '';
+        this.addForm.address = '';
+        this.addForm.areaId = '';
+        this.addForm.areaName = '';
+        this.addForm.factoryId = '';
+        this.addForm.factoryName = '';
+      },
       // 关闭时清理表单
       handleClose() {
         this.addForm = JSON.parse(JSON.stringify(formBaseData));
@@ -1106,6 +1153,12 @@
         });
 
         console.log('规则明细数据', data.details);
+        if (data.deviceId) {
+          this.addForm.deviceId = data.deviceId;
+          this.addForm.deviceName = data.deviceName;
+          this.addForm.deviceCode = data.deviceCode;
+          this.addForm.associatedObject = 2;
+        }
 
         this.addForm.ruleId = rules.id;
         this.addForm.ruleName = rules.name;
@@ -1187,6 +1240,76 @@
           row.formula = '';
         }
       },
+
+      handleAdd(row, index) {
+        this.currentRow = row;
+        this.currentIndex = index;
+        this.$refs.bindSubstanceRef.open(
+          this.addForm.deviceId,
+          this.addForm.deviceCode,
+          this.addForm.deviceName
+        );
+      },
+      bindSubstanceListOpen() {
+        this.currentIndex = 9999;
+        this.$refs.bindSubstanceRef.open(
+          this.addForm.deviceId,
+          this.addForm.deviceName,
+          this.addForm.deviceCode
+        );
+      },
+      bindSubstanceSuccess(list) {
+        console.log(list, 'list');
+        const currentIndex = this.currentIndex;
+        list.forEach((item, index) => {
+          if (!index && currentIndex != 9999) {
+            substanceKey.forEach((key) => {
+              this.$set(this.addForm.detailList[currentIndex], key, item[key]);
+            });
+            this.$set(this.addForm.detailList[currentIndex], 'paramType', 7);
+          } else {
+            this.addForm.detailList.push({
+              id: new Date().getTime(),
+              defaultValue: '',
+              maxValue: item.maxValue,
+              minValue: item.minValue,
+              paramType: 7,
+              paramValue: item.paramValue,
+              remark: '',
+              symbol: null,
+              tools: [],
+              unitName: item.unitName,
+              productName: '',
+              productCode: '',
+              paramCode: item.paramCode,
+              substanceId: item.substanceId,
+              substanceCode: item.substanceCode,
+              substanceName: item.substanceName,
+              // 1-成品统计,2-物料统计,3-工序统计"
+              statisticsType:
+                this.addForm.recordTemplateStyle == '4'
+                  ? this.statisticsType
+                  : null,
+              // 公式
+              formula: '',
+              _paramSelect: null,
+              _opSelect: null,
+              _replaceOrAppend: '',
+              formulaParts: [],
+              sortNum:
+                Math.max(
+                  ...this.addForm.detailList.map((item) => item.sortNum || 0)
+                ) + 1
+            });
+          }
+        });
+      },
+      // 清空工具
+      clearTool(row, index) {
+        substanceKey.forEach((key) => {
+          this.$set(this.addForm.detailList[index], key, '');
+        });
+      },
       // 选择物品 产品、物料等
       selectChooseModalProduct(row) {
         this.currentRow = row;

+ 20 - 2
src/views/recordComponents/redeployOther.vue

@@ -292,15 +292,33 @@
         }
 
         this.btnLoading = true;
-
         let params = {
           executeUsers,
           teamName: this.teamName,
           teamId: this.teamId,
           id: this.row.id,
-          // 0个人 1班组
           type: this.tabValue
         };
+        // 0个人 1班组
+
+        if (this.tabValue == 1) {
+          params = {
+            executeUsers: [],
+            teamName: this.teamName,
+            teamId: this.teamId,
+            id: this.row.id,
+            type: this.tabValue
+          };
+        } else {
+          params = {
+            executeUsers,
+            teamName: '',
+            teamId: '',
+            id: this.row.id,
+            type: this.tabValue
+          };
+        }
+
         recordrulesplanReManualDispatchOrder(params)
           .then(() => {
             this.$message.success(`该工单成功转派`);

+ 1 - 1
vue.config.js

@@ -36,7 +36,7 @@ module.exports = {
     proxy: {
       // 当我们的本地的请求 有/api的时候,就会代理我们的请求地址向另外一个服务器发出请求
       '/api': {
-        target: 'http://192.168.1.3:18086', //开发
+        target: 'http://192.168.1.251:18086', //开发
         // target: 'http://192.168.1.251:18186', //测试
         // target: 'http://192.168.1.23:18086',//罗
         // target: 'http://192.168.1.144:18086',//付