From 0cd692627d274be3bdf80b24ea4be9842cdd191b Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Fri, 09 May 2025 09:57:13 +0800
Subject: [PATCH] 个人工作台相关处理

---
 src/router/page/index.js                 |   20 
 public/img/bg/index_logo.png             |    0 
 src/config/website.js                    |    4 
 src/views/tickets/ticket.vue             |   80 ----
 src/api/tickets/ticket.js                |   64 +--
 src/views/tickets/orderLog.vue           |   72 +++-
 src/views/wel/index.vue                  |  652 +++++++++++++++++++++++++++++++++++++++-
 src/views/wel/components/flyratio.vue    |    2 
 src/router/views/index.js                |   32 +-
 src/views/wel/components/calendarBox.vue |   14 
 src/styles/common.scss                   |    3 
 11 files changed, 746 insertions(+), 197 deletions(-)

diff --git a/public/img/bg/index_logo.png b/public/img/bg/index_logo.png
new file mode 100644
index 0000000..43577c7
--- /dev/null
+++ b/public/img/bg/index_logo.png
Binary files differ
diff --git a/src/api/tickets/ticket.js b/src/api/tickets/ticket.js
index 9b1eeb8..57df423 100644
--- a/src/api/tickets/ticket.js
+++ b/src/api/tickets/ticket.js
@@ -1,30 +1,30 @@
-import request from '@/axios'
+import request from '@/axios';
 
 export const getList = (data) => {
   return request({
     url: '/drone-device-core/jobEvent/eventPage',
     method: 'post',
     data,
-  })
-}
+  });
+};
 
 // 修改创建工单的方法
 export const createTicket = (data, file) => {
-  const formData = new FormData()
-
+  const formData = new FormData();
+  
   // 创建 eventDto 对象,不显式设置 file 字段
   const eventDto = {
     ...data  // 直接使用传入的 data,不添加 file: null
-  }
+  };
 
   // 添加所有字段到 FormData
   Object.entries(eventDto).forEach(([key, value]) => {
-    formData.append(key, value)
-  })
-
+    formData.append(key, value);
+  });
+  
   // 只有当 file 存在时才添加文件
   if (file) {
-    formData.append("file", file)
+    formData.append("file", file);
   }
 
   return request({
@@ -34,8 +34,8 @@
     headers: {
       'Content-Type': 'multipart/form-data'
     }
-  })
-}
+  });
+};
 
 // 新增接口:获取工单详细信息
 export const getTicketInfo = (id) => {
@@ -43,23 +43,23 @@
     url: '/drone-device-core/jobEvent/getTicketInfo',
     method: 'get',
     params: { id }, // 使用工单 ID 查询
-  })
-}
+  });
+};
 
 // 修改接口:处理待审核状态,动态构建 FormData 提交
 export const flowEvent = (data, file) => {
-  const formData = new FormData()
+  const formData = new FormData();
 
   // 动态添加非空字段到 FormData
   Object.entries(data).forEach(([key, value]) => {
     if (value !== undefined && value !== null) {
-      formData.append(key, value)
+      formData.append(key, value);
     }
-  })
+  });
 
   // 如果 file 存在,则添加到 FormData
   if (file) {
-    formData.append('file', file)
+    formData.append('file', file);
   }
 
   return request({
@@ -69,8 +69,8 @@
     headers: {
       'Content-Type': 'multipart/form-data', // 设置为表单数据格式
     },
-  })
-}
+  });
+};
 
 // 新增接口:获取状态统计数据
 export const getstatusCount = (params) => {
@@ -78,29 +78,13 @@
     url: '/drone-device-core/jobEvent/getstatusCount',
     method: 'get',
     params,
-  })
-}
+  });
+};
 
 export const getStepInfo = (eventNum) => {
   return request({
     url: '/drone-device-core/jobEvent/getStepInfo',
     method: 'get',
     params: { eventNum }
-  })
-}
-
-// 人工复核接口
-export const getReviewById = (id) => {
-  return request({
-    url: `/drone-device-core/jobEvent/reviewById/${id}`,
-    method: 'get',
-  })
-}
-
-// 下发任务
-export const getCreateEventJob = (id) => {
-  return request({
-    url: `/drone-device-core/wayline/waylineJobInfo/createEventJob/${id}`,
-    method: 'post',
-  })
-}
\ No newline at end of file
+  });
+};
diff --git a/src/config/website.js b/src/config/website.js
index 9bba3e6..6a21638 100644
--- a/src/config/website.js
+++ b/src/config/website.js
@@ -33,8 +33,8 @@
   },
   fistPage: {
     name: '事件工单',
-    // path: '/wel/index',
-    path: '/tickets/ticket',
+    path: '/wel/index',
+    // path: '/tickets/ticket',
     
   },
   //配置菜单的属性
