| | |
| | | import axios from 'axios' |
| | | import { ElMessage } from 'element-plus' |
| | | |
| | | const debug = false |
| | | const debug = true |
| | | |
| | | var IP = '47.100.191.150' |
| | | var PORT = '9005' |
| | | if (debug) { |
| | | IP = '192.168.0.138' |
| | | PORT = '8080' |
| | | IP = '192.168.0.103' |
| | | PORT = '9001' |
| | | } |
| | | |
| | | let ws = `${IP}:${PORT}` |
| | |
| | | 'overlay': #102f63c9 |
| | | ), |
| | | $colors: ( |
| | | 'primary': ( |
| | | 'base': #e6a23c |
| | | 'info': ( |
| | | 'base': #ffb74c |
| | | ) |
| | | ), |
| | | $text-color: ( |
| | | 'regular': #fff |
| | | ) |
| | | ); |
| | |
| | | BaseMap: typeof import('./components/map/BaseMap.vue')['default'] |
| | | BaseTable: typeof import('./components/BaseTable.vue')['default'] |
| | | CoreHeader: typeof import('./components/core/CoreHeader.vue')['default'] |
| | | DataTable: typeof import('./components/DataTable.vue')['default'] |
| | | ElButton: typeof import('element-plus/es')['ElButton'] |
| | | ElCalendar: typeof import('element-plus/es')['ElCalendar'] |
| | | ElCard: typeof import('element-plus/es')['ElCard'] |
| | | ElCascader: typeof import('element-plus/es')['ElCascader'] |
| | | ElCol: typeof import('element-plus/es')['ElCol'] |
| | | ElCollapse: typeof import('element-plus/es')['ElCollapse'] |
| | | ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem'] |
| | | ElCollapseTransition: typeof import('element-plus/es')['ElCollapseTransition'] |
| | | ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] |
| | | ElDatePicker: typeof import('element-plus/es')['ElDatePicker'] |
| | | ElDivider: typeof import('element-plus/es')['ElDivider'] |
| | | ElEmpty: typeof import('element-plus/es')['ElEmpty'] |
| | | ElIcon: typeof import('element-plus/es')['ElIcon'] |
| | | ElImage: typeof import('element-plus/es')['ElImage'] |
| | | ElLink: typeof import('element-plus/es')['ElLink'] |
| | |
| | | ElSegmented: typeof import('element-plus/es')['ElSegmented'] |
| | | ElSelect: typeof import('element-plus/es')['ElSelect'] |
| | | ElSpace: typeof import('element-plus/es')['ElSpace'] |
| | | ElSpan: typeof import('element-plus/es')['ElSpan'] |
| | | ElStatistic: typeof import('element-plus/es')['ElStatistic'] |
| | | ElTable: typeof import('element-plus/es')['ElTable'] |
| | | ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] |
| | | ElTag: typeof import('element-plus/es')['ElTag'] |
| | | ElText: typeof import('element-plus/es')['ElText'] |
| | | ElTimeline: typeof import('element-plus/es')['ElTimeline'] |
| | | ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem'] |
| | | OptionLocation: typeof import('./components/search/OptionLocation.vue')['default'] |
| | | OptionSceneType: typeof import('./components/search/OptionSceneType.vue')['default'] |
| | | OptionTime: typeof import('./components/search/OptionTime.vue')['default'] |
| | |
| | | <template> |
| | | <div class="wrap-2"> |
| | | <div class="wrap-2 p-events-auto"> |
| | | <el-space> |
| | | <span class="close-icon" @click="showToggle"> |
| | | <el-icon :size="16"> |
| | | <!-- <Transition name="rotate"> |
| | | <Close v-if="show" /> |
| | | </Transition> |
| | | <Transition name="rotate-reverse"> |
| | | <Plus v-if="!show" /> |
| | | </Transition> --> |
| | | <Close :class="closeRotate" /> |
| | | </el-icon> |
| | | </span> |
| | | <el-row justify="space-between" align="middle"> |
| | | <span>{{ title }}</span> |
| | | <div class="m-l-16"> |
| | | <slot name="expand"></slot> |
| | | </div> |
| | | </el-row> |
| | | </el-space> |
| | | <!-- <Transition name="el-zoom-in-left"> --> |
| | | <div class="m-t-8" v-if="show"> |
| | | <slot></slot> |
| | | </div> |
| | | <!-- </Transition> --> |
| | | </div> |
| | | </template> |
| | | <script></script> |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | |
| | | const props = defineProps({ |
| | | title: String |
| | | }) |
| | | |
| | | const show = ref(true) |
| | | const closeRotate = ref('') |
| | | |
| | | function showToggle() { |
| | | show.value = !show.value |
| | | if (show.value) { |
| | | closeRotate.value = 'rotate-enter-active close-rotate' |
| | | } else { |
| | | closeRotate.value = 'rotate-enter-active close-rotate-reverse' |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped> |
| | | .wrap { |
| | | background-image: url('@/assets/icon/bg-border-1.png'); |
| | |
| | | } |
| | | |
| | | .wrap-2 { |
| | | border: 2px solid rgba(255, 255, 255, 0.829); |
| | | border: 2px solid rgb(255, 255, 255); |
| | | border-radius: 8px; |
| | | padding: 4px; |
| | | background: linear-gradient(#14428be8, #14428b8f); |
| | | /* background: linear-gradient(#14428be8, #14428b8f); */ |
| | | background: #0034888f; |
| | | } |
| | | |
| | | .close-icon { |
| | | border: 1px solid white; |
| | | border-radius: 4px; |
| | | width: 20px; |
| | | height: 20px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | } |
| | | .close-icon:hover { |
| | | border-color: #87f8f2; |
| | | color: #87f8f2; |
| | | } |
| | | .close-rotate { |
| | | transform: rotate(90deg); |
| | | } |
| | | .close-rotate-reverse { |
| | | transform: rotate(-135deg); |
| | | } |
| | | .rotate-enter-active { |
| | | transition: transform 0.5s ease; |
| | | } |
| | | </style> |
| | | <!-- <style> |
| | | |
| | | .rotate-enter-from { |
| | | transform: rotate(135deg); |
| | | } |
| | | |
| | | .rotate-reverse-enter-active { |
| | | transition: transform 0.5s ease; |
| | | /* transition: opacity 0.5s ease; */ |
| | | } |
| | | .rotate-reverse-enter-from { |
| | | transform: rotate(-135deg); |
| | | } |
| | | </style> --> |
| | |
| | | <template> |
| | | <!-- <div class="demo-progress border-r-small"> --> |
| | | <el-row justify="end"> |
| | | <el-text type="info">{{ name }}</el-text> |
| | | <el-row justify="start"> |
| | | <el-text>{{ name }}</el-text> |
| | | </el-row> |
| | | <el-row justify="space-evenly"> |
| | | <el-col span="12"> |
| | | <div class="v-center"> |
| | | <div> |
| | | <el-text>总量</el-text> |
| | | <el-text size="small">{{ completetask + '/' + totaltask }}</el-text> |
| | | <el-progress |
| | | :width="100" |
| | | type="circle" |
| | | style="width: 300px" |
| | | type="line" |
| | | status="warning" |
| | | :text-inside="true" |
| | | :stroke-width="18" |
| | | :striped="percentFormat(completetask, totaltask) < 100" |
| | | striped-flow |
| | | :percentage="percentFormat(completetask, totaltask)" |
| | | > |
| | | <template #default="{ percentage }"> |
| | | <span class="percentage-value">{{ percentage }}%</span> |
| | | <!-- <span class="percentage-label">{{ finish + '/' + total }}</span> --> |
| | | </template> |
| | | </el-progress> |
| | | <el-text size="small">{{ completetask + '/' + totaltask }}</el-text> |
| | | </div> |
| | | </el-col> |
| | | <el-col span="12" class="flex-bottom"> |
| | | <!-- </el-col> --> |
| | | <!-- <el-col span="12" class="flex-bottom"> --> |
| | | <!-- <div>{{ name }}</div> --> |
| | | <!-- <div>{{ planTime }}</div> --> |
| | | <!-- <div>{{ userName }}</div> --> |
| | | <el-row style="gap: 40px" justify="space-between"> |
| | | <div class="v-center" v-for="item in count" :key="item.sceneType"> |
| | | <el-text size="small">{{ item.sceneType }}</el-text> |
| | | <el-row class="m-t-8"> |
| | | <div |
| | | align="center" |
| | | :style="'width: ' + 300 / count.length + 'px'" |
| | | v-for="item in count" |
| | | :key="item.sceneType" |
| | | > |
| | | <el-progress |
| | | :width="50" |
| | | :stroke-width="3" |
| | | type="circle" |
| | | status="warning" |
| | | :stroke-width="18" |
| | | status="exception" |
| | | :text-inside="true" |
| | | :striped="percentFormat(item.finish, item.total) < 100" |
| | | striped-flow |
| | | :percentage="percentFormat(item.finish, item.total)" |
| | | > |
| | | <template #default="{ percentage }"> |
| | | <span class="percentage-value-small">{{ percentage }}%</span> |
| | | </template> |
| | | </el-progress> |
| | | <el-text size="small">{{ item.finish + '/' + item.total }}</el-text> |
| | | <el-text size="small" truncated>{{ item.sceneType }}</el-text> |
| | | <!-- <el-text size="small">{{ item.finish + '/' + item.total }}</el-text> --> |
| | | <!-- <span class="percentage-value-small">{{ percentFormat(item.finish, item.total) }}%</span> --> |
| | | <!-- <div class="percentage-label-small">{{ item.sceneType }}</div> --> |
| | | <!-- <span class="percentage-label-small">{{ item.finish + '/' + item.total }} </span> --> |
| | | </div> |
| | | </el-row> |
| | | </el-col> |
| | | </el-row> |
| | | <!-- </div> --> |
| | | </template> |
| | | |
| | | <script> |
| | |
| | | if (total == 0) { |
| | | return 0 |
| | | } else { |
| | | return Math.round((finish / total) * 100) |
| | | const per = finish / total > 1 ? 1 : finish / total |
| | | return Math.round(per * 100) |
| | | } |
| | | }, |
| | | format(percentage) { |
| | | percentage === 100 ? 'Full' : `${percentage}%` |
| | | } |
| | | } |
| | | } |
| | |
| | | |
| | | .percentage-value { |
| | | display: block; |
| | | margin-top: 10px; |
| | | font-size: var(--el-font-size-base); |
| | | font-size: var(--el-font-size-small); |
| | | } |
| | | .percentage-value-small { |
| | | display: block; |
| | |
| | | |
| | | // 巡查任务 |
| | | export const useSubtaskStore = defineStore('subtask', () => { |
| | | const allTask = ref(null) |
| | | const onFetchAllTask = [] |
| | | // 总任务信息 |
| | | const taskInfo = ref(null) |
| | | // 当期所有巡查统计信息 |
| | |
| | | |
| | | function fetchTopTaskProgress(area) { |
| | | subtaskLoading.value = true |
| | | taskApi.fetchTopTaskProgress(area).then((res) => { |
| | | taskApi |
| | | .fetchTopTaskProgress(area) |
| | | .then((res) => { |
| | | if (res.data.length == 0) return |
| | | |
| | | allTask.value = res.data |
| | | if (onFetchAllTask.length > 0) { |
| | | onFetchAllTask.forEach((e) => { |
| | | e(allTask.value) |
| | | }) |
| | | } |
| | | |
| | | const data = res.data[0] |
| | | // 存储为全局数据 |
| | | setSummary(data) |
| | | subtaskLoading.value = false |
| | | // 绘制地图标记 |
| | | marks.createLabelMarks(scene_1, unref(data.subTaskSummary), (v) => { |
| | | mapStore.focusMarker = v |
| | | }) |
| | | mapUtil.setFitView() |
| | | }) |
| | | .finally(() => (subtaskLoading.value = false)) |
| | | } |
| | | |
| | | function onAllTaskRefreshed(callback) { |
| | | if (allTask.value != null) { |
| | | callback(taskInfo.value) |
| | | } |
| | | onFetchAllTask.push(callback) |
| | | } |
| | | |
| | | // 设置新的值 |
| | |
| | | // summaryMap, |
| | | subtaskLoading, |
| | | fetchTopTaskProgress, |
| | | onAllTaskRefreshed, |
| | | setSummary, |
| | | getTaskInfo, |
| | | getSummaryList, |
| | |
| | | alwaysRender: false, |
| | | showLabel: true, |
| | | showBuildingBlock: true, |
| | | mapStyle: 'amap://styles/e1e78509de64ddcd2efb4cb34c6fae2a', |
| | | // mapStyle: 'amap://styles/e1e78509de64ddcd2efb4cb34c6fae2a', |
| | | mapStyle: 'amap://styles/macaron', |
| | | features: ['bg', 'road'], |
| | | pitch: 0, // 地图俯仰角度,有效范围 0 度- 83 度 |
| | | viewMode: '3D', // 地图模式 |
| | |
| | | retina: true |
| | | }, |
| | | text: { |
| | | content: data.sceneName, |
| | | // content: data.sceneName, |
| | | direction: 'top', |
| | | offset: [0, -5], |
| | | style: { |
| | | fontSize: 12, |
| | | fontWeight: 'normal', |
| | | // fontWeight: 'normal', |
| | | fillColor: '#fff', |
| | | strokeColor: '#333', |
| | | strokeWidth: 0, |
| | | backgroundColor: '#122b54a9' |
| | | // strokeColor: '#333', |
| | | // strokeWidth: 0, |
| | | backgroundColor: '#14428b' |
| | | } |
| | | } |
| | | } |
| | |
| | | <template></template> |
| | | <script></script> |
| | |
| | | <template> |
| | | <div class="wrapper"> |
| | | <el-row> |
| | | <el-col :span="12"> |
| | | <el-col span="12"> |
| | | <!-- <TaskSummary></TaskSummary> --> |
| | | <TaskStats></TaskStats> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-col span="12"> |
| | | <WorkStream></WorkStream> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <template> |
| | | <!-- <div class="border-r-small m-h-2 p-h-4"> --> |
| | | <BaseCard> |
| | | <!-- <div> |
| | | <input type="text" v-model="inputVal" /> |
| | | <button @click="handleSend">send</button> |
| | | <button @click="handleLink">link</button> |
| | | </div> --> |
| | | <div>业务状态中控</div> |
| | | <el-scrollbar ref="scrollbarRef" :height="height"> |
| | | <BaseCard title="业务状态中控"> |
| | | <el-scrollbar ref="scrollbarRef" class="scrollbar"> |
| | | <div ref="scrollContentRef"> |
| | | <el-row justify="center" class="m-t-16"> |
| | | <el-text v-if="streams.length == 0">暂无新消息</el-text> |
| | | </el-row> |
| | | <div v-for="item in streams" :key="item.index"> |
| | | <el-text type="primary">[{{ item.time }}]: </el-text> |
| | | <el-text type="warning">[{{ item.time }}]: </el-text> |
| | | <el-text>用户</el-text> |
| | | <el-text type="warning">{{ item.userName }}</el-text> |
| | | <!-- <el-text>在</el-text> |
| | | <el-text type="success">{{ item.obj }}</el-text> --> |
| | | <el-text>{{ item.event }}</el-text> |
| | | </div> |
| | | </div> |
| | |
| | | }, 100) |
| | | } |
| | | |
| | | const inputVal = ref('') |
| | | |
| | | const handleSend = () => { |
| | | if (socket) { |
| | | socket.send(inputVal.value) |
| | | } |
| | | } |
| | | // const inputVal = ref('') |
| | | // const handleSend = () => { |
| | | // if (socket) { |
| | | // socket.send(inputVal.value) |
| | | // } |
| | | // } |
| | | |
| | | let socket |
| | | const handleLink = () => { |
| | |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // handleLink() |
| | | setInterval(() => { |
| | | streams.push({ |
| | | time: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | userName: users[parseInt(Math.random() * users.length)], |
| | | obj: objs[parseInt(Math.random() * objs.length)], |
| | | event: events[parseInt(Math.random() * events.length)] |
| | | }) |
| | | scrollToBottom() |
| | | }, 5000) |
| | | handleLink() |
| | | if (import.meta.env.DEV) { |
| | | // setInterval(() => { |
| | | // streams.push({ |
| | | // time: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | // userName: users[parseInt(Math.random() * users.length)], |
| | | // obj: objs[parseInt(Math.random() * objs.length)], |
| | | // event: events[parseInt(Math.random() * events.length)] |
| | | // }) |
| | | // streams.push({ |
| | | // time: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | // userName: users[parseInt(Math.random() * users.length)], |
| | | // obj: objs[parseInt(Math.random() * objs.length)], |
| | | // event: events[parseInt(Math.random() * events.length)] |
| | | // }) |
| | | // streams.push({ |
| | | // time: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | // userName: users[parseInt(Math.random() * users.length)], |
| | | // obj: objs[parseInt(Math.random() * objs.length)], |
| | | // event: events[parseInt(Math.random() * events.length)] |
| | | // }) |
| | | // streams.push({ |
| | | // time: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | // userName: users[parseInt(Math.random() * users.length)], |
| | | // obj: objs[parseInt(Math.random() * objs.length)], |
| | | // event: events[parseInt(Math.random() * events.length)] |
| | | // }) |
| | | // streams.push({ |
| | | // time: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | // userName: users[parseInt(Math.random() * users.length)], |
| | | // obj: objs[parseInt(Math.random() * objs.length)], |
| | | // event: events[parseInt(Math.random() * events.length)] |
| | | // }) |
| | | // streams.push({ |
| | | // time: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | // userName: users[parseInt(Math.random() * users.length)], |
| | | // obj: objs[parseInt(Math.random() * objs.length)], |
| | | // event: events[parseInt(Math.random() * events.length)] |
| | | // }) |
| | | // scrollToBottom() |
| | | // }, 60000) |
| | | } |
| | | }) |
| | | onUnmounted(() => { |
| | | socket.close() |
| | | }) |
| | | </script> |
| | | <style scoped> |
| | | .scrollbar { |
| | | height: 80px; |
| | | width: 600px; |
| | | } |
| | | </style> |
| | |
| | | const option = pieChartOption('问题分布', chartData, 1) |
| | | const series = option.series[0] |
| | | // series.radius = '50%' |
| | | series.center = ['10%', '50%'] |
| | | series.center = ['15%', '50%'] |
| | | series.label.formatter = '{b}\n{c}个({d}%)' |
| | | echart.setOption(option) |
| | | setTimeout(() => { |
| | |
| | | <template> |
| | | <el-row> |
| | | <BaseMap></BaseMap> |
| | | <el-row class="overlay-container" v-if="false"> |
| | | <el-col :span="7" class="page-right"> |
| | | <el-scrollbar height="var(--fy-body-height)"> |
| | | <el-scrollbar height="var(--fy-body-height)" class="p-events-auto"> |
| | | <ManagementView></ManagementView> |
| | | </el-scrollbar> |
| | | </el-col> |
| | |
| | | <el-scrollbar class="page-left-top"> |
| | | <VisualizationView></VisualizationView> |
| | | </el-scrollbar> |
| | | <el-scrollbar class="page-left-bottom"> |
| | | <InspectionView></InspectionView> |
| | | <el-scrollbar class="page-left-bottom p-events-auto"> |
| | | <!-- <InspectionView></InspectionView> --> |
| | | </el-scrollbar> |
| | | </el-col> |
| | | <!-- <el-col :span="7" class="page-right"> |
| | |
| | | </el-scrollbar> |
| | | </el-col> --> |
| | | </el-row> |
| | | <SupervisionVisual class="supervision-view"></SupervisionVisual> |
| | | <TaskStats class="task-stats"></TaskStats> |
| | | <WorkStream class="work-stream"></WorkStream> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { provide, ref, unref } from 'vue' |
| | | import InspectionView from '@/views/inspection/InspectionView.vue' |
| | | import ManagementView from '@/views/management/ManagementView.vue' |
| | | import StatisticView from '@/views/management/StatisticView.vue' |
| | | import VisualizationView from '@/views/visualization/VisualizationView.vue' |
| | | |
| | | import { useAreaStore } from '@/stores/area.js' |
| | | import { useSubtaskStore } from '@/stores/subtask.js' |
| | | import { useMapStore } from '@/stores/map.js' |
| | | |
| | | import taskApi from '@/api/fysp/taskApi.js' |
| | | import marks from '@/utils/map/marks.js' |
| | | import mapUtil from '@/utils/map/util.js' |
| | | import scene_1 from '@/assets/icon/scene_1.png' |
| | | |
| | | provide('mapHeight', 'calc(var(--fy-body-height) / 4 * 3)') |
| | | import InspectionView from '@/views/inspection/InspectionView.vue' |
| | | import ManagementView from '@/views/management/ManagementView.vue' |
| | | import StatisticView from '@/views/management/StatisticView.vue' |
| | | import VisualizationView from '@/views/visualization/VisualizationView.vue' |
| | | import SupervisionVisual from '@/views/visualization/SupervisionVisual.vue' |
| | | import WorkStream from '@/views/inspection/WorkStream.vue' |
| | | import TaskStats from '@/views/management/TaskStats.vue' |
| | | |
| | | // provide('mapHeight', 'calc(var(--fy-body-height) / 4 * 3)') |
| | | provide('mapHeight', 'calc(var(--fy-body-height))') |
| | | provide('excludeMapHeight', 'calc(var(--fy-body-height) / 4 * 1)') |
| | | const windowHeight = ref(window.innerHeight) |
| | | |
| | |
| | | .page-right { |
| | | /* background-color: aliceblue; */ |
| | | } |
| | | |
| | | .overlay-container { |
| | | /* background: aliceblue; */ |
| | | position: absolute; |
| | | width: 100%; |
| | | /* height: 100vh; */ |
| | | top: 0; |
| | | left: 0; |
| | | /* padding: 4px; */ |
| | | pointer-events: none; |
| | | } |
| | | |
| | | .work-stream { |
| | | position: absolute; |
| | | bottom: 0; |
| | | right: 0; |
| | | } |
| | | |
| | | .task-stats { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | } |
| | | |
| | | .supervision-view { |
| | | position: absolute; |
| | | top: 0; |
| | | left: 0; |
| | | right: 0; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <!-- <el-row> 统计管理 </el-row> --> |
| | | <ProblemTrack ref="statusRef"></ProblemTrack> |
| | | <EvaluateSummary :height="height"></EvaluateSummary> |
| | | <!-- <EvaluateSummary :height="height"></EvaluateSummary> --> |
| | | </template> |
| | | |
| | | <script> |
| | |
| | | <template> |
| | | <BaseCard> |
| | | <div>任务监控</div> |
| | | <el-scrollbar ref="scrollbarRef" :height="height"> |
| | | <BaseCard title="任务监控"> |
| | | <!-- <template #expand> --> |
| | | <!-- <SupervisionVisual></SupervisionVisual> --> |
| | | <!-- </template> --> |
| | | <el-scrollbar ref="scrollbarRef"> |
| | | <!-- <el-row justify="space-evenly"> |
| | | <el-statistic title="今日完成" :value="10"> </el-statistic> |
| | | <el-statistic title="本周完成" :value="10"> </el-statistic> |
| | |
| | | <script setup> |
| | | import { inject, ref, onMounted, computed } from 'vue' |
| | | import { unCalc } from '@/utils/css-util' |
| | | |
| | | import SelfInspection from '@/views/inspection/SelfInspection.vue' |
| | | import JointEnforcement from '@/views/inspection/JointEnforcement.vue' |
| | | import SupervisionVisual from '@/views/visualization/SupervisionVisual.vue' |
| | | |
| | | import { useSubtaskStore } from '@/stores/subtask.js' |
| | | |
| | | /** |
| | |
| | | const tasks = ref([]) |
| | | const sceneTaskMap = ref(new Map()) |
| | | |
| | | function onGetTaskInfo(tInfo) { |
| | | function onGetTaskInfo(tInfoList) { |
| | | const resList = [] |
| | | sceneTaskMap.value.clear() |
| | | const total = tInfo.totaltask |
| | | tInfo.subTaskSummary.forEach((s) => { |
| | | if (!sceneTaskMap.value.has(s.scene.type)) { |
| | | sceneTaskMap.value.set(s.scene.type, { |
| | | sceneType: s.scene.type, |
| | | total: total, |
| | | finish: 0 |
| | | |
| | | tInfoList.forEach((tInfo) => { |
| | | const _sceneTaskMap = new Map() |
| | | for (const key in tInfo.totaltaskByScene) { |
| | | const e = tInfo.totaltaskByScene[key] |
| | | _sceneTaskMap.set(key, { |
| | | sceneType: key, |
| | | total: e, |
| | | finish: tInfo.completetaskByScene[key] ? tInfo.completetaskByScene[key] : 0 |
| | | }) |
| | | } |
| | | const st = sceneTaskMap.value.get(s.scene.type) |
| | | st.finish++ |
| | | }) |
| | | // const total = tInfo.totaltask |
| | | // tInfo.subTaskSummary.forEach((s) => { |
| | | // if (!_sceneTaskMap.has(s.scene.type)) { |
| | | // _sceneTaskMap.set(s.scene.type, { |
| | | // sceneType: s.scene.type, |
| | | // total: total, |
| | | // finish: 0 |
| | | // }) |
| | | // } |
| | | // const st = _sceneTaskMap.get(s.scene.type) |
| | | // st.finish++ |
| | | // }) |
| | | |
| | | const task = { |
| | | name: tInfo.name, |
| | |
| | | count: [] |
| | | } |
| | | |
| | | for (const key of sceneTaskMap.value.keys()) { |
| | | const value = sceneTaskMap.value.get(key) |
| | | for (const key of _sceneTaskMap.keys()) { |
| | | const value = _sceneTaskMap.get(key) |
| | | task.count.push(value) |
| | | } |
| | | resList.push(task) |
| | | }) |
| | | |
| | | tasks.value = resList |
| | | } |
| | | |
| | | function cal() { |
| | | subtaskStore.getTaskInfo(onGetTaskInfo) |
| | | subtaskStore.onAllTaskRefreshed(onGetTaskInfo) |
| | | } |
| | | |
| | | onMounted(() => { |
| | |
| | | <div class="font-small">状态:{{ subtask.status }}</div> |
| | | <div class="font-small">计划:{{ $fm.formatYMD(subtask.planstarttime) }}</div> |
| | | <div v-if="subtask.status != '未执行'" class="font-small"> |
| | | <span>执行:{{ $fm.formatH(subtask.executionstarttime) }}</span> |
| | | <span>执行:{{ $fm.formatYMDH(subtask.executionstarttime) }}</span> |
| | | <span> - </span> |
| | | <span>{{ $fm.formatH(subtask.executionendtime) }}</span> |
| | | <span>{{ $fm.formatYMDH(subtask.executionendtime) }}</span> |
| | | </div> |
| | | <div class="font-small">问题:</div> |
| | | <problem-item |
| | |
| | | <template> |
| | | <el-row> |
| | | <div class="p-events-auto"> |
| | | <el-row justify="center" class="wrapper"> |
| | | <div class="p-events-auto sv-content"> |
| | | <OptionLocation |
| | | :level="3" |
| | | :width="170" |
| | |
| | | v-model="sceneType" |
| | | ></OptionSceneType> |
| | | <OptionTime v-model="time"></OptionTime> |
| | | <el-button size="small" @click="fetchTaskProgress">查询</el-button> |
| | | <el-button :loading="subtaskStore.subtaskLoading" size="small" @click="fetchTaskProgress" |
| | | >查询</el-button |
| | | > |
| | | </div> |
| | | </el-row> |
| | | </template> |
| | |
| | | } |
| | | </script> |
| | | |
| | | <style scoped></style> |
| | | <style scoped> |
| | | .wrapper { |
| | | pointer-events: none; |
| | | } |
| | | |
| | | .sv-content { |
| | | background-color: #14428be8; |
| | | border: 2px solid rgb(255, 255, 255); |
| | | border-radius: 8px; |
| | | padding: 4px; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <!-- <el-row class="wrapper"> 可视化 </el-row> --> |
| | | <BaseMap></BaseMap> |
| | | <el-row class="overlay-container" :style="height"> |
| | | <el-row class="wrapper"> |
| | | <el-col :span="10"> |
| | | <SubtaskVisual></SubtaskVisual> |
| | | </el-col> |
| | |
| | | /* padding: 4px; */ |
| | | pointer-events: none; |
| | | } |
| | | |
| | | .wrapper { |
| | | background-color: aliceblue; |
| | | } |
| | | </style> |