Parcourir la source

feat:大屏数据对接;

zhangchong il y a 1 an
Parent
commit
71243a368b

+ 17 - 17
src/App.vue

@@ -1,41 +1,41 @@
 <template>
   <el-config-provider
-    :size="getGlobalComponentSize"
-    :locale="zhCn"
-    :message="messageConfig"
-    :button="buttonConfig"
+      :size="getGlobalComponentSize"
+      :locale="zhCn"
+      :message="messageConfig"
+      :button="buttonConfig"
   >
-    <el-watermark class="h100"  :font="config.font" :content="config.content"
-      :z-index="config.zIndex"
-      :rotate="config.rotate"
-      :gap="config.gap"
-      :offset="config.offset">
-      <RouterView />
+    <el-watermark class="h100" :font="config.font" :content="config.content"
+                  :z-index="config.zIndex"
+                  :rotate="config.rotate"
+                  :gap="config.gap"
+                  :offset="config.offset">
+      <RouterView/>
     </el-watermark>
   </el-config-provider>
 </template>
 <script setup lang="ts">
-import { computed,reactive,watch } from "vue";
+import {computed, reactive, watch} from "vue";
 import zhCn from "element-plus/es/locale/lang/zh-cn";
 import signalR from "@/utils/signalR";
 import {RouterView, useRoute} from "vue-router";
-import { useTitle } from "@/utils/tools";
+import {useTitle} from "@/utils/tools";
 //  signalR 初始化signalr
 signalR.init();
-signalR.joinGroup("BigScreen-DataShow");
-signalR.joinGroup("BigScreen-SeatState");
-
+signalR.joinGroup("BigScreen-DataShow"); //index
+signalR.joinGroup("BigScreen-SeatState"); // seat
+signalR.joinGroup("BigData-Screen"); // home
 // 获取全局组件大小
 const getGlobalComponentSize = computed(() => {
   return 'default';
 });
 // 可同时显示的消息最大数量
 const messageConfig = reactive<any>({
-	max: 3,
+  max: 3,
 });
 // 自动在两个中文字符之间插入空格
 const buttonConfig = reactive<any>({
-	autoInsertSpace: false,
+  autoInsertSpace: false,
 });
 // 水印配置
 const config = reactive({

+ 12 - 0
src/api/home.ts

@@ -110,6 +110,18 @@ export const areaAccept = (params?: object) => {
         params,
     });
 }
