Jelajahi Sumber

新增 总台

王智慧 3 tahun lalu
induk
melakukan
15c49edcb6
14 mengubah file dengan 928 tambahan dan 21 penghapusan
  1. 1 0
      index.html
  2. 2 1
      package.json
  3. 10 6
      src/App.vue
  4. 10 0
      src/apis/fetch.js
  5. TEMPAT SAMPAH
      src/assets/chain.png
  6. TEMPAT SAMPAH
      src/assets/rubber.png
  7. TEMPAT SAMPAH
      src/assets/ship-orange-icon.png
  8. TEMPAT SAMPAH
      src/assets/ship.png
  9. TEMPAT SAMPAH
      src/assets/unload.png
  10. 12 0
      src/auth/menuData.js
  11. 16 11
      src/main.js
  12. 9 0
      src/router/index.js
  13. 867 2
      src/views/index/Index.vue
  14. 1 1
      src/views/index/Login.vue

+ 1 - 0
index.html

@@ -24,6 +24,7 @@
       #app {
         height: 100%;
         width: 100%;
+        overflow-y: hidden;
       }
     </style>
   </head>

+ 2 - 1
package.json

@@ -18,7 +18,8 @@
     "vite-plugin-compression": "^0.3.5",
     "vue": "^3.2.16",
     "vue-router": "^4.0.4",