diff --git a/src/router/page/index.js b/src/router/page/index.js
index 2006514..0b59c6e 100644
--- a/src/router/page/index.js
+++ b/src/router/page/index.js
@@ -64,15 +64,15 @@
       isAuth: false,
     },
   },
-  // {
-  //   path: '/',
-  //   name: '主页',
-  //   // redirect: '/wel',
-  //   redirect:'/tickets/ticket',
-  // },
   {
-     path: '/',
-     name: '主页',
-     redirect: '/tickets/ticket',
-     },
+    path: '/',
+    name: '主页',
+    redirect: '/wel',
+ 
+  },
+  // {
+  //    path: '/',
+  //    name: '主页',
+  //    redirect: '/tickets/ticket',
+  //    },
 ];
diff --git a/src/router/views/index.js b/src/router/views/index.js
index a8977c6..d2da43f 100644
--- a/src/router/views/index.js
+++ b/src/router/views/index.js
@@ -28,22 +28,22 @@
     ],
   },
   // 事件工单
-  {
-     path: '/tickets',
-    component: () =>
-     Store.getters.isMacOs ? import('@/mac/index.vue') : import('@/page/index/index.vue'),
-     redirect: '/tickets/ticket',
-     children: [
-     {
-     path: 'ticket',
-   name: '事件工单',
-     meta: {
-     i18n: 'dashboard',
-    },
-    component: () => import(/* webpackChunkName: "views" */ '@/views/tickets/ticket.vue'),
-     },
-    ],
-     },
+  // {
+  //    path: '/tickets',
+  //   component: () =>
+  //    Store.getters.isMacOs ? import('@/mac/index.vue') : import('@/page/index/index.vue'),
+  //    redirect: '/tickets/ticket',
+  //    children: [
+  //    {
+  //    path: 'ticket',
+  //  name: '事件工单',
+  //    meta: {
+  //    i18n: 'dashboard',
+  //   },
+  //   component: () => import(/* webpackChunkName: "views" */ '@/views/tickets/ticket.vue'),
+  //    },
+  //   ],
+  //    },
 
   {
     path: '/test',
diff --git a/src/styles/common.scss b/src/styles/common.scss
index df04e57..6986257 100644
--- a/src/styles/common.scss
+++ b/src/styles/common.scss
@@ -73,7 +73,8 @@
   flex: 1;
   box-sizing: border-box;
   overflow: hidden;
-  background: #f0f2f5;
+  // background: #f0f2f5;
+  background: linear-gradient( 180deg, #EEF3FE 0%, #F8F9FB 100%);
 }
 
 #avue-view {
diff --git a/src/views/tickets/orderLog.vue b/src/views/tickets/orderLog.vue
index e396792..45bd403 100644
--- a/src/views/tickets/orderLog.vue
+++ b/src/views/tickets/orderLog.vue
@@ -102,29 +102,37 @@
 
             <template #menu="{ row }">
               <div class="menu-custom-box">
-                <template v-if="row.status == 1">
-                  <el-button v-if="hasPaddingBtnPermission()" type="text" icon="el-icon-view"
+                <div v-if="row.status == 1">
+                  <el-button class="audit-btn" v-if="hasPaddingBtnPermission()" type="text" icon="el-icon-view"
                     @click="handleCheckDetail(row)">审核</el-button>
-                </template>
+                </div>
 
-                <template v-if="
+                <div v-if="
                   (userInfo.user_id == row.create_user || hasRecallPaddingBtnPermission()) &&
                   row.status == 1
                 ">
                   <!--待审核状态-->
-                  <el-button type="text" icon="el-icon-warning" @click="orderLogRecall(row.id)">撤回</el-button>
-                </template>
+                  <el-button class="withdraw-btn" type="text" icon="el-icon-warning"
+                    @click="orderLogRecall(row.id)">撤回</el-button>
+                </div>
                 <!--已驳回-->
-                <template v-if="row.status == 2">
-                  <el-button type="text" icon="el-icon-warning" @click="rejectDetail(row.id)">驳回原因</el-button>
-                </template>
+                <div v-if="row.status == 2">
+                  <el-button class="reject-reason-btn" type="text" icon="el-icon-warning"
+                    @click="rejectDetail(row.id)">驳回原因</el-button>
+                </div>
                 <!--草稿-->
-                <el-button type="text" icon="el-icon-edit" @click="handleViewDetail(row)">编辑</el-button>
-                <el-button type="text" icon="el-icon-position" @click="userPublishPush(row.id)">发起</el-button>
-                <el-button type="text" icon="el-icon-delete" @click="deleteOrderLog(row.id)">删除</el-button>
-                <template v-if="row.status == 3 || row.status == 1 || row.status == 2">
-                  <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)">详情</el-button>
-                </template>
+                <div>
+                  <el-button class="edit-btn" type="text" icon="el-icon-edit"
+                    @click="handleViewDetail(row)">编辑</el-button>
+                  <el-button class="publish-btn" type="text" icon="el-icon-position"
+                    @click="userPublishPush(row.id)">发布</el-button>
+                  <el-button class="delete-btn" type="text" icon="el-icon-delete"
+                    @click="deleteOrderLog(row.id)">删除</el-button>
+                </div>
+                <div v-if="row.status == 3 || row.status == 1 || row.status == 2">
+                  <el-button class="detail-btn" type="text" icon="el-icon-view"
+                    @click="handleViewDetail(row)">详情</el-button>
+                </div>
               </div>
             </template>
             <template #status="{ row }">
