zhangchong 1 месяц назад
Родитель
Сommit
533815c250

+ 64 - 131
src/views/snapshot/center-bottom.vue

@@ -6,50 +6,13 @@
         <span>行业类型统计</span>
       </div>
     </div>
-    <div class="center_bottom-content" v-if="active === '0'">
-      <div class="table-header">
-        <div class="table-header-item">超期状态</div>
-        <div class="table-header-item">来源</div>
-        <div class="table-header-item">标题</div>
-        <div class="table-header-item">受理类型</div>
-        <div class="table-header-item">热点类型</div>
-        <div class="table-header-item">区域</div>
-        <div class="table-header-item">接办部门</div>
-      </div>
-      <div class="scroll" v-loading="loading">
-        <vue3-seamless-scroll
-          :list="list"
-          hover
-          :singleHeight="100"
-          v-if="list.length"
-        >
-          <div class="item" v-for="(item, index) in list" :key="index">
-            <span>
-              <span class="exceedSoon" v-if="item.expiredStatus === 1">{{
-                item.expiredStatusText
-              }}</span>
-              <span class="exceed" v-if="item.expiredStatus === 2">{{
-                item.expiredStatusText
-              }}</span>
-              <span class="normal" v-if="item.expiredStatus === 0">{{
-                item.expiredStatusText
-              }}</span>
-            </span>
-            <TextTooltip :content="item.sourceChannel"></TextTooltip>
-            <TextTooltip :content="item.title"></TextTooltip>
-            <TextTooltip :content="item.acceptType"></TextTooltip>
-            <TextTooltip :content="item.hotspotName"></TextTooltip>
-            <!--            <el-tooltip placement="top">
-                          <template #content> {{ item.hotspotName }}</template>
-                          <span>{{ item.hotspotName }}</span>
-                        </el-tooltip>-->
-            <TextTooltip :content="item.county"></TextTooltip>
-            <TextTooltip :content="item.actualHandleOrgName"></TextTooltip>
-          </div>
-        </vue3-seamless-scroll>
-        <empty v-else />
-      </div>
-    </div>
+    <v-chart
+      class="chart"
+      :option="option"
+      :loading="loading"
+      :loading-options="loadingOptions"
+      style="height: 340px"
+    />
   </div>
 </template>
 <script setup lang="ts">
@@ -60,33 +23,78 @@ import signalR from "@/utils/signalR";
 import { useThemeConfig } from "@/stores/themeConfig";
 import { storeToRefs } from "pinia";
 import { formatDate } from "@/utils/formatTime";
+import { loadingOptions } from "@/utils/constants";
 
-const TextTooltip = defineAsyncComponent(
-  () => import("@/components/TextTooltip/index.vue")
-);
-const Empty = defineAsyncComponent(
-  () => import("@/components/Empty/index.vue")
-);
-
-const active = ref("0");
 const list = ref([]);
 const loading = ref(false);
+const option = ref({});
 const getData = async () => {
   loading.value = true;
   try {
     const { result } = await orderView();
     list.value = result;
     loading.value = false;
+    setOption({});
   } catch (e) {
     console.log(e);
     loading.value = false;
   }
 };