+/**
+ * @description 区域明细数据
+ * @param {object} params
+ * @return {*}
+ */
+export const areaDetail = (params?: object) => {
+    return request({
+        url: `/api/v1/DataScreen/orderareaaccept-query`,
+        method: 'get',
+        params,
+    });
+}
 /**
  * @description 办理中工单阅览
  * @param {object} params

+ 2 - 3
src/components/empty-com/empty-com.vue

@@ -1,4 +1,3 @@
-
 <template>
   <div class="empty w-full h-full">
     暂无数据
@@ -8,10 +7,10 @@
 <script setup lang="ts">
 </script>
 <style scoped lang="scss">
-.empty{
+.empty {
   display: flex;
   align-items: center;
   justify-content: center;
-  font-size: 24px;
+  font-size: 18px;
 }
 </style>

+ 11 - 9
src/utils/mitt.ts

@@ -1,17 +1,19 @@
 // https://www.npmjs.com/package/mitt 全局事件总线
-import mitt, { Emitter } from 'mitt';
+import mitt, {Emitter} from 'mitt';
 
 // mitt 事件类型定义
 declare type MittType = {
-    Send?:string; // 加入分组消息
-    BsDataShowArea1?:string; // 工单办理
-    BsDataShowArea3?:string; // 来电实况
-    BsDataShowArea8?:string; // 工单概览
+    Send?: string; // 加入分组消息
+    BsDataShowArea1?: string; // 工单办理
+    BsDataShowArea3?: string; // 来电实况
+    BsDataShowArea8?: string; // 工单概览
     SeatState?: string; // 坐席监控
-    BsSeatStateDataShowArea1?:string; // 24小时话务量
-    BsSeatStateDataShowArea2?:string; // 24小时坐席话务top10
-    BsSeatStateDataShowArea3?:string; // 24小时坐席话务量数据
-    BsSeatStateDataShowArea4?:string; // 数据展示
+    BsSeatStateDataShowArea1?: string; // 24小时话务量
+    BsSeatStateDataShowArea2?: string; // 24小时坐席话务top10
+    BsSeatStateDataShowArea3?: string; // 24小时坐席话务量数据
+    BsSeatStateDataShowArea4?: string; // 数据展示
+    ordercountstatistics: string; // 大屏展示 中上工单数量
+    orderHandlingDetail: string; // 大屏展示 办理中工单概览
 };
 // 类型
 const emitter: Emitter<MittType> = mitt<MittType>();

+ 172 - 163
src/utils/signalR.ts

@@ -1,170 +1,179 @@
 // 官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/signalr/javascript-client?view=aspnetcore-6.0&viewFallbackFrom=aspnetcore-2.2&tabs=visual-studio
 import * as signalR from '@microsoft/signalr';
 import mittBus from '@/utils/mitt';
+
 export default {
-	// signalR对象
-	SR: null as any,
-	// 失败连接重试次数
-	failNum: 4,
-	baseUrl: import.meta.env.VITE_API_SOCKET_URL,
-	groupName:'',
-	init() {
-		const token = sessionStorage.getItem('token');
-		const connection = new signalR.HubConnectionBuilder()
-			.withUrl(this.baseUrl, { accessTokenFactory: () => '', skipNegotiation: true, transport: 1 })
-			.withAutomaticReconnect() //自动重新连接
-			.configureLogging(signalR.LogLevel.Warning)
-			.build();
+    // signalR对象
+    SR: null as any,
+    // 失败连接重试次数
+    failNum: 4,
+    baseUrl: import.meta.env.VITE_API_SOCKET_URL,
+    groupName: '',
+    init() {
+        const token = sessionStorage.getItem('token');
+        const connection = new signalR.HubConnectionBuilder()
+            .withUrl(this.baseUrl, {accessTokenFactory: () => '', skipNegotiation: true, transport: 1})
+            .withAutomaticReconnect() //自动重新连接
+            .configureLogging(signalR.LogLevel.Warning)
+            .build();
 
-		this.SR = connection;
-		// 断线重连
-		connection.onclose(async () => {
-			console.log('当前链接状态:', connection.state);
-			// 建议用户重新刷新浏览器
-			await this.start();
-		});
-		connection.onreconnected(() => {
-			console.log('断线重连成功');
-			location.reload();
-			/*ElNotification({
-				type: 'success',
-				title: '提示',
-				message: `断线重连成功`,
-			});*/
-		});
-		// 服务端推送消息
-		connection.on('Send', (message: any) => {
-			mittBus.emit('Send', message);// 通知
-		});
-		// 服务端推送消息
-		connection.on('BsDataShowArea1', (message: any) => {
-			// console.log(`工单办理`, message);
-			mittBus.emit('BsDataShowArea1', message);// 通知
-		});
-		// 服务端推送消息
-		connection.on('BsDataShowArea3', (message: any) => {
-			mittBus.emit('BsDataShowArea3', message);// 通知
-		});
-		// 服务端推送消息
-		connection.on('BsDataShowArea8', (message: any) => {
-			mittBus.emit('BsDataShowArea8', message);// 通知
-		});
-		// 服务端推送消息
-		connection.on('SeatState', (message: any) => {
-			mittBus.emit('SeatState', message);// 通知
-		});
-		// 服务端推送消息
-		connection.on('BsSeatStateDataShowArea1', (message: any) => {
-			mittBus.emit('BsSeatStateDataShowArea1', message);// 通知
-		});
-		// 服务端推送消息
-		connection.on('BsSeatStateDataShowArea2', (message: any) => {
-			mittBus.emit('BsSeatStateDataShowArea2', message);// 通知
-		});
-		// 服务端推送消息
-		connection.on('BsSeatStateDataShowArea3', (message: any) => {
-			mittBus.emit('BsSeatStateDataShowArea3', message);// 通知
-		});
-		// 服务端推送消息
-		connection.on('BsSeatStateDataShowArea4', (message: any) => {
-			mittBus.emit('BsSeatStateDataShowArea4', message);// 通知
-		});
-	},
-	/**
-	 * @description 调用 this.signalR.start().then(async () => { await this.SR.invoke("method")})
-	 * state  Connected 已连接  Connecting 正在连接  Disconnected 断开连接 Reconnecting 正在重新连接
-	 * @returns
-	 */
-	async start() {
-		try {
-			//使用async和await 或 promise的then 和catch 处理来自服务端的异常
-			await this.SR.start();
-			console.log('当前链接状态:', this.SR.state);
-			return Promise.resolve();
-		} catch (error: any) {
-			this.failNum--;
-			if (this.failNum > 0 && this.SR.state === 'Disconnected') {
-				//断开链接重新链接
-				/*ElNotification({
-					type: 'warning',
-					title: '提示',
-					message: `断开连接了,正在重连, 剩余自动重连次数${this.failNum} 次,如未重连成功,请刷新浏览器重试`,
-				});*/
-				setTimeout(async () => {
-					await this.SR.start();
-				}, 5000);
-			}
-			return Promise.reject(error);
-		}
-	},
-	/**
-	 * @description 加入分组
-	 * @param groupName string 分组名称
-	 * @params {string} CallCenter 呼叫中心
-	 * @params BigScreenDataShow 大屏数据展示
-	 * @returns
-	 */
-	async joinGroup(groupName: string) {
-		if (this.SR.state === 'Connected') {
-			// 判断是否已经建立链接 如果没有 先链接
-			await this.SR.invoke('JoinGroupUnauthAsync', {GroupName:groupName});
-		} else {
-			// 等待链接成功再发送
-			if(this.SR.state === 'Connecting') {
-				setTimeout(async () => {
-					await this.SR.invoke('JoinGroupUnauthAsync', {GroupName:groupName});
-				},500)
-				return
-			}
-			await this.start().then(async () => {
-				setTimeout(async () => {
-					await this.SR.invoke('JoinGroupUnauthAsync', {GroupName:groupName});
-				},500)
-			}).catch((err) => {
-				console.log(err);
-			})
-		}
-	},
-	/**
-	 * @description 离开分组
-	 * @param groupName string
-	 * @params CallCenter 呼叫中心
-	 * @params BigScreenDataShow 大屏数据展示
-	 * @returns
-	 */
-	async leaveGroup(groupName: string) {
-		if (this.SR.state === 'Connected') {
-			// 判断是否已经建立链接 如果没有 先链接
-			await this.SR.invoke('LeaveGroupUnauthAsync', {GroupName:groupName});
-		} else {
-			// 等待链接成功再发送
-			if(this.SR.state === 'Connecting') {
-				setTimeout(async () => {
-					await this.SR.invoke('LeaveGroupUnauthAsync', {GroupName:groupName});
-				},500)
-				return
-			}
-			await this.start().then(async () => {
-				setTimeout(async () => {
-					await this.SR.invoke('JoinGroupUnauthAsync', {GroupName:groupName});
-				},500)
-			}).catch((err) => {
-				console.log(err);
-			})
-		}
-	},
+        this.SR = connection;
+        // 断线重连
+        connection.onclose(async () => {
+            console.log('当前链接状态:', connection.state);
+            // 建议用户重新刷新浏览器
+            await this.start();
+        });
+        connection.onreconnected(() => {
+            console.log('断线重连成功');
+            location.reload();
+            /*ElNotification({
+                type: 'success',
+                title: '提示',
+                message: `断线重连成功`,
+            });*/
+        });
+        // 服务端推送消息
+        connection.on('Send', (message: any) => {
+            mittBus.emit('Send', message);// 通知
+        });
+        // 服务端推送消息
+        connection.on('BsDataShowArea1', (message: any) => {
+            // console.log(`工单办理`, message);
+            mittBus.emit('BsDataShowArea1', message);// 通知
+        });
+        // 服务端推送消息
+        connection.on('BsDataShowArea3', (message: any) => {
+            mittBus.emit('BsDataShowArea3', message);// 通知
+        });
+        // 服务端推送消息
+        connection.on('BsDataShowArea8', (message: any) => {
+            mittBus.emit('BsDataShowArea8', message);// 通知
+        });
+        // 服务端推送消息
+        connection.on('SeatState', (message: any) => {
+            mittBus.emit('SeatState', message);// 通知
+        });
+        // 服务端推送消息
+        connection.on('BsSeatStateDataShowArea1', (message: any) => {
+            mittBus.emit('BsSeatStateDataShowArea1', message);// 通知
+        });
+        // 服务端推送消息
+        connection.on('BsSeatStateDataShowArea2', (message: any) => {
+            mittBus.emit('BsSeatStateDataShowArea2', message);// 通知
+        });
+        // 服务端推送消息
+        connection.on('BsSeatStateDataShowArea3', (message: any) => {
+            mittBus.emit('BsSeatStateDataShowArea3', message);// 通知
+        });
+        // 服务端推送消息
+        connection.on('BsSeatStateDataShowArea4', (message: any) => {
+            mittBus.emit('BsSeatStateDataShowArea4', message);// 通知
+        });
+        // 服务端推送消息
+        connection.on('ordercountstatistics', (message: any) => {
+            mittBus.emit('ordercountstatistics', message);// 通知
+        });
+        // 服务端推送消息
+        connection.on('orderHandlingDetail', (message: any) => {
+            mittBus.emit('orderHandlingDetail', message);// 通知
+        });
+    },
+    /**
+     * @description 调用 this.signalR.start().then(async () => { await this.SR.invoke("method")})
+     * state  Connected 已连接  Connecting 正在连接  Disconnected 断开连接 Reconnecting 正在重新连接
+     * @returns
+     */
+    async start() {
+        try {
+            //使用async和await 或 promise的then 和catch 处理来自服务端的异常
+            await this.SR.start();
+            console.log('当前链接状态:', this.SR.state);
+            return Promise.resolve();
+        } catch (error: any) {
+            this.failNum--;
+            if (this.failNum > 0 && this.SR.state === 'Disconnected') {
+                //断开链接重新链接
+                /*ElNotification({
+                    type: 'warning',
+                    title: '提示',
+                    message: `断开连接了,正在重连, 剩余自动重连次数${this.failNum} 次,如未重连成功,请刷新浏览器重试`,
+                });*/
+                setTimeout(async () => {
+                    await this.SR.start();
+                }, 5000);
+            }
+            return Promise.reject(error);
+        }
+    },
+    /**
+     * @description 加入分组
+     * @param groupName string 分组名称
+     * @params {string} CallCenter 呼叫中心
+     * @params BigScreenDataShow 大屏数据展示
+     * @returns
+     */
+    async joinGroup(groupName: string) {
+        if (this.SR.state === 'Connected') {
+            // 判断是否已经建立链接 如果没有 先链接
+            await this.SR.invoke('JoinGroupUnauthAsync', {GroupName: groupName});
+        } else {
+            // 等待链接成功再发送
+            if (this.SR.state === 'Connecting') {
+                setTimeout(async () => {
+                    await this.SR.invoke('JoinGroupUnauthAsync', {GroupName: groupName});
+                }, 500)
+                return
+            }
+            await this.start().then(async () => {
+                setTimeout(async () => {
+                    await this.SR.invoke('JoinGroupUnauthAsync', {GroupName: groupName});
+                }, 500)
+            }).catch((err) => {
+                console.log(err);
+            })
+        }
+    },
+    /**
+     * @description 离开分组
+     * @param groupName string
+     * @params CallCenter 呼叫中心
+     * @params BigScreenDataShow 大屏数据展示
+     * @returns
+     */
+    async leaveGroup(groupName: string) {
+        if (this.SR.state === 'Connected') {
+            // 判断是否已经建立链接 如果没有 先链接
+            await this.SR.invoke('LeaveGroupUnauthAsync', {GroupName: groupName});
+        } else {
+            // 等待链接成功再发送
+            if (this.SR.state === 'Connecting') {
+                setTimeout(async () => {
+                    await this.SR.invoke('LeaveGroupUnauthAsync', {GroupName: groupName});
+                }, 500)
+                return
+            }
+            await this.start().then(async () => {
+                setTimeout(async () => {
+                    await this.SR.invoke('JoinGroupUnauthAsync', {GroupName: groupName});
+                }, 500)
+            }).catch((err) => {
+                console.log(err);
+            })
+        }
+    },
 