@@ -1301,15 +1309,37 @@
   .menu-custom-box {
     display: flex;
     justify-content: center;
-    flex-wrap: wrap;
 
-    &> ::v-deep(.el-button) {
+    &>div {
       flex: 1;
-      max-width: 44px;
+    }
 
-      &:nth-child(4n) {
-        margin-left: 0;
-      }
+    .audit-btn {
+      color: #1ba0ff;
+    }
+
+    .withdraw-btn {
+      color: #ff5d9e;
+    }
+
+    .reject-reason-btn {
+      color: #ff6a00;
+    }
+
+    .edit-btn {
+      color: #00b187;
+    }
+
+    .publish-btn {
+      color: #5e00ff;
+    }
+
+    .delete-btn {
+      color: #fe0202;
+    }
+
+    .detail-btn {
+      color: #1f4aff;
     }
   }
 }
diff --git a/src/views/tickets/ticket.vue b/src/views/tickets/ticket.vue
index 8517048..c15b2c1 100644
--- a/src/views/tickets/ticket.vue
+++ b/src/views/tickets/ticket.vue
@@ -48,13 +48,9 @@
                 <el-button type="text" icon="el-icon-delete" class="danger-button"
                   @click="handleDelete(row)">删除</el-button>
               </template>
-
               <template v-else>
                 <el-button type="text" icon="el-icon-view" @click="handleViewDetail(row)">详情</el-button>
               </template>
-
-              <el-button v-if="row.status === 4 && row.isReview !== 1" type="text" icon="el-icon-check"
-                @click="reCheck(row)">复核</el-button>
             </template>
             <template #status="{ row }">
               <span :style="getStatusTagType(row.status) ? 'color:' + getStatusTagType(row.status) : ''">
@@ -470,33 +466,13 @@
         </div>
       </template>
     </el-dialog>
-
-    <!-- 复核弹出层 -->
-
-    <el-dialog v-model="reCheckDialog" title="工单复核" width="30%" append-to-body custom-class="re-check-dialog"
-      @close="reCheckDialog = false">
-      <div class="dialog-footer">
-        <el-button type="primary" @click="reCheckConfirm(1)">人工复核</el-button>
-        <el-button type="primary" @click="reCheckConfirm(2)">机器复核</el-button>
-      </div>
-    </el-dialog>
   </basic-container>
 </template>
 
 <script>
-import { ElMessageBox, ElLoading } from 'element-plus'
 import { calculateDefaultRange } from '@/utils/util'
 import { gcj02ToWgs84, wgs84ToGcj02 } from '@/utils/coordinateTransformation'
-import {
-  getList,
-  createTicket,
-  getTicketInfo,
-  flowEvent,
-  getstatusCount,
-  getStepInfo,
-  getReviewById,
-  getCreateEventJob
-} from '@/api/tickets/ticket'
+import { getList, createTicket, getTicketInfo, flowEvent, getstatusCount, getStepInfo } from '@/api/tickets/ticket'
 import { export_json_to_excel } from '@/utils/exportExcel'
 import geoJson from '@/assets/geoJson.json'
 