-    "vuex": "^4.0.2"
+    "vuex": "^4.0.2",
+    "echarts": "^5.3.3"
   },
   "devDependencies": {
     "@vitejs/plugin-vue": "^1.9.3",

+ 10 - 6
src/App.vue

@@ -19,6 +19,9 @@
 import HeaderVue from "./components/Header.vue";
 import AsideVue from "./components/Aside.vue";
 import FooterVue from "./components/Footer.vue";
+import * as echarts from "echarts";
+import { provide } from "vue";
+
 export default {
   components: {
     HeaderVue,
@@ -28,6 +31,9 @@ export default {
   data() {
     return {};
   },
+  setup() {
+    provide("ec", echarts);
+  },
 };
 </script>
 
@@ -35,14 +41,10 @@ export default {
 .main-container {
   height: 100%;
   width: 100%;
-  min-height: 800px;
+  min-height: 875px;
   min-width: 1200px;
 }
 
-.aside {
-  width: 220px;
-}
-
 .footer {
   text-align: center;
 }
@@ -73,8 +75,10 @@ export default {
 
 .main-section {
   margin: 24px 0 0 24px;
-  height: calc(100% - 76px);
+  height: calc(100vh - 136px);
   overflow-y: auto;
+  background: #fff;
+  overflow-x: hidden;
 }
 
 .line-container-p18 {

+ 10 - 0
src/apis/fetch.js

@@ -450,4 +450,14 @@ export default {
   getAccidentList(data) {
     return $http("/voyage/getAccidentList", data);
   },
+
+  // 获取首页数据
+  getIndexData(data) {
+    return $http("/pc/index", data);
+  },
+
+  // 获取首页select
+  getIndexSelect(data) {
+    return $http("/pc/index/select", data);
+  },
 };

TEMPAT SAMPAH
src/assets/chain.png


TEMPAT SAMPAH
src/assets/rubber.png


TEMPAT SAMPAH
src/assets/ship-orange-icon.png


TEMPAT SAMPAH
src/assets/ship.png


TEMPAT SAMPAH
src/assets/unload.png


+ 12 - 0
src/auth/menuData.js

@@ -1,4 +1,16 @@
 let menuData = [
+  {
+    icon: "el-icon-s-data",
+    title: "总台",
+    code: "VOYAGELIST",
+    items: [
+      {
+        path: "/index",
+        name: "总台",
+        code: "VOYAGELIST",
+      },
+    ],
+  },
   {
     icon: "el-icon-s-data",
     title: "航次管理",

+ 16 - 11
src/main.js

@@ -31,20 +31,25 @@ router.beforeEach(async (to, from, next) => {
     if (store.state.menuData.length) {
       let path = store.state?.menuData[0]?.items[0].path;
       if (0 === to.matched.length) {
-        next(path);
-      } else if (to.path == "/login" || to.path == "/") {
-        next(path);
-      } else if (
-        rolePermission?.indexOf(to.meta.code) == -1 ||
-        to.meta.code == "DEFAULT"
-      ) {
-        next(path);
+        next("/index");
+      } else if (to.path == "/login") {
+        next("/index");
+      } else if (rolePermission?.indexOf(to.meta.code) == -1) {
+        if (to.path == "/index") {
+          next();
+        } else {
+          next("/index");
+        }
       } else {
-        next();
+        if (to.path == "/") {
+          next("/index");
+        } else {
+          next();
+        }
       }
     } else {
-      if (to.path == "/") {
-        next("/voyage/voyageList");
+      if (to.path == "/" || to.path == "/login") {
+        next("/index");
       } else {
         next();
       }

+ 9 - 0
src/router/index.js

@@ -4,12 +4,21 @@ import {
   createMemoryHistory,
   createRouter,
 } from "vue-router";
+import Index from "../views/index/Index.vue";
 import Login from "../views/index/Login.vue";
 import VoyageList from "../views/voyage/voyageList.vue";
 
 const router = createRouter({
   history: createWebHashHistory(),
   routes: [
+    {
+      path: "/index",
+      name: "index",
+      meta: {
+        title: "总台",
+      },
+      component: Index,
+    },
     {
       path: "/login",
       name: "login",

+ 867 - 2
src/views/index/Index.vue

@@ -1,2 +1,867 @@
-<template>主页</template>
-<script setup></script>
+<template>
+  <div v-loading="isLoading" style="height: 100%">
+    <div class="df main">
+      <div class="left">
+        <div id="map-container" class="map-container"></div>
+        <div class="df aic tabs">
+          <div
+            @click="changeVoyageType(0)"
+            :class="
+              status == 0
+                ? 'currentbtn radio-btns left-radius'
+                : 'radio-btns left-radius'
+            "
+          >
+            全部航次
+          </div>
+          <div
+            style="border-left: none"
+            @click="changeVoyageType(1)"
+            :class="status == 1 ? 'currentbtn radio-btns' : 'radio-btns'"
+          >
+            装货中
+          </div>
+
+          <div
+            style="border-left: none"
+            @click="changeVoyageType(2)"
+            :class="status == 2 ? 'currentbtn radio-btns' : 'radio-btns'"
+          >
+            运输中
+          </div>
+          <div
+            style="border-left: none"
+            @click="changeVoyageType(3)"
+            :class="
+              status == 3
+                ? 'currentbtn radio-btns right-radius'
+                : 'radio-btns right-radius '
+            "
+          >
+            卸货中
+          </div>
+        </div>
+        <div class="df aic filter">
+          <div class="mr4">装货港</div>
+          <el-select
+            style="width: 90px"
+            v-model="postData.loadPortId"
+            placeholder="装货港"
+            size="mini"
+            @change="getIndexData(1)"
+            filterable
+            clearable
+          >
+            <el-option
+              v-for="item in loadPortOptions"
+              :key="item"
+              :label="item.value"
+              :value="item.key"
+            />
+          </el-select>
+          <div class="mr4 mr10">卸货港</div>
+          <el-select
+            style="width: 90px"
+            v-model="postData.discPortId"
+            placeholder="卸货港"
+            size="mini"
+            @change="getIndexData(1)"
+            filterable
+            clearable
+          >
+            <el-option
+              v-for="item in discPortOptions"
+              :key="item"
+              :label="item.value"
+              :value="item.key"
+            />
+          </el-select>
+          <div class="mr4 mr10">到港状态</div>
+          <el-select
+            style="width: 90px"
+            v-model="postData.isArrived"
+            placeholder="到港状态"
+            size="mini"
+            @change="getIndexData(1)"
+          >
+            <el-option label="已到港" :value="0" />
+            <el-option label="未到港" :value="1" />
+          </el-select>
+          <div class="mr4 mr10">航次状态</div>
+          <el-select
+            style="width: 90px"
+            v-model="postData.abnormalStatus"
+            placeholder="航次状态"
+            size="mini"
+            @change="getIndexData(1)"
+          >
+            <el-option label="正常" :value="0" />
+            <el-option label="异常" :value="1" />
+          </el-select>
+          <div class="mr4 mr10">货种</div>
+          <el-select
+            style="width: 90px"
+            v-model="postData.cargoId"
+            placeholder="货种"
+            size="mini"
+            @change="getIndexData(1)"
+            filterable
+            clearable
+          >
+            <el-option
+              v-for="item in cargoOptions"
+              :key="item"
+              :label="item.value"
+              :value="item.key"
+            />
+          </el-select>
+          <div @click="resetFilter" class="all mr10">全部</div>
+        </div>
+      </div>
+      <div class="right">
+        <div class="df jcfe">
+          <el-popover placement="bottom" :width="100" trigger="hover">
+            <template #reference>
+              <div class="export">导出报告</div>
+            </template>
+            <div
+              style="
+                display: flex;
+                flex-direction: column;
+                height: 180px;
+                justify-content: space-between;
+                align-items: center;
+              "
+            >
+              <div>
+                <el-button
+                  type="primary"
+                  size="small"
+                  v-auth="'DOWNLOADVOYAGELIST'"
+                  @click="showExportModal('航次列表')"
+                >
+                  导出航次列表
+                </el-button>
+              </div>
+              <div>
+                <el-button
+                  type="primary"
+                  size="small"
+                  v-auth="'MULTDOWNLOADSHIPTRACK'"
+                  @click="showExportModal('航次跟踪')"
+                >
+                  导出航次跟踪
+                </el-button>
+              </div>
+              <div>
+                <el-button
+                  type="primary"
+                  size="small"
+                  @click="showExportModal('卸货记录')"
+                  v-auth="'MULTDOWNLOADDISCHARGE'"
+                >
+                  导出卸货记录
+                </el-button>
+              </div>
+              <div>
+                <el-button
+                  v-auth="'DOWNLOADFYDI'"
+                  type="primary"
+                  size="small"
+                  @click="downloadFYDI"
+                >
+                  下载FYDI指数
+                </el-button>
+              </div>
+            </div>
+          </el-popover>
+          <el-dialog
+            v-model="exportModalVisable"
+            :title="exportModalTitle"
+            :close-on-click-modal="false"
+            @close="isLoadingZip = false"
+            width="200px"
+          >
+            <div class="df aic jcsb">
+              <div
+                v-if="exportModalTitle != '航次列表' || cargoOwnerId == 7"
+                class="df aic"
+              >
+                <div class="mr20">请选择月份:</div>
+                <el-date-picker
+                  v-model="currentMonth"
+                  type="month"
+                  placeholder="请选择年月"
+                  value-format="YYYYMM"
+                  :disabled="isLoadingZip"
+                />
+              </div>
+              <div></div>
+              <el-button
+                type="primary"
+                @click="exportZip"
+                :loading="isLoadingZip"
+              >
+                导出{{ exportModalTitle }}
+              </el-button>
+            </div>
+          </el-dialog>
+        </div>
+        <div class="data">
+          <div class="df aic">
+            <div class="shu"></div>
+            <div class="right-title">数据统计</div>
+          </div>
+          <div class="df data-line">
+            <img class="icon" src="../../assets/ship.png" />
+            <div class="data-text">
+              <div class="data-title">总航次数</div>
+              <div class="df aib">
+                <div class="num">{{ indexData.totalVoyageNum }}</div>
+                <div class="unit">次</div>
+              </div>
+            </div>
+          </div>
+          <div class="df data-line">
+            <img class="icon" src="../../assets/rubber.png" />
+            <div class="data-text">
+              <div class="data-title">总实际装载吨数</div>
+              <div class="df aib">
+                <div class="num">{{ indexData.totalLoadTons }}</div>
+                <div class="unit">吨</div>
+              </div>
+            </div>
+          </div>
+          <div class="df data-line">
+            <img class="icon" src="../../assets/unload.png" />
+            <div class="data-text">
+              <div class="data-title">总已完成卸货吨位</div>
+              <div class="df aib">
+                <div class="num">{{ indexData.finshDiscTons }}</div>
+                <div class="unit">吨</div>
+              </div>
+            </div>
+          </div>
+          <div class="df data-line">
+            <img class="icon" src="../../assets/chain.png" />
+            <div class="data-text">
+              <div class="data-title">总剩余卸货吨位</div>
+              <div class="df aib">
+                <div class="num">{{ indexData.unfinshDiscTons }}</div>
+                <div class="unit">吨</div>
+              </div>
+            </div>
+          </div>
+        </div>
+        <div class="pie">
+          <div class="df aic">
+            <div class="shu"></div>
+            <div class="right-title">卸货占比</div>
+          </div>
+          <div id="pie" class="card-5">
+            <div>饼图</div>
+            <div>卸货</div>
+          </div>
+          <div class="df aic jcc mt10">
+            <div class="pie-point"></div>
+            <div class="pie-text mr20">已卸货吨位</div>
+            <div class="pie-point" style="background: #58daea"></div>
+            <div class="pie-text">剩余卸货吨位</div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script setup>
+import { ref, reactive, toRefs, computed, onMounted, inject } from "vue";
+import { ElNotification } from "element-plus";
+import store from "../../store";
+import router from "../../router";
+
+import md5 from "md5";
+import api from "../../apis/fetch";
+import downloadBlobFile from "../../utils/downloadBlobFile";
+import url from "../../apis/config";
+let map = ref({});
+let cargoOwnerId = localStorage.userId;
+let echarts = inject("ec");
+
+function initMap() {
+  map.value = new AMap.Map("map-container", {
+    zoom: 9, //级别
+    zooms: [4, 9],
+    center: [120.563757, 31.891174], //中心点坐标
+    mapStyle: "amap://styles/f48d96805f5fa7f5aada657c5ee37017",
+    zoomEnable: true,
+    dragEnable: true,
+  });
+  let toolBar = new AMap.ToolBar({
+    position: {
+      top: "40px",
+      right: "40px",
+    },
+  });
+  let hawkEye = new AMap.HawkEye({
+    opened: false,
+  });
+  map.value.addControl(toolBar);
+  map.value.addControl(hawkEye);
+  drawMarkers();
+}
+
+function drawMarkers() {
+  let markers = [];
+  for (let i of indexData.value.mapPoints) {
+    if (i.latitude && i.longitude) {
+      let content = `<div style='width:160px'>
+          <img src='https://frontend-1255802371.cos.ap-shanghai.myqcloud.com/ship-orange-icon.png' style='display:block;width:20px;height:20px;margin:6px auto'/
+        </div>`;
+
+      let marker = new AMap.Marker({
+        content,
+        position: new AMap.LngLat(i.longitude, i.latitude),
+        offset: new AMap.Pixel(-80, -20),
+      });
+      let infoWindowContent = `<div class='window-title pointer' style='font-size:12px'>${i.shipName}</div>
+        <div style='font-size:12px;margin-top:5px'>查看详情</div>
+        `;
+      let infoWindow = new AMap.InfoWindow({
+        position: new AMap.LngLat(i.longitude, i.latitude),
+        offset: new AMap.Pixel(0, -10),
+        content: infoWindowContent,
+      });
+
+      marker.on("mouseover", function () {
+        infoWindow.open(map.value);
+      });
+      marker.setLabel({
+        direction: "top",
+        offset: new AMap.Pixel(0, 0), //设置文本标注偏移量
+        content: `${i.shipName}`, //设置文本标注内容
+        style: "",
+      });
+
+      marker.on("click", () => {
+        goToVoyageDetail(i.voyageId);
+      });
+
+      markers.push(marker);
+    }
+  }
+  let overlayGroups = new AMap.OverlayGroup(markers);
+  map.value.add(overlayGroups);
+  map.value.setFitView(markers, true, [200, 50, 50, 50], 18);
+}
+let status = ref(3);
+function changeVoyageType(s) {
+  status.value = s;
+  postData.value = {
+    loadPortId: "",
+    discPortId: "",
+    isArrived: "",
+    abnormalStatus: "",
+    cargoId: "",
+  };
+  getIndexSelect();
+  getIndexData();
+}
+
+function goToVoyageDetail(id) {
+  router.push({
+    path: "/voyage/voyageDetail",
+    query: {
+      id,
+    },
+  });
+}
+
+let postData = ref({
+  status: 0,
+  loadPortId: "",
+  discPortId: "",
+  isArrived: "",
+  abnormalStatus: "",
+  cargoId: "",
+});
+let indexData = ref({
+  finshDiscTons: "",
+  mapPoints: [],
+  totalLoadTons: "",
+  totalVoyageNum: "",
+  unfinshDiscTons: "",
+});
+let isLoading = ref(false);
+async function getIndexData(type) {
+  isLoading.value = true;
+  postData.value.status = status.value;
+  try {
+    let res = await api.getIndexData({
+      ...postData.value,
+    });
+    isLoading.value = false;
+    if (res.data.status == 0) {
+      indexData.value = res.data.result;
+      if (type == "init") {
+        initMap();
+        drawPie("init");
+      } else {
+        map.value.clearMap();
+        drawMarkers();
+        drawPie();
+      }
+    } else {
+      indexData.value = {
+        finshDiscTons: 0,
+        mapPoints: [],
+        totalLoadTons: 0,
+        totalVoyageNum: 0,
+        unfinshDiscTons: 0,
+      };
+      if (type == "init") {
+        initMap();
+        drawPie("init");
+      } else {
+        map.value.clearMap();
+        drawMarkers();
+        drawPie();
+      }
+    }
+  } catch (error) {
+    console.log(error);
+    isLoading.value = false;
+  }
+}
+let chartDom = ref({});
+let myChart = ref({});
+
+function drawPie(type) {
+  if (!myChart.value.id) {
+    chartDom.value = document.getElementById("pie");
+    myChart.value = echarts.init(chartDom.value);
+  }
+
+  let option;
+  option = {
+    grid: {
+      bottom: 500,
+    },
+    tooltip: {
+      trigger: "item",
+    },
+    color: ["#0A6EFA", "#58DAEA"],
+    series: [
+      {
+        center: ["50%", "50%"],
+        type: "pie",
+        radius: ["60%", "85%"],
+        data: [
+          { value: indexData.value.finshDiscTons || 0, name: "已卸货吨位" },
+          { value: indexData.value.unfinshDiscTons || 0, name: "剩余卸货吨位" },
+        ],
+        emphasis: {
+          itemStyle: {
+            shadowBlur: 10,
+            shadowOffsetX: 0,
+            shadowColor: "rgba(0, 0, 0, 0.5)",
+          },
+        },
+        label: {
+          show: true,
+          position: "inner", // 数值显示在内部
+          formatter: "{d}%", // 格式化数值百分比输出
+        },
+      },
+    ],
+  };
+  myChart.value.setOption(option);
+}
+
+let portOptions = ref([]);
+async function getPortSelect() {
+  if (portOptions.value.length) return;
+  let res = await api.getCol({
+    term: "",
+  });
+  portOptions.value = res.data.result;
+}
+
+let loadPortOptions = ref([]);
+let discPortOptions = ref([]);
+
+let cargoOptions = ref([]);
+async function getCargoSelect() {
+  if (cargoOptions.value.length) return;
+  let res = await api.getCargoSelect({
+    status: 2,
+    term: "",
+  });
+  cargoOptions.value = res.data.result;
+}
+
+async function downloadFYDI() {
+  let res0 = await api.getFYFIDownloadUrl({
+    loginAccountId: localStorage.loginAccountId,
+  });
+
+  if (res0.data.result == 1) {
+    ElNotification({
+      type: "info",
+      title: "更新中",
+    });
+  } else {
+    let url = res0.data.result;
+    let a = document.createElement("a");
+    a.setAttribute("href", url);
+    a.click();
+  }
+}
+
+let exportModalVisable = ref(false);
+let exportModalTitle = ref("");
+let currentMonth = ref("");
+
+function showExportModal(type) {
+  exportModalVisable.value = true;
+  exportModalTitle.value = type;
+}
+
+let isLoadingZip = ref(false);
+
+async function exportZip() {
+  if (!currentMonth.value && exportModalTitle.value != "航次列表") return;
+
+  isLoadingZip.value = true;
+  let path = "";
+  let type = "";
+  let postData = {
+    loginAccountId: localStorage.loginAccountId,
+  };
+  let title = "";
+  switch (exportModalTitle.value) {
+    case "航次列表": {
+      if (localStorage.userId == 7) {
+        path = "/voyage/exportVoyageReportExcel";
+        postData.loginAccountId = localStorage.loginAccountId;
+        postData.date = currentMonth.value;
+      } else {
+        path = "/voyage/exportListExcel";
+        let arr = [];
+        for (let i of tableData.value) {
+          arr.push(i.id);
+        }
+        postData.voyageIds = arr.join(",");
+      }
+      type =
+        "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8";
+      title = `${exportModalTitle.value}`;
+      break;
+    }
+    case "航次跟踪": {
+      path = "/voyage/exportMultExcel";
+      type = "application/zip";
+      postData.date = currentMonth.value;
+      title = `${exportModalTitle.value}${currentMonth.value}`;
+
+      break;
+    }
+    case "卸货记录": {
+      path = "/voyage/exportMultDischargeExcel";
+      type = "application/zip";
+      postData.date = currentMonth.value;
+      title = `${exportModalTitle.value}${currentMonth.value}`;
+      break;
+    }
+  }
+  try {
+    let res = await downloadBlobFile(
+      `${url.baseurl}${path}`,
+      postData,
+      title,
+      "post",
+      type
+    );
+    if (res.status == 0) {
+      ElNotification({
+        title: "导出成功!",
+        type: "success",
+      });
+    } else {
+      ElNotification({
+        title: "暂无数据",
+      });
+    }
+  } catch (error) {
+    ElNotification({
+      title: "暂无数据",
+    });
+  } finally {
+    isLoadingZip.value = false;
+    currentMonth.value = "";
+    exportModalVisable.value = false;
+  }
+}
+
+function resetFilter() {
+  postData.value = {
+    loadPortId: "",
+    discPortId: "",
+    isArrived: "",
+    abnormalStatus: "",
+    cargoId: "",
+  };
+  getIndexData();
+}
+
+async function getIndexSelect() {
+  let res = await api.getIndexSelect({
+    status: status.value,
+  });
+  if (res.data.status == 0) {
+    loadPortOptions.value = res.data.result.loadPortSelect;
+    discPortOptions.value = res.data.result.discPortSelect;
+    cargoOptions.value = res.data.result.cargoSelect;
+  } else {
+    loadPortOptions.value = [];
+    discPortOptions.value = [];
+    cargoOptions.value = [];
+  }
+}
+onMounted(() => {
+  getIndexData("init");
+  getIndexSelect();
+});
+</script>
+
+<style scoped>
+.map-container {
+  width: 100%;
+  height: calc(100% - 94px);
+}
+
+.tabs {
+  position: absolute;
+  top: 20px;
+  left: 25px;
+}
+
+.radio-btns {
+  height: 30px;
+  width: 60px;
+  border: 1px solid #008efe;
+  line-height: 28px;
+  text-align: center;
+  font-size: 14px;
+  font-family: PingFangSC-Regular, PingFang SC;
+  font-weight: 400;
+  color: #0094fe;
+  cursor: pointer;
+  background: #fff;
+}
+
+.left-radius {
+  /* border-top-left-radius: 15px;
+    border-bottom-left-radius: 15px; */
+  width: 80px;
+}
+
+.right-radius {
+  /* border-top-right-radius: 15px; */
+  /* border-bottom-right-radius: 15px; */
+  width: 80px;
+}
+.currentbtn {
+  background: #008efe;
+  color: #fff;
+}
+
+:deep() .el-dialog {
+  width: 800px;
+}
+
+.window-title {
+  display: none;
+}
+.window-title:hover {
+  display: block;
+}
+
+.export {
+  font-size: 14px;
+  font-family: PingFangSC-Medium, PingFang SC;
+  font-weight: 500;
+  color: #ffffff;
+  line-height: 14px;
+  width: 90px;
+  height: 32px;
+  background: #008efe;
+  border-radius: 2px;
+  color: #fff;
+  line-height: 32px;
+  text-align: center;
+}
+
+.main {
+  width: 100%;
+  height: 100%;
+  background: #f4f5f6;
+}
+
+.left {
+  width: calc(100% - 315px);
+  position: relative;
+}
+
+.filter {
+  font-size: 12px;
+  color: #353a42;
+  width: calc(100vw - 320px);
+  flex-wrap: wrap;
+  margin-top: 36px;
+}
+
+.mr10 {
+  margin-left: 14px;
+}
+
+.all {
+  width: 60px;
+  height: 32px;
+  line-height: 32px;
+  background: #008efe;
+  border-radius: 2px;
+  font-size: 14px;
+  font-family: PingFangSC-Medium, PingFang SC;
+  font-weight: 500;
+  color: #ffffff;
+  text-align: center;
+}
+
+.right {
+  width: 267px;
+  border-radius: 4px;
+  height: calc(100% - 30px);
+  margin-left: 26px;
+  overflow-y: auto;
+  overflow-x: clip;
+}
+
+.data {
+  width: 267px;
+  background: #ffffff;
+  border-radius: 4px;
+  margin-top: 12px;
+  margin-bottom: 18px;
+  padding-top: 16px;
+  padding-left: 24px;
+  padding-bottom: 20px;
+  height: calc(50vh - 160px);
+  min-height: 356px;
+}
+
+.pie {
+  width: 267px;
+  background: #ffffff;
+  border-radius: 4px;
+  padding-top: 24px;
+  padding-left: 20px;
+  height: calc(50vh - 206px);
+  min-height: 260px;
+}
+
+.icon {
+  width: 48px;
+  height: 48px;
+  border-radius: 4px;
+  margin-right: 16px;
+}
+
+.data-line {
+  align-items: center;
+  width: 219px;
+  border-bottom: 1px solid rgba(216, 216, 216, 0.24);
+  padding: 12px 0;
+}
+
+.shu {
+  width: 3px;
+  height: 16px;
+  background: #008efe;
+  margin-right: 16px;
+}
+
+.right-title {
+  font-size: 20px;
+  font-family: PingFangSC-Medium, PingFang SC;
+  font-weight: 500;
+  color: #333333;
+}
+
+.data-title {
+  font-size: 14px;
+  font-family: PingFangSC-Regular, PingFang SC;
+  font-weight: 400;
+  color: #616975;
+}
+
+.num {
+  font-size: 30px;
+  font-family: PingFangSC-Medium, PingFang SC;
+  font-weight: 500;
+  color: #333333;
+  margin-right: 5px;
+}
+
+.unit {
+  font-size: 12px;
+  font-family: PingFangSC-Regular, PingFang SC;
+  font-weight: 400;
+  color: #353a42;
+}
+
+#pie {
+  width: 220px;
+  height: 200px;
+  margin: 0 auto;
+}
+
+/* :deep().amap-marker-label {
+    top: -22px;
+    left: 41px;
+    color: #fff !important;
+    width: 74px;
+    height: 28px;
+    line-height: 22px;
+    background: #212029;
+    border: none;
+    text-align: center;
+    font-size: 12px !important;
+    font-family: PingFangSC-Regular, PingFang SC;
+    font-weight: 400;
+  } */
+
+.pie-point {
+  width: 6px;
+  height: 6px;
+  background: #0a6efa;
+  border-radius: 30%;
+  margin-right: 6px;
+}
+
+.pie-text {
+  height: 12px;
+  font-size: 12px;
+  font-family: PingFangSC-Regular, PingFang SC;
+  font-weight: 400;
+  color: #7d7d7d;
+  line-height: 12px;
+}
+
+.aib {
+  align-items: baseline;
+}
+
+.mr4 {
+  margin-right: 4px;
+}
+</style>

+ 1 - 1
src/views/index/Login.vue

@@ -158,7 +158,7 @@ export default {
               localStorage.loginAccountId
             );
 
-            router.replace({ path: store.state.menuData[0]?.items[0].path });
+            router.replace("/index");
             store.commit("changeLogin", true);
           } else {
             ElNotification.error({