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