董国庆
6 天以前 7e8b61eb1d084d53458affcde0b79b506ac41a93
首页修改
2个文件已修改
552 ■■■■ 已修改文件
src/view/early-warning/index.vue 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/home/index.vue 537 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/view/early-warning/index.vue
@@ -43,6 +43,11 @@
                            <el-option label="将来处理" value="将来处理"></el-option>
                        </el-select>
                    </el-form-item>
                    <el-tabs  v-model="activeName" type="card" @tab-click="handleClick"
                        style="margin-left: 30px;border: none;">
                        <el-tab-pane v-for="(item, index) in options" :key="index" :label="item.name"
                            :name="item.name"></el-tab-pane>
                    </el-tabs>
                </el-form>
            </div>
            <div class="form-right mr--24 mb--22 shrink0">
@@ -94,10 +99,7 @@
            <el-button v-permission="11" class="search-button h--40 w--90 fs--14" icon="el-icon-top" type="primary"
                size="small" @click="exportExc">导出</el-button>
        </div>
        <el-tabs class="mt--23 " v-model="activeName" type="card" @tab-click="handleClick" style="margin-left: 30px;">
            <el-tab-pane v-for="(item, index) in options" :key="index" :label="item.name"
                :name="item.name"></el-tab-pane>
        </el-tabs>
        <div class="table-box ml--30 mr--30">
            <el-table :data="list" border stripe style="width: 100%" v-loading="listLoading">
                <!-- 固定前三列 -->