+const setOption = (data: any) => {
+  option.value = {
+    tooltip: {
+      trigger: "axis",
+      axisPointer: {
+        type: "shadow",
+      },
+    },
+    grid: {
+      left: "5%",
+      right: "5%",
+      bottom: "10%",
+      containLabel: true,
+    },
+    xAxis: {
+      type: "category",
+      data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
+      axisLine: {
+        lineStyle: {
+          color: "#d2e0f4",
+        },
+      },
+      axisTick: {
+        show: false,
+      },
+      axisLabel: {
+        color: "#7a869a",
+      },
+    },
+    yAxis: {
+      type: "value",
+      splitLine: {
+        lineStyle: {
+          color: "#e6effc",
+        },
+      },
+      axisLine: {
+        show: false,
+      },
+      axisLabel: {
+        color: "#7a869a",
+      },
+    },
+    series: [
+      {
+        data: [120, 200, 150, 80, 70, 110, 130],
+        type: "bar",
+        itemStyle: {
+          borderRadius: [4, 4, 0, 0],
+        },
+      },
+    ],
+  };
+};
 onMounted(() => {
-  // 接收消息
-  signalR.SR.on("orderHandlingDetail", (res: any) => {
-    list.value = res;
-  });
   getData();
 });
 onUnmounted(() => {
@@ -101,12 +109,6 @@ onUnmounted(() => {
 .center_bottom {
   padding: 10px 20px;
 
-  :deep(.custom-text-content) {
-    flex: 1;
-    text-align: center;
-    color: #cfd2d2;
-  }
-
   &-title {
     color: #fff;
     justify-content: space-between;
@@ -123,74 +125,5 @@ onUnmounted(() => {
       }
     }
   }
-
-  &-content {
-    margin-top: 10px;
-
-    .table-header {
-      display: flex;
-      justify-content: space-between;
-      background: linear-gradient(
-        to right,
-        rgba(27, 51, 55, 0.8),
-        rgba(45, 83, 91, 0.8)
-      );
-
-      width: 100%;
-      height: 40px;
-      line-height: 40px;
-
-      .table-header-item {
-        text-align: center;
-        color: #b4d7ec;
-        flex: 1;
-      }
-    }
-
-    .scroll {
-      height: 200px;
-      overflow: hidden;
-      margin-top: 10px;
-
-      .item {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        border-bottom: 1px solid #225073;
-        padding: 6px 0;
-
-        span {
-          display: inline-block;
-          white-space: nowrap;
-          overflow: hidden;
-          text-overflow: ellipsis;
-          text-align: center;
-          color: #cfd2d2;
-          flex: 1;
-        }
-
-        .exceedSoon {
-          border: 1px solid #eca455;
-          border-radius: 3px;
-          color: #eca455;
-          padding: 2px 5px;
-        }
-
-        .exceed {
-          border: 1px solid #d70024;
-          border-radius: 3px;
-          color: #d70024;
-          padding: 2px 5px;
-        }
-
-        .normal {
-          border: 1px solid #69bbf6;
-          border-radius: 3px;
-          color: #69bbf6;
-          padding: 2px 5px;
-        }
-      }
-    }
-  }
 }
 </style>

+ 48 - 66
src/views/snapshot/center-top.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="center-top">
+  <div class="center-top w-full h-full">
     <div class="center-top-title flex">
       <div class="flex items-center">
         <img src="@/assets/img/home/title_arrow.png" alt="" />
@@ -12,15 +12,12 @@
       ref="centerMapRef"
       :loading="loading"
       :loading-options="loadingOptions"
+      style="height: 450px"
     />
   </div>
 </template>
 <script setup lang="ts">
 import { ref, onMounted, watch, nextTick } from "vue";
-import { registerMap, getMap } from "echarts/core";
-import { optionHandle } from "@/views/home/center.map";
-import { loopShowTooltip } from "@/utils/tooltip-auto-show";
-import axios from "axios";
 import { areaDetail } from "api/home";
 import dayjs from "dayjs";
 import { loadingOptions } from "@/utils/constants";
@@ -52,39 +49,6 @@ watch(
 );
 const loading = ref(false);
 const option = ref({});
-const code = ref(themeConfig.value.cityCode); //100000 代表中国 其他地市是行政编码
-// const code = ref("510500");
-const dataSetHandle = async (regionCode: string, list: object[]) => {
-  code.value = regionCode;
-  const geoJson: any = await getGeoJson(regionCode);
-  let cityCenter: any = {};
-  //获取当前地图每块行政区中心点
-  geoJson.features.forEach((element: any) => {
-    cityCenter[element.properties.name] =
-      element.properties.centroid || element.properties.center;
-  });
-  option.value = optionHandle(regionCode, list);
-};
-
-const getGeoJson = (regionCode: string) => {
-  return new Promise<boolean>(async (resolve) => {
-    let mapJson = getMap(regionCode);
-    if (mapJson) {
-      mapJson = mapJson.geoJSON;
-      resolve(mapJson);
-    } else {
-      mapJson = await axios
-        .get(`./map-geojson/${regionCode}.json`)
-        .then((data) => data.data);
-      code.value = regionCode;
-      registerMap(regionCode, {
-        geoJSON: mapJson as any,
-        specialAreas: {},
-      });
-      resolve(mapJson);
-    }
-  });
-};
 // 获取数据设置到地图中
 const getData = async () => {
   loading.value = true;
@@ -93,40 +57,58 @@ const getData = async () => {
       StartTime: dayjs(date.value[0]).format("YYYY-MM-DD"),
       EndTime: dayjs(date.value[1]).format("YYYY-MM-DD"),
     });
-    const regionData = result.map((item: any) => {
-      return {
-        name: item.areaName,
-        ...item,
-      };
-    });
-    await dataSetHandle(code.value, regionData);
+    option.value = {
+      tooltip: {
+        trigger: "item",
+        formatter: "{a} <br/>{b} : {c} ({d}%)",
+      },
+      legend: {
+        orient: "vertical",
+        x: "left",
+        left: 10,
+        top: 20,
+        data: [
+          "二电一期",
+          "二电二期",
+          "二电三期",
+          "二电南线",
+          "大唐一期",
+          "大唐二期",
+        ],
+        textStyle: {
+          color: "#fff",
+        },
+      },
+      series: [
+        {
+          name: "大唐热源占比",
+          type: "pie",
+          radius: "55%",
+          center: ["50%", "70%"],
+          label: {
+            formatter: "{b}:{c} {{d}%} ",
+            color: "#fff",
+          },
+          data: [
+            { value: 335, name: "二电一期" },
+            { value: 310, name: "二电二期" },
+            { value: 234, name: "二电三期" },
+            { value: 135, name: "二电南线" },
+            { value: 154, name: "大唐一期" },
+            { value: 148, name: "大唐二期" },
+          ],
+        },
+      ],
+    };
+
     loading.value = false;
   } catch (e) {
     console.log(e);
     loading.value = false;
   }
 };
-const tooltipTimer = ref<any>(null);
-const centerMapRef = ref<any>(null);
-const tooltipMap = (myChart: any, option: any) => {
-  tooltipTimer.value && tooltipTimer.value.clearLoop(); // this.tooltipTimer 在data里定义
-  tooltipTimer.value = 0;
-  // 调用轮播的方法
-  // myChart为Echarts容器实例
-  tooltipTimer.value = loopShowTooltip(myChart, option, {
-    interval: 5000, // 轮播间隔时间
-    loopSeries: false, // 是否开启轮播循环
-    seriesIndex: 0, // 开始轮播的系列索引
-    // shunXu: "daoXu", // 显示顺序
-    // loopSeries: boolean类型,默认为false。true表示循环所有series的tooltip;false则显示指定seriesIndex的tooltip。
-    // seriesIndex: 默认为0,指定某个系列(option中的series索引)循环显示tooltip,当loopSeries为true时,从seriesIndex系列开始执行。
-  });
-};
-onMounted(async () => {
-  await getData();
-  await nextTick(() => {
-    tooltipMap(centerMapRef.value!.chart, option.value);
-  });
+onMounted(() => {
+  getData();
 });
 </script>
 

+ 6 - 4
src/views/snapshot/container.vue

@@ -91,11 +91,13 @@ const props = defineProps({
   .container-center {
     flex: 1;
     margin: 0 24px;
-    display: flex;
-    flex-direction: column;
-    overflow: hidden;
+    .container-center-top {
+      height: 540px;
+      overflow: hidden;
+      margin-top: 30px;
+    }
     .container-center-bottom {
-      height: 400px;
+      height: 390px;
       overflow: hidden;
       margin-top: 30px;
     }

+ 68 - 161
src/views/snapshot/left-bottom.vue

@@ -141,177 +141,84 @@ const getData = async () => {
       lineY.push(data);
       lineT.push(data1);
     }
-
-    option.value = {
-      backgroundColor: "rgba(0, 0, 0, 0)",
-      title: {
-        show: false,
+    const data = [
+      {
+        name: "分类1",
+        value: 2,
       },
-      tooltip: {
-        trigger: "axis",
-        axisPointer: {
-          type: "shadow",
-        },
-        formatter: function (params: any) {
-          let tar;
-          if (params[0].seriesIndex === 0) {
-            tar = params[0];
-          } else {
-            tar = params[1];
-          }
-          return tar.marker + tar.name + "<br/>" + " 当前数量: " + tar.value;
-        },
-
-        enterable: true, //滚动条
-        confine: true,
-        extraCssText: "max-width:90%;max-height:83%;overflow:auto;",
-        //改变提示框的位置 不超出屏幕显示
-        position: function (point, params, dom, rect, size) {
-          //其中point为当前鼠标的位置,
-          //size中有两个属性:viewSize和contentSize,分别为外层div和tooltip提示框的大小
-          // 鼠标坐标和提示框位置的参考坐标系是:以外层div的左上角那一点为原点,x轴向右,y轴向下
-          // 提示框位置
-          let x = 0; // x坐标位置
-          let y = 0; // y坐标位置
-          // 当前鼠标位置
-          const pointX = point[0];
-          const pointY = point[1];
-          // 提示框大小
-          const boxWidth = size.contentSize[0];
-          const boxHeight = size.contentSize[1];
-          // boxWidth > pointX 说明鼠标左边放不下提示框
-          if (boxWidth > pointX) {
-            x = 5;
-          } else {
-            // 左边放的下
-            x = pointX - boxWidth;
-          }
-          // boxHeight > pointY 说明鼠标上边放不下提示框
-          if (boxHeight > pointY) {
-            y = 5;
-          } else {
-            // 上边放得下
-            y = pointY - boxHeight;
-          }
-          return [x, y];
-        },
+      {
+        name: "分类2",
+        value: 10,
       },
-      grid: {
-        borderWidth: 0,
-        top: "5%",
-        left: "5%",
-        right: "15%",
-        bottom: "10%",
+      {
+        name: "分类3",
+        value: 5,
       },
-      color: color,
-      yAxis: [
-        {
-          type: "category",
-          inverse: true,
-          axisTick: {
-            show: false,
-          },
-          axisLine: {
-            show: false,
-          },
-          axisLabel: {
-            show: false,
-            inside: false,
-          },
-          data: top10CityList,
-        },
-        {
-          type: "category",
-          inverse: true,
-          axisLine: {
-            show: false,
-          },
-          axisTick: {
-            show: false,
-          },
-          axisLabel: {
-            show: true,
-            inside: false,
-            verticalAlign: "middle",
-            lineHeight: "40",
-            color: "#fff",
-            fontSize: "14",
-            fontFamily: "PingFangSC-Regular",
-            formatter: function (val) {
-              return `${val}`;
-            },
-          },
-          splitArea: {
-            show: false,
-          },
-          splitLine: {
-            show: false,
-          },
-          data: top10CityData,
-        },
-      ],
-      xAxis: {
-        type: "value",
-        axisTick: {
-          show: false,
-        },
-        axisLine: {
-          show: false,
-        },
-        splitLine: {
-          show: false,
-        },
-        axisLabel: {
-          show: false,
-        },
+      {
+        name: "分类4",
+        value: 3,
+      },
+      {
+        name: "分类5",
+        value: 4,
+      },
+      {
+        name: "分类6",
+        value: 5,
+      },
+      {
+        name: "分类7",
+        value: 1,
+      },
+      {
+        name: "分类8",
+        value: 5,
+      },
+      {
+        name: "分类9",
+        value: 10,
+      },
+    ];
+    option.value = {
+      tooltip: {
+        trigger: "item",
+        formatter: "{b} : {c} ({d}%)",
       },
       series: [
         {
-          type: "bar",
-          zLevel: 2,
-          barWidth: "10px",
-          data: lineY,
+          name: "",
+          type: "pie",
+          center: ["50%", "40%"],
+          radius: ["0%", "70%"],
+          roseType: "area",
+          itemStyle: {
+            borderRadius: 0,
+          },
+          data: data.sort((a, b) => b.value - a.value) || [],
           label: {
-            color: "#b3ccf8",
-            show: true,
-            position: [0, "-18px"],
-            fontSize: 16,
-            width: 40,
-            formatter: function (a) {
-              let num = "";
-              let str = "";
-              if (a.dataIndex + 1 < 10) {
-                num = "0" + (a.dataIndex + 1);
-              } else {
-                num = a.dataIndex + 1;
-              }
-              let names = "";
-              if (a.name.length > 25) {
-                names = a.name.slice(0, 25) + "...";
-              } else {
-                names = a.name;
-              }
-              if (a.dataIndex === 0) {
-                str = `{color1|${num}} {color4|${names}}`;
-              } else if (a.dataIndex === 1) {
-                str = `{color2|${num}} {color4|${names}}`;
-              } else {
-                str = `{color3|${num}} {color4|${names}}`;
-              }
-              return str;
-            },
+            alignTo: "none",
+            formatter: "{num|{c}}  {per|{d}%}\n{name|{b}}",
+            minMargin: 5,
+            edgeDistance: 10,
+            lineHeight: 15,
             rich: {
-              color1: {
-                color: "#ff9500",
-              },
-              color2: {
-                color: "#02d8f9",
+              num: {
+                fontSize: 14,
+                fontWeight: "bold",
+                lineHeight: 25,
+                color: "inherit",
               },
-              color3: {
-                color: "#027fff",
+              per: {
+                fontSize: 12,
+                fontWeight: "bold",
+                lineHeight: 25,
+                color: "inherit",
               },
-              color4: {
-                color: "#e5eaff",
+              name: {
+                fontSize: 12,
+                fontWeight: "bold",
+                lineHeight: 25,
+                color: "inherit",
               },
             },
           },

+ 247 - 161
src/views/snapshot/left-center.vue

@@ -1,31 +1,59 @@
 <template>
   <div class="left-center">
-    <div class="left-center-title flex items-center">
-      <img src="@/assets/img/home/title_arrow.png" alt="" />
-      受理类型办件分析
+    <div class="left-center-title flex items-center justify-between">
+      分析时间:
+      <el-date-picker
+        v-model="timeValue"
+        type="daterange"
+        unlink-panels
+        range-separator="至"
+        start-placeholder="开始时间"
+        end-placeholder="结束时间"
+        :shortcuts="shortcuts"
+        :clearable="false"
+        @change="changeDate"
+      />
     </div>
-    <div class="left-center-content">
-      <template v-if="xData.length">
+    <div class="left-center-content flex justify-center">
+      <div class="w-full">
         <v-chart
           class="chart"
           :option="option"
           :loading="loading"
           :loading-options="loadingOptions"
+          style="height: calc(100% - 50px)"
         />
-      </template>
-      <empty v-else />
+        <p class="w-full" style="text-align: center">已办件数</p>
+      </div>
+      <div class="w-full">
+        <v-chart
+          class="chart1"
+          :option="option1"
+          :loading="loading"
+          :loading-options="loadingOptions"
+          style="height: calc(100% - 50px)"
+        />
+        <p class="w-full" style="text-align: center">在办件数</p>
+      </div>
+      <div class="w-full">
+        <v-chart
+          class="chart2"
+          :option="option2"
+          :loading="loading"
+          :loading-options="loadingOptions"
+          style="height: calc(100% - 50px)"
+        />
+        <p class="w-full" style="text-align: center">上报数</p>
+      </div>
     </div>
   </div>
 </template>
 <script setup lang="ts">
-import { ref, onMounted, watch, defineAsyncComponent } from "vue";
+import { ref, onMounted, watch } from "vue";
 import { acceptType } from "@/api/home";
 import dayjs from "dayjs";
-import { loadingOptions } from "@/utils/constants";
+import { loadingOptions, shortcuts } from "@/utils/constants";
 
-const Empty = defineAsyncComponent(
-  () => import("@/components/Empty/index.vue")
-);
 const props = defineProps({
   dateArray: {
     type: Array,
@@ -42,6 +70,16 @@ watch(
   { immediate: true }
 );
 
+const emit = defineEmits(["changeDate"]);
+const timeValue = ref<any>([
+  dayjs().subtract(1, "month").toDate(),
+  dayjs().toDate(),
+]); //默认近一个月
+emit("changeDate", timeValue.value);
+const changeDate = (val: any) => {
+  emit("changeDate", val);
+};
+
 watch(
   () => props.dateArray,
   (val: any) => {
@@ -50,7 +88,8 @@ watch(
 );
 
 const option = ref({});
-const xData = ref([]);
+const option1 = ref({});
+const option2 = ref({});
 const loading = ref(true);
 const getData = async () => {
   loading.value = true;
@@ -59,171 +98,219 @@ const getData = async () => {
       StartTime: dayjs(date.value[0]).format("YYYY-MM-DD"),
       EndTime: dayjs(date.value[1]).format("YYYY-MM-DD"),
     });
-    xData.value = result.map((item: any) => item.acceptType);
-    const totalData = result.reduce((pre: any, cur: any) => {
-      pre.push(cur.sumCount);
-      return pre;
-    }, []);
-    const handlingCount = result.reduce((pre: any, cur: any) => {
-      pre.push(cur.handlingCount);
-      return pre;
-    }, []);
-    const filedCount = result.reduce((pre: any, cur: any) => {
-      pre.push(cur.filedCount);
-      return pre;
-    }, []);
-    const overTimeCount = result.reduce((pre: any, cur: any) => {
-      pre.push(cur.overTimeCount);
-      return pre;
-    }, []);
-    // mock 数据
-    let dataArr = {
-      xData: xData.value,
-      result: [
-        { name: "总数", data: totalData },
-        { name: "已办", data: handlingCount },
-        { name: "在办", data: filedCount },
-        { name: "超期", data: overTimeCount },
-      ],
-      series: [],
-    };
-    const diamondData = dataArr.result.reduce((pre, cur, index) => {
-      pre[index] = cur.data.map(
-        (el, id) => el + (pre[index - 1] ? pre[index - 1][id] : 0)
-      );
-      return pre;
-    }, []);
-    const color = [
-      [
-        { offset: 0, color: "#efff37" },
-        { offset: 1, color: "#d5e700" },
-      ],
-      [
-        { offset: 0, color: "#32ffee" },
-        { offset: 1, color: "#00e8d5" },
-      ],
-      [
-        { offset: 0, color: "#46c9ff" },
-        { offset: 1, color: "#00b4ff" },
-      ],
-      [
-        { offset: 0, color: "#54a0ff" },
-        { offset: 1, color: "#1f83ff" },
-      ],
-    ];
-
-    dataArr.series = dataArr.result.reduce((p, c, i, array) => {
-      p.push(
+    const data = { name: "已办件数", value: 91.22, data: 2020 };
+    setOption(data);
+    setOption1(data);
+    setOption2(data);
+    loading.value = false;
+  } catch (e) {
+    console.log(e);
+    loading.value = false;
+  }
+};
+// 圆环--开始色
+let baseColorStart = "#45A5DB";
+// 圆环--结束色
+let baseColorEnd = "#0A6BC5";
+// 圆环--环底色
+let ringColor = "#112A5D";
+const setOption = (data: any) => {
+  option.value = {
+    // 还原内部文字
+    title: [
+      {
+        text: data.value + "%",
+        top: "40%",
+        right: "30%",
+        textStyle: {
+          color: "#fff",
+          fontSize: 18,
+          fontWeight: 400,
+        },
+      },
+      {
+        text: data.data,
+        top: "53%",
+        right: "center",
+        textStyle: {
+          color: "#6F87B1",
+          fontSize: 14,
+          fontWeight: 400,
+        },
+      },
+    ],
+    series: {
+      name: "已办件数",
+      type: "pie",
+      radius: ["60%", "85%"],
+      silent: true,
+      clockwise: true,
+      startAngle: 90,
+      label: {
+        show: false,
+      },
+      data: [
         {
-          z: i + 1,
-          stack: true,
-          type: "bar",
-          name: c.name,
-          barWidth: 15,
-          data: c.data,
+          value: data.value,
           itemStyle: {
             color: {
               type: "linear",
               x: 0,
-              x2: 0,
               y: 0,
+              x2: 0,
               y2: 1,
-              colorStops: color[i],
+              colorStops: [
+                {
+                  offset: 0,
+                  color: baseColorStart,
+                },
+                {
+                  offset: 1,
+                  color: baseColorEnd,
+                },
+              ],
             },
           },
         },
         {
-          z: i + 10,
-          name: c.name,
-          type: "pictorialBar",
-          symbolPosition: "end",
-          symbol: "circle",
-          symbolOffset: [0, "-50%"],
-          symbolSize: [15, 12.5],
-          data: diamondData[i],
+          name: "待办件数",
+          value: 100 - data.value,
+          label: {
+            show: false,
+          },
           itemStyle: {
-            color: color[i + 1] ? color[i + 1][0].color : null,
+            // 圆环底色
+            color: ringColor,
           },
-          tooltip: { show: false },
-        }
-      );
-
-      return p;
-    }, []);
-
-    // 最上边顶
-    dataArr.series.push({
-      name: dataArr.result[dataArr.result.length - 1].name,
-      z: 20,
-      type: "pictorialBar",
-      symbolPosition: "end",
-      data: diamondData[diamondData.length - 1],
-      symbol: "circle",
-      symbolOffset: ["0%", "-50%"],
-      symbolSize: [15, 12.5],
-      itemStyle: {
-        color: color[color.length - 1][0].color,
+        },
+      ],
+    },
+  };
+};
+const setOption1 = (data: any) => {
+  option1.value = {
+    tooltip: {},
+    // 还原内部文字
+    title: [
+      {
+        text: data.value + "%",
+        top: "40%",
+        right: "30%",
+        textStyle: {
+          color: "#fff",
+          fontSize: 18,
+          fontWeight: 400,
+        },
       },
-      tooltip: { show: false },
-    });
-
-    // 最下边底
-    dataArr.series.push({
-      name: dataArr.result[0].name,
-      z: 30,
-      type: "pictorialBar",
-      symbolPosition: "start",
-      data: diamondData[0],
-      symbol: "circle",
-      symbolOffset: ["0%", "50%"],
-      symbolSize: [15, 12.5],
-      itemStyle: {
-        color: color[0][0].color,
+      {
+        text: data.data,
+        top: "53%",
+        right: "center",
+        textStyle: {
+          color: "#6F87B1",
+          fontSize: 14,
+          fontWeight: 400,
+        },
       },
-      tooltip: { show: false },
-    });
-    setOption(dataArr);
-    loading.value = false;
-  } catch (e) {
-    console.log(e);
-    loading.value = false;
-  }
-};
-const setOption = (data: any) => {
-  option.value = {
-    tooltip: {
-      trigger: "axis",
-      backgroundColor: "rgba(0,0,0,0.7)",
-      borderColor: "#000",
-      borderWidth: 1,
-      textStyle: { color: "#fff" },
-    },
-    xAxis: {
-      axisTick: { show: true },
-      axisLine: { lineStyle: { color: "rgba(255,255,255, .2)" } },
-      axisLabel: { fontSize: 12, color: "#fff" },
-      data: data.xData,
+    ],
+    series: {
+      name: "",
+      type: "pie",
+      radius: ["60%", "85%"],
+      silent: true,
+      clockwise: true,
+      startAngle: 90,
+      label: {
+        show: false,
+      },
+      data: [
+        {
+          value: data.value,
+          itemStyle: {
+            color: {
+              type: "linear",
+              x: 0,
+              y: 0,
+              x2: 0,
+              y2: 1,
+              colorStops: [
+                {
+                  offset: 0,
+                  color: baseColorStart,
+                },
+                {
+                  offset: 1,
+                  color: baseColorEnd,
+                },
+              ],
+            },
+          },
+        },
+        {
+          value: 100 - data.value,
+          label: {
+            show: false,
+          },
+          itemStyle: {
+            // 圆环底色
+            color: ringColor,
+          },
+        },
+      ],
     },
-    yAxis: [
+  };
+};
+const setOption2 = (data: any) => {
+  option2.value = {
+    tooltip: {},
+    // 还原内部文字
+    title: [
       {
-        name: "单位:件",
-        nameTextStyle: { color: "#fff", fontSize: 14 },
-        nameGap: 25,
-        splitLine: { lineStyle: { color: "rgba(255,255,255, .05)" } },
-        axisLine: { show: false },
-        axisLabel: { fontSize: 12, color: "#fff" },
+        text: data.data,
+        top: "45%",
+        right: "center",
+        textStyle: {
+          color: "#fff",
+          fontSize: 18,
+          fontWeight: 400,
+        },
       },
     ],
-    grid: { top: "20%", left: "10%", right: "3%", bottom: "10%" },
-    legend: {
-      data: data.result.map((item) => item.name),
-      textStyle: { fontSize: 12, color: "#fff" },
-      itemWidth: 15,
-      itemHeight: 10,
-      top: "10%",
-      right: "20",
+    series: {
+      name: "",
+      type: "pie",
+      radius: ["60%", "85%"],
+      silent: true,
+      clockwise: true,
+      startAngle: 90,
+      label: {
+        show: false,
+      },
+      data: [
+        {
+          value: data.value,
+          itemStyle: {
+            color: {
+              type: "linear",
+              x: 0,
+              y: 0,
+              x2: 0,
+              y2: 1,
+              colorStops: [
+                {
+                  offset: 0,
+                  color: baseColorStart,
+                },
+                {
+                  offset: 1,
+                  color: baseColorEnd,
+                },
+              ],
+            },
+          },
+        },
+      ],
     },
-    series: data.series,
   };
 };
 onMounted(() => {
@@ -232,15 +319,14 @@ onMounted(() => {
 </script>
 <style scoped lang="scss">
 .left-center {
-  padding: 10px 20px;
+  padding: 15px 20px;
 
   &-title {
-    font-size: 20px;
     color: #fff;
   }
-
   .left-center-content {
     height: 260px;
+    padding: 0 10px;
   }
 }
 </style>

+ 104 - 206
src/views/snapshot/right-bottom.vue

@@ -1,44 +1,47 @@
 <template>
-  <div class="left_bottom">
-    <div class="left_bottom-title flex">
+  <div class="right-bottom">
+    <div class="right-bottom-title flex">
       <div class="flex items-center">
         <img src="@/assets/img/home/title_arrow.png" alt="" />
-        占比分析
+        最近受理工单
       </div>
-      <div class="left_bottom-title-tabs">
-        <span
-          :class="{ active: activeIndex === 0 }"
-          class="mr-5 left_bottom-title-tabs-item"
-          @click="change(0)"
-          >来源方式</span
-        >
-        <span
-          :class="{ active: activeIndex === 1 }"
-          class="left_bottom-title-tabs-item"
-          @click="change(1)"
-          >受理类型</span
+    </div>
+    <div class="right-bottom-content">
+      <div class="table-header">
+        <div class="table-header-item">工单编码</div>
+        <div class="table-header-item">当前节点</div>
+        <div class="table-header-item">行业类型</div>
+        <div class="table-header-item">区域</div>
+        <div class="table-header-item">热点类型</div>
+      </div>
+      <div class="scroll" v-loading="loading">
+        <vue3-seamless-scroll
+          :list="list"
+          hover
+          :singleHeight="100"
+          v-if="list.length"
         >
+          <div class="item" v-for="(item, index) in list" :key="index">
+            <TextTooltip :content="item.no"></TextTooltip>
+            <TextTooltip :content="item.title"></TextTooltip>
+            <TextTooltip :content="item.acceptType"></TextTooltip>
+            <TextTooltip :content="item.county"></TextTooltip>
+            <TextTooltip :content="item.hotspotName"></TextTooltip>
+          </div>
+        </vue3-seamless-scroll>
+        <empty v-else />
       </div>
     </div>
-    <div class="left_bottom-content">
-      <template v-if="dataList.length">
-        <v-chart
-          class="chart"
-          :option="option"
-          :loading="loading"
-          :loading-options="loadingOptions"
-        />
-      </template>
-      <empty v-else />
-    </div>
   </div>
 </template>
 <script setup lang="ts">
-import { ref, onMounted, watch, computed, defineAsyncComponent } from "vue";
-import { proportionAnalysis } from "api/home";
-import dayjs from "dayjs";
-import { loadingOptions } from "@/utils/constants";
+import { ref, onMounted, watch, defineAsyncComponent } from "vue";
+import { orderView } from "api/home";
+import { Vue3SeamlessScroll } from "vue3-seamless-scroll";
 
+const TextTooltip = defineAsyncComponent(
+  () => import("@/components/TextTooltip/index.vue")
+);
 const Empty = defineAsyncComponent(
   () => import("@/components/Empty/index.vue")
 );
@@ -64,183 +67,25 @@ watch(
   }
 );
 
-const activeIndex = ref(0);
-const option = ref<any>({});
-const activeText = computed(() => {
-  return activeIndex.value === 0 ? "来源占比" : "类型占比";
-});
-const change = (index: number) => {
-  activeIndex.value = index;
-  getData();
-};
-const dataList = ref([]);
 const loading = ref(false);
+const list = ref([]);
 const getData = async () => {
   loading.value = true;
   try {
-    const { result } = await proportionAnalysis({
-      StartTime: dayjs(date.value[0]).format("YYYY-MM-DD"),
-      EndTime: dayjs(date.value[1]).format("YYYY-MM-DD"),
-      IsSource: activeIndex.value === 0,
-    });
-    const legEndTime = result
-      .map((item: any) => item.name)
-      .filter((item: any) => item);
-    dataList.value = result
-      .map((item: any) => {
-        return {
-          name: item.name ?? "",
-          value: item.hasCount,
-          ...item,
-        };
-      })
-      .filter((item: any) => item.name);
-    setOption(legEndTime, dataList.value);
+    const { result } = await orderView();
+    list.value = result;
     loading.value = false;
   } catch (e) {
     loading.value = false;
     console.log(e);
   }
 };
-const setOption = (legEndTime: any, data: any) => {
-  option.value = {
-    tooltip: {
-      trigger: "item",
-    },
-    legend: {
-      type: "scroll",
-      pageIconColor: "#fff",
-      pageIconInactiveColor: "#333",
-      height: "180",
-      icon: "circle",
-      top: "center",
-      right: "0",
-      orient: "vertical",
-      itemGap: 20,
-      data: legEndTime,
-      textStyle: {
-        color: "#fff",
-        fontSize: 14,
-      },
-      formatter: (name) => {
-        const item = dataList.value.find((item) => item.name == name);
-        const len = name.length;
-        let str = "";
-        if (len > 5) {
-          name = name.slice(0, 8) + "...";
-        } else {
-          name = name + str;
-        }
-        return `${name}  ${item.hasRate}% (${item.hasCount}件)`; //返回出图例所显示的内容是名称+百分比
-      },
-    },
-    graphic: [
-      {
-        type: "text",
-        z: 100,
-        left: "23%",
-        top: "40%",
-        style: {
-          fill: "#fff",
-          text: "100%",
-          font: "28px Microsoft YaHei",
-        },
-      },
-      {
-        type: "text",
-        z: 100,
-        left: "24%",
-        top: "56%",
-        style: {
-          fill: "#fff",
-          text: activeText.value,
-          font: "16px Microsoft YaHei",
-        },
-      },
-    ],
-    series: [
-      {
-        name: "",
-        type: "gauge",
-        splitNumber: 10,
-        radius: "65%",
-        center: ["30%", "50%"],
-        startAngle: 0,
-        endAngle: 360,
-        axisLine: {
-          show: false,
-        },
-        axisTick: {
-          show: true,
-          lineStyle: {
-            width: 4,
-          },
-          length: 8,
-          splitNumber: 3,
-        },
-        splitLine: {
-          show: false,
-        },
-        axisLabel: {
-          show: false,
-        },
-        detail: {
-          show: false,
-        },
-      },
-      {
-        name: "数量", //内部圆
-        type: "pie",
-        animation: false,
-        clockwise: false,
-        radius: "38%",
-        center: ["30%", "50%"],
-        data: [10],
-        itemStyle: {
-          color: "#082141",
-        },
-        label: {
-          show: false,
-        },
-        emphasis: {
-          show: false,
-          textStyle: {
-            fontSize: "14",
-          },
-        },
-        labelLine: {
-          show: false,
-        },
-      },
-      {
-        name: "",
-        type: "pie",
-        radius: ["55%", "80%"],
-        center: ["30%", "50%"],
-        avoidLabelOverlap: false,
-        itemStyle: {
-          borderRadius: 0,
-          borderColor: "#050D0E",
-          borderWidth: 10,
-        },
-        label: {
-          show: false,
-          formatter: "{b}:{d}%", // 用来换行
-        },
-        labelLine: {
-          show: false,
-        },
-        data: data,
-      },
-    ],
-  };
-};
 onMounted(() => {
   getData();
 });
 </script>
 <style scoped lang="scss">
-.left_bottom {
+.right-bottom {
   padding: 10px 20px;
 
   &-title {
@@ -248,26 +93,79 @@ onMounted(() => {
     color: #fff;
     justify-content: space-between;
     align-items: center;
+  }
+  :deep(.custom-text-content) {
+    flex: 1;
+    text-align: center;
+    color: #cfd2d2;
+  }
+  &-content {
+    margin-top: 10px;
+    font-size: 14px;
+    .table-header {
+      display: flex;
+      justify-content: space-between;
+      background: linear-gradient(
+        to right,
+        rgba(27, 51, 55, 0.8),
+        rgba(45, 83, 91, 0.8)
+      );
 
-    &-tabs {
-      font-size: 14px;
-      color: #7dbdec;
+      width: 100%;
+      height: 40px;
+      line-height: 40px;
 
-      &-item {
-        padding: 5px 10px;
-        cursor: pointer;
+      .table-header-item {
+        text-align: center;
+        color: #b4d7ec;
+        flex: 1;
       }
     }
 
-    .active {
-      color: #b4d7ec;
-      border: 1px solid #b4d7ec;
-      border-radius: 5px;
-    }
-  }
+    .scroll {
+      height: 380px;
+      overflow: hidden;
+      margin-top: 10px;
 
-  &-content {
-    height: calc(100% - 40px);
+      .item {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        border-bottom: 1px solid #225073;
+        padding: 6px 0;
+
+        span {
+          display: inline-block;
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          text-align: center;
+          color: #cfd2d2;
+          flex: 1;
+        }
+
+        .exceedSoon {
+          border: 1px solid #eca455;
+          border-radius: 3px;
+          color: #eca455;
+          padding: 2px 5px;
+        }
+
+        .exceed {
+          border: 1px solid #d70024;
+          border-radius: 3px;
+          color: #d70024;
+          padding: 2px 5px;
+        }
+
+        .normal {
+          border: 1px solid #69bbf6;
+          border-radius: 3px;
+          color: #69bbf6;
+          padding: 2px 5px;
+        }
+      }
+    }
   }
 }
 </style>