-	/**
-	 * @description 关闭链接
-	 * @returns
-	 */
-	async stop() {
-		try {
-			//使用async和await 或 promise的then 和catch 处理来自服务端的异常
-			await this.SR.stop();
-			console.log(this.SR.state, '断开链接');
-		} catch (error) {
-			console.log('signalR', error);
-		}
-	},
+    /**
+     * @description 关闭链接
+     * @returns
+     */
+    async stop() {
+        try {
+            //使用async和await 或 promise的then 和catch 处理来自服务端的异常
+            await this.SR.stop();
+            console.log(this.SR.state, '断开链接');
+        } catch (error) {
+            console.log('signalR', error);
+        }
+    },
 };

+ 14 - 6
src/views/home/center-bottom.vue

@@ -29,10 +29,10 @@
               <template #content> {{ item.title }}</template>
               <span>{{ item.title }}</span>
             </el-tooltip>
-            <span>{{ item.acceptType }}</span>
-            <span>{{ item.hotspotName }}</span>
-            <span>{{ item.county }}</span>
-            <span>{{ item.actualHandleOrgName }}</span>
+            <span :title="item.acceptType">{{ item.acceptType }}</span>
+            <span :title="item.hotspotName">{{ item.hotspotName }}</span>
+            <span :title="item.county">{{ item.county }}</span>
+            <span :title="item.actualHandleOrgName">{{ item.actualHandleOrgName }}</span>
           </div>
         </vue3-seamless-scroll>
       </div>
