¶Ô±ÈÐÂÎļþ |
| | |
| | | import { $fysp } from '../index'; |
| | | |
| | | export default { |
| | | // è·åè®¾å¤ |
| | | fetchDevices(sceneId, deviceTypeId) { |
| | | const params = `?sceneId=${sceneId}&deviceTypeId=${deviceTypeId}`; |
| | | return $fysp |
| | | .get(`device${params}`) |
| | | .then((res) => res) |
| | | .then((res) => res.data); |
| | | }, |
| | | // è·å设å¤ç¶æä»¥å设å¤è¯¦æ
|
| | | fetchDeviceStatus({ deviceId, sceneId, deviceTypeId }) { |
| | | const params = `?deviceId=${deviceId}&sceneId=${sceneId}&deviceTypeId=${deviceTypeId}`; |
| | | return $fysp |
| | | .get(`device/status${params}`) |
| | | .then((res) => res) |
| | | .then((res) => res.data); |
| | | } |
| | | }; |
¶Ô±ÈÐÂÎļþ |
| | |
| | | import { $fysp } from '../index'; |
| | | |
| | | export default { |
| | | /** |
| | | * è·åå·¡æ¥ä¸çä»»æå¾ç |
| | | */ |
| | | getRoutineByStGuid(stGuid) { |
| | | const params = `?stGuid=${stGuid}`; |
| | | return $fysp.get(`mediafile/routine${params}`).then((res) => res.data); |
| | | }, |
| | | getRoutineByiGuid(iGuid) { |
| | | const params = `?iGuid=${iGuid}`; |
| | | return $fysp.get(`mediafile/routine${params}`).then((res) => res.data); |
| | | }, |
| | | updateMediaFile(mediafile) { |
| | | return $fysp.post('mediafile', mediafile).then((res) => res.data); |
| | | } |
| | | }; |
| | |
| | | i.interceptors.request.use( |
| | | function (config) { |
| | | // å¨åé请æ±ä¹ååäºä»ä¹ |
| | | console.log('==>请æ±å¼å§') |
| | | console.log(`${config.baseURL}${config.url}`) |
| | | if (config.data) { |
| | | console.log('==>è¯·æ±æ°æ®', config.data) |
| | | } |
| | | // console.log('==>请æ±å¼å§') |
| | | // console.log(`${config.baseURL}${config.url}`) |
| | | // if (config.data) { |
| | | // console.log('==>è¯·æ±æ°æ®', config.data) |
| | | // } |
| | | return config |
| | | }, |
| | | function (error) { |
| | |
| | | function (response) { |
| | | // 2xx èå´å
çç¶æç é½ä¼è§¦åè¯¥å½æ°ã |
| | | // 对ååºæ°æ®åç¹ä»ä¹ |
| | | console.log('==>请æ±å¼å§') |
| | | console.log(`${response.config.baseURL}${response.config.url}`) |
| | | if (response.config.data) { |
| | | console.log('==>è¯·æ±æ°æ®', response.config.data) |
| | | } |
| | | console.log(response) |
| | | console.log('==>请æ±ç»æ') |
| | | if (response.status == 200) { |
| | |
| | | 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'] |
| | |
| | | ElStatistic: typeof import('element-plus/es')['ElStatistic'] |
| | | ElTable: typeof import('element-plus/es')['ElTable'] |
| | | ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] |
| | | ElTabPane: typeof import('element-plus/es')['ElTabPane'] |
| | | ElTabs: typeof import('element-plus/es')['ElTabs'] |
| | | ElTag: typeof import('element-plus/es')['ElTag'] |
| | | ElText: typeof import('element-plus/es')['ElText'] |
| | | FYImageSelectDialog: typeof import('./components/FYImageSelectDialog.vue')['default'] |
| | | OptionLocation: typeof import('./components/search/OptionLocation.vue')['default'] |
| | | OptionSceneType: typeof import('./components/search/OptionSceneType.vue')['default'] |
| | | OptionTime: typeof import('./components/search/OptionTime.vue')['default'] |
| | | ProblemItem: typeof import('./components/inspection/ProblemItem.vue')['default'] |
| | | RouterLink: typeof import('vue-router')['RouterLink'] |
| | | RouterView: typeof import('vue-router')['RouterView'] |
| | | SceneDevice: typeof import('./components/inspection/SceneDevice.vue')['default'] |
| | | SubtaskExamineItem: typeof import('./components/inspection/SubtaskExamineItem.vue')['default'] |
| | | SubtaskItem: typeof import('./components/inspection/SubtaskItem.vue')['default'] |
| | | TaskItem: typeof import('./components/inspection/TaskItem.vue')['default'] |
| | |
| | | </el-row> |
| | | </el-space> |
| | | <!-- <Transition name="el-zoom-in-left"> --> |
| | | <div class="m-t-8" v-if="show"> |
| | | <div class="m-t-8" v-show="show"> |
| | | <slot></slot> |
| | | </div> |
| | | <!-- </Transition> --> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <!-- <el-dialog |
| | | :model-value="dialogVisible" |
| | | @opened="handleOpen" |
| | | @closed="handleClose" |
| | | top="5vh" |
| | | width="68%" |
| | | destroy-on-close |
| | | :close-on-press-escape="false" |
| | | > --> |
| | | <!-- <el-row justify="end"> |
| | | <el-text v-if="onContextMenu != undefined" size="small" type="info">{{ |
| | | `ï¼${contextMenuStr}ï¼` |
| | | }}</el-text> |
| | | <div v-if="!readonly"> |
| | | <el-text size="small" type="info" class="m-r-8" |
| | | >æå¤éæ©{{ maxSelect }}å¼ å¾ç</el-text |
| | | > |
| | | <el-button |
| | | size="small" |
| | | type="primary" |
| | | @click="handleSubmit" |
| | | :disabled="selectedImgUrlList.length == 0" |
| | | >ç¡®å®</el-button |
| | | > |
| | | <el-button size="small" type="primary" @click="handleCancel" |
| | | >åæ¶</el-button |
| | | > |
| | | </div> |
| | | </el-row> --> |
| | | |
| | | <div class="center"> |
| | | <el-tabs v-if="typeList.length > 0" v-model="activeId" type="card"> |
| | | <el-tab-pane |
| | | v-for="item in typeList" |
| | | :key="item.typeId" |
| | | :label="item.typeName + ' (' + typeImgMap.get(item.typeId).length + ')'" |
| | | :name="item.typeId" |
| | | > |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | <el-scrollbar :height="height"> |
| | | <div v-if="typeImgMap.get(activeId) && typeImgMap.get(activeId).length > 0" class="imgs"> |
| | | <el-image |
| | | v-loading="img.loading" |
| | | v-for="(img, i) in typeImgMap.get(activeId)" |
| | | :key="i" |
| | | :class="[img.isSelect ? 'selected' : 'noActive', 'image']" |
| | | :style="`width: ${imageWidth}px;height: ${imageWidth}px;`" |
| | | fit="cover" |
| | | :src="img.url" |
| | | :preview-src-list="readonly ? typeImgMap.get(activeId).map((v) => v.url) : []" |
| | | :initial-index="i" |
| | | @contextmenu="(e) => showContextMenu(e, i)" |
| | | @click="onSelect(img, i)" |
| | | @load="onOneImgLoadSuccess(img)" |
| | | @error="onOneImgLoadError(img)" |
| | | /> |
| | | </div> |
| | | <el-row v-else justify="space-between"> |
| | | <el-empty description="ææ è®°å½" /> |
| | | </el-row> |
| | | </el-scrollbar> |
| | | </div> |
| | | <!-- </el-dialog> --> |
| | | </template> |
| | | <script setup> |
| | | import { ref, watch, computed, onMounted, onUnmounted } from 'vue' |
| | | |
| | | const props = defineProps({ |
| | | dialogVisible: Boolean, |
| | | /** |
| | | * å¾çåç±» |
| | | * ç»æ{ typeId, typeName } |
| | | */ |
| | | typeList: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | typeImgMap: { |
| | | type: Array, |
| | | default: () => new Map() |
| | | }, |
| | | // æ¯å¦ä»¥åªè¯»ç形弿¥çå½åé¡µé¢ |
| | | readonly: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // å¾çå¯éæ°éï¼å½ä¼ å
¥æ°åæ¶ï¼ä»£è¡¨å¾çæ°é |
| | | maxSelect: { |
| | | type: Number, |
| | | default: 3 |
| | | }, |
| | | // å¾çå³é®ç¹å»äºä»¶ |
| | | onContextMenu: { |
| | | type: Function |
| | | }, |
| | | contextMenuStr: { |
| | | type: String, |
| | | default: 'å³é®ç¹å»å¾ç触åé¢å¤æä½' |
| | | }, |
| | | height: { |
| | | type: String, |
| | | default: '70vh' |
| | | }, |
| | | imageWidth: { |
| | | type: Number, |
| | | default: 240 |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits(['submit', 'cancel', 'update:dialogVisible']) |
| | | |
| | | const activeId = ref('') |
| | | |
| | | const selectedImgUrlList = ref([]) |
| | | |
| | | let loadedImgCount = ref(0) |
| | | // å è½½ç¶æ |
| | | const loading = computed(() => { |
| | | if (activeId.value == '') { |
| | | return false |
| | | } |
| | | // ä¿è¯æå¼å§æ¯å è½½ç¶æï¼ä¸åä¹ä¸å è½½ä¹å忢å±ç¤ºå è½½ç¶æ |
| | | return !(props.typeImgMap.get(activeId.value).length / 3 <= loadedImgCount.value) |
| | | }) |
| | | function onOneImgLoadError(img) { |
| | | img.loading = false |
| | | loadedImgCount.value++ |
| | | } |
| | | function onOneImgLoadSuccess(img) { |
| | | img.loading = false |
| | | loadedImgCount.value++ |
| | | } |
| | | watch( |
| | | () => activeId.value, |
| | | (nV, oV) => { |
| | | loadedImgCount.value = 0 |
| | | }, |
| | | { immediate: true } |
| | | ) |
| | | |
| | | function onSelect(img, i) { |
| | | if (props.readonly) { |
| | | return |
| | | } |
| | | const imgList = selectedImgUrlList.value |
| | | const index = imgList.indexOf(img) |
| | | if (index == -1) { |
| | | if (props.maxSelect == 1) { |
| | | img.isSelect = true |
| | | imgList.push(img) |
| | | if (imgList.length > 1) { |
| | | imgList.splice(0, 1).forEach((e) => { |
| | | e.isSelect = false |
| | | }) |
| | | } |
| | | } else if (props.maxSelect > 1) { |
| | | if (imgList.length < props.maxSelect) { |
| | | img.isSelect = true |
| | | imgList.push(img) |
| | | } |
| | | } |
| | | } else { |
| | | imgList.splice(index, 1) |
| | | img.isSelect = false |
| | | } |
| | | } |
| | | function handleOpen() { |
| | | emit('update:dialogVisible', true) |
| | | } |
| | | function handleClose() { |
| | | selectedImgUrlList.value.forEach((item) => (item.isSelect = false)) |
| | | selectedImgUrlList.value = [] |
| | | emit('update:dialogVisible', false) |
| | | } |
| | | function handleSubmit() { |
| | | emit('submit', selectedImgUrlList.value) |
| | | emit('update:dialogVisible', false) |
| | | } |
| | | |
| | | function handleCancel() { |
| | | emit('cancel') |
| | | emit('update:dialogVisible', false) |
| | | } |
| | | |
| | | // å¾çå³é®ç¹å»æ¶é´ |
| | | function showContextMenu(event, index) { |
| | | if (props.onContextMenu) { |
| | | event.preventDefault() |
| | | props.onContextMenu(event, activeId.value, index) |
| | | } |
| | | } |
| | | |
| | | watch( |
| | | () => props.typeList, |
| | | (nV, oV) => { |
| | | if (nV != oV && nV.length > 0) { |
| | | activeId.value = nV[0].typeId |
| | | } |
| | | }, |
| | | { immediate: true } |
| | | ) |
| | | </script> |
| | | <style scoped> |
| | | .center { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | .text { |
| | | padding: 20px; |
| | | } |
| | | |
| | | .main { |
| | | /* 使ç¶å
ç´ å±
ä¸ */ |
| | | /* margin: 0 auto; */ |
| | | /* width: 100%; */ |
| | | } |
| | | |
| | | .imgs { |
| | | width: 100%; |
| | | /* border-style:solid; |
| | | border-radius: 1px; */ |
| | | /* height: 100%; */ |
| | | flex-grow: 1 !important; |
| | | overflow-y: auto !important; |
| | | /* å
容çå
è¾¹è· */ |
| | | display: flex !important; |
| | | flex-wrap: wrap !important; |
| | | /* overflow: hidden; */ |
| | | } |
| | | |
| | | .image { |
| | | margin: 5px; |
| | | /* height: 250px; |
| | | width: 240px; */ |
| | | border-radius: 4px; |
| | | } |
| | | |
| | | .selected { |
| | | margin: 3px; |
| | | color: #4abe84; |
| | | box-shadow: 0 2px 7px 0 rgba(85, 110, 97, 0.35); |
| | | border: 2px solid rgba(74, 190, 132, 1); |
| | | } |
| | | |
| | | .selected:before { |
| | | content: ''; |
| | | position: absolute; |
| | | right: 0; |
| | | bottom: 0; |
| | | border: 17px solid #4abe84; |
| | | border-top-color: transparent; |
| | | border-left-color: transparent; |
| | | } |
| | | |
| | | .selected:after { |
| | | content: ''; |
| | | width: 5px; |
| | | height: 12px; |
| | | position: absolute; |
| | | right: 6px; |
| | | bottom: 6px; |
| | | border: 2px solid #fff; |
| | | border-top-color: transparent; |
| | | border-left-color: transparent; |
| | | transform: rotate(45deg); |
| | | } |
| | | |
| | | .noActive { |
| | | /* padding: 5px; */ |
| | | } |
| | | |
| | | .blurry { |
| | | filter: blur(3px); |
| | | } |
| | | .filters { |
| | | display: flex; |
| | | padding: 5px; |
| | | } |
| | | |
| | | ::v-deep .el-dialog__body { |
| | | padding: 10px calc(var(--el-dialog-padding-primary) + 10px) !important; |
| | | } |
| | | |
| | | :deep(.el-tabs__item) { |
| | | /* color: var(--el-text-color-info); */ |
| | | } |
| | | |
| | | :deep(.el-tabs__item.is-active) { |
| | | color: var(--el-color-warning); |
| | | } |
| | | |
| | | :deep(.el-tabs--card > .el-tabs__header .el-tabs__nav) { |
| | | border: 1px solid rgba(255, 255, 255, 0.541); |
| | | } |
| | | :deep(.el-tabs--card > .el-tabs__header .el-tabs__item) { |
| | | border-left: 1px solid rgba(255, 255, 255, 0.541); |
| | | } |
| | | :deep(.el-tabs--card > .el-tabs__header .el-tabs__item:first-child) { |
| | | border-left: none; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div> |
| | | <el-text tag="b" type="warning" size="small">{{ index }}. </el-text> |
| | | <el-text type="warning" size="small">{{ title }}</el-text> |
| | | <el-text tag="b" size="large">{{ index }}. </el-text> |
| | | <el-text size="large">{{ title }}</el-text> |
| | | </div> |
| | | <!-- <div> |
| | | <el-text>{{ proStatus.name }}</el-text> |
| | |
| | | <template v-for="(pic, t) in pics" :key="t"> |
| | | <template v-if="pic.path.length > 0"> |
| | | <div> |
| | | <el-text size="small" type="info">{{ pic.title }}</el-text> |
| | | <el-text size="default" type="info">{{ pic.title }}</el-text> |
| | | </div> |
| | | <el-space> |
| | | <el-image |
| | |
| | | </script> |
| | | <style scoped> |
| | | .image { |
| | | width: 60px; |
| | | height: 60px; |
| | | width: 134px; |
| | | height: 134px; |
| | | border-radius: 2px; |
| | | } |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <!-- <CompGenericWrapper type="drawer"> |
| | | <template #content> --> |
| | | <!-- é项 --> |
| | | <!-- 设å¤ç±»å --> |
| | | <el-row> |
| | | <el-col> |
| | | <el-tabs class="child_select" placeholder="设å¤ç±»å" v-model="currSelect.topDeviceTypeId"> |
| | | <el-tab-pane v-for="item in deviceTopTypes" :key="item.id" :name="item.id"> |
| | | <template #label> |
| | | <el-badge :value="item.count" :type="item.count == 0 ? 'danger' : 'primary'"> |
| | | <span class="custom-tabs-label"> |
| | | <span>{{ item.label }}</span> |
| | | </span> |
| | | </el-badge> |
| | | </template> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-col> |
| | | </el-row> |
| | | <el-collapse v-model="activeNames" style="border: 4px"> |
| | | <el-collapse-item |
| | | v-for="item in formInfo" |
| | | :key="item.id" |
| | | :name="item.id" |
| | | class="collapse-item-class" |
| | | > |
| | | <template #title> |
| | | <div style="display: flex; width: 100%; justify-content: space-between"> |
| | | <div style=""> |
| | | <el-descriptions style="" :column="3" size="small" border> |
| | | <el-descriptions-item |
| | | width="64px" |
| | | :label="currSelect.topDeviceTypeId == 0 ? 'ç«ç¹åç§°' : '设å¤åç§°'" |
| | | :span="3" |
| | | >{{ item.name || 'æ ' }}</el-descriptions-item |
| | | > |
| | | <el-descriptions-item label="ä¾åºå">{{ |
| | | item.supplier || 'æ ' |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ç»´å">{{ |
| | | item.maintainer || 'æ ' |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ç»´é¢æ¬¡"> |
| | | <el-select |
| | | v-model="item.maintainFrequency" |
| | | :disabled="isDisabled" |
| | | style="width: 150px" |
| | | > |
| | | <el-option |
| | | v-for="frequency of maintainFrequencysArray" |
| | | :key="frequency.key" |
| | | :label="frequency.value" |
| | | :value="frequency.key" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="è¿ç»´äººå">{{ |
| | | item.maintainStaff || 'æ ' |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿ç»´èç³»æ¹å¼">{{ |
| | | item.maintainTel || 'æ ' |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="åçåå·">{{ |
| | | item.brandModel || 'æ ' |
| | | }}</el-descriptions-item> |
| | | <el-descriptions-item label="è¿è¡ç¶æ"> |
| | | <el-select v-model="item.runningStatus" :disabled="isDisabled" style="width: 150px"> |
| | | <el-option |
| | | v-for="status of runStatusArray" |
| | | :key="status.key" |
| | | :label="status.value" |
| | | :value="status.key" |
| | | ></el-option> |
| | | </el-select> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="ç±»å"> |
| | | {{ item._typename || 'æ ' }} |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | </div> |
| | | |
| | | <div style="display: flex"> |
| | | <!-- <div class="sub-title">{{ item.name }}</div> --> |
| | | <!-- å¾ç --> |
| | | <div class="image-container"> |
| | | <div |
| | | class="block-div" |
| | | @click="onClickPic($event)" |
| | | v-for="(status, index) in item._statusList" |
| | | :key="index" |
| | | > |
| | | <el-image |
| | | v-if="index == 0" |
| | | fit="cover" |
| | | class="pic-style" |
| | | :src="status._picUrl" |
| | | :preview-src-list="Array.of(status._picUrl)" |
| | | /> |
| | | <span class="abstract_pic_text" v-if="index == 0">{{ |
| | | `ææ°ç¶æå¾ç ${status.dlCreateTime.slice(0, 10)}` |
| | | }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <!-- 详ç»å
容å¼å§ --> |
| | | <el-form :model="item" class="form_class"> |
| | | <el-form-item label="ç¶æ"> |
| | | <el-tabs tab-position="top"> |
| | | <el-tab-pane |
| | | v-for="(status, i) in item._statusList" |
| | | :label="status.dlCreateTime.slice(0, 10)" |
| | | :key="i" |
| | | > |
| | | <el-form :model="status" class="form-class"> |
| | | <el-form-item label="ä½ç½®" style="margin-bottom: 10px"> |
| | | {{ status.dlLocation }} |
| | | </el-form-item> |
| | | <el-form-item label="å¾ç"> |
| | | <!-- å¾ç --> |
| | | <el-space> |
| | | <div v-if="status._paths && status._paths.length > 0"> |
| | | <el-image |
| | | v-for="(path, i) in status._paths" |
| | | fit="cover" |
| | | class="pic-style" |
| | | :src="path" |
| | | :preview-src-list="Array.of(path)" |
| | | :key="i" |
| | | /> |
| | | </div> |
| | | <el-empty v-else></el-empty> |
| | | </el-space> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-form-item> |
| | | </el-form> |
| | | <!-- 详ç»å
å®¹ç»æ --> |
| | | </el-collapse-item> |
| | | </el-collapse> |
| | | <!-- ç©ºç¶æ --> |
| | | <el-empty v-if="isEmpty" /> |
| | | <!-- </template> |
| | | </CompGenericWrapper> --> |
| | | </template> |
| | | |
| | | <script> |
| | | import deviceApi from '@/api/fysp/deviceApi' |
| | | import { $fysp } from '@/api/index' |
| | | import { toLabel } from '@/enum/device/device' |
| | | export default { |
| | | components: {}, |
| | | props: { |
| | | scene: Object |
| | | }, |
| | | watch: { |
| | | // éæ©æ¹åçå¬ |
| | | currSelect: { |
| | | handler(newObj, oldObj) { |
| | | this.getList() |
| | | }, |
| | | deep: true |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | activeNames: [], |
| | | // æ§å¶æ¯å¦å±ç¤ºç©ºç¶æ |
| | | isEmpty: false, |
| | | // 详æ
æé®å¤§å° |
| | | detailSize: '22px', |
| | | // 表å详æ
ç¹å»æé®ç徿 |
| | | isDetail: false, |
| | | currSelect: { |
| | | topDeviceTypeId: 0 |
| | | }, |
| | | // æ§å¶è¡¨åæ¯å¦å¯ä»¥ç¼è¾ |
| | | isDisabled: true, |
| | | formInfo: {}, |
| | | rules: [], |
| | | // 设å¤ç±»å |
| | | deviceTopTypes: [ |
| | | { id: 0, label: 'çæ§è®¾å¤' }, |
| | | { id: 1, label: 'æ²»ç设å¤' }, |
| | | { id: 2, label: 'ç产设å¤' } |
| | | ], |
| | | // è¿è¡ç¶æ |
| | | runStatusArray: [ |
| | | { key: 0, value: 'æªèç½' }, |
| | | { key: 1, value: 'ä¸çº¿ä¸' }, |
| | | { key: 2, value: 'ä¸çº¿' }, |
| | | { key: 3, value: 'æé¤' } |
| | | ], |
| | | // ç»´æ¤é¢çç¶æ |
| | | maintainFrequencysArray: [ |
| | | { key: 1, value: 'æ¯æä¸æ¬¡' }, |
| | | { key: 2, value: 'æ¯å£åº¦ä¸æ¬¡' }, |
| | | { key: 3, value: 'æ¯å年䏿¬¡' }, |
| | | { key: 4, value: 'æ¯å¹´ä¸æ¬¡' } |
| | | ], |
| | | // ç§èµæ¹å¼ |
| | | ownershipArray: [ |
| | | { key: 0, value: 'è´ä¹°' }, |
| | | { key: 1, value: 'ç§èµ' } |
| | | ], |
| | | scene: {} |
| | | } |
| | | }, |
| | | |
| | | mounted() {}, |
| | | methods: { |
| | | // è·åå½åç±»åè®¾å¤æ°é |
| | | getTabsCount() { |
| | | this.deviceTopTypes.forEach((item) => { |
| | | deviceApi.fetchDevices(this.scene.guid, item.id).then((result) => { |
| | | item.count = result.data.length |
| | | }) |
| | | }) |
| | | }, |
| | | // è·åè¿è¡ç¶æå¯¹åºçvalue |
| | | getRunStatusValueByRunStatusKey(status) { |
| | | var runningStatusValueArray = this.runStatusArray.filter((runStatus) => { |
| | | return runStatus.key == status |
| | | }) |
| | | if (runningStatusValueArray.length > 0) { |
| | | return runningStatusValueArray[0].value |
| | | } |
| | | }, |
| | | // å±ç¤ºè¡¨åç详æ
çç¹å»äºä»¶ |
| | | showDetail(item) { |
| | | item._isDetail = !item._isDetail |
| | | }, |
| | | init(scene) { |
| | | // ç¶ç»ä»¶ä¸»å¨è°ç¨åå§ååç»ä»¶çæ¹æ³ |
| | | this.scene = scene |
| | | |
| | | this.getList() |
| | | this.getTabsCount() |
| | | }, |
| | | // éç½®å±ç¤ºçæ°æ® |
| | | initList() { |
| | | this.formInfo = [] |
| | | this.isEmpty = false |
| | | }, |
| | | // æ åå屿§å |
| | | convertKeys(obj) { |
| | | // å°ä¸ä¸ªjså¯¹è±¡ä¸æædiï¼wiï¼piå¼å¤´ç屿§å
¨é¨æ¹æå»æè¿äºåç¼å¹¶ä¸éæ°å为驼峰å¼å½å |
| | | const newObj = {} |
| | | for (const key in obj) { |
| | | let newKey = key |
| | | if (key.startsWith('di')) { |
| | | newKey = key.substring(2) |
| | | } else if (key.startsWith('wi')) { |
| | | newKey = key.substring(2) |
| | | } else if (key.startsWith('pi')) { |
| | | newKey = key.substring(2) |
| | | } |
| | | newKey = newKey.charAt(0).toLowerCase() + newKey.slice(1) |
| | | newObj[newKey] = obj[key] |
| | | } |
| | | return newObj |
| | | }, |
| | | // æ°å¢å段 |
| | | initFormData(data) { |
| | | data._isDetail = false |
| | | }, |
| | | getList() { |
| | | deviceApi.fetchDevices(this.scene.guid, this.currSelect.topDeviceTypeId).then((result) => { |
| | | this.initList() |
| | | if (result.data == null || result.data.length <= 0) { |
| | | this.isEmpty = true |
| | | return |
| | | } |
| | | // æ åå屿§å |
| | | for (let index = 0; index < result.data.length; index++) { |
| | | var element = this.convertKeys(result.data[index]) |
| | | this.initFormData(element) |
| | | // è·å设å¤ç¶æä¿¡æ¯ |
| | | let data = { |
| | | deviceId: element.id, |
| | | sceneId: element.sceneGuid, |
| | | deviceTypeId: this.currSelect.topDeviceTypeId |
| | | } |
| | | deviceApi.fetchDeviceStatus(data).then((status) => { |
| | | var statusData = status.data |
| | | var imgPaths = [] |
| | | if (statusData) { |
| | | if (statusData.length == 0) { |
| | | this.formInfo.push(element) |
| | | return |
| | | } |
| | | element = this.convertKeys(result.data[index]) |
| | | element = this.setDeviceType(element) |
| | | element._picUrls = imgPaths |
| | | for (let index = 0; index < statusData.length; index++) { |
| | | const statusItem = statusData[index] |
| | | // 设å¤å¯¹è±¡æ·»å ä¸ä¸ªå±æ§åè¡¨å±æ§ç¨æ¥ä¿å设å¤ç¶æ |
| | | this.saveStatus(element, statusItem) |
| | | element.dlLocation = statusItem.dlLocation |
| | | this.formInfo.push(element) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | setDeviceType(element) { |
| | | var type = [] |
| | | type = toLabel(element.sceneTypeId, this.currSelect.topDeviceTypeId, [ |
| | | element.typeId, |
| | | element.subtypeId |
| | | ]) |
| | | element._typename = type.join('-') |
| | | return element |
| | | }, |
| | | // ä¿åç¶æä¿¡æ¯ |
| | | saveStatus(device, status) { |
| | | var _picUrl = $fysp.imgUrl + status.dlPicUrl |
| | | status._picUrl = _picUrl |
| | | status._paths = _picUrl.split(';') |
| | | device._picUrls.push(_picUrl) |
| | | if ('_statusList' in device) { |
| | | device._statusList.push(status) |
| | | } else { |
| | | device._statusList = Array.of(status) |
| | | } |
| | | // æåº |
| | | device._statusList.sort(function (x, y) { |
| | | return new Date(x.dlCreateTime) - new Date(y.dlCreateTime) // éåºï¼ååºååä¹ |
| | | }) |
| | | }, |
| | | submit() {}, |
| | | cancel() {}, |
| | | modifyObjectKeys(obj) { |
| | | const newObj = {} |
| | | for (const key in obj) { |
| | | // è·³è¿ä»¥ 'dl' æ '_' å¼å¤´ç屿§ |
| | | if (key.startsWith('dl') || key.startsWith('_')) { |
| | | newObj[key] = obj[key] |
| | | continue |
| | | } |
| | | // æ ¹æ® topDeviceTypeId æ·»å åç¼ |
| | | let prefix = '' |
| | | switch (this.currSelect.topDeviceTypeId) { |
| | | case 0: |
| | | prefix = 'di' |
| | | break |
| | | case 1: |
| | | prefix = 'pi' |
| | | break |
| | | case 2: |
| | | prefix = 'wi' |
| | | break |
| | | default: |
| | | // 妿 topDeviceTypeId 䏿¯ 0, 1, æ 2ï¼ä¸æ·»å åç¼ |
| | | newObj[key] = obj[key] |
| | | continue |
| | | } |
| | | |
| | | // æ·»å åç¼å¹¶è½¬æ¢ä¸ºé©¼å³°å¼å½å |
| | | const newKey = `${prefix}${key.charAt(0).toUpperCase() + key.slice(1)}` |
| | | newObj[newKey] = obj[key] |
| | | } |
| | | return newObj |
| | | }, |
| | | // çææ¥å£åæ° |
| | | generateQuery(obj) { |
| | | // éè¦æ ¹æ®åºæ¯ç±»åç¡®å®æ¥å£åæ°ç屿§å |
| | | var query = this.modifyObjectKeys(obj) |
| | | return query |
| | | }, |
| | | onClickPic(e, item) { |
| | | e.stopPropagation() |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .image-container { |
| | | justify-content: flex-end; |
| | | display: flex; |
| | | /* width: 300px; */ |
| | | /* flex-direction: row-reverse; */ |
| | | /* height: 225px; */ |
| | | /* overflow: hidden; ç¡®ä¿å¾çä¸ä¼è¶
åºå®¹å¨ */ |
| | | } |
| | | .pic-style { |
| | | width: 150px; |
| | | height: 150px; |
| | | border-radius: 4px; |
| | | } |
| | | .card-style { |
| | | height: 400px; |
| | | margin-bottom: 10px; |
| | | border-color: rgba(0, 0, 0, 0.308); |
| | | } |
| | | .centerDiv { |
| | | text-align: center; /* æ°´å¹³å±
ä¸ */ |
| | | } |
| | | .dot { |
| | | position: absolute; |
| | | top: 0; |
| | | right: 0; |
| | | width: 10px; |
| | | height: 10px; |
| | | background-color: #f56c6c; |
| | | border-radius: 50%; |
| | | } |
| | | .abstract_main { |
| | | width: 98%; |
| | | } |
| | | .abstract_main_item { |
| | | display: flex; |
| | | flex-direction: column; |
| | | margin-right: 50px; |
| | | margin-top: 10px; |
| | | /* width: 20%; */ |
| | | } |
| | | .abstract_other_item { |
| | | /* display: flex; |
| | | flex-direction: column; */ |
| | | /* margin-left: 50px; */ |
| | | /* margin-top: 10px; |
| | | width: 100vh; */ |
| | | } |
| | | .abstract_main_item_inner { |
| | | display: flex; |
| | | justify-content: center; |
| | | } |
| | | .abstract_other_item_inner { |
| | | margin-left: 10px; |
| | | display: flex; |
| | | } |
| | | .abstract_main_title { |
| | | /* margin-left: -400px; */ |
| | | color: #303133; |
| | | font-size: 16px; |
| | | } |
| | | .abstract_main_title { |
| | | color: #606266; |
| | | font-size: 13px; |
| | | margin-top: 10px; |
| | | } |
| | | .abstract_other_title { |
| | | color: #606266; |
| | | font-size: 13px; |
| | | margin-top: 45px; |
| | | } |
| | | .abstract_main_text { |
| | | color: #303133; |
| | | font-size: 17px; |
| | | margin-top: 5px; |
| | | } |
| | | .abstract_pic_text { |
| | | display: block; |
| | | color: var(--el-text-color-secondary); |
| | | font-size: 14px; |
| | | /* margin-top: 20px; */ |
| | | } |
| | | .block-div { |
| | | display: block; |
| | | } |
| | | .form_class { |
| | | /* margin-left: 10px; */ |
| | | } |
| | | |
| | | .el-collapse { |
| | | /* æå 颿¿æå æ¶çé«åº¦ */ |
| | | --el-collapse-header-height: auto; |
| | | } |
| | | .el-collapse-item__header { |
| | | width: 100%; |
| | | } |
| | | .form-class { |
| | | width: 50vw; |
| | | } |
| | | .form-item-class { |
| | | margin-bottom: 10px; |
| | | } |
| | | .sub-title { |
| | | font-size: var(--el-font-size-large); |
| | | margin-bottom: 30px; |
| | | margin-left: 20px; |
| | | } |
| | | .collapse-item-class { |
| | | height: 100%; |
| | | border: 5px; |
| | | } |
| | | |
| | | ::-webkit-scrollbar { |
| | | height: 0; |
| | | } |
| | | </style> |
| | |
| | | <template> |
| | | <div v-if="value"> |
| | | <el-row justify="start"> |
| | | <el-text>{{ value.name }}</el-text> |
| | | <div v-if="value" class="wrapper"> |
| | | <el-row justify="center"> |
| | | <el-text size="large">{{ value.districtName }}</el-text> |
| | | <!-- <el-tag type="info">{{ value.districtName }}</el-tag> --> |
| | | </el-row> |
| | | <div> |
| | | <el-text>æ»é</el-text> |
| | | <el-text v-if="value._totaltask > 0" size="default">{{ |
| | | value._completetask + '/' + value._totaltask |
| | | }}</el-text> |
| | | <el-text v-else size="default">{{ value.completetask + '/' + value.totaltask }}</el-text> |
| | | <div class="text_title">宿½è¿åº¦</div> |
| | | <template v-if="value._totaltask > 0"> |
| | | <el-space> |
| | | <!-- <el-text size="default">{{ value._completetask + '/' + value._totaltask }}</el-text> --> |
| | | <el-text>æ»è®¡</el-text> |
| | | <el-progress |
| | | style="width: 300px" |
| | | style="width: 350px" |
| | | type="line" |
| | | status="warning" |
| | | :text-inside="true" |
| | | :stroke-width="18" |
| | | :stroke-width="22" |
| | | :striped="percentFormat(value._completetask, value._totaltask) < 100" |
| | | striped-flow |
| | | :percentage="percentFormat(value._completetask, value._totaltask)" |
| | | > |
| | | <template #default="{ percentage }"> |
| | | <span class="percentage-value">{{ |
| | | `${value._completetask}/${value._totaltask} (${percentage}%)` |
| | | }}</span> |
| | | </template> |
| | | </el-progress> |
| | | </el-space> |
| | | </template> |
| | | <template v-else> |
| | | <el-space> |
| | | <!-- <el-text size="default">{{ value.completetask + '/' + value.totaltask }}</el-text> --> |
| | | <el-text>æ»è®¡</el-text> |
| | | <el-progress |
| | | style="width: 350px" |
| | | type="line" |
| | | status="warning" |
| | | :text-inside="true" |
| | | :stroke-width="22" |
| | | :striped="percentFormat(value.completetask, value.totaltask) < 100" |
| | | striped-flow |
| | | :percentage="percentFormat(value.completetask, value.totaltask)" |
| | | > |
| | | <template #default="{ percentage }"> |
| | | <span class="percentage-value">{{ percentage }}%</span> |
| | | <span class="percentage-value">{{ |
| | | `${value.completetask}/${value.totaltask} (${percentage}%)` |
| | | }}</span> |
| | | </template> |
| | | </el-progress> |
| | | </el-space> |
| | | </template> |
| | | </div> |
| | | <!-- </el-col> --> |
| | | <!-- <el-col span="12" class="flex-bottom"> --> |
| | | <!-- <div>{{ name }}</div> --> |
| | | <!-- <div>{{ planTime }}</div> --> |
| | | <!-- <div>{{ userName }}</div> --> |
| | | <el-row class="m-t-8"> |
| | | <div |
| | | align="center" |
| | | :style="'width: ' + 300 / value.count.length + 'px'" |
| | | v-for="item in value.count" |
| | | :key="item.sceneType" |
| | | > |
| | | <!-- :style="'width: ' + 300 / value.count.length + 'px'" --> |
| | | <!-- <el-row class="m-t-8"> --> |
| | | <div v-for="item in value.count" :key="item.sceneType"> |
| | | <el-space v-if="item.finish > 0"> |
| | | <el-text size="default" truncated>{{ item.sceneType }}</el-text> |
| | | <el-progress |
| | | :stroke-width="18" |
| | | :style="'width:' + width" |
| | | :stroke-width="16" |
| | | status="exception" |
| | | :text-inside="true" |
| | | :striped="percentFormat(item.finish, item.total) < 100" |
| | |
| | | :percentage="percentFormat(item.finish, item.total)" |
| | | > |
| | | <template #default="{ percentage }"> |
| | | <span class="percentage-value-small">{{ percentage }}%</span> |
| | | <span class="percentage-value-small">{{ |
| | | `${item.finish}/${item.total} (${percentage}%)` |
| | | }}</span> |
| | | </template> |
| | | </el-progress> |
| | | <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> --> |
| | | </el-space> |
| | | </div> |
| | | </el-row> |
| | | <div> |
| | | <div class="text_title">æ¥ç¨è¿åº¦</div> |
| | | <el-space> |
| | | <el-text style="color: transparent;">æ¥ç¨</el-text> |
| | | <el-progress |
| | | style="width: 350px" |
| | | type="line" |
| | | color="#00b487" |
| | | :text-inside="true" |
| | | :stroke-width="22" |
| | | :percentage="percentFormat(date, dayCount)" |
| | | > |
| | | <template #default="{ percentage }"> |
| | | <span class="percentage-value">{{ `${dateStr} (${percentage}%)` }}</span> |
| | | </template> |
| | | </el-progress> |
| | | </el-space> |
| | | </div> |
| | | <!-- </el-row> --> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | <script setup> |
| | | import { ref, computed } from 'vue' |
| | | import { useAreaStore } from '@/stores/area.js' |
| | | import dayjs from 'dayjs' |
| | | |
| | | /** |
| | | * å·¡æ¥ä»»å¡åºåç»è®¡ä¿¡æ¯ |
| | | */ |
| | | export default { |
| | | props: { |
| | | // name: String, |
| | | // province: String, |
| | | // district: String, |
| | | // planTime: String, |
| | | // startTime: String, |
| | | // endTime: String, |
| | | // userName: String, |
| | | // status: String, |
| | | // totaltask: Number, |
| | | // completetask: Number, |
| | | // count: Array, |
| | | const areaStore = useAreaStore() |
| | | |
| | | const props = defineProps({ |
| | | value: Object |
| | | }, |
| | | data() { |
| | | return {} |
| | | }, |
| | | watch: {}, |
| | | computed: { |
| | | // total() { |
| | | // let t = 0 |
| | | // this.count.forEach((c) => { |
| | | // t += c.total |
| | | // }) |
| | | // return t |
| | | // }, |
| | | // finish() { |
| | | // let t = 0 |
| | | // this.count.forEach((c) => { |
| | | // t += c.finish |
| | | // }) |
| | | // return t |
| | | // } |
| | | }, |
| | | methods: { |
| | | percentFormat(finish, total) { |
| | | }) |
| | | |
| | | const width = ref('300px') |
| | | |
| | | const dayCount = computed(() => dayjs(areaStore.area.endtime).daysInMonth()) |
| | | const date = computed(() => { |
| | | const today = dayjs() |
| | | const planEndTime = dayjs(areaStore.area.endtime) |
| | | if (today.isBefore(planEndTime)) { |
| | | return today.date() |
| | | } else { |
| | | return planEndTime.daysInMonth() |
| | | } |
| | | }) |
| | | const dateStr = computed(()=>{ |
| | | const today = dayjs() |
| | | const planEndTime = dayjs(areaStore.area.endtime) |
| | | if (today.isBefore(planEndTime)) { |
| | | return today.format('MMæDDæ¥') |
| | | } else { |
| | | return today.format('MMæDDæ¥') |
| | | } |
| | | }) |
| | | |
| | | function percentFormat(finish, total) { |
| | | if (total == 0) { |
| | | return 0 |
| | | } else { |
| | | const per = finish / total > 1 ? 1 : finish / total |
| | | return Math.round(per * 100) |
| | | } |
| | | }, |
| | | format(percentage) { |
| | | } |
| | | function format(percentage) { |
| | | percentage === 100 ? 'Full' : `${percentage}%` |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | |
| | | .wrapper { |
| | | border: var(--el-border); |
| | | border-radius: var(--el-border-radius-base); |
| | | box-shadow: var(--el-box-shadow-lighter); |
| | | background-color: rgba(161, 161, 161, 0.068); |
| | | padding: 8px 8px; |
| | | } |
| | | |
| | | .text_title { |
| | | border-left: 6px solid rgb(49, 221, 6); |
| | | border-bottom: 1px solid rgb(49, 221, 6); |
| | | padding: 0px 4px 0px 4px; |
| | | width: 100px; |
| | | font-size: 15px; |
| | | margin-bottom: 4px; |
| | | /* color: #00b487; */ |
| | | } |
| | | |
| | | .flex-bottom { |
| | |
| | | /* margin-top: 10px; */ |
| | | font-size: var(--el-font-size-small); |
| | | } |
| | | :deep(.el-progress-bar__outer) { |
| | | background-color: rgba(211, 211, 211, 0.411); |
| | | } |
| | | </style> |
| | |
| | | import * as ElementPlusIconsVue from '@element-plus/icons-vue' |
| | | import 'element-plus/theme-chalk/src/dark/css-vars.scss' |
| | | |
| | | import 'element-plus/theme-chalk/src/overlay.scss'; |
| | | import 'element-plus/theme-chalk/src/message.scss'; |
| | | import 'element-plus/theme-chalk/src/message-box.scss'; |
| | | import 'element-plus/theme-chalk/src/notification.scss'; |
| | | |
| | | import App from './App.vue' |
| | | import router from './router' |
| | | import timeUtil from './utils/time-util' |
| | |
| | | <template> |
| | | <BaseMap></BaseMap> |
| | | <el-row class="overlay-container" v-if="true"> |
| | | <el-col :span="17"> |
| | | <el-scrollbar class="page-left-top"> |
| | | <el-col :span="7" class="page-right"> |
| | | <el-scrollbar height="var(--fy-body-height)" class="p-events-auto" style="width: 450px"> |
| | | <TaskStats></TaskStats> |
| | | <TaskSummary></TaskSummary> |
| | | </el-scrollbar> |
| | | </el-col> |
| | | <el-col :span="10"> |
| | | <el-row justify="end"> |
| | | <SubtaskVisual class="subtask-visual"></SubtaskVisual> |
| | | </el-row> |
| | | <!-- <el-scrollbar class="page-left-top"> --> |
| | | <!-- <VisualizationView></VisualizationView> --> |
| | | </el-scrollbar> |
| | | <el-scrollbar class="page-left-bottom p-events-auto"> |
| | | <!-- <InspectionView></InspectionView> --> |
| | | </el-scrollbar> |
| | | <!-- </el-scrollbar> --> |
| | | <!-- <el-scrollbar class="page-left-bottom p-events-auto"> |
| | | <InspectionView></InspectionView> |
| | | </el-scrollbar> --> |
| | | </el-col> |
| | | <el-col :span="7" class="page-right"> |
| | | <el-scrollbar height="var(--fy-body-height)" class="p-events-auto"> |
| | | <ManagementView></ManagementView> |
| | | </el-scrollbar> |
| | | </el-col> |
| | | <!-- <el-col :span="7" class="page-right"> |
| | | <el-scrollbar height="var(--fy-body-height)"> |
| | | <StatisticView></StatisticView> |
| | | </el-scrollbar> |
| | | </el-col> --> |
| | | </el-row> |
| | | <SupervisionVisual class="supervision-view"></SupervisionVisual> |
| | | <TaskStats class="task-stats"></TaskStats> |
| | | |
| | | <WorkStream class="work-stream"></WorkStream> |
| | | <!-- <ProblemTrack class="problem-track"></ProblemTrack> --> |
| | | </template> |
| | |
| | | import SupervisionVisual from '@/views/visualization/SupervisionVisual.vue' |
| | | import WorkStream from '@/views/inspection/WorkStream.vue' |
| | | import TaskStats from '@/views/management/TaskStats.vue' |
| | | import TaskSummary from '@/views/management/TaskSummary.vue' |
| | | import SubtaskVisual from '@/views/visualization/SubtaskVisual.vue' |
| | | |
| | | // provide('mapHeight', 'calc(var(--fy-body-height) / 4 * 3)') |
| | | provide('mapHeight', 'calc(var(--fy-body-height))') |
| | |
| | | pName: '䏿µ·å¸', |
| | | cCode: '3100', |
| | | cName: '䏿µ·å¸', |
| | | dCode: '310106', |
| | | dName: 'éå®åº' |
| | | dCode: '310104', |
| | | dName: '徿±åº' |
| | | }) |
| | | areaStore.setSceneType({ label: 'å·¥å°', value: '1' }) |
| | | areaStore.setSceneType({ label: 'å
¨é¨åºæ¯', value: null }) |
| | | |
| | | // è·åæ¬æçææå·¡æ¥ç»è®¡ä¿¡æ¯ |
| | | subtaskStore.fetchTopTaskProgress(areaStore.area) |
| | |
| | | } |
| | | .problem-track { |
| | | } |
| | | |
| | | .subtask-visual { |
| | | margin-top: 50px; |
| | | /* min-width: 450px; |
| | | max-width: 600px; */ |
| | | } |
| | | </style> |
| | |
| | | </el-row> --> |
| | | <!-- <el-row> --> |
| | | <TaskItem v-for="item in tasks" :key="item.guid" :value="item"></TaskItem> |
| | | <TaskSummary></TaskSummary> |
| | | <!-- <TaskSummary></TaskSummary> --> |
| | | <!-- </el-row> --> |
| | | |
| | | <!-- <el-row> |
| | |
| | | } |
| | | |
| | | const task = { |
| | | name: tInfo.name, |
| | | province: tInfo.provinceName, |
| | | district: tInfo.districtName, |
| | | totaltask: tInfo.totaltask, |
| | | completetask: tInfo.completetask, |
| | | // name: tInfo.name, |
| | | // province: tInfo.provinceName, |
| | | // district: tInfo.districtName, |
| | | // totaltask: tInfo.totaltask, |
| | | // completetask: tInfo.completetask, |
| | | ...tInfo, |
| | | _totaltask, |
| | | _completetask, |
| | | count: [] |
| | |
| | | <template> |
| | | <el-row> å·¡æ¥æ±æ» </el-row> |
| | | <BaseCard title="å·¡æ¥æ±æ»"> |
| | | <!-- <el-row> å·¡æ¥æ±æ» </el-row> --> |
| | | <el-segmented v-model="value" :options="options" block /> |
| | | <div v-show="value == '仿¥æ±æ»'"> |
| | | <div ref="echart1" class="bar-chart"></div> |
| | |
| | | <div v-show="value == 'ä¸å¨æ±æ»'"> |
| | | <div ref="echart3" class="bar-chart"></div> |
| | | </div> |
| | | <div v-show="value == 'æåº¦æ±æ»'"> |
| | | <div v-show="value == 'æ¬ææ±æ»'"> |
| | | <div ref="echart4" class="bar-chart"></div> |
| | | </div> |
| | | </BaseCard> |
| | | </template> |
| | | |
| | | <script setup> |
| | |
| | | |
| | | const emits = defineEmits(['update:height']) |
| | | |
| | | const value = ref('æåº¦æ±æ»') |
| | | const options = ['仿¥æ±æ»', 'æ¬å¨æ±æ»', 'ä¸å¨æ±æ»', 'æåº¦æ±æ»'] |
| | | const value = ref('æ¬ææ±æ»') |
| | | const options = ['仿¥æ±æ»', 'æ¬å¨æ±æ»', 'ä¸å¨æ±æ»', 'æ¬ææ±æ»'] |
| | | |
| | | const subtaskToday = ref([]) |
| | | const subtaskWeek = ref([]) |
| | |
| | | yAxis: [ |
| | | { |
| | | type: 'category', |
| | | data: ['æ´æ¹æ°', 'é®é¢æ°', '宿é'] |
| | | data: ['夿 ¸æ°', 'æ´æ¹æ°', 'é®é¢æ°', '宿é'] |
| | | } |
| | | ], |
| | | series: series |
| | |
| | | const totalCount = { |
| | | numByTotal: {}, |
| | | numByDistrict: {}, |
| | | numByStreet: {}, |
| | | numByScene: {}, |
| | | numByUser: {} |
| | | } |
| | |
| | | const proCount = { |
| | | numByTotal: {}, |
| | | numByDistrict: {}, |
| | | numByStreet: {}, |
| | | numByScene: {}, |
| | | numByUser: {} |
| | | } |
| | |
| | | const changeCount = { |
| | | numByTotal: {}, |
| | | numByDistrict: {}, |
| | | numByStreet: {}, |
| | | numByScene: {}, |
| | | numByUser: {} |
| | | } |
| | | // // æç¨æ·åç±» |
| | | // const userCount = { |
| | | // numByTotal: {}, |
| | | // numByDistrict: {}, |
| | | // numByScene: {}, |
| | | // numByUser: {} |
| | | // } |
| | | // 夿 ¸æ° |
| | | const reCheckCount = { |
| | | numByTotal: {}, |
| | | numByDistrict: {}, |
| | | numByStreet: {}, |
| | | numByScene: {}, |
| | | numByUser: {} |
| | | } |
| | | const historySceneId = [] |
| | | |
| | | dataList.forEach((d) => { |
| | | const tName = 'æ»è®¡' |
| | | const dName = d.subtask.districtname |
| | | const townName = d.scene.townname |
| | | const sType = d.sceneType |
| | | const uName = d.subtask.deployerrealname |
| | | |
| | |
| | | // ä»»å¡éååºå¿ |
| | | totalCount.numByDistrict[dName] = totalCount.numByDistrict[dName] |
| | | ? totalCount.numByDistrict[dName] + 1 |
| | | : 1 |
| | | // ä»»å¡éåè¡é |
| | | totalCount.numByStreet[townName] = totalCount.numByStreet[townName] |
| | | ? totalCount.numByStreet[townName] + 1 |
| | | : 1 |
| | | // ä»»å¡éååºæ¯ç±»å |
| | | totalCount.numByScene[sType] = totalCount.numByScene[sType] |
| | |
| | | // é®é¢æ°ååºå¿ |
| | | proCount.numByDistrict[dName] = proCount.numByDistrict[dName] |
| | | ? proCount.numByDistrict[dName] + d.proCheckedNum |
| | | : d.proCheckedNum |
| | | // é®é¢æ°åè¡é |
| | | proCount.numByStreet[townName] = proCount.numByStreet[townName] |
| | | ? proCount.numByStreet[townName] + d.proCheckedNum |
| | | : d.proCheckedNum |
| | | // é®é¢æ°ååºæ¯ç±»å |
| | | proCount.numByScene[sType] = proCount.numByScene[sType] |
| | |
| | | changeCount.numByDistrict[dName] = changeCount.numByDistrict[dName] |
| | | ? changeCount.numByDistrict[dName] + d.changeCheckedNum |
| | | : d.changeCheckedNum |
| | | // æ´æ¹æ°åè¡é |
| | | changeCount.numByStreet[townName] = changeCount.numByStreet[townName] |
| | | ? changeCount.numByStreet[townName] + d.changeCheckedNum |
| | | : d.changeCheckedNum |
| | | // æ´æ¹æ°ååºæ¯ç±»å |
| | | changeCount.numByScene[sType] = changeCount.numByScene[sType] |
| | | ? changeCount.numByScene[sType] + d.changeCheckedNum |
| | |
| | | changeCount.numByUser[uName] = changeCount.numByUser[uName] |
| | | ? changeCount.numByUser[uName] + d.changeCheckedNum |
| | | : d.changeCheckedNum |
| | | |
| | | if (historySceneId.length == 0) { |
| | | reCheckCount.numByTotal[tName] = 0 |
| | | reCheckCount.numByDistrict[dName] = 0 |
| | | reCheckCount.numByScene[sType] = 0 |
| | | reCheckCount.numByUser[uName] = 0 |
| | | } else if (historySceneId.indexOf(d.sceneId) != -1) { |
| | | // 夿 ¸æ°æ»è®¡ |
| | | reCheckCount.numByTotal[tName] = reCheckCount.numByTotal[tName] |
| | | ? reCheckCount.numByTotal[tName] + 1 |
| | | : 1 |
| | | // 夿 ¸æ°ååºå¿ |
| | | reCheckCount.numByDistrict[dName] = reCheckCount.numByDistrict[dName] |
| | | ? reCheckCount.numByDistrict[dName] + 1 |
| | | : 1 |
| | | // 夿 ¸æ°åè¡é |
| | | reCheckCount.numByStreet[townName] = reCheckCount.numByStreet[townName] |
| | | ? reCheckCount.numByStreet[townName] + 1 |
| | | : 1 |
| | | // 夿 ¸æ°ååºæ¯ç±»å |
| | | reCheckCount.numByScene[sType] = reCheckCount.numByScene[sType] |
| | | ? reCheckCount.numByScene[sType] + 1 |
| | | : 1 |
| | | // 夿 ¸æ°åç¨æ· |
| | | reCheckCount.numByUser[uName] = reCheckCount.numByUser[uName] |
| | | ? reCheckCount.numByUser[uName] + 1 |
| | | : 1 |
| | | } else { |
| | | historySceneId.push(d.sceneId) |
| | | } |
| | | }) |
| | | |
| | | let series = {} |
| | | totalCount |
| | | proCount |
| | | changeCount |
| | | parseSeries(series, reCheckCount) |
| | | parseSeries(series, changeCount) |
| | | parseSeries(series, proCount) |
| | | parseSeries(series, totalCount) |
| | |
| | | label: { |
| | | show: true, |
| | | formatter: '{c}' |
| | | // position: [0, 10], |
| | | // position: 'top', |
| | | }, |
| | | data: [value] |
| | | } |
| | | } |
| | | } |
| | | // for (const key in c.numByStreet) { |
| | | // const value = c.numByStreet[key] |
| | | // if (series[key]) { |
| | | // series[key].data.push(value) |
| | | // } else { |
| | | // series[key] = { |
| | | // name: `è¡éï¼${key}`, |
| | | // type: 'bar', |
| | | // stack: 'street', |
| | | // emphasis: { |
| | | // focus: 'series' |
| | | // }, |
| | | // label: { |
| | | // show: true, |
| | | // formatter: '{c}' |
| | | // // position: 'top', |
| | | // }, |
| | | // data: [value] |
| | | // } |
| | | // } |
| | | // } |
| | | for (const key in c.numByScene) { |
| | | const value = c.numByScene[key] |
| | | if (series[key]) { |
| | |
| | | <template> |
| | | <el-scrollbar v-if="mapStore.focusMarker" :height="mapHeight"> |
| | | <el-card class="p-events-auto wrapper"> |
| | | <el-scrollbar v-if="mapStore.focusMarker" class="wrapper"> |
| | | <el-card class="p-events-auto"> |
| | | <el-row justify="space-between"> |
| | | <div class="font-small">{{ scene.name }}</div> |
| | | <!-- <div class="font-small">{{ scene.name }}</div> --> |
| | | <el-text size="large">{{ scene.name }}</el-text> |
| | | <el-button icon="Close" circle @click="mapStore.focusMarker = undefined"></el-button> |
| | | </el-row> |
| | | <el-row justify="space-between"> |
| | | <el-text size="small">{{ 'å°åï¼' + scene.location }}</el-text> |
| | | </el-row> |
| | | <el-space class="m-t-8"> |
| | | <el-tag type="info" effect="plain"> |
| | | {{ scene.districtname + scene.townname }} |
| | | </el-tag> |
| | | <el-tag type="info" effect="plain"> |
| | | {{ scene.type }} |
| | | </el-tag> |
| | | </el-space> |
| | | <el-divider></el-divider> |
| | | <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.formatYMDH(subtask.executionstarttime) }}</span> |
| | | <span> - </span> |
| | | <span>{{ $fm.formatYMDH(subtask.executionendtime) }}</span> |
| | | </div> |
| | | <div class="font-small">é®é¢ï¼</div> |
| | | <el-row justify="space-between"> |
| | | <el-col :span="8" style="text-align: center"> |
| | | <el-text>ç¶æï¼{{ subtask.status }}</el-text> |
| | | </el-col> |
| | | <el-col :span="8" style="text-align: center"> |
| | | <el-text>计åï¼{{ $fm.formatYMD(subtask.planstarttime) }}</el-text> |
| | | </el-col> |
| | | <el-col v-if="subtask.status != 'æªæ§è¡'" :span="8" style="text-align: center"> |
| | | <el-text> |
| | | <span>æ§è¡ï¼{{ $fm.formatH(subtask.executionstarttime) }}</span> |
| | | <!-- <span> - </span> |
| | | <span>{{ $fm.formatYMDH(subtask.executionendtime) }}</span> --> |
| | | </el-text> |
| | | </el-col> |
| | | </el-row> |
| | | |
| | | <el-segmented v-model="value" :options="options" block /> |
| | | <div v-show="value == 'ç°åºé®é¢'"> |
| | | <problem-item |
| | | v-for="(item, i) in problemList" |
| | | :key="item.guid" |
| | | :index="i + 1" |
| | | :problem="item" |
| | | ></problem-item> |
| | | <!-- <div v-for="item in problemList" :key="item.guid"> |
| | | {{ item.problemname }} |
| | | </div> --> |
| | | <!-- <el-timeline style="max-width: 600px"> |
| | | <el-timeline-item |
| | | v-for="(activity, index) in activities" |
| | | :key="index" |
| | | :timestamp="activity.timestamp" |
| | | :hide-timestamp="activity.running" |
| | | :type="activity.running ? 'danger' : 'success'" |
| | | :size="activity.running ? 'large' : 'normal'" |
| | | :hollow="false" |
| | | > |
| | | {{ activity.content }} |
| | | </el-timeline-item> |
| | | </el-timeline> --> |
| | | <el-empty v-if="problemList.length == 0" description="æ ç°åºé®é¢"> |
| | | <template #image> </template> |
| | | </el-empty> |
| | | </div> |
| | | <div v-show="value == 'åºæ¯å¾ç'"> |
| | | <FYImageSelectDialog |
| | | readonly |
| | | height="500px" |
| | | :imageWidth="134" |
| | | v-loading="scenePicLoading" |
| | | :typeList="scenePicTypeList" |
| | | :typeImgMap="scenePicTypeMap" |
| | | ></FYImageSelectDialog> |
| | | </div> |
| | | <div v-show="value == '设å¤è®¾æ½'"> |
| | | |
| | | </div> |
| | | </el-card> |
| | | </el-scrollbar> |
| | | </template> |
| | | |
| | | <script> |
| | | import { inject } from 'vue' |
| | | <script setup> |
| | | import { inject, ref, computed, watch } from 'vue' |
| | | import { useMapStore } from '@/stores/map.js' |
| | | import { mapStores } from 'pinia' |
| | | |
| | | import { $fysp } from '@/api/index.js' |
| | | import problemApi from '@/api/fysp/problemApi.js' |
| | | import mediafileApi from '@/api/fysp/mediafileApi.js' |
| | | import deviceApi from '@/api/fysp/deviceApi' |
| | | |
| | | /** |
| | | * å
·ä½å·¡æ¥ä»»å¡å¯è§å |
| | | * å
æ¬å°å¾å®ä½ä¿¡æ¯å±ç¤ºãå·¡æ¥ä»»å¡å
¨æµç¨å¹³éºå±ç¤º |
| | | */ |
| | | export default { |
| | | setup() { |
| | | const mapHeight = inject('mapHeight') |
| | | |
| | | const height = 'height:' + mapHeight |
| | | return { height, mapHeight } |
| | | }, |
| | | props: { |
| | | // subtask: { |
| | | // type: Object, |
| | | // default: () => { |
| | | // return { |
| | | // guid: 'SMuheEkjswioSn7A', |
| | | // name: 'ä¸ç§çææ°åæ¸¯é¡¹ç®å·¡æ¥ä¸ç§çææ°åæ¸¯é¡¹ç®å·¡æ¥', |
| | | // district: 'éå±±åº', |
| | | // planTime: '2024-06-04', |
| | | // startTime: '2024-06-04 13:31:26', |
| | | // endTime: '2024-06-04 13:33:37', |
| | | // userName: 'æ±æ£å¼º', |
| | | // status: 'å·²ç»æ', |
| | | // total: 4, |
| | | // checked: 2 |
| | | // } |
| | | // } |
| | | // } |
| | | }, |
| | | data() { |
| | | return { |
| | | // activities: [ |
| | | // { |
| | | // content: 'ä»»å¡å建', |
| | | // timestamp: '2024-06-04 08:00', |
| | | // running: false |
| | | // }, |
| | | // { |
| | | // content: 'å¼å§å·¡æ¥', |
| | | // timestamp: '2024-06-04 09:00', |
| | | // running: false |
| | | // }, |
| | | // { |
| | | // content: 'ç»æå·¡æ¥', |
| | | // timestamp: '2024-06-04 09:15', |
| | | // running: false |
| | | // }, |
| | | // { |
| | | // content: '宿é®é¢å®¡æ ¸', |
| | | // timestamp: '2024-06-04 10:15', |
| | | // running: false |
| | | // }, |
| | | // { |
| | | // content: 'é®é¢æ´æ¹ä¸...', |
| | | // timestamp: '2024-06-04 10:15', |
| | | // running: true |
| | | // } |
| | | // ] |
| | | problemList: [] |
| | | } |
| | | }, |
| | | computed: { |
| | | ...mapStores(useMapStore), |
| | | subtask() { |
| | | return this.mapStore.focusMarker ? this.mapStore.focusMarker.subtask : undefined |
| | | }, |
| | | scene() { |
| | | return this.mapStore.focusMarker ? this.mapStore.focusMarker.scene : undefined |
| | | }, |
| | | inspection() { |
| | | return this.mapStore.focusMarker ? this.mapStore.focusMarker.inspection : undefined |
| | | } |
| | | }, |
| | | watch: { |
| | | subtask(nV, oV) { |
| | | |
| | | const mapStore = useMapStore() |
| | | const subtask = computed(() => (mapStore.focusMarker ? mapStore.focusMarker.subtask : undefined)) |
| | | const scene = computed(() => (mapStore.focusMarker ? mapStore.focusMarker.scene : undefined)) |
| | | const inspection = computed(() => |
| | | mapStore.focusMarker ? mapStore.focusMarker.inspection : undefined |
| | | ) |
| | | |
| | | const value = ref('ç°åºé®é¢') |
| | | const options = ['ç°åºé®é¢', 'åºæ¯å¾ç', '设å¤è®¾æ½'] |
| | | |
| | | const problemList = ref([]) |
| | | const problemListLoading = ref(false) |
| | | |
| | | const scenePicTypeList = ref([]) |
| | | const scenePicTypeMap = ref(new Map()) |
| | | const scenePicLoading = ref(false) |
| | | |
| | | watch(subtask, (nV, oV) => { |
| | | if (nV != undefined && nV != oV) { |
| | | this.fetchProblem(nV.stguid) |
| | | fetchProblem(nV.stguid) |
| | | getRoutineByStGuid(nV.stguid) |
| | | } |
| | | }) |
| | | function fetchProblem(stguid) { |
| | | problemListLoading.value = true |
| | | problemApi |
| | | .fetchProblems(stguid) |
| | | .then((res) => { |
| | | problemList.value = res |
| | | }) |
| | | .finally(() => (problemListLoading.value = false)) |
| | | } |
| | | |
| | | // å¾çåç±» |
| | | function getRoutineByStGuid(stguid) { |
| | | scenePicLoading.value = true |
| | | mediafileApi |
| | | .getRoutineByStGuid(stguid) |
| | | .then((res) => { |
| | | let typeList = [] |
| | | let typeMap = new Map() |
| | | const data = res.data |
| | | for (const e of data) { |
| | | let img = { |
| | | url: $fysp.imgUrl + e.extension1 + e.guid + '.jpg', |
| | | data: e |
| | | } |
| | | const businesstype = e.businesstype |
| | | const businesstypeid = e.businesstypeid |
| | | if (typeList.find((item) => item.typeId == businesstypeid) != undefined) { |
| | | typeMap.get(businesstypeid).push(img) |
| | | } else { |
| | | typeList.push({ |
| | | typeId: businesstypeid, |
| | | typeName: businesstype |
| | | }) |
| | | typeMap.set(businesstypeid, [img]) |
| | | } |
| | | } |
| | | }, |
| | | methods: { |
| | | fetchProblem(stguid) { |
| | | problemApi.fetchProblems(stguid).then((res) => { |
| | | this.problemList = res |
| | | scenePicTypeList.value = typeList |
| | | scenePicTypeMap.value = typeMap |
| | | }) |
| | | .finally(() => (scenePicLoading.value = false)) |
| | | } |
| | | |
| | | function fetchDevices() { |
| | | deviceApi.fetchDevices(scene.value.guid, this.currSelect.topDeviceTypeId).then((result) => { |
| | | this.initList() |
| | | if (result.data == null || result.data.length <= 0) { |
| | | this.isEmpty = true |
| | | return |
| | | } |
| | | // æ åå屿§å |
| | | for (let index = 0; index < result.data.length; index++) { |
| | | var element = this.convertKeys(result.data[index]) |
| | | this.initFormData(element) |
| | | // è·å设å¤ç¶æä¿¡æ¯ |
| | | let data = { |
| | | deviceId: element.id, |
| | | sceneId: element.sceneGuid, |
| | | deviceTypeId: this.currSelect.topDeviceTypeId |
| | | } |
| | | deviceApi.fetchDeviceStatus(data).then((status) => { |
| | | var statusData = status.data |
| | | var imgPaths = [] |
| | | if (statusData) { |
| | | if (statusData.length == 0) { |
| | | this.formInfo.push(element) |
| | | return |
| | | } |
| | | element = this.convertKeys(result.data[index]) |
| | | element = this.setDeviceType(element) |
| | | element._picUrls = imgPaths |
| | | for (let index = 0; index < statusData.length; index++) { |
| | | const statusItem = statusData[index] |
| | | // 设å¤å¯¹è±¡æ·»å ä¸ä¸ªå±æ§åè¡¨å±æ§ç¨æ¥ä¿å设å¤ç¶æ |
| | | this.saveStatus(element, statusItem) |
| | | element.dlLocation = statusItem.dlLocation |
| | | this.formInfo.push(element) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .wrapper { |
| | | /* position: absolute; */ |
| | | top: 0; |
| | | right: 0; |
| | | /* background-color: wheat; */ |
| | | width: 450px; |
| | | max-height: 800px; |
| | | } |
| | | |
| | | .el-card { |
| | |
| | | pName: '䏿µ·å¸', |
| | | cCode: '3100', |
| | | cName: '䏿µ·å¸', |
| | | dCode: '310106', |
| | | dName: 'éå®åº' |
| | | dCode: '310104', |
| | | dName: '徿±åº' |
| | | }, |
| | | sceneType: { |
| | | label: 'å·¥å°', |
| | | value: '1' |
| | | label: 'å
¨é¨åºæ¯', |
| | | value: null |
| | | }, |
| | | time: '' |
| | | } |