@@ -677,9 +653,6 @@
 
       // 配置时间选择器默认配置
       datePickerDefaultVal: calculateDefaultRange(),
-
-      // 复核弹窗
-      reCheckDialog: false,
     }
   },
   created () {
@@ -855,6 +828,8 @@
 
     showIsReviewText () {
       return (row) => {
+        console.log(row, 111111)
+
         if (['4', '5'].includes(String(row.status))) return row.isReview === 1 ? '是' : '否'
 
         return '/'
@@ -2296,48 +2271,6 @@
       }
 
       return [String(lng), String(lat)]
-    },
-
-    // 复核按钮
-    reCheck (row) {
-      this.reCheckData = row
-      this.reCheckDialog = true
-    },
-
-    // 复核确认框按钮事件
-    reCheckConfirm (key) {
-      const that = this
-      if (key == 1) {
-        getReviewById(this.reCheckData.id).then(res => {
-          this.reCheckDialog = false
-          this.page.currentPage = 1
-          this.fetchTableData()
-          this.fetchTabCounts()
-        })
-      } else {
-
-        const loading = ElLoading.service({
-          lock: true,
-          text: '复核任务创建中……',
-          background: 'rgba(0, 0, 0, 0.7)',
-        })
-
-        // 获取时间的接口
-        getCreateEventJob(that.reCheckData.id).then(res => {
-          loading.close()
-
-          ElMessageBox.confirm(`预计复核执行时间为${res.data.data}`, '提示', {
-            confirmButtonText: '确定',
-            showCancelButton: false, // 关键配置
-            type: 'warning'
-          }).then(() => {
-            this.reCheckDialog = false
-            this.page.currentPage = 1
-            this.fetchTableData()
-            this.fetchTabCounts()
-          })
-        })
-      }
     }
   },
 }
@@ -2860,13 +2793,6 @@
 
 // 添加新的样式
 .review-dialog {
-  :deep(.el-dialog__body) {
-    padding: 0;
-    background-color: #f5f7fa;
-  }
-}
-
-.re-check-dialog {
   :deep(.el-dialog__body) {
     padding: 0;
     background-color: #f5f7fa;
diff --git a/src/views/wel/components/calendarBox.vue b/src/views/wel/components/calendarBox.vue
index aea2ade..92e4549 100644
--- a/src/views/wel/components/calendarBox.vue
+++ b/src/views/wel/components/calendarBox.vue
@@ -56,19 +56,13 @@
     }
 
     if (newV && oldV) {
-       const newDate = dayjs(newV);
+      const newDate = dayjs(newV);
       const oldDate = dayjs(oldV);
-      
-      // 格式化为 YYYY-MM-DD HH:mm:ss
-      const newDateStr = newDate.format('YYYY-MM-DD HH:mm:ss');
-      const oldDateStr = oldDate.format('YYYY-MM-DD HH:mm:ss');
-      params.
-      console.log('新日期:', newDateStr, '旧日期:', oldDateStr);
 
       if (newDate.isBefore(oldDate, 'month')) {
-        console.log('点击了上个月',newDateStr);
+        console.log('点击了上个月');
       } else if (newDate.isAfter(oldDate, 'month')) {
-        console.log('点击了下个月',newDateStr);
+        console.log('点击了下个月');
       }
     }
   },
@@ -95,7 +89,7 @@
 };
 // 获取对应日期的事件
 const getEvents = dateString => {
-  //  console.log('000',dateString);
+  // console.log('000',dateString);
 
   return events.value[dateString] || [];
 };