@@ -40,10 +40,10 @@
   </div>
 </template>
 <script setup lang="ts">
-import {ref, onMounted} from "vue";
+import {ref, onMounted, onUnmounted} from "vue";
 import {Vue3SeamlessScroll} from "vue3-seamless-scroll";
 import {orderView} from "api/home";
-import dayjs from "dayjs";
+import mittBus from "@/utils/mitt";
 
 const list = ref([])
 const getData = async () => {
@@ -55,8 +55,16 @@ const getData = async () => {
   }
 }
 onMounted(() => {
+  // 接收消息
+  mittBus.on('orderHandlingDetail', (res: any) => {
+    list.value = res;
+  });
   getData();
 })
+onUnmounted(() => {
+  // 取消接收消息
+  mittBus.off('orderHandlingDetail');
+})
 </script>
 
 <style scoped lang="scss">

+ 12 - 6
src/views/home/center-float.vue

@@ -7,12 +7,17 @@
       <span>办结率</span>
     </div>
     <div class="table-body">
-      <div v-for="(item,index) in list" :key="item.id" class="table-body-item">
-        <span :class="index<=2 ? 'num' : ''"><CountUp :endVal="index + 1" :duration="1"/></span>
-        <span :class=" (index<=2 ? 'color' : '')">{{ item.areaName }}</span>
-        <span :class=" (index<=2 ? 'color' : '')"> {{ item.acceptedCount }}</span>
-        <span class="color">{{ item.completionRate }}%</span>
-      </div>
+      <template v-if="list.length">
+        <div v-for="(item,index) in list" :key="item.id" class="table-body-item">
+          <span :class="index<=2 ? 'num' : ''"><CountUp :endVal="index + 1" :duration="1"/></span>
+          <span :class=" (index<=2 ? 'color' : '')">{{ item.areaName }}</span>
+          <span :class=" (index<=2 ? 'color' : '')"> {{ item.acceptedCount }}</span>
+          <span class="color">{{ item.completionRate }}%</span>
+        </div>
+      </template>
+      <template v-else>
+        <EmptyCom style="font-size: 14px" class="mt-5"></EmptyCom>
+      </template>
     </div>
   </div>
 </template>