@@ -262,7 +264,7 @@
        this.fetchData()
        getCarType().then(res => {
            let arr = [{ name: '全部' }]
            this.options = [...arr, ...res];
            this.options = [ ...res,...arr,];
        });
        const query = this.$route.query;
        if (query && Object.keys(query).length > 0) {
@@ -382,6 +384,9 @@
</script>
<style scoped lang="less">
::v-deep .el-tabs--card>.el-tabs__header {
    border: none !important;
}
.color1 {
    color: #0E6EFD;
}
src/view/home/index.vue
@@ -1,21 +1,22 @@
<template>
  <div class="flex homePage">
    <!-- 头部 -->
    <div class="mapTop">
      <!-- 车辆统计 -->
      <div class="carCount">
        <div class="title">车辆统计</div>
        <div class="fir">
          <div class="countCard mid" v-for="(item, index) in carCountData.slice(0, 3)" :key="item.id"
            @click="toCarManage(item.name)">
            <img class="iconImg" :src="imgList[index]" />
            <div>
              <div class="name">{{ item.name || "" }}(辆)</div>
              <div class="num">{{ item.carNum || 0 }}</div>
    <div class="left">
      <!-- 头部 -->
      <div class="mapTop">
        <!-- 车辆统计 -->
        <div class="carCount">
          <!-- <div class="title">车辆统计</div> -->
          <div class="fir">
            <div class="countCard mid" v-for="(item, index) in carCountData" :key="item.id"
              @click="toCarManage(item.name)">
              <img class="iconImg" :src="imgList[index]" />
              <div>
                <div class="name">{{ item.name || "" }}(辆)</div>
                <div class="num">{{ item.carNum || 0 }}</div>
              </div>
            </div>
          </div>
        </div>
        <div class="sec">
          <!-- <div class="sec">
          <div class="countCard" v-for="(item, index) in carCountData.slice(3, 7)" @click="toCarManage(item.name)"
            :key="item.id">
            <img class="iconImg" :src="imgList[index + 3]" />
@@ -24,16 +25,15 @@
              <div class="num">{{ item.carNum || 0 }}</div>
            </div>
          </div>
        </div> -->
        </div>
      </div>
      <!-- 车辆状态 -->
      <div class="carStatus">
        <!-- 车辆状态 -->
        <!-- <div class="carStatus">
        <div class="title">车辆状态</div>
        <div class="statusFir">
          <div class="statusCard">
            <div class="statusLeft">
              <div class="name">在线</div>
              <div class="num">{{ carStatusData.online || 0 }}</div>
            </div>
            <el-progress type="circle" :width="20" :show-text="false" stroke-linecap="butt"
              :percentage="carStatusData.onlinePercent" color="rgba(91, 143, 249, 1)"
@@ -42,8 +42,7 @@
          <div class="statusLine"></div>
          <div class="statusCard">
            <div class="statusLeft">
              <div class="name">离线</div>
              <div class="num">{{ carStatusData.offline || 0 }}</div>
            </div>
            <el-progress type="circle" :width="20" :show-text="false" stroke-linecap="butt"
              :percentage="carStatusData.offlinePercent" color="rgba(93, 112, 146, 1)"
@@ -52,115 +51,145 @@
        </div>
        <div class="statusSec">
          <div class="statusCard">
            <div class="statusLeft">
              <div class="name">故障</div>
              <div class="num">{{ carStatusData.breakdown || 0 }}</div>
            </div>
            <el-progress type="circle" :width="20" :show-text="false" stroke-linecap="butt"
              :percentage="carStatusData.breakdownPercent" color="rgba(253, 83, 118, 1)"
              define-back-color="rgba(253, 83, 118, 0.25)" class="progressCard"></el-progress>
          </div>
          <div class="statusLine"></div>
          <div class="statusCard">
            <div class="statusLeft">
              <div class="name">异常</div>
              <div class="num">{{ carStatusData.abnormal || 0 }}</div>
            </div>
            <el-progress type="circle" :width="20" :show-text="false" stroke-linecap="butt"
              :percentage="carStatusData.abnormalPercent" color="rgba(246, 189, 22, 1)"
              define-back-color="rgba(246, 189, 22, 0.25)" class="progressCard"></el-progress>
          </div>
        </div>
      </div>
    </div>
    <!-- 左边 地图 -->
    <div class="leftMap">
      <div class="mapContainer" id="mapContainer"></div>
    </div>
    <!-- 右边 内容 -->
    <div class="right">
      </div> -->
      <div class="firCard">
        <div class="companyCard">
          <div class="lineCard"></div>
          <div class="name">运营公司(家)</div>
          <div class="value">{{ carStatusData.enterprise || 0 }}</div>
        </div>
        <div class="companyCard">
          <div class="lineCard"></div>
          <div class="name">运营车辆(辆)</div>
          <div class="value">{{ carStatusData.car || 0 }}</div>
        </div>
        <div class="companyCard">
            <div class="companyCard">
              <div class="lineCard"></div>
              <div class="name">运营公司(家)</div>
              <div class="value">{{ carStatusData.enterprise || 0 }}</div>
            </div>
            <div class="companyCard">
              <div class="statusLeft">
                <div class="name">运营车辆(辆)</div>
                <div class="value">{{ carStatusData.car || 0 }}</div>
              </div>
              <div class="statusLeft">
                <div class="name">在线</div>
                <div class="num">{{ carStatusData.online || 0 }}</div>
              </div>
              <div class="statusLeft">
                <div class="name">离线</div>
                <div class="num">{{ carStatusData.offline || 0 }}</div>
              </div>
              <div class="statusLeft">
                <div class="name">故障</div>
                <div class="num">{{ carStatusData.breakdown || 0 }}</div>
              </div>
              <div class="statusLeft">
                <div class="name">异常</div>
                <div class="num">{{ carStatusData.abnormal || 0 }}</div>
              </div>
            </div>
            <!-- <div class="companyCard">
          <div class="lineCard"></div>
          <div class="name">驾驶员(人)</div>
          <div class="value">{{ carStatusData.driver || 0 }}</div>
        </div>
        </div> -->
          </div>
      </div>
      <!-- 今日预警 -->
      <div class="todayWarn">
        <div class="title">今日预警</div>
        <div class="warnList" v-if="warnList.length > 0">
          <div class="warnItem" v-for="(item, index) in warnList" :key="index" :class="item.warnLevel
            ? ['oneWarn', 'twoWarn', 'threeWarn', 'fourWarn'][
            item.warnLevel - 1
            ]
            : 'fiveWarn'
            ">
            <div class="grade">
              {{
                item.warnLevel
                  ? ["一级", "二级", "三级", "四级"][item.warnLevel - 1]
                  : "-"
              }}
      <div class="leftContent">
        <!-- 左边统计 -->
        <div class="leftData">
          <div class="warnCount">
            <div class="title ">预警类型排行榜</div>
            <div class="countChart" id="countChart"></div>
          </div>
          <!-- 预警排行榜(前10) -->
          <div class="warnRank">
            <div class="title mt-0">公司预警排行榜</div>
            <div class="rankChart" id="rankChart">
              <div class="rankItem" v-for="(item, index) in rankList" :key="index">
                <div class="left">{{ item.name }}</div>
                <div class="rankRight" :class="[0, 1, 2].includes(index) ? 'rankColor' : ''">
                  <div class="rank" :style="{ width: item.percentage + '%' }"></div>
                </div>
              </div>
            </div>
            <div class="info">
              {{ item.vehicleNumber }} {{ item.warnType }} {{ item.keepTime }}
              {{ item.startTime }}
            <div class="noData" v-if="rankList.length == 0">
              <el-empty description="暂无数据" :image-size="80"></el-empty>
            </div>
          </div>
        </div>
        <div class="noData" v-else>
          <el-empty description="暂无数据" :image-size="80"></el-empty>
        <!-- 左边 地图 -->
        <div class="leftMap">
          <div class="mapContainer" id="mapContainer"></div>
        </div>
      </div>
      <!-- 预警情况统计 -->
      <div class="warnCount">
        <div class="title ">预警情况统计</div>
        <el-table v-if="tableData.length" :data="tableData" border stripe style="width: 100%">
          <el-table-column prop="operate_type" label="车辆类型">
            <template #default="{ row }">
              <span class="operate_type" @click="toWarningList(row.operate_type)">{{ row.operate_type }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="total" label="预警总数"></el-table-column>
          <el-table-column prop="processed" label="已处理数"></el-table-column>
          <el-table-column prop="unprocessed" label="未处理数"></el-table-column>
          <el-table-column prop="rate" label="处置率"></el-table-column>
        </el-table>
        <div class="noData" v-else>
          <el-empty description="暂无数据" :image-size="80"></el-empty>
        </div>
      </div>
      <div class="warnCount">
        <div class="title ">预警类型排行榜</div>
        <div class="countChart" id="countChart"></div>
      </div>
      <!-- 预警排行榜(前10) -->
      <div class="warnRank">
        <div class="title mt-0">预警排行榜(前10)</div>
        <div class="rankChart" id="rankChart">
          <div class="rankItem" v-for="(item, index) in rankList" :key="index">
            <div class="left">{{ item.name }}</div>
            <div class="rankRight" :class="[0, 1, 2].includes(index) ? 'rankColor' : ''">
              <div class="rank" :style="{ width: item.percentage + '%' }"></div>
        <!-- 右边 内容 -->
        <div class="right">
          <!-- 今日预警 -->
          <div class="todayWarn">
            <div class="title">今日预警</div>
            <div class="warnList" v-if="warnList.length > 0">
              <div class="warnItem" v-for="(item, index) in warnList" :key="index" :class="item.warnLevel
                ? ['oneWarn', 'twoWarn', 'threeWarn', 'fourWarn'][
                item.warnLevel - 1
                ]
                : 'fiveWarn'
                ">
                <div class="grade">
                  {{
                    item.warnLevel
                      ? ["一级", "二级", "三级", "四级"][item.warnLevel - 1]
                      : "-"
                  }}
                </div>
                <div class="info">
                  {{ item.vehicleNumber }} {{ item.warnType }} {{ item.keepTime }}
                  {{ item.startTime }}
                </div>
              </div>
            </div>
            <div class="noData" v-else>
              <el-empty description="暂无数据" :image-size="80"></el-empty>
            </div>
          </div>
        </div>
        <div class="noData" v-if="rankList.length == 0">
          <el-empty description="暂无数据" :image-size="80"></el-empty>
          <!-- 预警情况统计 -->
          <div class="warnCount">
            <div class="title ">预警情况统计</div>
            <el-table v-if="tableData.length" :data="tableData" border stripe style="width: 100%" :height="300">
              <el-table-column prop="operate_type" label="车辆类型">
                <template #default="{ row }">
                  <span class="operate_type" @click="toWarningList(row.operate_type)">{{ row.operate_type }}</span>
                </template>
              </el-table-column>
              <el-table-column prop="total" label="预警总数"></el-table-column>
              <el-table-column prop="processed" label="已处理数"></el-table-column>
              <el-table-column prop="unprocessed" label="未处理数"></el-table-column>
              <el-table-column prop="rate" label="处置率"></el-table-column>
            </el-table>
            <div class="noData" v-else>
              <el-empty description="暂无数据" :image-size="80"></el-empty>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
@@ -939,8 +968,141 @@
<style scoped lang="less">
.homePage {
  display: flex;
  height: 100vh;
  height: 100%;
  position: relative;
  background: #f4f4ff;
  .left {
    flex: 1;
    .leftContent {
      display: flex;
      height: calc(100% - 138px);
      padding-top: 20px;
      .title {
      margin-top: 10px;
      font-weight: 600;
      font-size: 18px;
      color: rgba(0, 0, 0, 0.88);
      line-height: 25px;
      text-transform: none;
      margin-bottom: 10px;
    }
      .leftData {
        display: flex;
        flex-direction: column;
        width: 493px;
        height: 100%;
        padding-right: 20px;
      }
      .warnCount {
        // position: relative;
        flex: 1;
        padding: 10px;
        box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
        border-radius: 10px 10px 0px 0px;
        background: #f4f4ff;
        // margin-bottom: 10px;
        #countChart {
          width: 100%;
          height: 88%;
        }
        .noData {
          display: flex;
          flex-direction: column;
          align-content: center;
          justify-content: center;
          // position: absolute;
          // bottom: 0;
          // left: 0;
          width: 100%;
          height: 180px;
        }
      }
      .warnRank {
        flex: 1;
        position: relative;
        box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
        border-radius: 10px 10px 0px 0px;
        background: #f4f4ff;
        padding: 10px;
        margin-top: 10px;
        .rankChart {
          padding: 5px;
          width: 100%;
          height: 90%;
          margin-top: 10px;
          padding-top: 10px;
          background: #fff;
          // height: 300px;
          .rankItem {
            display: flex;
            align-content: center;
            margin-bottom: 24px;
            .left {
              flex: 2;
              padding-right: 25px;
              font-weight: 400;
              font-size: 13px;
              color: rgba(0, 0, 0, 0.45);
              line-height: 17px;
              text-align: right;
              overflow: hidden;
              white-space: nowrap;
              text-overflow: ellipsis;
            }
            .rankRight {
              flex: 5;
              height: 15px;
              background: rgba(93, 112, 146, 0.2);
              border-radius: 8px;
              .rank {
                height: 15px;
                border-radius: 8px;
                background: rgba(93, 112, 146, 0.6);
              }
            }
            .rankColor {
              background: rgba(91, 143, 249, 0.2);
              .rank {
                background: rgba(91, 143, 249, 0.85);
              }
            }
          }
          .rankItem:last-child {
            margin-bottom: 0 !important;
          }
        }
        .noData {
          display: flex;
          flex-direction: column;
          align-content: center;
          justify-content: center;
          position: absolute;
          bottom: 0;
          left: 0;
          width: 100%;
          height: 300px;
        }
      }
    }
  }
  .leftMap {
    // width: 100%;
@@ -958,13 +1120,13 @@
  .mapTop {
    z-index: 99;
    position: absolute;
    top: 20px;
    left: 20px;
    right: 513px;
    // position: absolute;
    // top: 20px;
    // left: 20px;
    // right: 513px;
    display: flex;
    justify-content: space-between;
    width: calc(100% - 770px);
    width: calc(100%);
    .title {
      font-weight: 600;
@@ -992,7 +1154,7 @@
        .countCard {
          background: #ffffff;
          margin-right: 20px;
          padding: 14px 60px 18px 24px;
          padding: 14px 14px 18px 24px;
        }
        .countCard:last-child {
@@ -1074,7 +1236,7 @@
          font-size: 16px;
          color: rgba(0, 0, 0, 0.8);
          line-height: 19px;
          text-align: right;
          text-align: left;
          margin-top: 1px;
        }
      }
@@ -1144,21 +1306,94 @@
        box-sizing: border-box;
      }
    }
    .firCard {
      display: flex;
      justify-content: space-between;
      box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
      border-radius: 10px 10px 0px 0px;
      background: #f4f4ff;
      // margin-bottom: 10px;
      padding: 10px;
      width: 473px;
      padding-left: 20px;
      .companyCard {
        width: 100px;
        // height: 90px;
        background: #fff;
        border-radius: 0px 10px 10px 0px;
        position: relative;
        .lineCard {
          position: absolute;
          left: 0;
          top: 0;
          width: 4px;
          // height: 90px;
          background: #0e6efd;
          border-radius: 2px;
        }
        .name {
          margin: 18px 10px 12px 10px;
          text-align: left;
          font-size: 12px;
          color: rgba(0, 0, 0, 0.6);
          line-height: 17px;
        }
        .value {
          padding-left: 10px;
          margin-bottom: 22px;
          text-align: left;
          font-weight: 900;
          font-size: 18px;
          color: #0e6efd;
          line-height: 21px;
        }
      }
      .companyCard:nth-child(2) {
        flex: 1;
        margin-left: 10px;
        display: flex;
        justify-content: space-between;
        padding-right: 10px;
        .statusLeft {
          text-align: left;
          .num {
            padding-left: 10px;
            // padding-right: 10px;
          }
        }
      }
    }
  }
  .right {
    // width: 493px;
    flex: 1;
    height: calc(100% - 20px);
    margin: 20px 17px 0 20px;
    background: #f4f4ff;
    box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
    border-radius: 10px 10px 0px 0px;
    padding: 20px;
    overflow-y: auto;
    // position: absolute;
    // right: 0;
    // top: 0;
    width: 493px;
    // flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    height: 100%;
    // margin: 20px 17px 0 20px;
    background: transparent;
    // box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
    // border-radius: 10px 10px 0px 0px;
    padding: 0 0 0 20px;
    // overflow-y: auto;
    .title {
      margin-top: 30px;
      margin-top: 10px;
      font-weight: 600;
      font-size: 18px;
      color: rgba(0, 0, 0, 0.88);
@@ -1174,13 +1409,19 @@
    .firCard {
      display: flex;
      justify-content: space-between;
      box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
      border-radius: 10px 10px 0px 0px;
      background: #f4f4ff;
      margin-bottom: 10px;
      padding: 10px;
      .companyCard {
        width: 140px;
        width: 100px;
        // height: 90px;
        background: #fff;
        border-radius: 0px 10px 10px 0px;
        position: relative;
        .lineCard {
          position: absolute;
@@ -1193,28 +1434,57 @@
        }
        .name {
          margin: 18px 0 12px 19px;
          margin: 18px 10px 12px 10px;
          text-align: left;
          font-size: 12px;
          color: rgba(0, 0, 0, 0.6);
          line-height: 17px;
        }
        .value {
          padding-left: 10px;
          margin-bottom: 22px;
          text-align: center;
          text-align: left;
          font-weight: 900;
          font-size: 18px;
          color: #0e6efd;
          line-height: 21px;
        }
      }
      .companyCard:nth-child(2) {
        flex: 1;
        margin-left: 10px;
        display: flex;
        justify-content: space-between;
        padding-right: 10px;
        .statusLeft {
          text-align: left;
          .num {
            padding-left: 10px;
            // padding-right: 10px;
          }
        }
      }
    }
    .todayWarn {
      box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
      border-radius: 10px 10px 0px 0px;
      background: #f4f4ff;
      margin-bottom: 10px;
      padding: 10px;
      flex: 1;
      .warnList {
        height: 134px;
        height: 100%;
        overflow-y: auto;
        box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
        border-radius: 10px 10px 0px 0px;
        background-color: #fff;
        .warnItem {
          height: 26px;
@@ -1323,10 +1593,16 @@
    .warnCount {
      // position: relative;
      padding: 10px;
      box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
      border-radius: 10px 10px 0px 0px;
      background: #f4f4ff;
      margin-bottom: 0px !important;
      flex: 1;
      #countChart {
        width: 100%;
        height: 180px;
        height: 100%;
      }
      .noData {
@@ -1344,6 +1620,11 @@
    .warnRank {
      position: relative;
      box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.2);
      border-radius: 10px 10px 0px 0px;
      background: #f4f4ff;
      padding: 10px;
      flex: 1;
      .rankChart {
        padding: 5px;