diff --git a/src/views/wel/components/flyratio.vue b/src/views/wel/components/flyratio.vue
index 38fc011..08cb6fc 100644
--- a/src/views/wel/components/flyratio.vue
+++ b/src/views/wel/components/flyratio.vue
@@ -39,6 +39,8 @@
 // 获取机巢事件数据
 const getIndustryJobNumPieChart = value => {
   industryJobNumPieChart(value).then(res => {
+    console.log('ppp', res);
+
     const resList = res?.data?.data || [];
     jcOrder.value = resList;
     pieInit(resList);
diff --git a/src/views/wel/index.vue b/src/views/wel/index.vue
index 916c7af..b7dedcd 100644
--- a/src/views/wel/index.vue
+++ b/src/views/wel/index.vue
@@ -1,29 +1,416 @@
 <template>
-  <div>
-    个人工作台
+  <div class="workbench">
+    <div class="workleft">
+      <!-- 设备统计  -->
+      <statistics></statistics>
+      <!-- 综合统计分析 -->
+      <div class="comprehensiveCon">
+        <div class="comprehensive">
+          <div class="title">
+            <div class="name">
+              <span> 综合统计分析</span>
+              <img src="/src/assets/images/workbench/st1.png" alt="" />
+              <div class="time-card">
+                <div
+                  class="card-item"
+                  :class="item === checked ? 'active' : ''"
+                  v-for="(item, index) in timeListEnum"
+                  :key="index"
+                  @click="timeClick(item, index)"
+                >
+                  {{ timeListStr[index] }}
+                </div>
+              </div>
+            </div>
+            <div class="arrow">
+              <img src="/src/assets/images/workbench/st2.png" alt="" />
+            </div>
+          </div>
+          <div class="center">
+            <div class="centerLeft">
+              <!-- 工单统计 -->
+              <div class="workOrder">
+                <div class="card-group">
+                  <div class="main-card">
+                    <div class="card-title">
+                      <img :src="overviewImg1" alt="" />
+                      <div class="cardtotal">
+                        <p>工单统计占比</p>
+                        <!-- <div class="total-number">{{ eventTotal }}</div>
+                        <span>个</span> -->
+                      </div>
+                    </div>
+
+                    <div class="status-grid">
+                      <div class="status-item" v-for="(item, index) in eventTypeList" :key="index">
+                        <div class="statusCon">
+                          <div class="status-label">{{ item.name }}</div>
+                          <div :style="{ color: item.color }" class="status-value">
+                            {{ item.value }}<span>个</span>
+                          </div>
+                          <div class="ratio">
+                            占比
+                            <span :style="{ color: item.color }"
+                              >{{ (item.rate / 100) * 100 }}%</span
+                            >
+                          </div>
+                        </div>
+                        <img :src="item.img" alt="" />
+                      </div>
+                    </div>
+                  </div>
+                </div>
+                <div class="charts">
+                  <div class="chart" ref="echartsRef"></div>
+                </div>
+              </div>
+              <!-- 飞行统计 -->
+              <div class="flyOrder">
+                <div class="fytitle">
+                  <img src="@/assets/images/workbench/fy1.png" alt="" />
+                  <span>飞行统计</span>
+                </div>
+                <div class="flycenter">
+                  <div class="centerBox">
+                    <div class="centerItem" v-for="(item, index) in 3" :key="index">
+                      <div><img src="@/assets/images/workbench/fy2.png" alt="" />飞行时长</div>
+                      <div class="flydata"><span>5421.56</span>时</div>
+                    </div>
+                  </div>
+                  <div class="lineChart">
+                    <div class="lineBox" ref="chartRef"></div>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="centerRight">
+              <flyratio></flyratio>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div class="workright">
+      <Bocklog></Bocklog>
+      <CalenBox></CalenBox>
+    </div>
   </div>
 </template>
 
-<script>
+<script setup>
+import flyratio from './components/flyratio.vue';
+import Bocklog from './components/backlog.vue';
+import CalenBox from './components/calendarBox.vue';
+import * as echarts from 'echarts';
+import useEchartsResize from '@/hooks/useEchartsResize';
 import { mapGetters } from 'vuex';
-
-export default {
-  name: 'wel',
-  data() {
-    return {
-      activeNames: ['1', '2', '3', '5'],
-      logActiveNames: ['37'],
-    };
-  },
-  computed: {
-    ...mapGetters(['userInfo']),
-  },
-  methods: {
-    handleChange(val) {
-      window.console.log(val);
-    },
-  },
+import { ref } from 'vue';
+import overviewImg1 from '@/assets/images/workbench/tc1.png';
+import overviewImg2 from '@/assets/images/workbench/tc2.png';
+import overviewImg3 from '@/assets/images/workbench/tc3.png';
+import overviewImg4 from '@/assets/images/workbench/tc4.png';
+import overviewImg5 from '@/assets/images/workbench/tc5.png';
+import overviewImg6 from '@/assets/images/workbench/tc6.png';
+import flyImg1 from '@/assets/images/workbench/fy2.png';
+import statistics from './components/statistics.vue';
+import { getJobEventByStatus, getJobEventTotal } from '@/api/home/index';
+// const value = ref(new Date());
+let checked = ref('CURRENT_WEEK');
+let timeListStr = ['本周', '本月', '本年'];
+let timeListEnum = ['CURRENT_WEEK', 'CURRENT_MONTH', 'CURRENT_YEAR'];
+let timeClick = (item, index) => {
+  checked.value = item;
+  params.value.date_enum = item;
+  console.log('日期选择', params.value.date_enum);
+  getTypeData();
 };
+const eventTypeList = ref([
+  { name: '待审核', value: 0, img: overviewImg2, color: '#FF6560', status: '2', rate: 0 },
+  { name: '待处理', value: 0, img: overviewImg3, color: '#5D77FB', status: '0', rate: 0 },
+  { name: '处理中', value: 0, img: overviewImg4, color: '#FF8B26', status: '3', rate: 0 },
+  { name: '已完成', value: 0, img: overviewImg5, color: '#0291A1', status: '4', rate: 0 },
+]);
+const flyTypeList = ref([
+  { name: '飞行时长', value: 0, img: overviewImg2 },
+  { name: '飞行里程', value: 0, img: overviewImg3 },
+  { name: '任务成功', value: 0, img: overviewImg4 },
+]);
+const params = ref({
+  date_enum: 'CURRENT_WEEK',
+  device_sn: '',
+  end_date: undefined,
+  start_date: undefined,
+});
+const eventTotal = ref(0);
+const data = ref([]);
+//  工单统计
+const getTypeData = () => {
+  getJobEventByStatus(params.value).then(res => {
+    const resList = res?.data?.data || [];
+    console.log('工单统计', res.data.data);
+
+    resList.forEach(item => {
+      eventTypeList.value.forEach(item1 => {
+        if (item1.name === item.name) {
+          item1.value = item.num;
+          item1.rate = item.rate;
+        }
+      });
+    });
+    initChart(resList);
+  });
+};
+// 图表
+const echartsRef = ref(null);
+let { chart } = useEchartsResize(echartsRef);
+const chartRef = ref(null);
+let { chart: lineChart } = useEchartsResize(chartRef);
+const initChart = val => {
+  // 转换数据格式并计算总数
+  const totalNum = val.reduce((sum, item) => sum + item.num, 0);
+  const data = {
+    total: {
+      title: '总计',
+      figure: totalNum.toString(), // 动态计算总数
+    },
+    data: val.map(item => ({
+      value: item.num,
+      name: item.name,
+      rate: item.rate,
+    })),
+  };
+
+  const echartsOption = {
+    color: ['#FF6560', '#5D77FB', '#FF8B26', '#0291A1'],
+    tooltip: {
+      trigger: 'item',
+      padding: 0,
+      borderWidth: 0,
+      formatter: params => {
+        return `<div style="background-color: rgba($color: #FFFFFF, $alpha: 0.95);
+          box-shadow: 0 4px 9px 0 rgba($color: #000000, $alpha: 0.1);
+          padding:0 12px;
+          display: flex;
+          align-items: center;
+          border-radius: 4px;
+          font-size: 12px;" class="tooltip-area">
+          <p>${params.marker}${params.name}</p>
+          <h4 style="margin-left: 30px;">${params.data.rate || params.percent}%</h4>
+        </div>`;
+      },
+    },
+    legend: {
+      show: false,
+    },
+    title: {
+      text: data.total.title,
+      textStyle: {
+        color: 'rgba(28, 31, 35, 0.80)',
+        fontSize: '12px',
+        fontWeight: 'normal',
+      },
+      subtext: data.total.figure,
+      subtextStyle: {
+        color: '#1C1F23',
+        fontSize: '20px',
+        fontWeight: '600',
+      },
+      top: '40%',
+      left: 'center',
+    },
+    series: [
+      {
+        name: '',
+        type: 'pie',
+        radius: ['30%', '45%'],
+        avoidLabelOverlap: true,
+        // avoidLabelOverlap: false,
+        label: {
+          formatter: `{a|{b}}: {b|{d}%}`,
+          alignTo: 'labelLine',
+          rich: {
+            a: {
+              color: 'rgba(28, 31, 35, 0.80)',
+              fontSize: '12px',
+            },
+            b: {
+              color: '#1C1F23',
+              fontSize: '14px',
+              fontWeight: '600',
+            },
+          },
+        },
+        labelLine: {
+          show: true,
+          lineStyle: {
+            cap: 'round',
+          },
+        },
+        data: data.data,
+      },
+    ],
+  };
+
+  chart.value.setOption(echartsOption);
+};
+
+// 柱状图
+const lineCharts = () => {
+  var option = {
+    tooltip: {
+      trigger: 'item',
+      axisPointer: {
+        type: 'shadow',
+      },
+    },
+    grid: {
+      left: '2%',
+      right: '4%',
+      bottom: '14%',
+      top: '16%',
+      containLabel: true,
+    },
+    legend: {
+      data: ['飞行时长', '飞行里程', '任务成果'],
+      left: 'center',
+      top: '5%',
+      textStyle: {
+        color: '#666666',
+      },
+      itemWidth: 15,
+      itemHeight: 10,
+      itemGap: 25,
+    },
+    xAxis: {
+      type: 'category',
+      data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
+      axisLine: {
+        lineStyle: {
+          color: '#cdd5e2',
+        },
+      },
+
+      axisLabel: {
+        interval: 0,
+        textStyle: {
+          color: '#666666',
+        },
+      },
+    },
+    yAxis: [
+      // 只保留第一个y轴
+      {
+        type: 'log',
+        name: '单位:万套',
+        nameTextStyle: {
+          color: '#666666',
+        },
+        min: 1,
+        logBase: 3,
+        axisLine: {
+          show: false,
+          lineStyle: {
+            color: '#cdd5e2',
+          },
+        },
+
+        splitLine: {
+          show: true, // 显示分割线
+          lineStyle: {
+            type: 'dashed', // 设置为虚线
+            color: '#cdd5e2', // 颜色与轴线一致
+            width: 1, // 线宽
+            opacity: 0.5, // 透明度
+          },
+        },
+        axisLabel: {
+          textStyle: {
+            color: '#666666',
+          },
+        },
+        axisLine: {
+          lineStyle: {
+            color: '#cdd5e2',
+          },
+        },
+      },
+      // 移除第二个y轴配置
+    ],
+    series: [
+      {
+        name: '飞行时长',
+        type: 'bar',
+        barWidth: '12px',
+        itemStyle: {
+          normal: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              {
+                offset: 0,
+                color: '#29acff',
+              },
+              {
+                offset: 1,
+                color: '#4bdfff',
+              },
+            ]),
+            barBorderRadius: 6,
+          },
+        },
+        data: [11, 14, 133, 4, 10, 14, 116, 12, 12, 58, 15, 12],
+      },
+      {
+        name: '飞行里程',
+        type: 'bar',
+        barWidth: '12px',
+        itemStyle: {
+          normal: {
+            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+              {
+                offset: 0,
+                color: '#01c871',
+              },
+              {
+                offset: 1,
+                color: '#55f49c',
+              },
+            ]),
+            barBorderRadius: 6,
+          },
+        },
+        data: [0, 1, 9, 0, 5, 3, 0, 2, 0, 0, 1, 0],
+      },
+      {
+        name: '任务成果',
+        type: 'line',
+        yAxisIndex: 0, // 改为使用第一个y轴
+        smooth: true,
+        // symbol: 'circle',
+        // symbolSize: 8,
+        // itemStyle: {
+        //   normal: {
+        //     color: '#ffa43a',
+        //     borderColor: 'rgba(255, 234, 0, 0.5)',
+        //     borderWidth: 5,
+        //   },
+        // },
+        lineStyle: {
+          color: 'rgba(52, 146, 242, 1)',
+        },
+        data: [1, 7, 6, 30, 20, 21.43, 11, 16.67, 22, 88, 6.67, 10],
+      },
+    ],
+  };
+  lineChart.value.setOption(option);
+};
+onMounted(() => {
+  getJobEventTotal().then(res => {
+    eventTotal.value = res?.data?.data || 0;
+  });
+
+  getTypeData();
+  lineCharts();
+});
 </script>
 
 <style>