@@ -21,6 +26,7 @@ import {ref, onMounted, watch} from 'vue'
 import CountUp from "@/components/count-up";
 import dayjs from "dayjs";
 import {areaAccept} from "api/home";
+import EmptyCom from "@/components/empty-com";
 
 const props = defineProps({
   dateArray: {

+ 56 - 10
src/views/home/center-map.vue

@@ -8,16 +8,32 @@
   </div>
 </template>
 <script setup lang="ts">
-import {ref, nextTick, onMounted} from "vue";
+import {ref, nextTick, onMounted, watch} from "vue";
 import {registerMap, getMap} from "echarts/core";
 import {optionHandle, regionCodes} from "./center.map";
 import {loopShowTooltip} from "@/utils/tooltip-auto-show";
 import axios from "axios";
+import {areaDetail} from "api/home";
+import dayjs from "dayjs";
+
+const props = defineProps({
+  dateArray: {
+    type: Array,
+    default: () => []
+  }
+})
+const date = ref([]);
+watch(() => props.dateArray, (val: any) => {
+  date.value = val;
+}, {immediate: true})
+
+watch(() => props.dateArray, (val: any) => {
+  getData();
+})
 
 const option = ref({});
 const code = ref("511500"); //100000 代表中国 其他地市是行政编码
 const dataSetHandle = async (regionCode: string, list: object[]) => {
-
   code.value = regionCode;
   const geoJson: any = await getGeoJson(regionCode);
   let cityCenter: any = {};
@@ -48,6 +64,25 @@ const getGeoJson = (regionCode: string) => {
     }
   });
 };
+// 获取数据设置到地图中
+const getData = async () => {
+  try {
+    const {result} = await areaDetail({
+      StartDate: dayjs(date.value[0]).format('YYYY-MM-DD'),
+      EndDate: dayjs(date.value[1]).format('YYYY-MM-DD')
+    });
+
+    const regionData = result.map((item: any) => {
+      return {
+        name: item.areaName,
+        ...item
+      }
+    })
+    await dataSetHandle(code.value, regionData);
+  } catch (e) {
+    console.log(e);
+  }
+};
 const tooltipTimer = ref<any>(null);
 const centerMapRef = ref<any>(null);
 const tooltipMap = (myChart, option) => {
@@ -70,7 +105,7 @@ setTimeout(() => {
 }, 1000);
 
 onMounted(() => {
-  dataSetHandle(code.value, regionCodes);
+  getData();
 });
 </script>
 
@@ -165,7 +200,7 @@ onMounted(() => {
     .custom-tooltip-name {
       font-size: 20px;
       font-weight: bold;
-      margin-bottom: 20px;
+      margin-bottom: 15px;
       display: flex;
       align-items: center;
 
@@ -180,7 +215,7 @@ onMounted(() => {
 
     .custom-tooltip-style-box {
       display: flex;
-      color: #AAAFAF;
+      color: #d5e7e7;
       font-size: 14px;
 
       .ball {
@@ -193,33 +228,44 @@ onMounted(() => {
           font-size: 28px;
           font-weight: bold;
           text-align: center;
-          margin-top: 30px;
+          margin-top: 37px;
+
+          span {
+            font-size: 16px;
+            font-weight: normal;
+            margin-left: 1px;
+          }
         }
 
         .ball-text {
           color: #fff;
           font-size: 16px;
           text-align: center;
-          margin-top: 10px;
+          margin-top: 3px;
         }
       }
 
       .custom-tooltip-style-box-text {
         flex: 1;
-        margin-left: 20px;
+        margin-left: 10px;
 
         .custom-tooltip-style-box-text-item {
           margin-bottom: 8px;
+          display: flex;
+          align-items: center;
 
           span {
+            display: inline-block;
             color: #fff;
             font-weight: bold;
-            font-size: 16px;
+            max-width: 90px;
+            overflow: hidden;
+            text-overflow: ellipsis;
           }
 
           b {
             color: #fff;
-            font-weight: bold;
+            font-weight: normal;
           }
         }
       }

+ 10 - 1
src/views/home/center-top.vue

@@ -33,8 +33,9 @@
   </div>
 </template>
 <script setup lang="ts">
-import {defineAsyncComponent, reactive, onMounted} from "vue";
+import {defineAsyncComponent, reactive, onMounted, onUnmounted} from "vue";
 import {orderDay} from '@/api/home';
+import mittBus from "@/utils/mitt";
 
 const CountFlop = defineAsyncComponent(() => import('@/components/Count-flop/index.vue'));
 const state = reactive({
@@ -56,8 +57,16 @@ const getData = async () => {
   }
 }
 onMounted(() => {
+  // 接收消息
+  mittBus.on('ordercountstatistics', (res: any) => {
+    state.orderDay = res;
+  });
   getData();
 })
+onUnmounted(() => {
+  // 取消接收消息
+  mittBus.off('ordercountstatistics');
+})
 </script>
 <style scoped lang="scss">
 .center-top {

+ 5 - 5
src/views/home/center.map.ts

@@ -51,14 +51,14 @@ export const optionHandle = (regionCode: string,
                         <div class='custom-tooltip-name'> <span class="custom-tooltip-arrow"></span> ${params.name}</div>
                         <div class='custom-tooltip-style-box'>
                             <div class="ball">
-                                <div class="ball-value">${params.data.value}<span>%</span></div>
+                                <div class="ball-value">${params.data.satisfiedRate}<span>%</span></div>
                                 <div class="ball-text">满意率</div>
                             </div>
                             <div class="custom-tooltip-style-box-text">
-                                <div class="custom-tooltip-style-box-text-item">在办工单:<span>${params.data.value}</span> <b>件</b></div>
-                                <div class="custom-tooltip-style-box-text-item">已办工单:<span>${params.data.value}</span> <b>件</b></div>
-                                <div class="custom-tooltip-style-box-text-item">超期工单:<span>${params.data.value}</span> <b>件</b></div>
-                                <div class="custom-tooltip-style-box-text-item">高频热点:<span>${params.data.value}</span></div>
+                                <div class="custom-tooltip-style-box-text-item">在办工单:<span>${params.data.handlingCount}</span> <b>件</b></div>
+                                <div class="custom-tooltip-style-box-text-item">已办工单:<span>${params.data.filedCount}</span> <b>件</b></div>
+                                <div class="custom-tooltip-style-box-text-item">超期工单:<span>${params.data.overTimeCount}</span> <b>件</b></div>
+                                <div class="custom-tooltip-style-box-text-item">高频热点:<span>${params.data.hotspotName}</span></div>
                             </div>
                         </div>
                     </div>

+ 14 - 9
src/views/home/left-bottom.vue

@@ -15,21 +15,25 @@
         <template #dropdown>
           <el-dropdown-menu>
             <el-dropdown-item v-for="item in areaList" :key="item.value" :command="item">{{ item.name }}</el-dropdown-item>
-            "
           </el-dropdown-menu>
         </template>
       </el-dropdown>
     </div>
     <div class="left_bottom-content">
-      <div class="left_bottom-content-item" v-for="item in list" :key="item.hotspotId">
-        <span class="left_bottom-content-item-title text-ellipsis text-no-wrap" style="display:inline-block;max-width: 100px" :title="item.hotspotName">{{ item.hotspotName }}</span>
-        <div class="left_bottom-content-item-content">
-          <b>
-            <CountUp :endVal="item.sumCount" :duration="3"/>
-          </b>件
+      <template v-if="list.length">
+        <div class="left_bottom-content-item" v-for="item in list" :key="item.hotspotId">
+          <span class="left_bottom-content-item-title text-ellipsis text-no-wrap" style="display:inline-block;max-width: 100px" :title="item.hotspotName">{{ item.hotspotName }}</span>
+          <div class="left_bottom-content-item-content">
+            <b>
+              <CountUp :endVal="item.sumCount" :duration="3"/>
+            </b>件
+          </div>
+          <img src="@/assets/img/home/zhui.png" alt="">
         </div>
-        <img src="@/assets/img/home/zhui.png" alt="">
-      </div>
+      </template>
+      <template v-else>
+        <EmptyCom class="mt-10"></EmptyCom>
+      </template>
     </div>
   </div>
 </template>
@@ -39,6 +43,7 @@ import {ArrowDown} from '@element-plus/icons-vue'
 import CountUp from "@/components/count-up";
 import {hotSpot} from "@/api/home";
 import dayjs from "dayjs";
+import EmptyCom from "@/components/empty-com";
 
 const props = defineProps({
   dateArray: {

+ 16 - 4
src/views/home/left-center.vue

@@ -4,13 +4,21 @@
       <img src="@/assets/img/home/title_arrow.png" alt="">
       受理类型办件分析
     </div>
-    <v-chart class="chart" :option="option"/>
+    <div class="left-center-content">
+      <template v-if="xData.length">
+        <v-chart class="chart" :option="option"/>
+      </template>
+      <template v-else>
+        <EmptyCom></EmptyCom>
+      </template>
+    </div>
   </div>
 </template>
 <script setup lang="ts">
 import {ref, onMounted, watch} from "vue";
 import {acceptType} from "@/api/home";
 import dayjs from "dayjs";
+import EmptyCom from "@/components/empty-com";
 
 const props = defineProps({
   dateArray: {
@@ -30,11 +38,11 @@ watch(() => props.dateArray, (val: any) => {
 
 
 const option = ref({});
-
+const xData = ref([]);
 const getData = async () => {
   try {
     const {result} = await acceptType({StartDate: dayjs(date.value[0]).format('YYYY-MM-DD'), EndDate: dayjs(date.value[1]).format('YYYY-MM-DD')});
-    const xData = result.map((item: any) => item.acceptType);
+    xData.value = result.map((item: any) => item.acceptType);
     const totalData = result.reduce((pre: any, cur: any) => {
       pre.push(cur.sumCount);
       return pre;
@@ -53,7 +61,7 @@ const getData = async () => {
     }, []);
     // mock 数据
     let dataArr = {
-      xData: xData,
+      xData: xData.value,
       result: [
         {name: '总数', data: totalData},
         {name: '已办', data: handlingCount},
@@ -183,5 +191,9 @@ onMounted(() => {
     font-size: 20px;
     color: #fff;
   }
+
+  .left-center-content {
+    height: calc(100% - 30px);
+  }
 }
 </style>

+ 1 - 1
src/views/home/left-top.vue

@@ -222,7 +222,7 @@ onMounted(() => {
           display: block;
           width: 50%;
           height: 30px;
-          background: linear-gradient(to right, rgba(255, 255, 255, .3), rgba(255, 255, 255, .2));
+          background: linear-gradient(to right, rgba(255, 255, 255, .2), rgba(255, 255, 255, .1));
           border-radius: 20px;
           position: absolute;
           top: 20%;

+ 10 - 4
src/views/home/right-bottom.vue

@@ -11,7 +11,12 @@
       </div>
     </div>
     <div class="left_bottom-content">
-      <v-chart class="chart" :option="option"/>
+      <template v-if="dataList.length">
+        <v-chart class="chart" :option="option"/>
+      </template>
+      <template v-else>
+        <EmptyCom></EmptyCom>
+      </template>
     </div>
   </div>
 </template>
@@ -19,6 +24,7 @@
 import {ref, onMounted, watch} from "vue";
 import {proportionAnalysis} from "api/home";
 import dayjs from "dayjs";
+import EmptyCom from "@/components/empty-com";
 
 
 const props = defineProps({
@@ -122,7 +128,7 @@ const setOption = (legendDate, data: any) => {
             name: '小环',
             type: 'gauge',
             splitNumber: 8,
-            radius: '70%',
+            radius: '65%',
             center: ['30%', '40%'],
             startAngle: 0,
             endAngle: 360,
@@ -151,13 +157,13 @@ const setOption = (legendDate, data: any) => {
           {
             name: '',
             type: 'pie',
-            radius: ['60%', '85%'],
+            radius: ['55%', '80%'],
             center: ['30%', '40%'],
             avoidLabelOverlap: false,
             itemStyle: {
               borderRadius: 0,
               borderColor: '#050D0E',
-              borderWidth: 15,
+              borderWidth: 10,
             },
             label: {
               show: false,

+ 16 - 10
src/views/home/right-center.vue

@@ -7,17 +7,22 @@
       </div>
     </div>
     <div class="right_center-content">
-      <div class="scroll">
-        <div class="scroll-item" v-for="(item, index) in list" :key="index">
-          <span class="scroll-item-area" :class="index<=2 ? 'three' : ''">NO.{{ index + 1 }}</span>
-          <el-tooltip placement="top">
-            <template #content> {{ item.visitOrgName }}</template>
-            <span class="scroll-item-title">{{ item.visitOrgName }}</span>
-          </el-tooltip>
-          <span class="scroll-item-hotspot"><CountUp :endVal="item.visitCount " :duration="2"/>(件)</span>
-          <span class="scroll-item-num">{{ item.satisfiedRate }}%</span>
+      <template v-if="list.length">
+        <div class="scroll">
+          <div class="scroll-item" v-for="(item, index) in list" :key="index">
+            <span class="scroll-item-area" :class="index<=2 ? 'three' : ''">NO.{{ index + 1 }}</span>
+            <el-tooltip placement="top">
+              <template #content> {{ item.visitOrgName }}</template>
+              <span class="scroll-item-title">{{ item.visitOrgName }}</span>
+            </el-tooltip>
+            <span class="scroll-item-hotspot"><CountUp :endVal="item.visitCount " :duration="2"/>(件)</span>
+            <span class="scroll-item-num">{{ item.satisfiedRate }}%</span>
+          </div>
         </div>
-      </div>
+      </template>
+      <template v-else>
+        <EmptyCom class="mt-20"></EmptyCom>
+      </template>
     </div>
   </div>
 </template>
@@ -26,6 +31,7 @@ import {onMounted, ref, watch} from "vue";
 import CountUp from "@/components/count-up";
 import {departmentSatisfaction} from "api/home";
 import dayjs from "dayjs";
+import EmptyCom from "@/components/empty-com";
 
 const props = defineProps({
   dateArray: {