@@ -31,3 +418,228 @@
   font-size: 14px;
 }
 </style>
+<style scoped lang="scss">
+// 开始
+.workbench {
+  padding: 0px 20px 0 20px;
+  display: flex;
+  justify-content: space-between;
+}
+.workleft {
+  width: 68%;
+  margin-right: 10px;
+  // 综合
+  .comprehensiveCon {
+    // height: 736px;
+    background: #ffffff;
+    border-radius: 8px 8px 8px 8px;
+    .comprehensive {
+      padding: 14px 14px 0 21px;
+      .title {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        .name {
+          display: flex;
+          align-items: center;
+          span {
+            margin-right: 4px;
+          }
+        }
+        .arrow {
+          cursor: pointer;
+        }
+        .time-card {
+          text-align: center;
+          height: 30px;
+          background: #ffffff;
+          border-radius: 4px 0px 0px 4px;
+          border: 1px solid #e5e5e5;
+          font-weight: 400;
+          font-size: 14px;
+          color: #7c8091;
+          display: flex;
+          width: 282px;
+          margin-left: 15px;
+          .card-item {
+            width: 94px;
+            height: 100%;
+            line-height: 32px;
+            cursor: pointer;
+          }
+          .card-item:first-child {
+            border-right: 1px solid #e5e5e5;
+          }
+          .card-item:nth-child(2) {
+            border-right: 1px solid #e5e5e5;
+          }
+          .active {
+            color: #1441ff;
+          }
+        }
+      }
+      // 工、单
+      .center {
+        display: flex;
+        .centerLeft {
+          width: 60%;
+          border-right: 1px solid #dfdfdf;
+          .workOrder {
+            margin-top: 21px;
+            display: flex;
+            border-bottom: 1px solid #dfdfdf;
+            .card-group {
+              width: 40%;
+              .card-title {
+                display: flex;
+                margin-bottom: 10px;
+                align-items: center;
+                img {
+                  width: 36px;
+                  height: 40px;
+                }
+              }
+              .cardtotal {
+                display: flex;
+                align-items: center;
+                margin-left: 9px;
+                p {
+                  font-weight: bold;
+                  font-size: 14px;
+                  color: #363636;
+                }
+                span {
+                  font-weight: 400;
+                  font-size: 14px;
+                  color: #7c8091;
+                }
+                .total-number {
+                  font-family: 'YouSheBiaoTiHei';
+                  font-weight: bold;
+                  font-size: 32px;
+                  color: #2a54ff;
+                }
+              }
+              .status-grid {
+                display: grid;
+                grid-template-columns: repeat(2, 1fr);
+                row-gap: 14px;
+                gap: 10px;
+                .status-item {
+                  display: flex;
+                  text-align: center;
+                  height: 97px;
+                  background: #f6f8fe;
+                  border-radius: 8px 8px 8px 8px;
+                  img {
+                    width: 26px;
+                    height: 26px;
+                    padding: 9px 2px;
+                  }
+                  .statusCon {
+                    display: flex;
+                    flex-direction: column;
+                    align-items: center;
+                    padding: 9px 4px 0 4px;
+                    .status-label {
+                      font-weight: 400;
+                      font-size: 14px;
+                      color: #383838;
+                    }
+                    .ratio {
+                      font-weight: 400;
+                      font-size: 12px;
+                      color: #363636;
+                      white-space: nowrap;
+                    }
+                    .status-value {
+                      font-family: 'YouSheBiaoTiHei';
+                      font-weight: bold;
+                      font-size: 24px;
+                      margin: 5px 0;
+                      span {
+                        font-weight: 400;
+                        font-size: 14px;
+                        color: #7c8091;
+                      }
+                    }
+                  }
+                }
+              }
+            }
+            .charts {
+              margin-top: 30px;
+              width: 348px;
+              height: 242px;
+              .chart {
+                width: 100%;
+                height: 100%;
+              }
+            }
+          }
+
+          // 飞行统计
+          .flyOrder {
+            margin-top: 5px;
+            .fytitle {
+              display: flex;
+              align-items: center;
+              img {
+                width: 39px;
+                height: 38px;
+              }
+              span {
+                font-weight: bold;
+                font-size: 14px;
+                color: #363636;
+              }
+            }
+            .flycenter {
+              margin-top: 13px;
+              .centerBox {
+                display: flex;
+                justify-content: space-between;
+                .centerItem {
+                  padding: 7px 7px 0 15px;
+                  // width: 196px;
+                  flex: 1;
+                  height: 80px;
+                  background: #f6f8fe;
+                  box-shadow: 0px 5px 4px 0px #ebf1ff;
+                  border-radius: 8px 8px 8px 8px;
+                  border: 1px solid #ffffff;
+                  margin-right: 16px;
+                  .flydata {
+                    margin-top: 15px;
+                    text-align: right;
+                    font-size: 14px;
+                    color: #7c8091;
+                    span {
+                      font-weight: bold;
+                      font-size: 24px;
+                      color: #343434;
+                      margin-right: 6px;
+                    }
+                  }
+                }
+              }
+
+              .lineChart {
+                height: 209px;
+                width: 100%;
+                .lineBox {
+                  width: 100%;
+                  height: 100%;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+.workright {
+  width: 32%;
+}
+</style>

--
Gitblit v1.9.3